add get-dirsize command (#750)

This commit is contained in:
Christian Zangl 2022-02-12 10:21:49 +01:00 committed by GitHub
parent 86e84c9151
commit cbb80a0d44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 90 additions and 3 deletions

View File

@ -60,6 +60,7 @@ var (
"echomsg", "echomsg",
"echoerr", "echoerr",
"cd", "cd",
"get-dirsize",
"select", "select",
"glob-select", "glob-select",
"glob-unselect", "glob-unselect",

5
doc.go
View File

@ -31,6 +31,7 @@ The following commands are provided by lf:
unselect (default 'u') unselect (default 'u')
glob-select glob-select
glob-unselect glob-unselect
get-dirsize
copy (default 'y') copy (default 'y')
cut (default 'd') cut (default 'd')
paste (default 'p') paste (default 'p')
@ -274,6 +275,10 @@ Select files that match the given glob.
Unselect files that match the given glob. Unselect files that match the given glob.
get-dirsize
Get the total size for each of the selected directories.
copy (default 'y') copy (default 'y')
If there are no selections, save the path of the current file to the copy buffer, otherwise, copy the paths of selected files. If there are no selections, save the path of the current file to the copy buffer, otherwise, copy the paths of selected files.

View File

@ -35,6 +35,7 @@ The following commands are provided by lf:
unselect (default 'u') unselect (default 'u')
glob-select glob-select
glob-unselect glob-unselect
get-dirsize
copy (default 'y') copy (default 'y')
cut (default 'd') cut (default 'd')
paste (default 'p') paste (default 'p')
@ -286,6 +287,10 @@ Select files that match the given glob.
Unselect files that match the given glob. Unselect files that match the given glob.
get-dirsize
Get the total size for each of the selected directories.
copy (default 'y') copy (default 'y')
If there are no selections, save the path of the current file to the copy If there are no selections, save the path of the current file to the copy

View File

@ -913,6 +913,15 @@ func (e *callExpr) eval(app *app, args []string) {
app.nav.invert() app.nav.invert()
case "unselect": case "unselect":
app.nav.unselect() app.nav.unselect()
case "get-dirsize":
err := app.nav.getDirSize()
if err != nil {
app.ui.echoerrf("get-dirsize: %s", err)
return
}
app.ui.loadFileInfo(app.nav)
app.nav.sort()
app.ui.sort()
case "copy": case "copy":
if err := app.nav.save(true); err != nil { if err := app.nav.save(true); err != nil {
app.ui.echoerrf("copy: %s", err) app.ui.echoerrf("copy: %s", err)

7
lf.1
View File

@ -47,6 +47,7 @@ The following commands are provided by lf:
unselect (default 'u') unselect (default 'u')
glob-select glob-select
glob-unselect glob-unselect
get-dirsize
copy (default 'y') copy (default 'y')
cut (default 'd') cut (default 'd')
paste (default 'p') paste (default 'p')
@ -320,6 +321,12 @@ Select files that match the given glob.
.PP .PP
Unselect files that match the given glob. Unselect files that match the given glob.
.PP .PP
.EX
get-dirsize
.EE
.PP
Get the total size for each of the selected directories.
.PP
.EX .EX
copy (default 'y') copy (default 'y')
.EE .EE

56
nav.go
View File

@ -32,11 +32,22 @@ type file struct {
linkTarget string linkTarget string
path string path string
dirCount int dirCount int
dirSize int64
accessTime time.Time accessTime time.Time
changeTime time.Time changeTime time.Time
ext string ext string
} }
func (file *file) TotalSize() int64 {
if file.IsDir() {
if file.dirSize >= 0 {
return file.dirSize
}
return 0
}
return file.Size()
}
func readdir(path string) ([]*file, error) { func readdir(path string) ([]*file, error) {
f, err := os.Open(path) f, err := os.Open(path)
if err != nil { if err != nil {
@ -95,6 +106,7 @@ func readdir(path string) ([]*file, error) {
linkTarget: linkTarget, linkTarget: linkTarget,
path: fpath, path: fpath,
dirCount: -1, dirCount: -1,
dirSize: -1,
accessTime: at, accessTime: at,
changeTime: ct, changeTime: ct,
ext: ext, ext: ext,
@ -172,7 +184,7 @@ func (dir *dir) sort() {
}) })
case sizeSort: case sizeSort:
sort.SliceStable(dir.files, func(i, j int) bool { sort.SliceStable(dir.files, func(i, j int) bool {
return dir.files[i].Size() < dir.files[j].Size() return dir.files[i].TotalSize() < dir.files[j].TotalSize()
}) })
case timeSort: case timeSort:
sort.SliceStable(dir.files, func(i, j int) bool { sort.SliceStable(dir.files, func(i, j int) bool {
@ -1487,3 +1499,45 @@ func (nav *nav) currFileOrSelections() (list []string, err error) {
return nav.currSelections(), nil return nav.currSelections(), nil
} }
func (nav *nav) getDirSize() error {
calc := func(f *file) error {
if f.IsDir() {
total, err := copySize([]string{f.path})
if err != nil {
return err
}
f.dirSize = total
}
return nil
}
if len(nav.selections) == 0 {
curr, err := nav.currFile()
if err != nil {
return errors.New("no file selected")
}
return calc(curr)
} else {
for sel, _ := range nav.selections {
lstat, err := os.Lstat(sel)
if err != nil || !lstat.IsDir() {
continue
}
path, name := filepath.Dir(sel), filepath.Base(sel)
dir := nav.loadDir(path)
for _, f := range dir.files {
if f.Name() == name {
err := calc(f)
if err != nil {
return err
}
break
}
}
}
}
return nil
}

10
ui.go
View File

@ -292,8 +292,14 @@ func fileInfo(f *file, d *dir) string {
for _, s := range gOpts.info { for _, s := range gOpts.info {
switch s { switch s {
case "size": case "size":
if !(gOpts.dircounts && f.IsDir()) { if !(f.IsDir() && gOpts.dircounts) {
info = fmt.Sprintf("%s %4s", info, humanize(f.Size())) var sz string
if f.IsDir() && f.dirSize < 0 {
sz = "-"
} else {
sz = humanize(f.TotalSize())
}
info = fmt.Sprintf("%s %4s", info, sz)
continue continue
} }