Skip to content

Commit

Permalink
Add rulerfmt option for improved ruler customization (#1386)
Browse files Browse the repository at this point in the history
* Implement basic rulerfmt mechanism

* Add deprecation warning for ruler option

* Implement basic placeholders

* Add placeholder for number of hidden files

* Implement placeholders for options

* Add documentation
  • Loading branch information
joelim-work authored Sep 3, 2023
1 parent 8d013c9 commit 439fb03
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 28 deletions.
1 change: 1 addition & 0 deletions complete.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ var (
"noreverse",
"reverse!",
"ruler",
"rulerfmt",
"preserve",
"sixel",
"nosixel",
Expand Down
10 changes: 10 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ The following options can be used to customize the behavior of lf:
relativenumber bool (default false)
reverse bool (default false)
ruler []string (default 'acc:progress:selection:filter:ind')
rulerfmt string (default "%a |%p |\033[7;31m %m \033[0m |\033[7;33m %c \033[0m |\033[7;35m %s \033[0m |\033[7;34m %f \033[0m |%i/%t")
scrolloff int (default 0)
selmode string (default 'all')
shell string (default 'sh' for Unix and 'cmd' for Windows)
Expand Down Expand Up @@ -875,6 +876,7 @@ Reverse the direction of sort.
ruler []string (default 'acc:progress:selection:filter:ind')
This option is deprecated in favor of using the `rulerfmt` option (see below).
List of information shown in status line ruler.
Currently supported information types are 'acc', 'progress', 'selection', 'filter', 'ind', 'df' and names starting with 'lf_'.
`acc` shows the pressed keys (e.g. for bindings with multiple key presses or counts given to bindings).
Expand All @@ -886,6 +888,14 @@ Currently supported information types are 'acc', 'progress', 'selection', 'filte
Names starting with `lf_` show the value of environment variables exported by lf. This is useful for displaying the current settings (e.g. `lf_selmode` displays the current setting for the `selmode` option).
User defined options starting with `lf_user_` are also supported, so it is possible to display information set from external sources.
rulerfmt string (default "%a |%p |\033[7;31m %m \033[0m |\033[7;33m %c \033[0m |\033[7;35m %s \033[0m |\033[7;34m %f \033[0m |%i/%t")
Format string of the ruler shown in the bottom right corner.
Special expansions are provided, '%a' as the pressed keys, '%p' as the progress of file operations, '%m' as the number of files to be cut (moved), '%c' as the number of files to be copied, '%s' as the number of selected files, '%f' as the filter, '%i' as the position of the cursor, '%t' as the number of files shown in the current directory, '%h' as the number of files hidden in the current directory, and '%d' as the amount of free disk space remaining.
Additional expansions are provided for environment variables exported by lf, in the form `%{lf_<name>}` (e.g. `%{lf_selmode}`). This is useful for displaying the current settings.
Expansions are also provided for user defined options, in the form `%{lf_user_<name>}` (e.g. `%{lf_user_foo}`).
The `|` character splits the format string into sections. Any section containing a failed expansion (result is a blank string) is discarded and not shown.
selmode string (default 'all')
Selection mode for commands.
Expand Down
18 changes: 18 additions & 0 deletions docstring.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,10 @@ func (e *setExpr) eval(app *app, args []string) {
}
}
gOpts.ruler = toks
app.ui.echoerr("option 'ruler' is deprecated, use 'rulerfmt' instead")
return
case "rulerfmt":
gOpts.rulerfmt = e.val
case "preserve":
if e.val == "" {
gOpts.preserve = nil
Expand Down
9 changes: 8 additions & 1 deletion lf.1
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ The following options can be used to customize the behavior of lf:
relativenumber bool (default false)
reverse bool (default false)
ruler []string (default 'acc:progress:selection:filter:ind')
rulerfmt string (default "%a |%p |\e033[7;31m %m \e033[0m |\e033[7;33m %c \e033[0m |\e033[7;35m %s \e033[0m |\e033[7;34m %f \e033[0m |%i/%t")
scrolloff int (default 0)
selmode string (default 'all')
shell string (default 'sh' for Unix and 'cmd' for Windows)
Expand Down Expand Up @@ -1052,7 +1053,13 @@ Reverse the direction of sort.
ruler []string (default 'acc:progress:selection:filter:ind')
.EE
.PP
List of information shown in status line ruler. Currently supported information types are 'acc', 'progress', 'selection', 'filter', 'ind', 'df' and names starting with 'lf_'. `acc` shows the pressed keys (e.g. for bindings with multiple key presses or counts given to bindings). `progress` shows the progress of file operations (e.g. copying a large directory). `selection` shows the number of files that are selected, or designated for being cut/copied. `filter` shows 'F' if a filter is currently being applied. `ind` shows the current position of the cursor as well as the number of files in the current directory. `df` shows the amount of free disk space remaining. Names starting with `lf_` show the value of environment variables exported by lf. This is useful for displaying the current settings (e.g. `lf_selmode` displays the current setting for the `selmode` option). User defined options starting with `lf_user_` are also supported, so it is possible to display information set from external sources.
This option is deprecated in favor of using the `rulerfmt` option (see below). List of information shown in status line ruler. Currently supported information types are 'acc', 'progress', 'selection', 'filter', 'ind', 'df' and names starting with 'lf_'. `acc` shows the pressed keys (e.g. for bindings with multiple key presses or counts given to bindings). `progress` shows the progress of file operations (e.g. copying a large directory). `selection` shows the number of files that are selected, or designated for being cut/copied. `filter` shows 'F' if a filter is currently being applied. `ind` shows the current position of the cursor as well as the number of files in the current directory. `df` shows the amount of free disk space remaining. Names starting with `lf_` show the value of environment variables exported by lf. This is useful for displaying the current settings (e.g. `lf_selmode` displays the current setting for the `selmode` option). User defined options starting with `lf_user_` are also supported, so it is possible to display information set from external sources.
.PP
.EX
rulerfmt string (default "%a |%p |\e033[7;31m %m \e033[0m |\e033[7;33m %c \e033[0m |\e033[7;35m %s \e033[0m |\e033[7;34m %f \e033[0m |%i/%t")
.EE
.PP
Format string of the ruler shown in the bottom right corner. Special expansions are provided, '%a' as the pressed keys, '%p' as the progress of file operations, '%m' as the number of files to be cut (moved), '%c' as the number of files to be copied, '%s' as the number of selected files, '%f' as the filter, '%i' as the position of the cursor, '%t' as the number of files shown in the current directory, '%h' as the number of files hidden in the current directory, and '%d' as the amount of free disk space remaining. Additional expansions are provided for environment variables exported by lf, in the form `%{lf_<name>}` (e.g. `%{lf_selmode}`). This is useful for displaying the current settings. Expansions are also provided for user defined options, in the form `%{lf_user_<name>}` (e.g. `%{lf_user_foo}`). The `|` character splits the format string into sections. Any section containing a failed expansion (result is a blank string) is discarded and not shown.
.PP
.EX
selmode string (default 'all')
Expand Down
1 change: 1 addition & 0 deletions misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ func naturalLess(s1, s2 string) bool {
}

var reModKey = regexp.MustCompile(`<(c|s|a)-(.+)>`)
var reRulerSub = regexp.MustCompile(`%[apmcsfithd]|%\{[^}]+\}`)

var reWord = regexp.MustCompile(`(\pL|\pN)+`)
var reWordBeg = regexp.MustCompile(`([^\pL\pN]|^)(\pL|\pN)`)
Expand Down
4 changes: 3 additions & 1 deletion opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ var gOpts struct {
history bool
info []string
ruler []string
rulerfmt string
preserve []string
shellopts []string
keys map[string]expr
Expand Down Expand Up @@ -232,7 +233,8 @@ func init() {
gOpts.hiddenfiles = []string{".*"}
gOpts.history = true
gOpts.info = nil
gOpts.ruler = []string{"acc", "progress", "selection", "filter", "ind"}
gOpts.ruler = nil
gOpts.rulerfmt = "%a |%p |\033[7;31m %m \033[0m |\033[7;33m %c \033[0m |\033[7;35m %s \033[0m |\033[7;34m %f \033[0m |%i/%t"
gOpts.preserve = []string{"mode"}
gOpts.shellopts = nil
gOpts.sortType = sortType{naturalSort, dirfirstSort}
Expand Down
101 changes: 75 additions & 26 deletions ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ func formatRulerOpt(name string, val string) string {
return val
}

func (ui *ui) drawStatLine(nav *nav) {
func (ui *ui) drawRuler(nav *nav) {
st := tcell.StyleDefault

dir := nav.currDir()
Expand All @@ -839,13 +839,14 @@ func (ui *ui) drawStatLine(nav *nav) {

tot := len(dir.files)
ind := min(dir.ind+1, tot)
hid := len(dir.allFiles) - tot
acc := string(ui.keyCount) + string(ui.keyAcc)

selection := []string{}

copy := 0
move := 0
if len(nav.saves) > 0 {
copy := 0
move := 0
for _, cp := range nav.saves {
if cp {
copy++
Expand Down Expand Up @@ -882,34 +883,82 @@ func (ui *ui) drawStatLine(nav *nav) {
}

opts := getOptsMap()
ruler := []string{}
for _, s := range gOpts.ruler {
switch s {
case "df":
df := diskFree(dir.path)
if df != "" {
ruler = append(ruler, df)
}
case "acc":
ruler = append(ruler, acc)
case "progress":
ruler = append(ruler, progress...)
case "selection":
ruler = append(ruler, selection...)
case "filter":
if len(dir.filter) != 0 {
ruler = append(ruler, "\033[34;7m F \033[0m")

// 'ruler' option is deprecated and can be removed in future
if len(gOpts.ruler) > 0 {
ruler := []string{}
for _, s := range gOpts.ruler {
switch s {
case "df":
df := diskFree(dir.path)
if df != "" {
ruler = append(ruler, df)
}
case "acc":
ruler = append(ruler, acc)
case "progress":
ruler = append(ruler, progress...)
case "selection":
ruler = append(ruler, selection...)
case "filter":
if len(dir.filter) != 0 {
ruler = append(ruler, "\033[34;7m F \033[0m")
}
case "ind":
ruler = append(ruler, fmt.Sprintf("%d/%d", ind, tot))
default:
if val, ok := opts[s]; ok {
ruler = append(ruler, formatRulerOpt(s, val))
}
}
case "ind":
ruler = append(ruler, fmt.Sprintf("%d/%d", ind, tot))
}

ui.msgWin.printRight(ui.screen, 0, st, strings.Join(ruler, " "))
return
}

rulerfmt := strings.ReplaceAll(gOpts.rulerfmt, "|", "\x1f")
rulerfmt = reRulerSub.ReplaceAllStringFunc(rulerfmt, func(s string) string {
var result string
switch s {
case "%a":
result = acc
case "%p":
result = strings.Join(progress, " ")
case "%m":
result = fmt.Sprintf("%.d", move)
case "%c":
result = fmt.Sprintf("%.d", copy)
case "%s":
result = fmt.Sprintf("%.d", len(currSelections))
case "%f":
result = strings.Join(dir.filter, " ")
case "%i":
result = fmt.Sprint(ind)
case "%t":
result = fmt.Sprint(tot)
case "%h":
result = fmt.Sprint(hid)
case "%d":
result = diskFree(dir.path)
default:
s = strings.TrimSuffix(strings.TrimPrefix(s, "%{"), "}")
if val, ok := opts[s]; ok {
ruler = append(ruler, formatRulerOpt(s, val))
result = formatRulerOpt(s, val)
}
}
if result == "" {
return "\x00"
}
return result
})
ruler := ""
for _, section := range strings.Split(rulerfmt, "\x1f") {
if !strings.Contains(section, "\x00") {
ruler += section
}
}

ui.msgWin.printRight(ui.screen, 0, st, strings.Join(ruler, " "))
ui.msgWin.printRight(ui.screen, 0, st, ruler)
}

func (ui *ui) drawBox() {
Expand Down Expand Up @@ -988,7 +1037,7 @@ func (ui *ui) draw(nav *nav) {

switch ui.cmdPrefix {
case "":
ui.drawStatLine(nav)
ui.drawRuler(nav)
ui.screen.HideCursor()
case ">":
maxWidth := ui.msgWin.w - 1 // leave space for cursor at the end
Expand Down

0 comments on commit 439fb03

Please sign in to comment.