From e0036b5ad208f71d02447c233a621e67185b0fff Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Sun, 15 Jan 2017 19:42:28 +0900 Subject: [PATCH] Add --filepath-word option Close #802 --- CHANGELOG.md | 2 ++ man/man1/fzf.1 | 12 ++++++++++++ src/options.go | 7 +++++++ src/terminal.go | 19 +++++++++++++++---- test/test_go.rb | 13 +++++++++++++ 5 files changed, 49 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22a5b75..d5802c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ CHANGELOG - Latin script letters will be normalized before matching so that it's easier to match against accented letters. e.g. `sodanco` can match `Só Danço Samba`. - Normalization can be disabled via `--literal` +- Added `--filepath-word` to make word-wise movements/actions (`alt-b`, + `alt-f`, `alt-bs`, `alt-d`) respect path separators 0.15.9 ------ diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index 8980316..accf3f2 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -129,6 +129,18 @@ Number of screen columns to keep to the right of the highlighted substring (default: 10). Setting it to a large value will cause the text to be positioned on the center of the screen. .TP +.B "--filepath-word" +Make word-wise movements and actions respect path separators. The following +actions are affected: + +\fBbackward-kill-word\fR +.br +\fBbackward-word\fR +.br +\fBforward-word\fR +.br +\fBkill-word\fR +.TP .BI "--jump-labels=" "CHARS" Label characters for \fBjump\fR and \fBjump-accept\fR .SS Layout diff --git a/src/options.go b/src/options.go index a0653d4..7885325 100644 --- a/src/options.go +++ b/src/options.go @@ -45,6 +45,7 @@ const usage = `usage: fzf [options] --no-hscroll Disable horizontal scroll --hscroll-off=COL Number of screen columns to keep to the right of the highlighted substring (default: 10) + --filepath-word Make word-wise movements respect path separators --jump-labels=CHARS Label characters for jump and jump-accept Layout @@ -160,6 +161,7 @@ type Options struct { Cycle bool Hscroll bool HscrollOff int + FileWord bool InlineInfo bool JumpLabels string Prompt string @@ -208,6 +210,7 @@ func defaultOptions() *Options { Cycle: false, Hscroll: true, HscrollOff: 10, + FileWord: false, InlineInfo: false, JumpLabels: defaultJumpLabels, Prompt: "> ", @@ -976,6 +979,10 @@ func parseOptions(opts *Options, allArgs []string) { opts.Hscroll = false case "--hscroll-off": opts.HscrollOff = nextInt(allArgs, &i, "hscroll offset required") + case "--filepath-word": + opts.FileWord = true + case "--no-filepath-word": + opts.FileWord = false case "--inline-info": opts.InlineInfo = true case "--no-inline-info": diff --git a/src/terminal.go b/src/terminal.go index 3a89bb4..69735d9 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -59,6 +59,8 @@ type Terminal struct { reverse bool hscroll bool hscrollOff int + wordRubout string + wordNext string cx int cy int offset int @@ -291,6 +293,13 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal { } else { renderer = tui.NewFullscreenRenderer(opts.Theme, opts.Black, opts.Mouse) } + wordRubout := "[^[:alnum:]][[:alnum:]]" + wordNext := "[[:alnum:]][^[:alnum:]]|(.$)" + if opts.FileWord { + sep := regexp.QuoteMeta(string(os.PathSeparator)) + wordRubout = fmt.Sprintf("%s[^%s]", sep, sep) + wordNext = fmt.Sprintf("[^%s]%s|(.$)", sep, sep) + } return &Terminal{ initDelay: delay, inlineInfo: opts.InlineInfo, @@ -298,6 +307,8 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal { reverse: opts.Reverse, hscroll: opts.Hscroll, hscrollOff: opts.HscrollOff, + wordRubout: wordRubout, + wordNext: wordNext, cx: len(input), cy: 0, offset: 0, @@ -1448,7 +1459,7 @@ func (t *Terminal) Loop() { } case actBackwardKillWord: if t.cx > 0 { - t.rubout("[^[:alnum:]][[:alnum:]]") + t.rubout(t.wordRubout) } case actYank: suffix := copySlice(t.input[t.cx:]) @@ -1467,12 +1478,12 @@ func (t *Terminal) Loop() { t.jumping = jumpAcceptEnabled req(reqJump) case actBackwardWord: - t.cx = findLastMatch("[^[:alnum:]][[:alnum:]]", string(t.input[:t.cx])) + 1 + t.cx = findLastMatch(t.wordRubout, string(t.input[:t.cx])) + 1 case actForwardWord: - t.cx += findFirstMatch("[[:alnum:]][^[:alnum:]]|(.$)", string(t.input[t.cx:])) + 1 + t.cx += findFirstMatch(t.wordNext, string(t.input[t.cx:])) + 1 case actKillWord: ncx := t.cx + - findFirstMatch("[[:alnum:]][^[:alnum:]]|(.$)", string(t.input[t.cx:])) + 1 + findFirstMatch(t.wordNext, string(t.input[t.cx:])) + 1 if ncx > t.cx { t.yanked = copySlice(t.input[t.cx:ncx]) t.input = append(t.input[:t.cx], t.input[ncx:]...) diff --git a/test/test_go.rb b/test/test_go.rb index e41201f..6a8e3bf 100644 --- a/test/test_go.rb +++ b/test/test_go.rb @@ -322,6 +322,19 @@ class TestGoFZF < TestBase tmux.until { |lines| lines.last !~ /^>/ } end + def test_file_word + tmux.send_keys "#{FZF} -q '--/foo bar/foo-bar/baz' --filepath-word", :Enter + tmux.until { |lines| lines.last =~ /^>/ } + + tmux.send_keys :Escape, :b + tmux.send_keys :Escape, :b + tmux.send_keys :Escape, :b + tmux.send_keys :Escape, :d + tmux.send_keys :Escape, :f + tmux.send_keys :Escape, :BSpace + tmux.until { |lines| lines.last == '> --///baz' } + end + def test_multi_order tmux.send_keys "seq 1 10 | #{fzf :multi}", :Enter tmux.until { |lines| lines.last =~ /^>/ }