Sort By Access Time and Change Time (#226)
- Add access time and change time as sort by types. This is powered by github.com/djherbis/times. - Fall back to modification time if access time and change time cannot be determined. - Add `sa` and `sc` as default bindings for sort by access time and sort by change time respectively. - Add access time and change time to info types allowing them to be displayed by the file list in the ui
This commit is contained in:
parent
d13cc79bc4
commit
9515bd73d0
@ -177,6 +177,8 @@ The following additional keybindings are provided by default:
|
||||
map sn :set sortby natural; set info
|
||||
map ss :set sortby size; set info size
|
||||
map st :set sortby time; set info time
|
||||
map sa :set sortby atime; set info atime
|
||||
map sc :set sortby ctime; set info ctime
|
||||
map gh cd ~
|
||||
|
||||
The following keybindings to applications are provided by default:
|
||||
|
17
eval.go
17
eval.go
@ -238,10 +238,6 @@ func (e *setExpr) eval(app *app, args []string) {
|
||||
case "shell":
|
||||
gOpts.shell = e.val
|
||||
case "sortby":
|
||||
if e.val != "natural" && e.val != "name" && e.val != "size" && e.val != "time" {
|
||||
app.ui.echoerr("sortby: value should either be 'natural', 'name', 'size' or 'time'")
|
||||
return
|
||||
}
|
||||
switch e.val {
|
||||
case "natural":
|
||||
gOpts.sortType.method = naturalSort
|
||||
@ -251,6 +247,13 @@ func (e *setExpr) eval(app *app, args []string) {
|
||||
gOpts.sortType.method = sizeSort
|
||||
case "time":
|
||||
gOpts.sortType.method = timeSort
|
||||
case "ctime":
|
||||
gOpts.sortType.method = ctimeSort
|
||||
case "atime":
|
||||
gOpts.sortType.method = atimeSort
|
||||
default:
|
||||
app.ui.echoerr("sortby: value should either be 'natural', 'name', 'size', 'time', 'atime' or 'ctime'")
|
||||
return
|
||||
}
|
||||
app.nav.sort()
|
||||
app.ui.sort()
|
||||
@ -281,8 +284,10 @@ func (e *setExpr) eval(app *app, args []string) {
|
||||
case "info":
|
||||
toks := strings.Split(e.val, ":")
|
||||
for _, s := range toks {
|
||||
if s != "" && s != "size" && s != "time" {
|
||||
app.ui.echoerr("info: should consist of 'size' or 'time' separated with colon")
|
||||
switch s {
|
||||
case "", "size", "time", "atime", "ctime":
|
||||
default:
|
||||
app.ui.echoerr("info: should consist of 'size', 'time', 'atime' or 'ctime' separated with colon")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
1
go.mod
1
go.mod
@ -5,4 +5,5 @@ go 1.12
|
||||
require (
|
||||
github.com/mattn/go-runewidth v0.0.4
|
||||
github.com/nsf/termbox-go v0.0.0-20190325093121-288510b9734e
|
||||
gopkg.in/djherbis/times.v1 v1.2.0
|
||||
)
|
||||
|
2
go.sum
2
go.sum
@ -2,3 +2,5 @@ github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/nsf/termbox-go v0.0.0-20190325093121-288510b9734e h1:Vbib8wJAaMEF9jusI/kMSYMr/LtRzM7+F9MJgt/nH8k=
|
||||
github.com/nsf/termbox-go v0.0.0-20190325093121-288510b9734e/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
|
||||
gopkg.in/djherbis/times.v1 v1.2.0 h1:UCvDKl1L/fmBygl2Y7hubXCnY7t4Yj46ZrBFNUipFbM=
|
||||
gopkg.in/djherbis/times.v1 v1.2.0/go.mod h1:AQlg6unIsrsCEdQYhTzERy542dz6SFdQFZFv6mUY0P8=
|
||||
|
39
nav.go
39
nav.go
@ -13,6 +13,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
times "gopkg.in/djherbis/times.v1"
|
||||
)
|
||||
|
||||
type linkState byte
|
||||
@ -25,9 +27,11 @@ const (
|
||||
|
||||
type file struct {
|
||||
os.FileInfo
|
||||
linkState linkState
|
||||
path string
|
||||
dirCount int
|
||||
linkState linkState
|
||||
path string
|
||||
dirCount int
|
||||
accessTime time.Time
|
||||
changeTime time.Time
|
||||
}
|
||||
|
||||
func readdir(path string) ([]*file, error) {
|
||||
@ -62,11 +66,24 @@ func readdir(path string) ([]*file, error) {
|
||||
}
|
||||
}
|
||||
|
||||
ts := times.Get(lstat)
|
||||
at := ts.AccessTime()
|
||||
var ct time.Time
|
||||
// from times docs: ChangeTime() panics unless HasChangeTime() is true
|
||||
if ts.HasChangeTime() {
|
||||
ct = ts.ChangeTime()
|
||||
} else {
|
||||
// fall back to ModTime if ChangeTime cannot be determined
|
||||
ct = lstat.ModTime()
|
||||
}
|
||||
|
||||
files = append(files, &file{
|
||||
FileInfo: lstat,
|
||||
linkState: linkState,
|
||||
path: fpath,
|
||||
dirCount: -1,
|
||||
FileInfo: lstat,
|
||||
linkState: linkState,
|
||||
path: fpath,
|
||||
dirCount: -1,
|
||||
accessTime: at,
|
||||
changeTime: ct,
|
||||
})
|
||||
}
|
||||
|
||||
@ -124,6 +141,14 @@ func (dir *dir) sort() {
|
||||
sort.SliceStable(dir.files, func(i, j int) bool {
|
||||
return dir.files[i].ModTime().Before(dir.files[j].ModTime())
|
||||
})
|
||||
case atimeSort:
|
||||
sort.SliceStable(dir.files, func(i, j int) bool {
|
||||
return dir.files[i].accessTime.Before(dir.files[j].accessTime)
|
||||
})
|
||||
case ctimeSort:
|
||||
sort.SliceStable(dir.files, func(i, j int) bool {
|
||||
return dir.files[i].changeTime.Before(dir.files[j].changeTime)
|
||||
})
|
||||
}
|
||||
|
||||
if gOpts.sortType.option&reverseSort != 0 {
|
||||
|
4
opts.go
4
opts.go
@ -9,6 +9,8 @@ const (
|
||||
nameSort
|
||||
sizeSort
|
||||
timeSort
|
||||
atimeSort
|
||||
ctimeSort
|
||||
)
|
||||
|
||||
type sortOption byte
|
||||
@ -153,6 +155,8 @@ func init() {
|
||||
gOpts.keys["sn"] = &listExpr{[]expr{&setExpr{"sortby", "natural"}, &setExpr{"info", ""}}}
|
||||
gOpts.keys["ss"] = &listExpr{[]expr{&setExpr{"sortby", "size"}, &setExpr{"info", "size"}}}
|
||||
gOpts.keys["st"] = &listExpr{[]expr{&setExpr{"sortby", "time"}, &setExpr{"info", "time"}}}
|
||||
gOpts.keys["sa"] = &listExpr{[]expr{&setExpr{"sortby", "atime"}, &setExpr{"info", "atime"}}}
|
||||
gOpts.keys["sc"] = &listExpr{[]expr{&setExpr{"sortby", "ctime"}, &setExpr{"info", "ctime"}}}
|
||||
gOpts.keys["gh"] = &callExpr{"cd", []string{"~"}, 1}
|
||||
|
||||
gOpts.cmdkeys = make(map[string]expr)
|
||||
|
4
ui.go
4
ui.go
@ -231,6 +231,10 @@ func fileInfo(f *file, d *dir) string {
|
||||
}
|
||||
case "time":
|
||||
info = fmt.Sprintf("%s %12s", info, f.ModTime().Format("Jan _2 15:04"))
|
||||
case "atime":
|
||||
info = fmt.Sprintf("%s %12s", info, f.accessTime.Format("Jan _2 15:04"))
|
||||
case "ctime":
|
||||
info = fmt.Sprintf("%s %12s", info, f.changeTime.Format("Jan _2 15:04"))
|
||||
default:
|
||||
log.Printf("unknown info type: %s", s)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user