count dirs while reading the parent dir

This commit moves directory counting with 'dircounts' option from ui
printing to dir reading to be run asynchronously without locking the ui.
On the other side, disadvantage of this approach is that if 'dircounts'
option is changed at runtime, then directory counts may not be available
requiring a manual 'reload'. Indicators for errors are changed to '!'
instead of '?' to distinguish them from missing values.
This commit is contained in:
Gokcehan 2022-03-19 19:01:24 +03:00
parent 5927a506f4
commit 2ddaf43421
2 changed files with 20 additions and 20 deletions

19
nav.go
View File

@ -101,12 +101,29 @@ func readdir(path string) ([]*file, error) {
// i.e. directories, filenames without extensions // i.e. directories, filenames without extensions
ext := filepath.Ext(fpath) ext := filepath.Ext(fpath)
dirCount := -1
if lstat.IsDir() && gOpts.dircounts {
d, err := os.Open(fpath)
if err != nil {
dirCount = -2
}
names, err := d.Readdirnames(1000)
d.Close()
if names == nil && err != io.EOF {
dirCount = -2
} else {
dirCount = len(names)
}
}
files = append(files, &file{ files = append(files, &file{
FileInfo: lstat, FileInfo: lstat,
linkState: linkState, linkState: linkState,
linkTarget: linkTarget, linkTarget: linkTarget,
path: fpath, path: fpath,
dirCount: -1, dirCount: dirCount,
dirSize: -1, dirSize: -1,
accessTime: at, accessTime: at,
changeTime: ct, changeTime: ct,

21
ui.go
View File

@ -3,7 +3,6 @@ package main
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io"
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
@ -287,8 +286,6 @@ func infotimefmt(t time.Time) string {
func fileInfo(f *file, d *dir) string { func fileInfo(f *file, d *dir) string {
var info string var info string
path := filepath.Join(d.path, f.Name())
for _, s := range gOpts.info { for _, s := range gOpts.info {
switch s { switch s {
case "size": case "size":
@ -303,23 +300,9 @@ func fileInfo(f *file, d *dir) string {
continue continue
} }
if f.dirCount == -1 {
d, err := os.Open(path)
if err != nil {
f.dirCount = -2
}
names, err := d.Readdirnames(1000)
d.Close()
if names == nil && err != io.EOF {
f.dirCount = -2
} else {
f.dirCount = len(names)
}
}
switch { switch {
case f.dirCount < -1:
info = fmt.Sprintf("%s !", info)
case f.dirCount < 0: case f.dirCount < 0:
info = fmt.Sprintf("%s ?", info) info = fmt.Sprintf("%s ?", info)
case f.dirCount < 1000: case f.dirCount < 1000: