diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index 09d7e893..fabe5d2b 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -438,10 +438,10 @@ Do not display scrollbar. A synonym for \fB--scrollbar=''\fB Input prompt (default: '> ') .TP .BI "--pointer=" "STR" -Pointer to the current line (default: '>') +Pointer to the current line (default: '▌' or '>' depending on \fB--no-unicode\fR) .TP .BI "--marker=" "STR" -Multi-select marker (default: '>') +Multi-select marker (default: '▏' or '>' depending on \fB--no-unicode\fR) .TP .BI "--header=" "STR" The given string will be printed as the sticky header. The lines are displayed diff --git a/src/options.go b/src/options.go index ded8a92d..efeb75a9 100644 --- a/src/options.go +++ b/src/options.go @@ -83,8 +83,8 @@ const Usage = `usage: fzf [options] --scrollbar[=C1[C2]] Scrollbar character(s) (each for main and preview window) --no-scrollbar Hide scrollbar --prompt=STR Input prompt (default: '> ') - --pointer=STR Pointer to the current line (default: '>') - --marker=STR Multi-select marker (default: '>') + --pointer=STR Pointer to the current line (default: '▌' or '>') + --marker=STR Multi-select marker (default: '▏' or '>') --header=STR String to print as header --header-lines=N The first N lines of the input are treated as header --header-first Print header before the prompt line @@ -420,8 +420,8 @@ type Options struct { Separator *string JumpLabels string Prompt string - Pointer string - Marker string + Pointer *string + Marker *string Query string Select1 bool Exit0 bool @@ -515,8 +515,8 @@ func defaultOptions() *Options { Separator: nil, JumpLabels: defaultJumpLabels, Prompt: "> ", - Pointer: ">", - Marker: ">", + Pointer: nil, + Marker: nil, Query: "", Select1: false, Exit0: false, @@ -2153,13 +2153,15 @@ func parseOptions(opts *Options, allArgs []string) error { if err != nil { return err } - opts.Pointer = firstLine(str) + str = firstLine(str) + opts.Pointer = &str case "--marker": str, err := nextString(allArgs, &i, "selected sign string required") if err != nil { return err } - opts.Marker = firstLine(str) + str = firstLine(str) + opts.Marker = &str case "--sync": opts.Sync = true case "--no-sync", "--async": @@ -2395,9 +2397,11 @@ func parseOptions(opts *Options, allArgs []string) error { } else if match, value := optString(arg, "--prompt="); match { opts.Prompt = value } else if match, value := optString(arg, "--pointer="); match { - opts.Pointer = firstLine(value) + str := firstLine(value) + opts.Pointer = &str } else if match, value := optString(arg, "--marker="); match { - opts.Marker = firstLine(value) + str := firstLine(value) + opts.Marker = &str } else if match, value := optString(arg, "-n", "--nth="); match { if opts.Nth, err = splitNth(value); err != nil { return err @@ -2586,11 +2590,27 @@ func postProcessOptions(opts *Options) error { opts.BorderShape = tui.BorderNone } - if err := validateSign(opts.Pointer, "pointer"); err != nil { + if opts.Pointer == nil { + defaultPointer := "▌" + if !opts.Unicode { + defaultPointer = ">" + } + opts.Pointer = &defaultPointer + } + + if opts.Marker == nil { + defaultMarker := "▏" + if !opts.Unicode { + defaultMarker = ">" + } + opts.Marker = &defaultMarker + } + + if err := validateSign(*opts.Pointer, "pointer"); err != nil { return err } - if err := validateSign(opts.Marker, "marker"); err != nil { + if err := validateSign(*opts.Marker, "marker"); err != nil { return err } diff --git a/src/terminal.go b/src/terminal.go index 530c9eb6..01960552 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -811,8 +811,8 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor lastAction: actStart, lastFocus: minItem.Index()} t.prompt, t.promptLen = t.parsePrompt(opts.Prompt) - t.pointer, t.pointerLen = t.processTabs([]rune(opts.Pointer), 0) - t.marker, t.markerLen = t.processTabs([]rune(opts.Marker), 0) + t.pointer, t.pointerLen = t.processTabs([]rune(*opts.Pointer), 0) + t.marker, t.markerLen = t.processTabs([]rune(*opts.Marker), 0) // Pre-calculated empty pointer and marker signs t.pointerEmpty = strings.Repeat(" ", t.pointerLen) t.markerEmpty = strings.Repeat(" ", t.markerLen) diff --git a/test/test_go.rb b/test/test_go.rb index 5563c080..d70c0bcc 100755 --- a/test/test_go.rb +++ b/test/test_go.rb @@ -24,7 +24,7 @@ DEFAULT_TIMEOUT = 10 FILE = File.expand_path(__FILE__) BASE = File.expand_path('..', __dir__) Dir.chdir(BASE) -FZF = "FZF_DEFAULT_OPTS=--no-scrollbar FZF_DEFAULT_COMMAND= #{BASE}/bin/fzf" +FZF = "FZF_DEFAULT_OPTS=\"--no-scrollbar --pointer \\> --marker \\>\" FZF_DEFAULT_COMMAND= #{BASE}/bin/fzf" def wait since = Time.now @@ -66,7 +66,7 @@ class Shell end def fish - "unset #{UNSETS.join(' ')}; FZF_DEFAULT_OPTS=--no-scrollbar fish_history= fish" + "unset #{UNSETS.join(' ')}; FZF_DEFAULT_OPTS=\"--no-scrollbar --pointer '>' --marker '>'\" fish_history= fish" end end end @@ -3397,12 +3397,16 @@ module TestShell end def test_ctrl_r_multiline + # NOTE: Current bash implementation shows an extra new line if there's + # only enty in the history + tmux.send_keys ':', :Enter tmux.send_keys 'echo "foo', :Enter, 'bar"', :Enter tmux.until { |lines| assert_equal %w[foo bar], lines[-2..] } tmux.prepare tmux.send_keys 'C-r' tmux.until { |lines| assert_equal '>', lines[-1] } tmux.send_keys 'foo bar' + tmux.until { |lines| assert lines[-4]&.match?(/"foo/) } unless shell == :zsh tmux.until { |lines| assert lines[-3]&.match?(/bar"␊?/) } tmux.send_keys :Enter tmux.until { |lines| assert lines[-1]&.match?(/bar"␊?/) } @@ -3742,7 +3746,7 @@ unset <%= UNSETS.join(' ') %> unset $(env | sed -n /^_fzf_orig/s/=.*//p) unset $(declare -F | sed -n "/_fzf/s/.*-f //p") -export FZF_DEFAULT_OPTS=--no-scrollbar +export FZF_DEFAULT_OPTS="--no-scrollbar --pointer '>' --marker '>'" # Setup fzf # ---------