13 Commits

Author SHA1 Message Date
Enno
ddc14a6a54 Avoid cooked terminal mode (#1604)
as `:help system()` states

		When prepended by |:silent| the terminal will not be set to
		cooked mode.  This is meant to be used for commands that do
		not need the user to type.  It avoids stray characters showing
		up on the screen which require |CTRL-L| to remove. >
			:silent let f = system('ls *.vim')
2025-12-09 08:49:13 +09:00
Junegunn Choi
879db51d09 Update README.md 2025-09-03 09:59:37 +09:00
phanium
3725f364cc Fix cmd hisotry correctly (#1594) 2025-06-20 17:04:48 +09:00
Junegunn Choi
98dcd77a18 Fix dictionary alignments 2025-06-08 10:51:25 +09:00
Scott Lai
a2ed9fb885 Add :BMarks command (#1593)
And allow passing arguments of :marks to :Marks command. Close #1158.

Co-authored-by: Junegunn Choi <junegunn.c@gmail.com>
2025-06-08 10:48:17 +09:00
Max Coplan
3ed6ac56d0 feat(preview): teach preview.sh to print directories (#1590) 2025-05-24 19:00:23 +09:00
Mo-tmd
3cb44a8ba5 Add workaround for normal! bug in nvim terminals (#1588)
There's a known issue regarding `normal` usage in neovim. See
https://github.com/neovim/neovim/issues/4895 for more details.

As a temporary workaround, use setpos to set the
bookmark instead.
2025-04-16 07:58:52 +09:00
Junegunn Choi
1fff637559 Use FugitiveWorkTree() to find the git root
Fix #1586
2025-03-21 17:31:10 +09:00
Junegunn Choi
245eaf8e50 Allow specifying command-level fzf options
Close #1583
2025-03-03 19:35:54 +09:00
Simon Désaulniers
f06bd1e69b autoload/fzf: don't user fzf#shellescape in favor of shellescape (#1582)
fzf#shellescape should only be used when building commands that fzf will run.
2025-02-22 10:41:20 +09:00
Junegunn Choi
6cda389bde Update README 2025-02-02 23:27:53 +09:00
Junegunn Choi
b3a49d7993 Apply --scheme=path where appropriate
See https://github.com/junegunn/fzf/pull/4192
2025-01-30 00:26:53 +09:00
Junegunn Choi
80d1cc2e68 Clean up scroll offset expression 2025-01-30 00:19:58 +09:00
5 changed files with 89 additions and 46 deletions

View File

@@ -1,20 +1,16 @@
<div align="center">
<sup>Special thanks to:</sup>
<br>
<br>
<a href="https://warp.dev/?utm_source=github&utm_medium=referral&utm_campaign=fzfvim_20240209">
<div>
<img src="https://raw.githubusercontent.com/junegunn/i/master/warp.png" width="300" alt="Warp">
</div>
<b>Warp is a modern, Rust-based terminal with AI built in so you and your team can build great software, faster.</b>
<div>
<sup>Visit warp.dev to learn more.</sup>
</div>
</a>
<br>
<hr>
<div align="center" markdown="1">
<sup>Special thanks to:</sup>
<br>
<a href="https://tuple.app/fzf.vim">
<img alt="Tuple's sponsorship image" src="https://raw.githubusercontent.com/junegunn/i/master/tuple.png" width="400">
</a>
### [Tuple, the premier screen sharing app for developers](https://tuple.app/fzf.vim)
[Available for MacOS & Windows](https://tuple.app/fzf.vim)<br>
</div>
<br>
---
fzf :heart: vim
===============
@@ -97,6 +93,7 @@ Commands
| `:BTags [QUERY]` | Tags in the current buffer |
| `:Changes` | Changelist across all open buffers |
| `:Marks` | Marks |
| `:BMarks` | Marks in the current buffer |
| `:Jumps` | Jumps |
| `:Windows` | Windows |
| `:Locate PATTERN` | `locate` command output |
@@ -201,6 +198,19 @@ let g:fzf_vim.tags_command = 'ctags -R'
let g:fzf_vim.commands_expect = 'alt-enter,ctrl-x'
```
#### Command-level fzf options
You can set fzf options for each command by setting
`g:fzf_vim.{command}_options`.
```vim
" In string
let g:fzf_vim.buffers_options = '--style full --border-label " Open Buffers "'
" In list (No need to quote or escape values)
let g:fzf_vim.buffers_options = ['--style', 'full', '--border-label', ' Open Buffers ']
```
#### List type to handle multiple selections
The following commands will fill the quickfix list when multiple entries are

View File

@@ -340,6 +340,10 @@ function! s:fzf(name, opts, extra)
let eopts = has_key(extra, 'options') ? remove(extra, 'options') : ''
let merged = extend(copy(a:opts), extra)
call s:merge_opts(merged, eopts)
" Command-level fzf options
call s:merge_opts(merged, s:conf(a:name.'_options', []))
return fzf#run(s:wrap(a:name, merged, bang))
endfunction
@@ -365,7 +369,7 @@ function! s:action_for(key, ...)
" errors. e.g. E471: Argument required: tab drop
if !a:0
if !edit
normal! m'
call setpos("''", getpos('.'))
silent! call s:execute_silent(cmd)
endif
else
@@ -374,7 +378,7 @@ function! s:action_for(key, ...)
" instructed to stay on the current buffer.
let stay = edit && (a:0 > 1 && a:2 || fnamemodify(a:1, ':p') ==# expand('%:p'))
if !stay
normal! m'
call setpos("''", getpos('.'))
call s:execute_silent((len(cmd) ? cmd : 'edit').' '.s:escape(a:1))
endif
endif
@@ -455,7 +459,7 @@ function! fzf#vim#files(dir, ...)
let dir = s:shortpath()
endif
let args.options = ['-m', '--prompt', strwidth(dir) < &columns / 2 - 20 ? dir : '> ']
let args.options = ['--scheme', 'path', '-m', '--prompt', strwidth(dir) < &columns / 2 - 20 ? dir : '> ']
call s:merge_opts(args, s:conf('files_options', []))
return s:fzf('files', args, a:000)
endfunction
@@ -665,9 +669,8 @@ function! s:history_sink(type, lines)
let key = a:lines[0]
let item = matchstr(a:lines[1], ' *[0-9]\+ *\zs.*')
if key == 'ctrl-e'
call histadd(a:type, item)
redraw
call feedkeys(a:type."\<up>", 'n')
call feedkeys(a:type.item, 'nt')
else
if a:type == ':'
call histadd(a:type, item)
@@ -711,8 +714,11 @@ endfunction
" ------------------------------------------------------------------
function! s:get_git_root(dir)
if empty(a:dir) && exists('*FugitiveWorkTree')
return FugitiveWorkTree()
endif
let dir = len(a:dir) ? a:dir : substitute(split(expand('%:p:h'), '[/\\]\.git\([/\\]\|$\)')[0], '^fugitive://', '', '')
let root = systemlist('git -C ' . fzf#shellescape(dir) . ' rev-parse --show-toplevel')[0]
silent let root = systemlist('git -C ' . shellescape(dir) . ' rev-parse --show-toplevel')[0]
return v:shell_error ? '' : (len(a:dir) ? fnamemodify(a:dir, ':p') : root)
endfunction
@@ -748,7 +754,7 @@ function! fzf#vim#gitfiles(args, ...)
return s:fzf('gfiles', {
\ 'source': source,
\ 'dir': root,
\ 'options': '-m --read0 --prompt "GitFiles> "'
\ 'options': '--scheme path -m --read0 --prompt "GitFiles> "'
\}, a:000)
endif
@@ -766,7 +772,7 @@ function! fzf#vim#gitfiles(args, ...)
let wrapped = fzf#wrap({
\ 'source': prefix . '-c color.status=always status --short --untracked-files=all',
\ 'dir': root,
\ 'options': ['--ansi', '--multi', '--nth', '2..,..', '--tiebreak=index', '--prompt', 'GitFiles?> ', '--preview', preview]
\ 'options': ['--scheme', 'path', '--ansi', '--multi', '--nth', '2..,..', '--tiebreak=index', '--prompt', 'GitFiles?> ', '--preview', preview]
\})
call s:remove_layout(wrapped)
let wrapped.common_sink = remove(wrapped, 'sink*')
@@ -856,7 +862,7 @@ function! fzf#vim#buffers(...)
return s:fzf('buffers', {
\ 'source': map(sorted, 'fzf#vim#_format_buffer(v:val)'),
\ 'sink*': s:function('s:bufopen'),
\ 'options': ['+m', '-x', '--tiebreak=index', header_lines, '--ansi', '-d', '\t', '--with-nth', '3..', '-n', '2,1..2', '--prompt', 'Buf> ', '--query', query, '--preview-window', '+{2}-/2', '--tabstop', tabstop]
\ 'options': ['+m', '-x', '--tiebreak=index', header_lines, '--ansi', '-d', '\t', '--with-nth', '3..', '-n', '2,1..2', '--prompt', 'Buf> ', '--query', query, '--preview-window', '+{2}/2', '--tabstop', tabstop]
\}, args)
endfunction
@@ -965,7 +971,7 @@ function! fzf#vim#grep(grep_command, ...)
let opts = {
\ 'options': ['--ansi', '--prompt', capname.'> ',
\ '--multi', '--bind', 'alt-a:select-all,alt-d:deselect-all',
\ '--delimiter', ':', '--preview-window', '+{2}-/2']
\ '--delimiter', ':', '--preview-window', '+{2}/2']
\}
if len(args) && type(args[0]) == s:TYPE.bool
call remove(args, 0)
@@ -1001,11 +1007,11 @@ function! fzf#vim#grep2(command_prefix, query, ...)
let name = join(words, '-')
let fallback = s:is_win ? '' : ' || :'
let opts = {
\ 'source': s:is_win ? 'cd .' : ':',
\ 'source': s:is_win ? 'cd .' : ':',
\ 'options': ['--ansi', '--prompt', toupper(name).'> ', '--query', a:query,
\ '--disabled',
\ '--multi', '--bind', 'alt-a:select-all,alt-d:deselect-all',
\ '--delimiter', ':', '--preview-window', '+{2}-/2']
\ '--delimiter', ':', '--preview-window', '+{2}/2']
\}
let [opts, suffix] = s:grep_multi_line(opts)
@@ -1082,7 +1088,7 @@ function! fzf#vim#buffer_tags(query, ...)
return s:fzf('btags', {
\ 'source': s:btags_source(tag_cmds),
\ 'sink*': s:function('s:btags_sink'),
\ 'options': s:reverse_list(['-m', '-d', '\t', '--with-nth', '1,4..', '-n', '1', '--prompt', 'BTags> ', '--query', a:query, '--preview-window', '+{3}-/2'])}, args)
\ 'options': s:reverse_list(['-m', '-d', '\t', '--with-nth', '1,4..', '-n', '1', '--prompt', 'BTags> ', '--query', a:query, '--preview-window', '+{3}/2'])}, args)
catch
return s:warn(v:exception)
endtry
@@ -1229,9 +1235,9 @@ function! s:command_sink(lines)
endif
let cmd = matchstr(a:lines[1], s:tab.'\zs\S*\ze'.s:tab)
if empty(a:lines[0])
call feedkeys(':'.cmd.(a:lines[1][0] == '!' ? '' : ' '), 'n')
call feedkeys(':'.cmd.(a:lines[1][0] == '!' ? '' : ' '), 'nt')
else
call feedkeys(':'.cmd."\<cr>", 'n')
call feedkeys(':'.cmd."\<cr>", 'nt')
endif
endfunction
@@ -1355,15 +1361,25 @@ function! s:mark_sink(lines)
execute 'normal! `'.matchstr(a:lines[1], '\S').'zz'
endfunction
function! fzf#vim#marks(...)
function! fzf#vim#marks(...) abort
let [initial_marks, extra] = (a:0 && type(a:1) == type('')) ?
\ [a:1, a:000[1:]] : ['', a:000]
redir => cout
silent marks
execute 'silent! marks' initial_marks
redir END
let list = split(cout, "\n")
" If first line is not the expected header, no marks found
if empty(list) || list[0] =~# '^E'
return s:warn('No marks found')
endif
return s:fzf('marks', {
\ 'source': extend(list[0:0], map(list[1:], 's:format_mark(v:val)')),
\ 'sink*': s:function('s:mark_sink'),
\ 'options': '+m -x --ansi --tiebreak=index --header-lines 1 --tiebreak=begin --prompt "Marks> "'}, a:000)
\ 'options': '+m -x --ansi --tiebreak=index --header-lines 1 --tiebreak=begin --prompt "Marks> "'}, extra)
endfunction
" ------------------------------------------------------------------
@@ -1413,9 +1429,9 @@ function! fzf#vim#jumps(...)
let s:jump_current = pos
let current = -pos-1
return s:fzf('jumps', {
\ 'source' : map(s:jumplist, 's:jump_format(v:val)'),
\ 'sink*' : s:function('s:jump_sink'),
\ 'options' : ['+m', '-x', '--ansi', '--tiebreak=index', '--cycle', '--scroll-off=999', '--sync', '--bind', 'start:pos('.current.')+offset-middle', '--tac', '--tiebreak=begin', '--prompt', 'Jumps> ', '--preview-window', '+{3}-/2', '--tabstop=2', '--delimiter', '[:\s]+'],
\ 'source': map(s:jumplist, 's:jump_format(v:val)'),
\ 'sink*': s:function('s:jump_sink'),
\ 'options': ['+m', '-x', '--ansi', '--tiebreak=index', '--cycle', '--scroll-off=999', '--sync', '--bind', 'start:pos('.current.')+offset-middle', '--tac', '--tiebreak=begin', '--prompt', 'Jumps> ', '--preview-window', '+{3}/2', '--tabstop=2', '--delimiter', '[:\s]+'],
\ }, a:000)
endfunction

View File

@@ -66,7 +66,7 @@ if [[ -z "$BATCAT" ]]; then
fi
fi
if [ -z "$FZF_PREVIEW_COMMAND" ] && [ "${BATCAT:+x}" ]; then
if [ -z "$FZF_PREVIEW_COMMAND" ] && [ "${BATCAT:+x}" ] && [[ ! -d "$FILE" ]] ; then
${BATCAT} --style="${BAT_STYLE:-numbers}" --color=always --pager=never \
--highlight-line=$CENTER -- "$FILE"
exit $?
@@ -74,12 +74,15 @@ fi
FILE_LENGTH=${#FILE}
MIME=$(file --dereference --mime -- "$FILE")
if [[ "${MIME:FILE_LENGTH}" =~ binary ]]; then
if [[ "${MIME:FILE_LENGTH}" =~ binary ]] && [[ ! -d "$FILE" ]]; then
echo "$MIME"
exit 0
fi
DEFAULT_COMMAND="highlight -O ansi -l {} || coderay {} || rougify {} || cat {}"
if [[ -d "$FILE" ]]; then
DEFAULT_COMMAND="tree -C -L2 {} || ls -l --color=always {}"
fi
CMD=${FZF_PREVIEW_COMMAND:-$DEFAULT_COMMAND}
CMD=${CMD//{\}/"$(printf %q "$FILE")"}

View File

@@ -1,4 +1,4 @@
fzf-vim.txt fzf-vim Last change: October 29 2024
fzf-vim.txt fzf-vim Last change: June 8 2025
FZF-VIM - TABLE OF CONTENTS *fzf-vim* *fzf-vim-toc*
==============================================================================
@@ -14,6 +14,7 @@ FZF-VIM - TABLE OF CONTENTS *fzf-vim* *fzf-vim-to
Configuration options for fzf.vim |fzf-vim-configuration-options-for-fzf-vim|
Preview window |fzf-vim-preview-window|
Command-level options |fzf-vim-command-level-options|
Command-level fzf options |fzf-vim-command-level-fzf-options|
List type to handle multiple selections |fzf-vim-list-type-to-handle-multiple-selections|
Advanced customization |fzf-vim-advanced-customization|
Vim functions |fzf-vim-vim-functions|
@@ -109,8 +110,8 @@ COMMANDS *fzf-vim-commands*
==============================================================================
*:Files* *:GFiles* *:Buffers* *:Colors* *:Ag* *:Rg* *:RG* *:Lines* *:BLines* *:Tags* *:BTags*
*:Changes* *:Marks* *:Jumps* *:Windows* *:Locate* *:History* *:Snippets* *:Commits* *:BCommits*
*:Commands* *:Maps* *:Helptags* *:Filetypes*
*:Changes* *:Marks* *:BMarks* *:Jumps* *:Windows* *:Locate* *:History* *:Snippets* *:Commits*
*:BCommits* *:Commands* *:Maps* *:Helptags* *:Filetypes*
-----------------------+--------------------------------------------------------------------------------------
Command | List ~
@@ -129,6 +130,7 @@ COMMANDS *fzf-vim-commands*
`:BTags [QUERY]` | Tags in the current buffer
`:Changes` | Changelist across all open buffers
`:Marks` | Marks
`:BMarks` | Marks in the current buffer
`:Jumps` | Jumps
`:Windows` | Windows
`:Locate PATTERN` | `locate` command output
@@ -228,7 +230,7 @@ Command-level options~
*g:fzf_vim.commands_expect* *g:fzf_vim.tags_command* *g:fzf_vim.commits_log_options*
*g:fzf_vim.buffers_jump*
>
" [Buffers] Jump to the existing window if possible
" [Buffers] Jump to the existing window if possible (default: 0)
let g:fzf_vim.buffers_jump = 1
" [Ag|Rg|RG] Display path on a separate line for narrow screens (default: 0)
@@ -253,6 +255,19 @@ Command-level options~
let g:fzf_vim.commands_expect = 'alt-enter,ctrl-x'
<
Command-level fzf options~
*fzf-vim-command-level-fzf-options*
You can set fzf options for each command by setting
`g:fzf_vim.{command}_options`.
>
" In string
let g:fzf_vim.buffers_options = '--style full --border-label " Open Buffers "'
" In list (No need to quote or escape values)
let g:fzf_vim.buffers_options = ['--style', 'full', '--border-label', ' Open Buffers ']
<
List type to handle multiple selections~
*fzf-vim-list-type-to-handle-multiple-selections*
@@ -383,8 +398,6 @@ Example: git grep wrapper~
The following example implements `GGrep` command that works similarly to
predefined `Ag` or `Rg` using `fzf#vim#grep`.
*:LINE*
- We set the base directory to git root by setting `dir` attribute in spec
dictionary.
- {The preview script}{12} supports `grep` format (`FILE_PATH:LINE_NO:...`), so

View File

@@ -67,7 +67,8 @@ call s:defs([
\'command! -bar -bang Snippets call fzf#vim#snippets(<bang>0)',
\'command! -bar -bang Commands call fzf#vim#commands(<bang>0)',
\'command! -bar -bang Jumps call fzf#vim#jumps(fzf#vim#with_preview({ "placeholder": "{2..4}"}), <bang>0)',
\'command! -bar -bang Marks call fzf#vim#marks(<bang>0)',
\'command! -bar -bang -nargs=* Marks call fzf#vim#marks(<q-args>, <bang>0)',
\'command! -bar -bang -nargs=* BMarks call fzf#vim#marks("abcdefghijklmnopqrstuvwxyz", <bang>0)',
\'command! -bar -bang Changes call fzf#vim#changes(<bang>0)',
\'command! -bar -bang Helptags call fzf#vim#helptags(fzf#vim#with_preview({ "placeholder": "--tag {2}:{3}:{4}" }), <bang>0)',
\'command! -bar -bang Windows call fzf#vim#windows(fzf#vim#with_preview({ "placeholder": "{2}" }), <bang>0)',