Merge branch 'master' into michael
This commit is contained in:
commit
25b4f6943a
@ -18,7 +18,7 @@ See [faq](https://github.com/gokcehan/lf/wiki/FAQ) for more information and [tut
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Cross-platform (Linux, MacOS, BSDs, Windows)
|
- Cross-platform (Linux, macOS, BSDs, Windows)
|
||||||
- Single binary without any runtime dependencies
|
- Single binary without any runtime dependencies
|
||||||
- Fast startup and low memory footprint due to native code and static binaries
|
- Fast startup and low memory footprint due to native code and static binaries
|
||||||
- Asynchronous IO operations to avoid UI locking
|
- Asynchronous IO operations to avoid UI locking
|
||||||
|
6
app.go
6
app.go
@ -59,8 +59,10 @@ func newApp(ui *ui, nav *nav) *app {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *app) quit() {
|
func (app *app) quit() {
|
||||||
if err := app.writeHistory(); err != nil {
|
if gOpts.history {
|
||||||
log.Printf("writing history file: %s", err)
|
if err := app.writeHistory(); err != nil {
|
||||||
|
log.Printf("writing history file: %s", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !gSingleMode {
|
if !gSingleMode {
|
||||||
if err := remote(fmt.Sprintf("drop %d", gClientID)); err != nil {
|
if err := remote(fmt.Sprintf("drop %d", gClientID)); err != nil {
|
||||||
|
@ -110,6 +110,8 @@ func applyAnsiCodes(s string, st tcell.Style) tcell.Style {
|
|||||||
st = st.Bold(true)
|
st = st.Bold(true)
|
||||||
case n == 2:
|
case n == 2:
|
||||||
st = st.Dim(true)
|
st = st.Dim(true)
|
||||||
|
case n == 3:
|
||||||
|
st = st.Italic(true)
|
||||||
case n == 4:
|
case n == 4:
|
||||||
st = st.Underline(true)
|
st = st.Underline(true)
|
||||||
case n == 5 || n == 6:
|
case n == 5 || n == 6:
|
||||||
@ -319,7 +321,7 @@ func (sm styleMap) get(f *file) tcell.Style {
|
|||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
if val, ok := sm["*"+f.ext]; ok {
|
if val, ok := sm["*"+strings.ToLower(f.ext)]; ok {
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
194
complete.go
194
complete.go
@ -13,7 +13,9 @@ var (
|
|||||||
gCmdWords = []string{
|
gCmdWords = []string{
|
||||||
"set",
|
"set",
|
||||||
"map",
|
"map",
|
||||||
|
"cmap",
|
||||||
"cmd",
|
"cmd",
|
||||||
|
"quit",
|
||||||
"up",
|
"up",
|
||||||
"half-up",
|
"half-up",
|
||||||
"page-up",
|
"page-up",
|
||||||
@ -24,20 +26,38 @@ var (
|
|||||||
"scroll-down",
|
"scroll-down",
|
||||||
"updir",
|
"updir",
|
||||||
"open",
|
"open",
|
||||||
"quit",
|
"jump-next",
|
||||||
|
"jump-prev",
|
||||||
"top",
|
"top",
|
||||||
"bottom",
|
"bottom",
|
||||||
|
"high",
|
||||||
|
"middle",
|
||||||
|
"low",
|
||||||
"toggle",
|
"toggle",
|
||||||
"invert",
|
"invert",
|
||||||
"unselect",
|
"unselect",
|
||||||
|
"glob-select",
|
||||||
|
"glob-unselect",
|
||||||
|
"calcdirsize",
|
||||||
"copy",
|
"copy",
|
||||||
"cut",
|
"cut",
|
||||||
"paste",
|
"paste",
|
||||||
"clear",
|
"clear",
|
||||||
|
"sync",
|
||||||
|
"draw",
|
||||||
"redraw",
|
"redraw",
|
||||||
|
"load",
|
||||||
"reload",
|
"reload",
|
||||||
"read",
|
"echo",
|
||||||
|
"echomsg",
|
||||||
|
"echoerr",
|
||||||
|
"cd",
|
||||||
|
"select",
|
||||||
|
"delete",
|
||||||
"rename",
|
"rename",
|
||||||
|
"source",
|
||||||
|
"push",
|
||||||
|
"read",
|
||||||
"shell",
|
"shell",
|
||||||
"shell-pipe",
|
"shell-pipe",
|
||||||
"shell-wait",
|
"shell-wait",
|
||||||
@ -53,24 +73,37 @@ var (
|
|||||||
"filter",
|
"filter",
|
||||||
"setfilter",
|
"setfilter",
|
||||||
"mark-save",
|
"mark-save",
|
||||||
"mark-remove",
|
|
||||||
"mark-load",
|
"mark-load",
|
||||||
"draw",
|
"mark-remove",
|
||||||
"load",
|
|
||||||
"sync",
|
|
||||||
"echo",
|
|
||||||
"echomsg",
|
|
||||||
"echoerr",
|
|
||||||
"cd",
|
|
||||||
"calcdirsize",
|
|
||||||
"select",
|
|
||||||
"glob-select",
|
|
||||||
"glob-unselect",
|
|
||||||
"source",
|
|
||||||
"push",
|
|
||||||
"delete",
|
|
||||||
"tag",
|
"tag",
|
||||||
"tag-toggle",
|
"tag-toggle",
|
||||||
|
"cmd-escape",
|
||||||
|
"cmd-complete",
|
||||||
|
"cmd-menu-complete",
|
||||||
|
"cmd-menu-complete-back",
|
||||||
|
"cmd-menu-accept",
|
||||||
|
"cmd-enter",
|
||||||
|
"cmd-interrupt",
|
||||||
|
"cmd-history-next",
|
||||||
|
"cmd-history-prev",
|
||||||
|
"cmd-left",
|
||||||
|
"cmd-right",
|
||||||
|
"cmd-home",
|
||||||
|
"cmd-end",
|
||||||
|
"cmd-delete",
|
||||||
|
"cmd-delete-back",
|
||||||
|
"cmd-delete-home",
|
||||||
|
"cmd-delete-end",
|
||||||
|
"cmd-delete-unix-word",
|
||||||
|
"cmd-yank",
|
||||||
|
"cmd-transpose",
|
||||||
|
"cmd-transpose-word",
|
||||||
|
"cmd-word",
|
||||||
|
"cmd-word-back",
|
||||||
|
"cmd-delete-word",
|
||||||
|
"cmd-capitalize-word",
|
||||||
|
"cmd-uppercase-word",
|
||||||
|
"cmd-lowercase-word",
|
||||||
}
|
}
|
||||||
|
|
||||||
gOptWords = []string{
|
gOptWords = []string{
|
||||||
@ -151,6 +184,7 @@ var (
|
|||||||
"errorfmt",
|
"errorfmt",
|
||||||
"filesep",
|
"filesep",
|
||||||
"hiddenfiles",
|
"hiddenfiles",
|
||||||
|
"history",
|
||||||
"ifs",
|
"ifs",
|
||||||
"info",
|
"info",
|
||||||
"previewer",
|
"previewer",
|
||||||
@ -170,7 +204,7 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func matchLongest(s1, s2 string) string {
|
func matchLongest(s1, s2 []rune) []rune {
|
||||||
i := 0
|
i := 0
|
||||||
for ; i < len(s1) && i < len(s2); i++ {
|
for ; i < len(s1) && i < len(s2); i++ {
|
||||||
if s1[i] != s2[i] {
|
if s1[i] != s2[i] {
|
||||||
@ -180,28 +214,28 @@ func matchLongest(s1, s2 string) string {
|
|||||||
return s1[:i]
|
return s1[:i]
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchWord(s string, words []string) (matches []string, longest string) {
|
func matchWord(s string, words []string) (matches []string, longest []rune) {
|
||||||
for _, w := range words {
|
for _, w := range words {
|
||||||
if !strings.HasPrefix(w, s) {
|
if !strings.HasPrefix(w, s) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
matches = append(matches, w)
|
matches = append(matches, w)
|
||||||
if longest != "" {
|
if len(longest) != 0 {
|
||||||
longest = matchLongest(longest, w)
|
longest = matchLongest(longest, []rune(w))
|
||||||
} else if s != "" {
|
} else if s != "" {
|
||||||
longest = w + " "
|
longest = []rune(w + " ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if longest == "" {
|
if len(longest) == 0 {
|
||||||
longest = s
|
longest = []rune(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchExec(s string) (matches []string, longest string) {
|
func matchExec(s string) (matches []string, longest []rune) {
|
||||||
var words []string
|
var words []string
|
||||||
|
|
||||||
paths := strings.Split(envPath, string(filepath.ListSeparator))
|
paths := strings.Split(envPath, string(filepath.ListSeparator))
|
||||||
@ -251,7 +285,8 @@ func matchExec(s string) (matches []string, longest string) {
|
|||||||
return matchWord(s, words)
|
return matchWord(s, words)
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchFile(s string) (matches []string, longest string) {
|
func matchFile(s string) (matches []string, longest []rune) {
|
||||||
|
s = unescape(s)
|
||||||
dir := replaceTilde(s)
|
dir := replaceTilde(s)
|
||||||
|
|
||||||
if !filepath.IsAbs(dir) {
|
if !filepath.IsAbs(dir) {
|
||||||
@ -263,7 +298,7 @@ func matchFile(s string) (matches []string, longest string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dir = unescape(filepath.Dir(dir))
|
dir = filepath.Dir(dir)
|
||||||
|
|
||||||
files, err := ioutil.ReadDir(dir)
|
files, err := ioutil.ReadDir(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -272,25 +307,20 @@ func matchFile(s string) (matches []string, longest string) {
|
|||||||
|
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
name := filepath.Join(dir, f.Name())
|
name := filepath.Join(dir, f.Name())
|
||||||
f, err := os.Stat(name)
|
f, err := os.Lstat(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fl, err := os.Lstat(name)
|
log.Printf("getting file information: %s", err)
|
||||||
if err == nil && fl.Mode()&os.ModeSymlink != 0 {
|
continue
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
log.Printf("getting file information: %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, last := filepath.Split(s)
|
_, last := filepath.Split(s)
|
||||||
if !strings.HasPrefix(escape(f.Name()), last) {
|
if !strings.HasPrefix(f.Name(), last) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
name = f.Name()
|
name = f.Name()
|
||||||
if isRoot(s) || filepath.Base(s) != s {
|
if isRoot(s) || filepath.Base(s) != s {
|
||||||
name = filepath.Join(filepath.Dir(unescape(s)), f.Name())
|
name = filepath.Join(filepath.Dir(s), f.Name())
|
||||||
}
|
}
|
||||||
name = escape(name)
|
name = escape(name)
|
||||||
|
|
||||||
@ -300,66 +330,79 @@ func matchFile(s string) (matches []string, longest string) {
|
|||||||
}
|
}
|
||||||
matches = append(matches, item)
|
matches = append(matches, item)
|
||||||
|
|
||||||
if longest != "" {
|
if len(longest) != 0 {
|
||||||
longest = matchLongest(longest, name)
|
longest = matchLongest(longest, []rune(name))
|
||||||
} else if s != "" {
|
} else if s != "" {
|
||||||
if f.Mode().IsRegular() {
|
if f.Mode().IsRegular() {
|
||||||
longest = name + " "
|
longest = []rune(name + " ")
|
||||||
} else {
|
} else {
|
||||||
longest = name + escape(string(filepath.Separator))
|
longest = []rune(name + escape(string(filepath.Separator)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if longest == "" {
|
if len(longest) == 0 {
|
||||||
longest = s
|
longest = []rune(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func matchCmd(s string) (matches []string, longest []rune) {
|
||||||
|
words := gCmdWords
|
||||||
|
for c := range gOpts.cmds {
|
||||||
|
words = append(words, c)
|
||||||
|
}
|
||||||
|
sort.Strings(words)
|
||||||
|
j := 0
|
||||||
|
for i := 1; i < len(words); i++ {
|
||||||
|
if words[j] == words[i] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
j++
|
||||||
|
words[i], words[j] = words[j], words[i]
|
||||||
|
}
|
||||||
|
words = words[:j+1]
|
||||||
|
matches, longest = matchWord(s, words)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func completeCmd(acc []rune) (matches []string, longestAcc []rune) {
|
func completeCmd(acc []rune) (matches []string, longestAcc []rune) {
|
||||||
s := string(acc)
|
s := string(acc)
|
||||||
f := tokenize(s)
|
f := tokenize(s)
|
||||||
|
|
||||||
var longest string
|
var longest []rune
|
||||||
|
|
||||||
switch len(f) {
|
switch len(f) {
|
||||||
case 1:
|
case 1:
|
||||||
words := gCmdWords
|
matches, longestAcc = matchCmd(s)
|
||||||
for c := range gOpts.cmds {
|
|
||||||
words = append(words, c)
|
|
||||||
}
|
|
||||||
sort.Strings(words)
|
|
||||||
j := 0
|
|
||||||
for i := 1; i < len(words); i++ {
|
|
||||||
if words[j] == words[i] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
j++
|
|
||||||
words[i], words[j] = words[j], words[i]
|
|
||||||
}
|
|
||||||
words = words[:j+1]
|
|
||||||
matches, longest = matchWord(s, words)
|
|
||||||
longestAcc = []rune(longest)
|
|
||||||
case 2:
|
case 2:
|
||||||
switch f[0] {
|
switch f[0] {
|
||||||
case "set":
|
case "set":
|
||||||
matches, longest = matchWord(f[1], gOptWords)
|
matches, longest = matchWord(f[1], gOptWords)
|
||||||
longestAcc = append(acc[:len(acc)-len(f[len(f)-1])], []rune(longest)...)
|
longestAcc = append(acc[:len(acc)-len([]rune(f[len(f)-1]))], longest...)
|
||||||
case "map", "cmd":
|
case "map", "cmap", "cmd":
|
||||||
longestAcc = acc
|
longestAcc = acc
|
||||||
default:
|
default:
|
||||||
matches, longest = matchFile(f[len(f)-1])
|
matches, longest = matchFile(f[len(f)-1])
|
||||||
longestAcc = append(acc[:len(acc)-len(f[len(f)-1])], []rune(longest)...)
|
longestAcc = append(acc[:len(acc)-len([]rune(f[len(f)-1]))], longest...)
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
switch f[0] {
|
||||||
|
case "map", "cmap":
|
||||||
|
matches, longest = matchCmd(f[2])
|
||||||
|
longestAcc = append(acc[:len(acc)-len([]rune(f[len(f)-1]))], longest...)
|
||||||
|
default:
|
||||||
|
matches, longest = matchFile(f[len(f)-1])
|
||||||
|
longestAcc = append(acc[:len(acc)-len([]rune(f[len(f)-1]))], longest...)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
switch f[0] {
|
switch f[0] {
|
||||||
case "set", "map", "cmd":
|
case "set", "map", "cmap", "cmd":
|
||||||
longestAcc = acc
|
longestAcc = acc
|
||||||
default:
|
default:
|
||||||
matches, longest = matchFile(f[len(f)-1])
|
matches, longest = matchFile(f[len(f)-1])
|
||||||
longestAcc = append(acc[:len(acc)-len(f[len(f)-1])], []rune(longest)...)
|
longestAcc = append(acc[:len(acc)-len([]rune(f[len(f)-1]))], longest...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,8 +422,6 @@ func completeFile(acc []rune) (matches []string, longestAcc []rune) {
|
|||||||
log.Printf("reading directory: %s", err)
|
log.Printf("reading directory: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var longest string
|
|
||||||
|
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
if !strings.HasPrefix(f.Name(), s) {
|
if !strings.HasPrefix(f.Name(), s) {
|
||||||
continue
|
continue
|
||||||
@ -388,19 +429,17 @@ func completeFile(acc []rune) (matches []string, longestAcc []rune) {
|
|||||||
|
|
||||||
matches = append(matches, f.Name())
|
matches = append(matches, f.Name())
|
||||||
|
|
||||||
if longest != "" {
|
if len(longestAcc) != 0 {
|
||||||
longest = matchLongest(longest, f.Name())
|
longestAcc = matchLongest(longestAcc, []rune(f.Name()))
|
||||||
} else if s != "" {
|
} else if s != "" {
|
||||||
longest = f.Name()
|
longestAcc = []rune(f.Name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if longest == "" {
|
if len(longestAcc) == 0 {
|
||||||
longest = s
|
longestAcc = acc
|
||||||
}
|
}
|
||||||
|
|
||||||
longestAcc = []rune(longest)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,15 +447,14 @@ func completeShell(acc []rune) (matches []string, longestAcc []rune) {
|
|||||||
s := string(acc)
|
s := string(acc)
|
||||||
f := tokenize(s)
|
f := tokenize(s)
|
||||||
|
|
||||||
var longest string
|
var longest []rune
|
||||||
|
|
||||||
switch len(f) {
|
switch len(f) {
|
||||||
case 1:
|
case 1:
|
||||||
matches, longest = matchExec(s)
|
matches, longestAcc = matchExec(s)
|
||||||
longestAcc = []rune(longest)
|
|
||||||
default:
|
default:
|
||||||
matches, longest = matchFile(f[len(f)-1])
|
matches, longest = matchFile(f[len(f)-1])
|
||||||
longestAcc = append(acc[:len(acc)-len([]rune(f[len(f)-1]))], []rune(longest)...)
|
longestAcc = append(acc[:len(acc)-len([]rune(f[len(f)-1]))], longest...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -18,10 +18,11 @@ func TestMatchLongest(t *testing.T) {
|
|||||||
{"foo", "foobar", "foo"},
|
{"foo", "foobar", "foo"},
|
||||||
{"foo", "barfoo", ""},
|
{"foo", "barfoo", ""},
|
||||||
{"foobar", "foobaz", "fooba"},
|
{"foobar", "foobaz", "fooba"},
|
||||||
|
{"год", "гол", "го"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
if got := matchLongest(test.s1, test.s2); got != test.exp {
|
if got := string(matchLongest([]rune(test.s1), []rune(test.s2))); got != test.exp {
|
||||||
t.Errorf("at input '%s' and '%s' expected '%s' but got '%s'", test.s1, test.s2, test.exp, got)
|
t.Errorf("at input '%s' and '%s' expected '%s' but got '%s'", test.s1, test.s2, test.exp, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,8 +49,8 @@ func TestMatchWord(t *testing.T) {
|
|||||||
t.Errorf("at input '%s' with '%s' expected '%s' but got '%s'", test.s, test.words, test.matches, m)
|
t.Errorf("at input '%s' with '%s' expected '%s' but got '%s'", test.s, test.words, test.matches, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
if l != test.longest {
|
if ls := string(l); ls != test.longest {
|
||||||
t.Errorf("at input '%s' with '%s' expected '%s' but got '%s'", test.s, test.words, test.longest, l)
|
t.Errorf("at input '%s' with '%s' expected '%s' but got '%s'", test.s, test.words, test.longest, ls)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
42
doc.go
42
doc.go
@ -85,6 +85,7 @@ The following command line commands are provided by lf:
|
|||||||
cmd-complete (default '<tab>')
|
cmd-complete (default '<tab>')
|
||||||
cmd-menu-complete
|
cmd-menu-complete
|
||||||
cmd-menu-complete-back
|
cmd-menu-complete-back
|
||||||
|
cmd-menu-accept
|
||||||
cmd-enter (default '<c-j>' and '<enter>')
|
cmd-enter (default '<c-j>' and '<enter>')
|
||||||
cmd-interrupt (default '<c-c>')
|
cmd-interrupt (default '<c-c>')
|
||||||
cmd-history-next (default '<c-n>')
|
cmd-history-next (default '<c-n>')
|
||||||
@ -124,6 +125,7 @@ The following options can be used to customize the behavior of lf:
|
|||||||
globsearch bool (default off)
|
globsearch bool (default off)
|
||||||
hidden bool (default off)
|
hidden bool (default off)
|
||||||
hiddenfiles []string (default '.*')
|
hiddenfiles []string (default '.*')
|
||||||
|
history bool (default on)
|
||||||
icons bool (default off)
|
icons bool (default off)
|
||||||
ifs string (default '')
|
ifs string (default '')
|
||||||
ignorecase bool (default on)
|
ignorecase bool (default on)
|
||||||
@ -491,6 +493,10 @@ Autocomplete the current word with menu selection.
|
|||||||
You need to assign keys to these commands (e.g. 'cmap <tab> cmd-menu-complete; cmap <backtab> cmd-menu-complete-back').
|
You need to assign keys to these commands (e.g. 'cmap <tab> cmd-menu-complete; cmap <backtab> cmd-menu-complete-back').
|
||||||
You can use the assigned keys assigned to display the menu and then cycle through completion options.
|
You can use the assigned keys assigned to display the menu and then cycle through completion options.
|
||||||
|
|
||||||
|
cmd-menu-accept
|
||||||
|
|
||||||
|
Accept the currently selected match in menu completion and close the menu.
|
||||||
|
|
||||||
cmd-enter (default '<c-j>' and '<enter>')
|
cmd-enter (default '<c-j>' and '<enter>')
|
||||||
|
|
||||||
Execute the current line.
|
Execute the current line.
|
||||||
@ -570,7 +576,7 @@ Automatically quit server when there are no clients left connected.
|
|||||||
Set the path of a cleaner file.
|
Set the path of a cleaner file.
|
||||||
The file should be executable.
|
The file should be executable.
|
||||||
This file is called if previewing is enabled, the previewer is set, and the previously selected file had its preview cache disabled.
|
This file is called if previewing is enabled, the previewer is set, and the previously selected file had its preview cache disabled.
|
||||||
One argument is passed to the file, path to the file whose preview should be cleaned.
|
Five arguments are passed to the file, (1) current file name, (2) width, (3) height, (4) horizontal position, and (5) vertical position of preview pane respectively.
|
||||||
Preview clearing is disabled when the value of this option is left empty.
|
Preview clearing is disabled when the value of this option is left empty.
|
||||||
|
|
||||||
dircache bool (default on)
|
dircache bool (default on)
|
||||||
@ -629,6 +635,10 @@ Patterns can be given as relative or absolute paths.
|
|||||||
Globbing supports the usual special characters, '*' to match any sequence, '?' to match any character, and '[...]' or '[^...] to match character sets or ranges.
|
Globbing supports the usual special characters, '*' to match any sequence, '?' to match any character, and '[...]' or '[^...] to match character sets or ranges.
|
||||||
In addition, if a pattern starts with '!', then its matches are excluded from hidden files.
|
In addition, if a pattern starts with '!', then its matches are excluded from hidden files.
|
||||||
|
|
||||||
|
history bool (default on)
|
||||||
|
|
||||||
|
Save command history.
|
||||||
|
|
||||||
icons bool (default off)
|
icons bool (default off)
|
||||||
|
|
||||||
Show icons before each item in the list.
|
Show icons before each item in the list.
|
||||||
@ -708,7 +718,7 @@ Preview filtering is disabled and files are displayed as they are when the value
|
|||||||
promptfmt string (default "\033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m")
|
promptfmt string (default "\033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m")
|
||||||
|
|
||||||
Format string of the prompt shown in the top line.
|
Format string of the prompt shown in the top line.
|
||||||
Special expansions are provided, '%u' as the user name, '%h' as the host name, '%w' as the working directory, '%d' as the working directory with a trailing path separator, '%f' as the file name, and '%F' as the current filter.
|
Special expansions are provided, '%u' as the user name, '%h' as the host name, '%w' as the working directory, '%d' as the working directory with a trailing path separator, '%f' as the file name, and '%F' as the current filter. '%S' may be used once and will provide a spacer so that the following parts are right aligned on the screen.
|
||||||
Home folder is shown as '~' in the working directory expansion.
|
Home folder is shown as '~' in the working directory expansion.
|
||||||
Directory names are automatically shortened to a single character starting from the left most parent when the prompt does not fit to the screen.
|
Directory names are automatically shortened to a single character starting from the left most parent when the prompt does not fit to the screen.
|
||||||
|
|
||||||
@ -862,7 +872,7 @@ This shell command can be defined to override the default 'paste' command.
|
|||||||
|
|
||||||
rename
|
rename
|
||||||
|
|
||||||
This shell command can be defined to override the default 'paste' command.
|
This shell command can be defined to override the default 'rename' command.
|
||||||
|
|
||||||
delete
|
delete
|
||||||
|
|
||||||
@ -920,9 +930,10 @@ Command 'map' is used to bind a key to a command which can be builtin command, c
|
|||||||
map i $less $f # shell command
|
map i $less $f # shell command
|
||||||
map U !du -csh * # waiting shell command
|
map U !du -csh * # waiting shell command
|
||||||
|
|
||||||
Command 'cmap' is used to bind a key to a command line command which can only be one of the builtin commands:
|
Command 'cmap' is used to bind a key on the command line to a command line command or any other command:
|
||||||
|
|
||||||
cmap <c-g> cmd-escape
|
cmap <c-g> cmd-escape
|
||||||
|
cmap <a-i> set incsearch!
|
||||||
|
|
||||||
You can delete an existing binding by leaving the expression empty:
|
You can delete an existing binding by leaving the expression empty:
|
||||||
|
|
||||||
@ -1046,7 +1057,7 @@ A first attempt to write such a command may look like this:
|
|||||||
if [ -z "$fs" ]; then
|
if [ -z "$fs" ]; then
|
||||||
mv "$f" ~/.trash
|
mv "$f" ~/.trash
|
||||||
else
|
else
|
||||||
IFS="`printf '\n\t'`"; mv $fs ~/.trash
|
IFS="$(printf '\n\t')"; mv $fs ~/.trash
|
||||||
fi
|
fi
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@ -1057,7 +1068,7 @@ We can use this variable to get rid of the conditional:
|
|||||||
|
|
||||||
cmd trash ${{
|
cmd trash ${{
|
||||||
mkdir -p ~/.trash
|
mkdir -p ~/.trash
|
||||||
IFS="`printf '\n\t'`"; mv $fx ~/.trash
|
IFS="$(printf '\n\t')"; mv $fx ~/.trash
|
||||||
}}
|
}}
|
||||||
|
|
||||||
The trash directory is checked each time the command is executed.
|
The trash directory is checked each time the command is executed.
|
||||||
@ -1065,13 +1076,13 @@ We can move it outside of the command so it would only run once at startup:
|
|||||||
|
|
||||||
${{ mkdir -p ~/.trash }}
|
${{ mkdir -p ~/.trash }}
|
||||||
|
|
||||||
cmd trash ${{ IFS="`printf '\n\t'`"; mv $fx ~/.trash }}
|
cmd trash ${{ IFS="$(printf '\n\t')"; mv $fx ~/.trash }}
|
||||||
|
|
||||||
Since these are one liners, we can drop '{{' and '}}':
|
Since these are one liners, we can drop '{{' and '}}':
|
||||||
|
|
||||||
$mkdir -p ~/.trash
|
$mkdir -p ~/.trash
|
||||||
|
|
||||||
cmd trash $IFS="`printf '\n\t'`"; mv $fx ~/.trash
|
cmd trash $IFS="$(printf '\n\t')"; mv $fx ~/.trash
|
||||||
|
|
||||||
Finally note that we set 'IFS' variable manually in these commands.
|
Finally note that we set 'IFS' variable manually in these commands.
|
||||||
Instead we could use the 'ifs' option to set it for all shell commands (i.e. 'set ifs "\n"').
|
Instead we could use the 'ifs' option to set it for all shell commands (i.e. 'set ifs "\n"').
|
||||||
@ -1217,14 +1228,10 @@ You can enable 'globsearch' option to match with a glob pattern.
|
|||||||
Globbing supports '*' to match any sequence, '?' to match any character, and '[...]' or '[^...] to match character sets or ranges.
|
Globbing supports '*' to match any sequence, '?' to match any character, and '[...]' or '[^...] to match character sets or ranges.
|
||||||
You can enable 'incsearch' option to jump to the current match at each keystroke while typing.
|
You can enable 'incsearch' option to jump to the current match at each keystroke while typing.
|
||||||
In this mode, you can either use 'cmd-enter' to accept the search or use 'cmd-escape' to cancel the search.
|
In this mode, you can either use 'cmd-enter' to accept the search or use 'cmd-escape' to cancel the search.
|
||||||
Alternatively, you can also map some other commands with 'cmap' to accept the search and execute the command immediately afterwards.
|
You can also map some other commands with 'cmap' to accept the search and execute the command immediately afterwards.
|
||||||
Possible candidates are 'up', 'down' and their variants, 'top', 'bottom', 'updir', and 'open' commands.
|
For example, you can use the right arrow key to finish the search and open the selected file with the following mapping:
|
||||||
For example, you can use arrow keys to finish the search with the following mappings:
|
|
||||||
|
|
||||||
cmap <up> up
|
cmap <right> :cmd-enter; open
|
||||||
cmap <down> down
|
|
||||||
cmap <left> updir
|
|
||||||
cmap <right> open
|
|
||||||
|
|
||||||
Finding mechanism is implemented with commands 'find' (default 'f'), 'find-back' (default 'F'), 'find-next' (default ';'), 'find-prev' (default ',').
|
Finding mechanism is implemented with commands 'find' (default 'f'), 'find-back' (default 'F'), 'find-next' (default ';'), 'find-prev' (default ',').
|
||||||
You can disable 'anchorfind' option to match a pattern at an arbitrary position in the filename instead of the beginning.
|
You can disable 'anchorfind' option to match a pattern at an arbitrary position in the filename instead of the beginning.
|
||||||
@ -1254,8 +1261,7 @@ It is possible to use different command types:
|
|||||||
You may want to use either file extensions or mime types from 'file' command:
|
You may want to use either file extensions or mime types from 'file' command:
|
||||||
|
|
||||||
cmd open ${{
|
cmd open ${{
|
||||||
test -L $f && f=$(readlink -f $f)
|
case $(file --mime-type -Lb $f) in
|
||||||
case $(file --mime-type $f -b) in
|
|
||||||
text/*) vi $fx;;
|
text/*) vi $fx;;
|
||||||
*) for f in $fx; do xdg-open $f > /dev/null 2> /dev/null & done;;
|
*) for f in $fx; do xdg-open $f > /dev/null 2> /dev/null & done;;
|
||||||
esac
|
esac
|
||||||
@ -1274,7 +1280,7 @@ Previewing Files
|
|||||||
|
|
||||||
lf previews files on the preview pane by printing the file until the end or the preview pane is filled.
|
lf previews files on the preview pane by printing the file until the end or the preview pane is filled.
|
||||||
This output can be enhanced by providing a custom preview script for filtering.
|
This output can be enhanced by providing a custom preview script for filtering.
|
||||||
This can be used to highlight source codes, list contents of archive files or view pdf or image files to name few.
|
This can be used to highlight source codes, list contents of archive files or view pdf or image files to name a few.
|
||||||
For coloring lf recognizes ansi escape codes.
|
For coloring lf recognizes ansi escape codes.
|
||||||
|
|
||||||
In order to use this feature you need to set the value of 'previewer' option to the path of an executable file.
|
In order to use this feature you need to set the value of 'previewer' option to the path of an executable file.
|
||||||
|
60
docstring.go
60
docstring.go
@ -89,6 +89,7 @@ The following command line commands are provided by lf:
|
|||||||
cmd-complete (default '<tab>')
|
cmd-complete (default '<tab>')
|
||||||
cmd-menu-complete
|
cmd-menu-complete
|
||||||
cmd-menu-complete-back
|
cmd-menu-complete-back
|
||||||
|
cmd-menu-accept
|
||||||
cmd-enter (default '<c-j>' and '<enter>')
|
cmd-enter (default '<c-j>' and '<enter>')
|
||||||
cmd-interrupt (default '<c-c>')
|
cmd-interrupt (default '<c-c>')
|
||||||
cmd-history-next (default '<c-n>')
|
cmd-history-next (default '<c-n>')
|
||||||
@ -128,6 +129,7 @@ The following options can be used to customize the behavior of lf:
|
|||||||
globsearch bool (default off)
|
globsearch bool (default off)
|
||||||
hidden bool (default off)
|
hidden bool (default off)
|
||||||
hiddenfiles []string (default '.*')
|
hiddenfiles []string (default '.*')
|
||||||
|
history bool (default on)
|
||||||
icons bool (default off)
|
icons bool (default off)
|
||||||
ifs string (default '')
|
ifs string (default '')
|
||||||
ignorecase bool (default on)
|
ignorecase bool (default on)
|
||||||
@ -519,6 +521,10 @@ to these commands (e.g. 'cmap <tab> cmd-menu-complete; cmap <backtab>
|
|||||||
cmd-menu-complete-back'). You can use the assigned keys assigned to display
|
cmd-menu-complete-back'). You can use the assigned keys assigned to display
|
||||||
the menu and then cycle through completion options.
|
the menu and then cycle through completion options.
|
||||||
|
|
||||||
|
cmd-menu-accept
|
||||||
|
|
||||||
|
Accept the currently selected match in menu completion and close the menu.
|
||||||
|
|
||||||
cmd-enter (default '<c-j>' and '<enter>')
|
cmd-enter (default '<c-j>' and '<enter>')
|
||||||
|
|
||||||
Execute the current line.
|
Execute the current line.
|
||||||
@ -600,9 +606,10 @@ Automatically quit server when there are no clients left connected.
|
|||||||
|
|
||||||
Set the path of a cleaner file. The file should be executable. This file is
|
Set the path of a cleaner file. The file should be executable. This file is
|
||||||
called if previewing is enabled, the previewer is set, and the previously
|
called if previewing is enabled, the previewer is set, and the previously
|
||||||
selected file had its preview cache disabled. One argument is passed to the
|
selected file had its preview cache disabled. Five arguments are passed to
|
||||||
file, path to the file whose preview should be cleaned. Preview clearing is
|
the file, (1) current file name, (2) width, (3) height, (4) horizontal
|
||||||
disabled when the value of this option is left empty.
|
position, and (5) vertical position of preview pane respectively. Preview
|
||||||
|
clearing is disabled when the value of this option is left empty.
|
||||||
|
|
||||||
dircache bool (default on)
|
dircache bool (default on)
|
||||||
|
|
||||||
@ -665,6 +672,10 @@ any sequence, '?' to match any character, and '[...]' or '[^...] to match
|
|||||||
character sets or ranges. In addition, if a pattern starts with '!', then
|
character sets or ranges. In addition, if a pattern starts with '!', then
|
||||||
its matches are excluded from hidden files.
|
its matches are excluded from hidden files.
|
||||||
|
|
||||||
|
history bool (default on)
|
||||||
|
|
||||||
|
Save command history.
|
||||||
|
|
||||||
icons bool (default off)
|
icons bool (default off)
|
||||||
|
|
||||||
Show icons before each item in the list.
|
Show icons before each item in the list.
|
||||||
@ -754,10 +765,11 @@ value of this option is left empty.
|
|||||||
Format string of the prompt shown in the top line. Special expansions are
|
Format string of the prompt shown in the top line. Special expansions are
|
||||||
provided, '%u' as the user name, '%h' as the host name, '%w' as the working
|
provided, '%u' as the user name, '%h' as the host name, '%w' as the working
|
||||||
directory, '%d' as the working directory with a trailing path separator,
|
directory, '%d' as the working directory with a trailing path separator,
|
||||||
'%f' as the file name, and '%F' as the current filter. Home folder is shown
|
'%f' as the file name, and '%F' as the current filter. '%S' may be used once
|
||||||
as '~' in the working directory expansion. Directory names are automatically
|
and will provide a spacer so that the following parts are right aligned on
|
||||||
shortened to a single character starting from the left most parent when the
|
the screen. Home folder is shown as '~' in the working directory expansion.
|
||||||
prompt does not fit to the screen.
|
Directory names are automatically shortened to a single character starting
|
||||||
|
from the left most parent when the prompt does not fit to the screen.
|
||||||
|
|
||||||
ratios []int (default '1:2:3')
|
ratios []int (default '1:2:3')
|
||||||
|
|
||||||
@ -928,7 +940,7 @@ This shell command can be defined to override the default 'paste' command.
|
|||||||
|
|
||||||
rename
|
rename
|
||||||
|
|
||||||
This shell command can be defined to override the default 'paste' command.
|
This shell command can be defined to override the default 'rename' command.
|
||||||
|
|
||||||
delete
|
delete
|
||||||
|
|
||||||
@ -993,10 +1005,11 @@ command, custom command, or shell command:
|
|||||||
map i $less $f # shell command
|
map i $less $f # shell command
|
||||||
map U !du -csh * # waiting shell command
|
map U !du -csh * # waiting shell command
|
||||||
|
|
||||||
Command 'cmap' is used to bind a key to a command line command which can
|
Command 'cmap' is used to bind a key on the command line to a command line
|
||||||
only be one of the builtin commands:
|
command or any other command:
|
||||||
|
|
||||||
cmap <c-g> cmd-escape
|
cmap <c-g> cmd-escape
|
||||||
|
cmap <a-i> set incsearch!
|
||||||
|
|
||||||
You can delete an existing binding by leaving the expression empty:
|
You can delete an existing binding by leaving the expression empty:
|
||||||
|
|
||||||
@ -1135,7 +1148,7 @@ this:
|
|||||||
if [ -z "$fs" ]; then
|
if [ -z "$fs" ]; then
|
||||||
mv "$f" ~/.trash
|
mv "$f" ~/.trash
|
||||||
else
|
else
|
||||||
IFS="'printf '\n\t''"; mv $fs ~/.trash
|
IFS="$(printf '\n\t')"; mv $fs ~/.trash
|
||||||
fi
|
fi
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@ -1146,7 +1159,7 @@ conditional:
|
|||||||
|
|
||||||
cmd trash ${{
|
cmd trash ${{
|
||||||
mkdir -p ~/.trash
|
mkdir -p ~/.trash
|
||||||
IFS="'printf '\n\t''"; mv $fx ~/.trash
|
IFS="$(printf '\n\t')"; mv $fx ~/.trash
|
||||||
}}
|
}}
|
||||||
|
|
||||||
The trash directory is checked each time the command is executed. We can
|
The trash directory is checked each time the command is executed. We can
|
||||||
@ -1154,13 +1167,13 @@ move it outside of the command so it would only run once at startup:
|
|||||||
|
|
||||||
${{ mkdir -p ~/.trash }}
|
${{ mkdir -p ~/.trash }}
|
||||||
|
|
||||||
cmd trash ${{ IFS="'printf '\n\t''"; mv $fx ~/.trash }}
|
cmd trash ${{ IFS="$(printf '\n\t')"; mv $fx ~/.trash }}
|
||||||
|
|
||||||
Since these are one liners, we can drop '{{' and '}}':
|
Since these are one liners, we can drop '{{' and '}}':
|
||||||
|
|
||||||
$mkdir -p ~/.trash
|
$mkdir -p ~/.trash
|
||||||
|
|
||||||
cmd trash $IFS="'printf '\n\t''"; mv $fx ~/.trash
|
cmd trash $IFS="$(printf '\n\t')"; mv $fx ~/.trash
|
||||||
|
|
||||||
Finally note that we set 'IFS' variable manually in these commands. Instead
|
Finally note that we set 'IFS' variable manually in these commands. Instead
|
||||||
we could use the 'ifs' option to set it for all shell commands (i.e. 'set
|
we could use the 'ifs' option to set it for all shell commands (i.e. 'set
|
||||||
@ -1345,16 +1358,12 @@ pattern. Globbing supports '*' to match any sequence, '?' to match any
|
|||||||
character, and '[...]' or '[^...] to match character sets or ranges. You can
|
character, and '[...]' or '[^...] to match character sets or ranges. You can
|
||||||
enable 'incsearch' option to jump to the current match at each keystroke
|
enable 'incsearch' option to jump to the current match at each keystroke
|
||||||
while typing. In this mode, you can either use 'cmd-enter' to accept the
|
while typing. In this mode, you can either use 'cmd-enter' to accept the
|
||||||
search or use 'cmd-escape' to cancel the search. Alternatively, you can also
|
search or use 'cmd-escape' to cancel the search. You can also map some other
|
||||||
map some other commands with 'cmap' to accept the search and execute the
|
commands with 'cmap' to accept the search and execute the command
|
||||||
command immediately afterwards. Possible candidates are 'up', 'down' and
|
immediately afterwards. For example, you can use the right arrow key to
|
||||||
their variants, 'top', 'bottom', 'updir', and 'open' commands. For example,
|
finish the search and open the selected file with the following mapping:
|
||||||
you can use arrow keys to finish the search with the following mappings:
|
|
||||||
|
|
||||||
cmap <up> up
|
cmap <right> :cmd-enter; open
|
||||||
cmap <down> down
|
|
||||||
cmap <left> updir
|
|
||||||
cmap <right> open
|
|
||||||
|
|
||||||
Finding mechanism is implemented with commands 'find' (default 'f'),
|
Finding mechanism is implemented with commands 'find' (default 'f'),
|
||||||
'find-back' (default 'F'), 'find-next' (default ';'), 'find-prev' (default
|
'find-back' (default 'F'), 'find-next' (default ';'), 'find-prev' (default
|
||||||
@ -1390,8 +1399,7 @@ You may want to use either file extensions or mime types from 'file'
|
|||||||
command:
|
command:
|
||||||
|
|
||||||
cmd open ${{
|
cmd open ${{
|
||||||
test -L $f && f=$(readlink -f $f)
|
case $(file --mime-type -Lb $f) in
|
||||||
case $(file --mime-type $f -b) in
|
|
||||||
text/*) vi $fx;;
|
text/*) vi $fx;;
|
||||||
*) for f in $fx; do xdg-open $f > /dev/null 2> /dev/null & done;;
|
*) for f in $fx; do xdg-open $f > /dev/null 2> /dev/null & done;;
|
||||||
esac
|
esac
|
||||||
@ -1414,7 +1422,7 @@ Previewing Files
|
|||||||
lf previews files on the preview pane by printing the file until the end or
|
lf previews files on the preview pane by printing the file until the end or
|
||||||
the preview pane is filled. This output can be enhanced by providing a
|
the preview pane is filled. This output can be enhanced by providing a
|
||||||
custom preview script for filtering. This can be used to highlight source
|
custom preview script for filtering. This can be used to highlight source
|
||||||
codes, list contents of archive files or view pdf or image files to name
|
codes, list contents of archive files or view pdf or image files to name a
|
||||||
few. For coloring lf recognizes ansi escape codes.
|
few. For coloring lf recognizes ansi escape codes.
|
||||||
|
|
||||||
In order to use this feature you need to set the value of 'previewer' option
|
In order to use this feature you need to set the value of 'previewer' option
|
||||||
|
@ -36,8 +36,7 @@ map O $mimeopen --ask $f
|
|||||||
# use either file extensions and/or mime types here. Below uses an editor for
|
# use either file extensions and/or mime types here. Below uses an editor for
|
||||||
# text files and a file opener for the rest.
|
# text files and a file opener for the rest.
|
||||||
cmd open ${{
|
cmd open ${{
|
||||||
test -L $f && f=$(readlink -f $f)
|
case $(file --mime-type -Lb $f) in
|
||||||
case $(file --mime-type $f -b) in
|
|
||||||
text/*) $EDITOR $fx;;
|
text/*) $EDITOR $fx;;
|
||||||
*) for f in $fx; do setsid $OPENER $f > /dev/null 2> /dev/null & done;;
|
*) for f in $fx; do setsid $OPENER $f > /dev/null 2> /dev/null & done;;
|
||||||
esac
|
esac
|
||||||
|
77
eval.go
77
eval.go
@ -125,6 +125,12 @@ func (e *setExpr) eval(app *app, args []string) {
|
|||||||
app.nav.position()
|
app.nav.position()
|
||||||
app.ui.sort()
|
app.ui.sort()
|
||||||
app.ui.loadFile(app.nav, true)
|
app.ui.loadFile(app.nav, true)
|
||||||
|
case "history":
|
||||||
|
gOpts.history = true
|
||||||
|
case "nohistory":
|
||||||
|
gOpts.history = false
|
||||||
|
case "history!":
|
||||||
|
gOpts.history = !gOpts.history
|
||||||
case "icons":
|
case "icons":
|
||||||
gOpts.icons = true
|
gOpts.icons = true
|
||||||
case "noicons":
|
case "noicons":
|
||||||
@ -505,6 +511,9 @@ func update(app *app) {
|
|||||||
switch {
|
switch {
|
||||||
case gOpts.incsearch && app.ui.cmdPrefix == "/":
|
case gOpts.incsearch && app.ui.cmdPrefix == "/":
|
||||||
app.nav.search = string(app.ui.cmdAccLeft) + string(app.ui.cmdAccRight)
|
app.nav.search = string(app.ui.cmdAccLeft) + string(app.ui.cmdAccRight)
|
||||||
|
if app.nav.search == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
dir := app.nav.currDir()
|
dir := app.nav.currDir()
|
||||||
old := dir.ind
|
old := dir.ind
|
||||||
@ -519,6 +528,9 @@ func update(app *app) {
|
|||||||
}
|
}
|
||||||
case gOpts.incsearch && app.ui.cmdPrefix == "?":
|
case gOpts.incsearch && app.ui.cmdPrefix == "?":
|
||||||
app.nav.search = string(app.ui.cmdAccLeft) + string(app.ui.cmdAccRight)
|
app.nav.search = string(app.ui.cmdAccLeft) + string(app.ui.cmdAccRight)
|
||||||
|
if app.nav.search == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
dir := app.nav.currDir()
|
dir := app.nav.currDir()
|
||||||
old := dir.ind
|
old := dir.ind
|
||||||
@ -588,6 +600,8 @@ func normal(app *app) {
|
|||||||
app.ui.cmdAccRight = nil
|
app.ui.cmdAccRight = nil
|
||||||
app.ui.cmdTmp = nil
|
app.ui.cmdTmp = nil
|
||||||
app.ui.cmdPrefix = ""
|
app.ui.cmdPrefix = ""
|
||||||
|
|
||||||
|
app.cmdHistoryInd = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func insert(app *app, arg string) {
|
func insert(app *app, arg string) {
|
||||||
@ -1581,7 +1595,7 @@ func (e *callExpr) eval(app *app, args []string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the completition menu as in bash/vim
|
// Reset the completion menu as in bash/vim
|
||||||
// and update the pertinent variables
|
// and update the pertinent variables
|
||||||
if app.ui.menuBuf != nil {
|
if app.ui.menuBuf != nil {
|
||||||
app.ui.menuBuf = nil
|
app.ui.menuBuf = nil
|
||||||
@ -1622,27 +1636,21 @@ func (e *callExpr) eval(app *app, args []string) {
|
|||||||
app.ui.menuBuf = b
|
app.ui.menuBuf = b
|
||||||
}
|
}
|
||||||
case "cmd-menu-complete":
|
case "cmd-menu-complete":
|
||||||
var target []rune
|
|
||||||
|
|
||||||
// target will store the current menu query
|
|
||||||
// note that, as we will store the current selected value
|
// note that, as we will store the current selected value
|
||||||
// in cmdAccLeft, we can not call the complete function with its
|
// in cmdAccLeft, we can not call the complete function with its
|
||||||
// value, as it is already a final completition result
|
// value, as it is already a final completion result
|
||||||
if app.ui.menuBuf == nil {
|
if app.ui.menuBuf == nil {
|
||||||
target = app.ui.cmdAccLeft
|
|
||||||
app.ui.cmdTmp = app.ui.cmdAccLeft
|
app.ui.cmdTmp = app.ui.cmdAccLeft
|
||||||
} else {
|
|
||||||
target = app.ui.cmdTmp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var matches []string
|
var matches []string
|
||||||
switch app.ui.cmdPrefix {
|
switch app.ui.cmdPrefix {
|
||||||
case ":":
|
case ":":
|
||||||
matches, app.ui.cmdAccLeft = completeCmd(target)
|
matches, app.ui.cmdAccLeft = completeCmd(app.ui.cmdTmp)
|
||||||
case "/", "?":
|
case "/", "?":
|
||||||
matches, app.ui.cmdAccLeft = completeFile(target)
|
matches, app.ui.cmdAccLeft = completeFile(app.ui.cmdTmp)
|
||||||
case "$", "%", "!", "&":
|
case "$", "%", "!", "&":
|
||||||
matches, app.ui.cmdAccLeft = completeShell(target)
|
matches, app.ui.cmdAccLeft = completeShell(app.ui.cmdTmp)
|
||||||
default:
|
default:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1650,13 +1658,12 @@ func (e *callExpr) eval(app *app, args []string) {
|
|||||||
app.ui.draw(app.nav)
|
app.ui.draw(app.nav)
|
||||||
|
|
||||||
if len(matches) > 1 {
|
if len(matches) > 1 {
|
||||||
step := 1
|
// Check if the tab-selection was inited
|
||||||
|
|
||||||
// Check if the tab-selecttion was inited
|
|
||||||
if app.ui.menuSelected == -2 {
|
if app.ui.menuSelected == -2 {
|
||||||
app.ui.menuSelected = -1
|
app.ui.menuSelected = -1
|
||||||
} else {
|
} else {
|
||||||
app.ui.menuSelected = mod(app.ui.menuSelected+step, len(matches))
|
app.ui.menuSelected++
|
||||||
|
app.ui.menuSelected %= len(matches)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := listMatchesMenu(app.ui, matches); err != nil {
|
if err := listMatchesMenu(app.ui, matches); err != nil {
|
||||||
@ -1667,23 +1674,18 @@ func (e *callExpr) eval(app *app, args []string) {
|
|||||||
app.ui.menuSelected = -2
|
app.ui.menuSelected = -2
|
||||||
}
|
}
|
||||||
case "cmd-menu-complete-back":
|
case "cmd-menu-complete-back":
|
||||||
var target []rune
|
|
||||||
|
|
||||||
if app.ui.menuBuf == nil {
|
if app.ui.menuBuf == nil {
|
||||||
target = app.ui.cmdAccLeft
|
|
||||||
app.ui.cmdTmp = app.ui.cmdAccLeft
|
app.ui.cmdTmp = app.ui.cmdAccLeft
|
||||||
} else {
|
|
||||||
target = app.ui.cmdTmp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var matches []string
|
var matches []string
|
||||||
switch app.ui.cmdPrefix {
|
switch app.ui.cmdPrefix {
|
||||||
case ":":
|
case ":":
|
||||||
matches, app.ui.cmdAccLeft = completeCmd(target)
|
matches, app.ui.cmdAccLeft = completeCmd(app.ui.cmdTmp)
|
||||||
case "/", "?":
|
case "/", "?":
|
||||||
matches, app.ui.cmdAccLeft = completeFile(target)
|
matches, app.ui.cmdAccLeft = completeFile(app.ui.cmdTmp)
|
||||||
case "$", "%", "!", "&":
|
case "$", "%", "!", "&":
|
||||||
matches, app.ui.cmdAccLeft = completeShell(target)
|
matches, app.ui.cmdAccLeft = completeShell(app.ui.cmdTmp)
|
||||||
default:
|
default:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1691,13 +1693,13 @@ func (e *callExpr) eval(app *app, args []string) {
|
|||||||
app.ui.draw(app.nav)
|
app.ui.draw(app.nav)
|
||||||
|
|
||||||
if len(matches) > 1 {
|
if len(matches) > 1 {
|
||||||
step := -1
|
// Check if the tab-selection was inited
|
||||||
|
|
||||||
// Check if the tab-selecttion was inited
|
|
||||||
if app.ui.menuSelected == -2 {
|
if app.ui.menuSelected == -2 {
|
||||||
app.ui.menuSelected = -1
|
app.ui.menuSelected = -1
|
||||||
|
} else if app.ui.menuSelected <= 0 {
|
||||||
|
app.ui.menuSelected = len(matches) - 1
|
||||||
} else {
|
} else {
|
||||||
app.ui.menuSelected = mod(app.ui.menuSelected+step, len(matches))
|
app.ui.menuSelected--
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := listMatchesMenu(app.ui, matches); err != nil {
|
if err := listMatchesMenu(app.ui, matches); err != nil {
|
||||||
@ -1707,6 +1709,9 @@ func (e *callExpr) eval(app *app, args []string) {
|
|||||||
app.ui.menuBuf = nil
|
app.ui.menuBuf = nil
|
||||||
app.ui.menuSelected = -2
|
app.ui.menuSelected = -2
|
||||||
}
|
}
|
||||||
|
case "cmd-menu-accept":
|
||||||
|
app.ui.menuBuf = nil
|
||||||
|
app.ui.menuSelected = -2
|
||||||
case "cmd-enter":
|
case "cmd-enter":
|
||||||
s := string(append(app.ui.cmdAccLeft, app.ui.cmdAccRight...))
|
s := string(append(app.ui.cmdAccLeft, app.ui.cmdAccRight...))
|
||||||
if len(s) == 0 && app.ui.cmdPrefix != "filter: " {
|
if len(s) == 0 && app.ui.cmdPrefix != "filter: " {
|
||||||
@ -1881,31 +1886,27 @@ func (e *callExpr) eval(app *app, args []string) {
|
|||||||
app.cmdHistoryInd--
|
app.cmdHistoryInd--
|
||||||
}
|
}
|
||||||
if app.cmdHistoryInd == 0 {
|
if app.cmdHistoryInd == 0 {
|
||||||
app.ui.menuBuf = nil
|
normal(app)
|
||||||
app.ui.menuSelected = -2
|
|
||||||
app.ui.cmdAccLeft = nil
|
|
||||||
app.ui.cmdAccRight = nil
|
|
||||||
app.ui.cmdTmp = nil
|
|
||||||
app.ui.cmdPrefix = ":"
|
app.ui.cmdPrefix = ":"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cmd := app.cmdHistory[len(app.cmdHistory)-app.cmdHistoryInd]
|
historyInd := app.cmdHistoryInd
|
||||||
|
cmd := app.cmdHistory[len(app.cmdHistory)-historyInd]
|
||||||
normal(app)
|
normal(app)
|
||||||
|
app.cmdHistoryInd = historyInd
|
||||||
app.ui.cmdPrefix = cmd.prefix
|
app.ui.cmdPrefix = cmd.prefix
|
||||||
app.ui.cmdAccLeft = []rune(cmd.value)
|
app.ui.cmdAccLeft = []rune(cmd.value)
|
||||||
case "cmd-history-prev":
|
case "cmd-history-prev":
|
||||||
if app.ui.cmdPrefix == ">" {
|
if app.ui.cmdPrefix == ">" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if app.ui.cmdPrefix == "" {
|
|
||||||
app.cmdHistoryInd = 0
|
|
||||||
}
|
|
||||||
if app.cmdHistoryInd == len(app.cmdHistory) {
|
if app.cmdHistoryInd == len(app.cmdHistory) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
app.cmdHistoryInd++
|
historyInd := app.cmdHistoryInd + 1
|
||||||
cmd := app.cmdHistory[len(app.cmdHistory)-app.cmdHistoryInd]
|
cmd := app.cmdHistory[len(app.cmdHistory)-historyInd]
|
||||||
normal(app)
|
normal(app)
|
||||||
|
app.cmdHistoryInd = historyInd
|
||||||
app.ui.cmdPrefix = cmd.prefix
|
app.ui.cmdPrefix = cmd.prefix
|
||||||
app.ui.cmdAccLeft = []rune(cmd.value)
|
app.ui.cmdAccLeft = []rune(cmd.value)
|
||||||
case "cmd-delete":
|
case "cmd-delete":
|
||||||
|
2
icons.go
2
icons.go
@ -156,7 +156,7 @@ func (im iconMap) get(f *file) string {
|
|||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
if val, ok := im["*"+f.ext]; ok {
|
if val, ok := im["*"+strings.ToLower(f.ext)]; ok {
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
43
lf.1
43
lf.1
@ -102,6 +102,7 @@ The following command line commands are provided by lf:
|
|||||||
cmd-complete (default '<tab>')
|
cmd-complete (default '<tab>')
|
||||||
cmd-menu-complete
|
cmd-menu-complete
|
||||||
cmd-menu-complete-back
|
cmd-menu-complete-back
|
||||||
|
cmd-menu-accept
|
||||||
cmd-enter (default '<c-j>' and '<enter>')
|
cmd-enter (default '<c-j>' and '<enter>')
|
||||||
cmd-interrupt (default '<c-c>')
|
cmd-interrupt (default '<c-c>')
|
||||||
cmd-history-next (default '<c-n>')
|
cmd-history-next (default '<c-n>')
|
||||||
@ -143,6 +144,7 @@ The following options can be used to customize the behavior of lf:
|
|||||||
globsearch bool (default off)
|
globsearch bool (default off)
|
||||||
hidden bool (default off)
|
hidden bool (default off)
|
||||||
hiddenfiles []string (default '.*')
|
hiddenfiles []string (default '.*')
|
||||||
|
history bool (default on)
|
||||||
icons bool (default off)
|
icons bool (default off)
|
||||||
ifs string (default '')
|
ifs string (default '')
|
||||||
ignorecase bool (default on)
|
ignorecase bool (default on)
|
||||||
@ -599,6 +601,12 @@ Autocomplete the current word.
|
|||||||
.PP
|
.PP
|
||||||
Autocomplete the current word with menu selection. You need to assign keys to these commands (e.g. 'cmap <tab> cmd-menu-complete; cmap <backtab> cmd-menu-complete-back'). You can use the assigned keys assigned to display the menu and then cycle through completion options.
|
Autocomplete the current word with menu selection. You need to assign keys to these commands (e.g. 'cmap <tab> cmd-menu-complete; cmap <backtab> cmd-menu-complete-back'). You can use the assigned keys assigned to display the menu and then cycle through completion options.
|
||||||
.PP
|
.PP
|
||||||
|
.EX
|
||||||
|
cmd-menu-accept
|
||||||
|
.EE
|
||||||
|
.PP
|
||||||
|
Accept the currently selected match in menu completion and close the menu.
|
||||||
|
.PP
|
||||||
.EX
|
.EX
|
||||||
cmd-enter (default '<c-j>' and '<enter>')
|
cmd-enter (default '<c-j>' and '<enter>')
|
||||||
.EE
|
.EE
|
||||||
@ -704,7 +712,7 @@ Automatically quit server when there are no clients left connected.
|
|||||||
cleaner string (default '') (not called if empty)
|
cleaner string (default '') (not called if empty)
|
||||||
.EE
|
.EE
|
||||||
.PP
|
.PP
|
||||||
Set the path of a cleaner file. The file should be executable. This file is called if previewing is enabled, the previewer is set, and the previously selected file had its preview cache disabled. One argument is passed to the file, path to the file whose preview should be cleaned. Preview clearing is disabled when the value of this option is left empty.
|
Set the path of a cleaner file. The file should be executable. This file is called if previewing is enabled, the previewer is set, and the previously selected file had its preview cache disabled. Five arguments are passed to the file, (1) current file name, (2) width, (3) height, (4) horizontal position, and (5) vertical position of preview pane respectively. Preview clearing is disabled when the value of this option is left empty.
|
||||||
.PP
|
.PP
|
||||||
.EX
|
.EX
|
||||||
dircache bool (default on)
|
dircache bool (default on)
|
||||||
@ -772,6 +780,12 @@ Show hidden files. On Unix systems, hidden files are determined by the value of
|
|||||||
.PP
|
.PP
|
||||||
List of hidden file glob patterns. Patterns can be given as relative or absolute paths. Globbing supports the usual special characters, '*' to match any sequence, '?' to match any character, and '[...]' or '[^...] to match character sets or ranges. In addition, if a pattern starts with '!', then its matches are excluded from hidden files.
|
List of hidden file glob patterns. Patterns can be given as relative or absolute paths. Globbing supports the usual special characters, '*' to match any sequence, '?' to match any character, and '[...]' or '[^...] to match character sets or ranges. In addition, if a pattern starts with '!', then its matches are excluded from hidden files.
|
||||||
.PP
|
.PP
|
||||||
|
.EX
|
||||||
|
history bool (default on)
|
||||||
|
.EE
|
||||||
|
.PP
|
||||||
|
Save command history.
|
||||||
|
.PP
|
||||||
.EX
|
.EX
|
||||||
icons bool (default off)
|
icons bool (default off)
|
||||||
.EE
|
.EE
|
||||||
@ -860,7 +874,7 @@ Set the path of a previewer file to filter the content of regular files for prev
|
|||||||
promptfmt string (default "\e033[32;1m%u@%h\e033[0m:\e033[34;1m%d\e033[0m\e033[1m%f\e033[0m")
|
promptfmt string (default "\e033[32;1m%u@%h\e033[0m:\e033[34;1m%d\e033[0m\e033[1m%f\e033[0m")
|
||||||
.EE
|
.EE
|
||||||
.PP
|
.PP
|
||||||
Format string of the prompt shown in the top line. Special expansions are provided, '%u' as the user name, '%h' as the host name, '%w' as the working directory, '%d' as the working directory with a trailing path separator, '%f' as the file name, and '%F' as the current filter. Home folder is shown as '~' in the working directory expansion. Directory names are automatically shortened to a single character starting from the left most parent when the prompt does not fit to the screen.
|
Format string of the prompt shown in the top line. Special expansions are provided, '%u' as the user name, '%h' as the host name, '%w' as the working directory, '%d' as the working directory with a trailing path separator, '%f' as the file name, and '%F' as the current filter. '%S' may be used once and will provide a spacer so that the following parts are right aligned on the screen. Home folder is shown as '~' in the working directory expansion. Directory names are automatically shortened to a single character starting from the left most parent when the prompt does not fit to the screen.
|
||||||
.PP
|
.PP
|
||||||
.EX
|
.EX
|
||||||
ratios []int (default '1:2:3')
|
ratios []int (default '1:2:3')
|
||||||
@ -1060,7 +1074,7 @@ This shell command can be defined to override the default 'paste' command.
|
|||||||
rename
|
rename
|
||||||
.EE
|
.EE
|
||||||
.PP
|
.PP
|
||||||
This shell command can be defined to override the default 'paste' command.
|
This shell command can be defined to override the default 'rename' command.
|
||||||
.PP
|
.PP
|
||||||
.EX
|
.EX
|
||||||
delete
|
delete
|
||||||
@ -1127,10 +1141,11 @@ Command 'map' is used to bind a key to a command which can be builtin command, c
|
|||||||
map U !du -csh * # waiting shell command
|
map U !du -csh * # waiting shell command
|
||||||
.EE
|
.EE
|
||||||
.PP
|
.PP
|
||||||
Command 'cmap' is used to bind a key to a command line command which can only be one of the builtin commands:
|
Command 'cmap' is used to bind a key on the command line to a command line command or any other command:
|
||||||
.PP
|
.PP
|
||||||
.EX
|
.EX
|
||||||
cmap <c-g> cmd-escape
|
cmap <c-g> cmd-escape
|
||||||
|
cmap <a-i> set incsearch!
|
||||||
.EE
|
.EE
|
||||||
.PP
|
.PP
|
||||||
You can delete an existing binding by leaving the expression empty:
|
You can delete an existing binding by leaving the expression empty:
|
||||||
@ -1276,7 +1291,7 @@ Regular shell commands are the most basic command type that is useful for many p
|
|||||||
if [ -z "$fs" ]; then
|
if [ -z "$fs" ]; then
|
||||||
mv "$f" ~/.trash
|
mv "$f" ~/.trash
|
||||||
else
|
else
|
||||||
IFS="`printf '\en\et'`"; mv $fs ~/.trash
|
IFS="$(printf '\en\et')"; mv $fs ~/.trash
|
||||||
fi
|
fi
|
||||||
}}
|
}}
|
||||||
.EE
|
.EE
|
||||||
@ -1286,7 +1301,7 @@ We check '$fs' to see if there are any selected files. Otherwise we just delete
|
|||||||
.EX
|
.EX
|
||||||
cmd trash ${{
|
cmd trash ${{
|
||||||
mkdir -p ~/.trash
|
mkdir -p ~/.trash
|
||||||
IFS="`printf '\en\et'`"; mv $fx ~/.trash
|
IFS="$(printf '\en\et')"; mv $fx ~/.trash
|
||||||
}}
|
}}
|
||||||
.EE
|
.EE
|
||||||
.PP
|
.PP
|
||||||
@ -1297,7 +1312,7 @@ The trash directory is checked each time the command is executed. We can move it
|
|||||||
.EE
|
.EE
|
||||||
.PP
|
.PP
|
||||||
.EX
|
.EX
|
||||||
cmd trash ${{ IFS="`printf '\en\et'`"; mv $fx ~/.trash }}
|
cmd trash ${{ IFS="$(printf '\en\et')"; mv $fx ~/.trash }}
|
||||||
.EE
|
.EE
|
||||||
.PP
|
.PP
|
||||||
Since these are one liners, we can drop '{{' and '}}':
|
Since these are one liners, we can drop '{{' and '}}':
|
||||||
@ -1307,7 +1322,7 @@ Since these are one liners, we can drop '{{' and '}}':
|
|||||||
.EE
|
.EE
|
||||||
.PP
|
.PP
|
||||||
.EX
|
.EX
|
||||||
cmd trash $IFS="`printf '\en\et'`"; mv $fx ~/.trash
|
cmd trash $IFS="$(printf '\en\et')"; mv $fx ~/.trash
|
||||||
.EE
|
.EE
|
||||||
.PP
|
.PP
|
||||||
Finally note that we set 'IFS' variable manually in these commands. Instead we could use the 'ifs' option to set it for all shell commands (i.e. 'set ifs "\en"'). This can be especially useful for interactive use (e.g. '$rm $f' or '$rm $fs' would simply work). This option is not set by default as it can behave unexpectedly for new users. However, use of this option is highly recommended and it is assumed in the rest of the documentation.
|
Finally note that we set 'IFS' variable manually in these commands. Instead we could use the 'ifs' option to set it for all shell commands (i.e. 'set ifs "\en"'). This can be especially useful for interactive use (e.g. '$rm $f' or '$rm $fs' would simply work). This option is not set by default as it can behave unexpectedly for new users. However, use of this option is highly recommended and it is assumed in the rest of the documentation.
|
||||||
@ -1411,13 +1426,10 @@ By default, lf does not assign 'delete' command to a key to protect new users. Y
|
|||||||
.SH SEARCHING FILES
|
.SH SEARCHING FILES
|
||||||
There are two mechanisms implemented in lf to search a file in the current directory. Searching is the traditional method to move the selection to a file matching a given pattern. Finding is an alternative way to search for a pattern possibly using fewer keystrokes.
|
There are two mechanisms implemented in lf to search a file in the current directory. Searching is the traditional method to move the selection to a file matching a given pattern. Finding is an alternative way to search for a pattern possibly using fewer keystrokes.
|
||||||
.PP
|
.PP
|
||||||
Searching mechanism is implemented with commands 'search' (default '/'), 'search-back' (default '?'), 'search-next' (default 'n'), and 'search-prev' (default 'N'). You can enable 'globsearch' option to match with a glob pattern. Globbing supports '*' to match any sequence, '?' to match any character, and '[...]' or '[^...] to match character sets or ranges. You can enable 'incsearch' option to jump to the current match at each keystroke while typing. In this mode, you can either use 'cmd-enter' to accept the search or use 'cmd-escape' to cancel the search. Alternatively, you can also map some other commands with 'cmap' to accept the search and execute the command immediately afterwards. Possible candidates are 'up', 'down' and their variants, 'top', 'bottom', 'updir', and 'open' commands. For example, you can use arrow keys to finish the search with the following mappings:
|
Searching mechanism is implemented with commands 'search' (default '/'), 'search-back' (default '?'), 'search-next' (default 'n'), and 'search-prev' (default 'N'). You can enable 'globsearch' option to match with a glob pattern. Globbing supports '*' to match any sequence, '?' to match any character, and '[...]' or '[^...] to match character sets or ranges. You can enable 'incsearch' option to jump to the current match at each keystroke while typing. In this mode, you can either use 'cmd-enter' to accept the search or use 'cmd-escape' to cancel the search. You can also map some other commands with 'cmap' to accept the search and execute the command immediately afterwards. For example, you can use the right arrow key to finish the search and open the selected file with the following mapping:
|
||||||
.PP
|
.PP
|
||||||
.EX
|
.EX
|
||||||
cmap <up> up
|
cmap <right> :cmd-enter; open
|
||||||
cmap <down> down
|
|
||||||
cmap <left> updir
|
|
||||||
cmap <right> open
|
|
||||||
.EE
|
.EE
|
||||||
.PP
|
.PP
|
||||||
Finding mechanism is implemented with commands 'find' (default 'f'), 'find-back' (default 'F'), 'find-next' (default ';'), 'find-prev' (default ','). You can disable 'anchorfind' option to match a pattern at an arbitrary position in the filename instead of the beginning. You can set the number of keys to match using 'findlen' option. If you set this value to zero, then the the keys are read until there is only a single match. Default values of these two options are set to jump to the first file with the given initial.
|
Finding mechanism is implemented with commands 'find' (default 'f'), 'find-back' (default 'F'), 'find-next' (default ';'), 'find-prev' (default ','). You can disable 'anchorfind' option to match a pattern at an arbitrary position in the filename instead of the beginning. You can set the number of keys to match using 'findlen' option. If you set this value to zero, then the the keys are read until there is only a single match. Default values of these two options are set to jump to the first file with the given initial.
|
||||||
@ -1440,8 +1452,7 @@ You may want to use either file extensions or mime types from 'file' command:
|
|||||||
.PP
|
.PP
|
||||||
.EX
|
.EX
|
||||||
cmd open ${{
|
cmd open ${{
|
||||||
test -L $f && f=$(readlink -f $f)
|
case $(file --mime-type -Lb $f) in
|
||||||
case $(file --mime-type $f -b) in
|
|
||||||
text/*) vi $fx;;
|
text/*) vi $fx;;
|
||||||
*) for f in $fx; do xdg-open $f > /dev/null 2> /dev/null & done;;
|
*) for f in $fx; do xdg-open $f > /dev/null 2> /dev/null & done;;
|
||||||
esac
|
esac
|
||||||
@ -1458,7 +1469,7 @@ Following command is provided by default:
|
|||||||
.PP
|
.PP
|
||||||
You may also use any other existing file openers as you like. Possible options are 'libfile-mimeinfo-perl' (executable name is 'mimeopen'), 'rifle' (ranger's default file opener), or 'mimeo' to name a few.
|
You may also use any other existing file openers as you like. Possible options are 'libfile-mimeinfo-perl' (executable name is 'mimeopen'), 'rifle' (ranger's default file opener), or 'mimeo' to name a few.
|
||||||
.SH PREVIEWING FILES
|
.SH PREVIEWING FILES
|
||||||
lf previews files on the preview pane by printing the file until the end or the preview pane is filled. This output can be enhanced by providing a custom preview script for filtering. This can be used to highlight source codes, list contents of archive files or view pdf or image files to name few. For coloring lf recognizes ansi escape codes.
|
lf previews files on the preview pane by printing the file until the end or the preview pane is filled. This output can be enhanced by providing a custom preview script for filtering. This can be used to highlight source codes, list contents of archive files or view pdf or image files to name a few. For coloring lf recognizes ansi escape codes.
|
||||||
.PP
|
.PP
|
||||||
In order to use this feature you need to set the value of 'previewer' option to the path of an executable file. Five arguments are passed to the file, (1) current file name, (2) width, (3) height, (4) horizontal position, and (5) vertical position of preview pane respectively. Output of the execution is printed in the preview pane. You may also want to use the same script in your pager mapping as well:
|
In order to use this feature you need to set the value of 'previewer' option to the path of an executable file. Five arguments are passed to the file, (1) current file name, (2) width, (3) height, (4) horizontal position, and (5) vertical position of preview pane respectively. Output of the execution is printed in the preview pane. You may also want to use the same script in your pager mapping as well:
|
||||||
.PP
|
.PP
|
||||||
|
6
misc.go
6
misc.go
@ -91,7 +91,7 @@ func unescape(s string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This function splits the given string by whitespaces. It is aware of escaped
|
// This function splits the given string by whitespaces. It is aware of escaped
|
||||||
// whitespaces so that they are not splitted unintentionally.
|
// whitespaces so that they are not split unintentionally.
|
||||||
func tokenize(s string) []string {
|
func tokenize(s string) []string {
|
||||||
esc := false
|
esc := false
|
||||||
var buf []rune
|
var buf []rune
|
||||||
@ -295,10 +295,6 @@ func max(a, b int) int {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func mod(a, b int) int {
|
|
||||||
return (a%b + b) % b
|
|
||||||
}
|
|
||||||
|
|
||||||
// We don't need no generic code
|
// We don't need no generic code
|
||||||
// We don't need no type control
|
// We don't need no type control
|
||||||
// No dark templates in compiler
|
// No dark templates in compiler
|
||||||
|
8
nav.go
8
nav.go
@ -612,17 +612,21 @@ func (nav *nav) previewLoop(ui *ui) {
|
|||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
win := ui.wins[len(ui.wins)-1]
|
||||||
if clear && len(gOpts.previewer) != 0 && len(gOpts.cleaner) != 0 && nav.volatilePreview {
|
if clear && len(gOpts.previewer) != 0 && len(gOpts.cleaner) != 0 && nav.volatilePreview {
|
||||||
nav.exportFiles()
|
nav.exportFiles()
|
||||||
exportOpts()
|
exportOpts()
|
||||||
cmd := exec.Command(gOpts.cleaner, prev)
|
cmd := exec.Command(gOpts.cleaner, prev,
|
||||||
|
strconv.Itoa(win.w),
|
||||||
|
strconv.Itoa(win.h),
|
||||||
|
strconv.Itoa(win.x),
|
||||||
|
strconv.Itoa(win.y))
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
log.Printf("cleaning preview: %s", err)
|
log.Printf("cleaning preview: %s", err)
|
||||||
}
|
}
|
||||||
nav.volatilePreview = false
|
nav.volatilePreview = false
|
||||||
}
|
}
|
||||||
if len(path) != 0 {
|
if len(path) != 0 {
|
||||||
win := ui.wins[len(ui.wins)-1]
|
|
||||||
nav.preview(path, win)
|
nav.preview(path, win)
|
||||||
prev = path
|
prev = path
|
||||||
}
|
}
|
||||||
|
2
opts.go
2
opts.go
@ -67,6 +67,7 @@ var gOpts struct {
|
|||||||
truncatechar string
|
truncatechar string
|
||||||
ratios []int
|
ratios []int
|
||||||
hiddenfiles []string
|
hiddenfiles []string
|
||||||
|
history bool
|
||||||
info []string
|
info []string
|
||||||
shellopts []string
|
shellopts []string
|
||||||
keys map[string]expr
|
keys map[string]expr
|
||||||
@ -117,6 +118,7 @@ func init() {
|
|||||||
gOpts.truncatechar = "~"
|
gOpts.truncatechar = "~"
|
||||||
gOpts.ratios = []int{1, 2, 3}
|
gOpts.ratios = []int{1, 2, 3}
|
||||||
gOpts.hiddenfiles = []string{".*"}
|
gOpts.hiddenfiles = []string{".*"}
|
||||||
|
gOpts.history = true
|
||||||
gOpts.info = nil
|
gOpts.info = nil
|
||||||
gOpts.shellopts = nil
|
gOpts.shellopts = nil
|
||||||
gOpts.sortType = sortType{naturalSort, dirfirstSort}
|
gOpts.sortType = sortType{naturalSort, dirfirstSort}
|
||||||
|
16
ui.go
16
ui.go
@ -733,6 +733,13 @@ func (ui *ui) drawPromptLine(nav *nav) {
|
|||||||
prompt = strings.Replace(prompt, "%F", "", -1)
|
prompt = strings.Replace(prompt, "%F", "", -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// spacer
|
||||||
|
avail := ui.promptWin.w - printLength(prompt) + 2
|
||||||
|
if avail > 0 {
|
||||||
|
prompt = strings.Replace(prompt, "%S", strings.Repeat(" ", avail), 1)
|
||||||
|
}
|
||||||
|
prompt = strings.Replace(prompt, "%S", "", -1)
|
||||||
|
|
||||||
ui.promptWin.print(ui.screen, 0, 0, st, prompt)
|
ui.promptWin.print(ui.screen, 0, 0, st, prompt)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1258,13 +1265,14 @@ func listMatchesMenu(ui *ui, matches []string) error {
|
|||||||
|
|
||||||
// Handle menu tab match only if wanted
|
// Handle menu tab match only if wanted
|
||||||
if ui.menuSelected == i {
|
if ui.menuSelected == i {
|
||||||
|
comp := []rune(escape(target))
|
||||||
toks := tokenize(string(ui.cmdAccLeft))
|
toks := tokenize(string(ui.cmdAccLeft))
|
||||||
last := toks[len(toks)-1]
|
_, last := filepath.Split(toks[len(toks)-1])
|
||||||
|
|
||||||
if strings.Contains(target, last) {
|
if last == "" {
|
||||||
ui.cmdAccLeft = append(ui.cmdAccLeft[:len(ui.cmdAccLeft)-len(last)], []rune(target)...)
|
ui.cmdAccLeft = append(ui.cmdAccLeft, comp...)
|
||||||
} else {
|
} else {
|
||||||
ui.cmdAccLeft = append(ui.cmdAccLeft, []rune(target)...)
|
ui.cmdAccLeft = append(ui.cmdAccLeft[:len(ui.cmdAccLeft)-len([]rune(last))], comp...)
|
||||||
}
|
}
|
||||||
|
|
||||||
target = fmt.Sprintf("\033[7m%s\033[0m%*s", target, wcol-len(target), "")
|
target = fmt.Sprintf("\033[7m%s\033[0m%*s", target, wcol-len(target), "")
|
||||||
|
Loading…
Reference in New Issue
Block a user