mirror of
https://github.com/junegunn/fzf.git
synced 2026-09-05 06:17:05 +08:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6a6c8586c |
@@ -14,6 +14,9 @@ CHANGELOG
|
|||||||
```vim
|
```vim
|
||||||
let g:fzf_layout = { 'popup': '90%,70%' }
|
let g:fzf_layout = { 'popup': '90%,70%' }
|
||||||
```
|
```
|
||||||
|
- fzf now opens in a tmux or Zellij floating pane by default, so the window it was started from stays visible and can be used while fzf is running
|
||||||
|
- Requires tmux 3.7+ or Zellij 0.44+
|
||||||
|
- Set `g:fzf_layout` to pick a different layout
|
||||||
|
|
||||||
0.74.3
|
0.74.3
|
||||||
------
|
------
|
||||||
|
|||||||
+73
-19
@@ -1,6 +1,26 @@
|
|||||||
FZF Vim integration
|
FZF Vim integration
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
<!-- vim-markdown-toc GFM -->
|
||||||
|
|
||||||
|
* [Installation](#installation)
|
||||||
|
* [Summary](#summary)
|
||||||
|
* [`:FZF[!]`](#fzf)
|
||||||
|
* [Configuration](#configuration)
|
||||||
|
* [Examples](#examples)
|
||||||
|
* [Explanation of `g:fzf_colors`](#explanation-of-gfzf_colors)
|
||||||
|
* [`fzf#run`](#fzfrun)
|
||||||
|
* [`fzf#wrap`](#fzfwrap)
|
||||||
|
* [Global options supported by `fzf#wrap`](#global-options-supported-by-fzfwrap)
|
||||||
|
* [Tips](#tips)
|
||||||
|
* [fzf inside terminal buffer](#fzf-inside-terminal-buffer)
|
||||||
|
* [Starting fzf in a Vim popup window](#starting-fzf-in-a-vim-popup-window)
|
||||||
|
* [Starting fzf in a tmux/Zellij popup window](#starting-fzf-in-a-tmuxzellij-popup-window)
|
||||||
|
* [Hide statusline](#hide-statusline)
|
||||||
|
* [License](#license)
|
||||||
|
|
||||||
|
<!-- vim-markdown-toc -->
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@@ -133,19 +153,35 @@ let g:fzf_action = {
|
|||||||
\ 'ctrl-v': 'vsplit' }
|
\ 'ctrl-v': 'vsplit' }
|
||||||
|
|
||||||
" Default fzf layout
|
" Default fzf layout
|
||||||
" - Popup window (center of the screen)
|
if exists('$TMUX') || exists('$ZELLIJ')
|
||||||
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } }
|
" The Vim plugin will try to open fzf in a tmux or Zellij popup
|
||||||
|
" if possible (requires recent fzf and tmux/zellij) using --popup option,
|
||||||
|
" with the following argument:
|
||||||
|
let g:fzf_layout = { 'popup': '90%,60%' }
|
||||||
|
else
|
||||||
|
" If --popup option is not available, it will open in a popup window inside
|
||||||
|
" Vim (center of the screen)
|
||||||
|
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } }
|
||||||
|
endif
|
||||||
|
|
||||||
" - Popup window (center of the current window)
|
" Here are some more layout examples:
|
||||||
|
|
||||||
|
" - Tmux or Zellij popup at the bottom 40%
|
||||||
|
let g:fzf_layout = { 'popup': 'bottom,40%' }
|
||||||
|
|
||||||
|
" - Tmux or Zellij popup at the top with a different size
|
||||||
|
let g:fzf_layout = { 'popup': 'top,90%,40%' }
|
||||||
|
|
||||||
|
" - Vim popup window: at the center of the current window (relative)
|
||||||
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'relative': v:true } }
|
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'relative': v:true } }
|
||||||
|
|
||||||
" - Popup window (anchored to the bottom of the current window)
|
" - Vim popup window: anchored to the bottom of the current window
|
||||||
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'relative': v:true, 'yoffset': 1.0 } }
|
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'relative': v:true, 'yoffset': 1.0 } }
|
||||||
|
|
||||||
" - down / up / left / right
|
" - Vim split window: down / up / left / right
|
||||||
let g:fzf_layout = { 'down': '40%' }
|
let g:fzf_layout = { 'down': '40%' }
|
||||||
|
|
||||||
" - Window using a Vim command
|
" - Vim window using a Vim command
|
||||||
let g:fzf_layout = { 'window': 'enew' }
|
let g:fzf_layout = { 'window': 'enew' }
|
||||||
let g:fzf_layout = { 'window': '-tabnew' }
|
let g:fzf_layout = { 'window': '-tabnew' }
|
||||||
let g:fzf_layout = { 'window': '10new' }
|
let g:fzf_layout = { 'window': '10new' }
|
||||||
@@ -408,10 +444,10 @@ Tips
|
|||||||
|
|
||||||
### fzf inside terminal buffer
|
### fzf inside terminal buffer
|
||||||
|
|
||||||
On the latest versions of Vim and Neovim, fzf will start in a terminal buffer.
|
When fzf is configured to start in a terminal buffer inside Vim or Neovim, you
|
||||||
If you find the default ANSI colors to be different, consider configuring the
|
may find the default ANSI colors to be different. In that case, configure the
|
||||||
colors using `g:terminal_ansi_colors` in regular Vim or `g:terminal_color_x`
|
colors using `g:terminal_ansi_colors` in regular Vim or `g:terminal_color_x` in
|
||||||
in Neovim.
|
Neovim.
|
||||||
|
|
||||||
```vim
|
```vim
|
||||||
" Terminal colors for seoul256 color scheme
|
" Terminal colors for seoul256 color scheme
|
||||||
@@ -442,7 +478,10 @@ else
|
|||||||
endif
|
endif
|
||||||
```
|
```
|
||||||
|
|
||||||
### Starting fzf in a popup window
|
### Starting fzf in a Vim popup window
|
||||||
|
|
||||||
|
You can configure fzf to start in a Vim popup window by setting the `window` key
|
||||||
|
in `g:fzf_layout`.
|
||||||
|
|
||||||
```vim
|
```vim
|
||||||
" Required:
|
" Required:
|
||||||
@@ -458,18 +497,32 @@ endif
|
|||||||
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } }
|
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } }
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, you can make fzf open in a popup window (requires tmux 3.3 or
|
### Starting fzf in a tmux/Zellij popup window
|
||||||
above, or Zellij 0.44 or above) by putting `--popup` option value in `popup`
|
|
||||||
key. `tmux` is accepted as a synonym, just as `--tmux` is an alias of
|
fzf can also start in a popup of the multiplexer instead of a window inside
|
||||||
`--popup`.
|
Vim, by putting a `--popup` option value in the `popup` key. `tmux` is
|
||||||
|
accepted as a synonym, just as `--tmux` is an alias of `--popup`.
|
||||||
|
|
||||||
|
The layout works on tmux 3.3 or above, or on Zellij 0.44 or above with fzf
|
||||||
|
0.71.0 or above. It is the default on tmux 3.7 or above with fzf 0.74.0 or
|
||||||
|
above, and on Zellij, where the pane is not modal: Vim keeps the window fzf
|
||||||
|
was started from visible, and you can switch to it while fzf is open. Below
|
||||||
|
those versions tmux gives a popup that cannot be left, so a window inside Vim
|
||||||
|
is the default there. On tmux, an explicit `--border` style also gives a modal
|
||||||
|
popup rather than a floating pane, because the native border of a tmux
|
||||||
|
floating pane cannot be removed. Drop `--border` to keep the floating pane and
|
||||||
|
its native border. Zellij keeps the floating pane either way, and hides its
|
||||||
|
native border when fzf draws one. Set `g:fzf_layout` yourself to choose either
|
||||||
|
one.
|
||||||
|
|
||||||
```vim
|
```vim
|
||||||
" See `--popup` option in `man fzf` for available options
|
|
||||||
" [center|top|bottom|left|right][,SIZE[%]][,SIZE[%]]
|
|
||||||
if exists('$TMUX') || exists('$ZELLIJ')
|
if exists('$TMUX') || exists('$ZELLIJ')
|
||||||
|
" See `--popup` option in `man fzf` for available options
|
||||||
|
" [center|top|bottom|left|right][,SIZE[%]][,SIZE[%]]
|
||||||
let g:fzf_layout = { 'popup': '90%,70%' }
|
let g:fzf_layout = { 'popup': '90%,70%' }
|
||||||
else
|
else
|
||||||
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } }
|
" Configure the Vim popup window in case not on the multiplexer
|
||||||
|
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.7 } }
|
||||||
endif
|
endif
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -477,7 +530,8 @@ endif
|
|||||||
|
|
||||||
When fzf starts in a terminal buffer, the file type of the buffer is set to
|
When fzf starts in a terminal buffer, the file type of the buffer is set to
|
||||||
`fzf`. So you can set up `FileType fzf` autocmd to customize the settings of
|
`fzf`. So you can set up `FileType fzf` autocmd to customize the settings of
|
||||||
the window.
|
the window. This applies to the layouts that open inside Vim, not to the tmux
|
||||||
|
or Zellij pane the default uses, which is not a buffer.
|
||||||
|
|
||||||
For example, if you open fzf on the bottom on the screen (e.g. `{'down':
|
For example, if you open fzf on the bottom on the screen (e.g. `{'down':
|
||||||
'40%'}`), you might want to temporarily disable the statusline for a cleaner
|
'40%'}`), you might want to temporarily disable the statusline for a cleaner
|
||||||
|
|||||||
+56
-18
@@ -14,7 +14,8 @@ FZF - TABLE OF CONTENTS *fzf* *fzf-to
|
|||||||
Global options supported by fzf#wrap |fzf-global-options-supported-by-fzf#wrap|
|
Global options supported by fzf#wrap |fzf-global-options-supported-by-fzf#wrap|
|
||||||
Tips |fzf-tips|
|
Tips |fzf-tips|
|
||||||
fzf inside terminal buffer |fzf-inside-terminal-buffer|
|
fzf inside terminal buffer |fzf-inside-terminal-buffer|
|
||||||
Starting fzf in a popup window |fzf-starting-fzf-in-a-popup-window|
|
Starting fzf in a Vim popup window |fzf-starting-fzf-in-a-vim-popup-window|
|
||||||
|
Starting fzf in a tmux/Zellij popup window |fzf-starting-fzf-in-a-tmuxzellij-popup-window|
|
||||||
Hide statusline |fzf-hide-statusline|
|
Hide statusline |fzf-hide-statusline|
|
||||||
License |fzf-license|
|
License |fzf-license|
|
||||||
|
|
||||||
@@ -161,19 +162,35 @@ Examples~
|
|||||||
\ 'ctrl-v': 'vsplit' }
|
\ 'ctrl-v': 'vsplit' }
|
||||||
|
|
||||||
" Default fzf layout
|
" Default fzf layout
|
||||||
" - Popup window (center of the screen)
|
if exists('$TMUX') || exists('$ZELLIJ')
|
||||||
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } }
|
" The Vim plugin will try to open fzf in a tmux or Zellij popup
|
||||||
|
" if possible (requires recent fzf and tmux/zellij) using --popup option,
|
||||||
|
" with the following argument:
|
||||||
|
let g:fzf_layout = { 'popup': '90%,60%' }
|
||||||
|
else
|
||||||
|
" If --popup option is not available, it will open in a popup window inside
|
||||||
|
" Vim (center of the screen)
|
||||||
|
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } }
|
||||||
|
endif
|
||||||
|
|
||||||
" - Popup window (center of the current window)
|
" Here are some more layout examples:
|
||||||
|
|
||||||
|
" - Tmux or Zellij popup at the bottom 40%
|
||||||
|
let g:fzf_layout = { 'popup': 'bottom,40%' }
|
||||||
|
|
||||||
|
" - Tmux or Zellij popup at the top with a different size
|
||||||
|
let g:fzf_layout = { 'popup': 'top,90%,40%' }
|
||||||
|
|
||||||
|
" - Vim popup window: at the center of the current window (relative)
|
||||||
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'relative': v:true } }
|
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'relative': v:true } }
|
||||||
|
|
||||||
" - Popup window (anchored to the bottom of the current window)
|
" - Vim popup window: anchored to the bottom of the current window
|
||||||
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'relative': v:true, 'yoffset': 1.0 } }
|
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'relative': v:true, 'yoffset': 1.0 } }
|
||||||
|
|
||||||
" - down / up / left / right
|
" - Vim split window: down / up / left / right
|
||||||
let g:fzf_layout = { 'down': '40%' }
|
let g:fzf_layout = { 'down': '40%' }
|
||||||
|
|
||||||
" - Window using a Vim command
|
" - Vim window using a Vim command
|
||||||
let g:fzf_layout = { 'window': 'enew' }
|
let g:fzf_layout = { 'window': 'enew' }
|
||||||
let g:fzf_layout = { 'window': '-tabnew' }
|
let g:fzf_layout = { 'window': '-tabnew' }
|
||||||
let g:fzf_layout = { 'window': '10new' }
|
let g:fzf_layout = { 'window': '10new' }
|
||||||
@@ -418,8 +435,8 @@ TIPS *fzf-tips*
|
|||||||
*fzf-inside-terminal-buffer*
|
*fzf-inside-terminal-buffer*
|
||||||
|
|
||||||
|
|
||||||
On the latest versions of Vim and Neovim, fzf will start in a terminal buffer.
|
When fzf is configured to start in a terminal buffer inside Vim or Neovim, you
|
||||||
If you find the default ANSI colors to be different, consider configuring the
|
may find the default ANSI colors to be different. In that case, configure the
|
||||||
colors using `g:terminal_ansi_colors` in regular Vim or `g:terminal_color_x`
|
colors using `g:terminal_ansi_colors` in regular Vim or `g:terminal_color_x`
|
||||||
in Neovim.
|
in Neovim.
|
||||||
|
|
||||||
@@ -452,8 +469,11 @@ in Neovim.
|
|||||||
endif
|
endif
|
||||||
<
|
<
|
||||||
|
|
||||||
< Starting fzf in a popup window >____________________________________________~
|
< Starting fzf in a Vim popup window >________________________________________~
|
||||||
*fzf-starting-fzf-in-a-popup-window*
|
*fzf-starting-fzf-in-a-vim-popup-window*
|
||||||
|
|
||||||
|
You can configure fzf to start in a Vim popup window by setting the `window`
|
||||||
|
key in `g:fzf_layout`.
|
||||||
>
|
>
|
||||||
" Required:
|
" Required:
|
||||||
" - width [float range [0 ~ 1]] or [integer range [8 ~ ]]
|
" - width [float range [0 ~ 1]] or [integer range [8 ~ ]]
|
||||||
@@ -467,16 +487,33 @@ in Neovim.
|
|||||||
" - 'rounded' / 'sharp' / 'horizontal' / 'vertical' / 'top' / 'bottom' / 'left' / 'right'
|
" - 'rounded' / 'sharp' / 'horizontal' / 'vertical' / 'top' / 'bottom' / 'left' / 'right'
|
||||||
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } }
|
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } }
|
||||||
<
|
<
|
||||||
Alternatively, you can make fzf open in a popup window (requires tmux 3.3 or
|
|
||||||
above, or Zellij 0.44 or above) by putting `--popup` options in `popup` key.
|
< Starting fzf in a tmux/Zellij popup window >________________________________~
|
||||||
`tmux` is accepted as a synonym, just as `--tmux` is an alias of `--popup`.
|
*fzf-starting-fzf-in-a-tmuxzellij-popup-window*
|
||||||
|
|
||||||
|
fzf can also start in a popup of the multiplexer instead of a window inside
|
||||||
|
Vim, by putting a `--popup` option value in the `popup` key. `tmux` is
|
||||||
|
accepted as a synonym, just as `--tmux` is an alias of `--popup`.
|
||||||
|
|
||||||
|
The layout works on tmux 3.3 or above, or on Zellij 0.44 or above with fzf
|
||||||
|
0.71.0 or above. It is the default on tmux 3.7 or above with fzf 0.74.0 or
|
||||||
|
above, and on Zellij, where the pane is not modal: Vim keeps the window fzf
|
||||||
|
was started from visible, and you can switch to it while fzf is open. Below
|
||||||
|
those versions tmux gives a popup that cannot be left, so a window inside Vim
|
||||||
|
is the default there. On tmux, an explicit `--border` style also gives a modal
|
||||||
|
popup rather than a floating pane, because the native border of a tmux
|
||||||
|
floating pane cannot be removed. Drop `--border` to keep the floating pane and
|
||||||
|
its native border. Zellij keeps the floating pane either way, and hides its
|
||||||
|
native border when fzf draws one. Set `g:fzf_layout` yourself to choose either
|
||||||
|
one.
|
||||||
>
|
>
|
||||||
" See `--popup` option in `man fzf` for available options
|
|
||||||
" [center|top|bottom|left|right][,SIZE[%]][,SIZE[%]]
|
|
||||||
if exists('$TMUX') || exists('$ZELLIJ')
|
if exists('$TMUX') || exists('$ZELLIJ')
|
||||||
|
" See `--popup` option in `man fzf` for available options
|
||||||
|
" [center|top|bottom|left|right][,SIZE[%]][,SIZE[%]]
|
||||||
let g:fzf_layout = { 'popup': '90%,70%' }
|
let g:fzf_layout = { 'popup': '90%,70%' }
|
||||||
else
|
else
|
||||||
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } }
|
" Configure the Vim popup window in case not on the multiplexer
|
||||||
|
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.7 } }
|
||||||
endif
|
endif
|
||||||
<
|
<
|
||||||
|
|
||||||
@@ -485,7 +522,8 @@ above, or Zellij 0.44 or above) by putting `--popup` options in `popup` key.
|
|||||||
|
|
||||||
When fzf starts in a terminal buffer, the file type of the buffer is set to
|
When fzf starts in a terminal buffer, the file type of the buffer is set to
|
||||||
`fzf`. So you can set up `FileType fzf` autocmd to customize the settings of
|
`fzf`. So you can set up `FileType fzf` autocmd to customize the settings of
|
||||||
the window.
|
the window. This applies to the layouts that open inside Vim, not to the tmux
|
||||||
|
or Zellij pane the default uses, which is not a buffer.
|
||||||
|
|
||||||
For example, if you open fzf on the bottom on the screen (e.g. `{'down':
|
For example, if you open fzf on the bottom on the screen (e.g. `{'down':
|
||||||
'40%'}`), you might want to temporarily disable the statusline for a cleaner
|
'40%'}`), you might want to temporarily disable the statusline for a cleaner
|
||||||
|
|||||||
+90
-12
@@ -140,6 +140,11 @@ function! s:popup_support()
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:default_layout()
|
function! s:default_layout()
|
||||||
|
" A floating pane leaves the window fzf was started from visible and
|
||||||
|
" reachable while fzf is open. A popup covers it, inside Vim or not
|
||||||
|
if s:floating_pane()
|
||||||
|
return { 'tmux': '90%,60%' }
|
||||||
|
endif
|
||||||
return s:popup_support()
|
return s:popup_support()
|
||||||
\ ? { 'window' : { 'width': 0.9, 'height': 0.6 } }
|
\ ? { 'window' : { 'width': 0.9, 'height': 0.6 } }
|
||||||
\ : { 'down': '~40%' }
|
\ : { 'down': '~40%' }
|
||||||
@@ -165,6 +170,12 @@ function! fzf#install()
|
|||||||
if v:shell_error
|
if v:shell_error
|
||||||
throw 'Failed to download fzf: '.script
|
throw 'Failed to download fzf: '.script
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
" A new binary invalidates the chosen executable and everything derived from
|
||||||
|
" its version, including whether fzf opens a floating pane. fzf#install() is
|
||||||
|
" also the vim-plug 'do' hook, so this can run long after the first fzf call
|
||||||
|
let [s:versions, s:checked] = [{}, {}]
|
||||||
|
unlet! s:exec s:tmux s:tmux_floating
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
let s:versions = {}
|
let s:versions = {}
|
||||||
@@ -257,7 +268,7 @@ function! fzf#exec(...)
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Path to the fzf-tmux script, or an empty string if it is not available. Only
|
" Path to the fzf-tmux script, or an empty string if it is not available. Only
|
||||||
" the legacy options still need it. --tmux is handled by fzf itself.
|
" the legacy options still need it. --popup is handled by fzf itself.
|
||||||
function! s:fzf_tmux_script()
|
function! s:fzf_tmux_script()
|
||||||
if !executable(s:fzf_tmux)
|
if !executable(s:fzf_tmux)
|
||||||
if !executable('fzf-tmux')
|
if !executable('fzf-tmux')
|
||||||
@@ -273,14 +284,7 @@ function! s:tmux_enabled()
|
|||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" --tmux covers Zellij as well, where the fzf-tmux script and the tmux
|
if empty($TMUX) && empty($ZELLIJ)
|
||||||
" version are irrelevant, but the binary only learned it in 0.71.0
|
|
||||||
if exists('$ZELLIJ')
|
|
||||||
return exists('s:exec')
|
|
||||||
\ && s:compare_versions(s:get_version(s:exec), '0.71.0') >= 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
if !exists('$TMUX')
|
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -288,7 +292,21 @@ function! s:tmux_enabled()
|
|||||||
return s:tmux
|
return s:tmux
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let s:tmux = 0
|
let [s:tmux, s:tmux_floating] = [0, 0]
|
||||||
|
|
||||||
|
" --popup covers Zellij as well, where the fzf-tmux script and the tmux
|
||||||
|
" version are irrelevant. fzf learned it in 0.71.0, and the floating pane
|
||||||
|
" options it passes need Zellij 0.44 or above. fzf checks tmux first, so
|
||||||
|
" this branch is Zellij without tmux. Both non-empty means tmux wins.
|
||||||
|
" empty(), not exists(), to match how fzf reads the two variables
|
||||||
|
if empty($TMUX)
|
||||||
|
let s:tmux =
|
||||||
|
\ s:compare_versions(s:get_version(s:fzf_binary()), '0.71.0') >= 0
|
||||||
|
\ && s:compare_versions(s:zellij_version(), '0.44') >= 0
|
||||||
|
let s:tmux_floating = s:tmux
|
||||||
|
return s:tmux
|
||||||
|
endif
|
||||||
|
|
||||||
let output = system('tmux -V')
|
let output = system('tmux -V')
|
||||||
if v:shell_error
|
if v:shell_error
|
||||||
return s:tmux
|
return s:tmux
|
||||||
@@ -296,9 +314,15 @@ function! s:tmux_enabled()
|
|||||||
" e.g. 'tmux 3.7b', 'tmux next-3.8'
|
" e.g. 'tmux 3.7b', 'tmux next-3.8'
|
||||||
let ver = matchstr(output, '\d\+\.\d\+')
|
let ver = matchstr(output, '\d\+\.\d\+')
|
||||||
|
|
||||||
" --tmux requires tmux 3.3 or above, and needs no fzf-tmux script
|
" --popup requires tmux 3.3 or above, and needs no fzf-tmux script. The
|
||||||
|
" default layout wants a floating pane, which also needs fzf 0.74.0 or
|
||||||
|
" above. fzf opens a modal popup otherwise. The version here only skips the
|
||||||
|
" probe for servers too old to answer it
|
||||||
if s:compare_versions(ver, '3.3') >= 0
|
if s:compare_versions(ver, '3.3') >= 0
|
||||||
let s:tmux = 1
|
let s:tmux = 1
|
||||||
|
let s:tmux_floating = s:compare_versions(ver, '3.7') >= 0
|
||||||
|
\ && s:tmux_floating_pane_info()
|
||||||
|
\ && s:compare_versions(s:get_version(s:fzf_binary()), '0.74.0') >= 0
|
||||||
return s:tmux
|
return s:tmux
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -451,7 +475,10 @@ function! fzf#wrap(...)
|
|||||||
if !exists('g:fzf_layout') && exists('g:fzf_height')
|
if !exists('g:fzf_layout') && exists('g:fzf_height')
|
||||||
let opts.down = g:fzf_height
|
let opts.down = g:fzf_height
|
||||||
else
|
else
|
||||||
let opts = extend(opts, s:validate_layout(get(g:, 'fzf_layout', s:default_layout())))
|
" Not get(), which would evaluate s:default_layout() and run its version
|
||||||
|
" checks even when g:fzf_layout makes the answer irrelevant
|
||||||
|
let opts = extend(opts, s:validate_layout(
|
||||||
|
\ exists('g:fzf_layout') ? g:fzf_layout : s:default_layout()))
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -627,6 +654,57 @@ function! s:present(dict, ...)
|
|||||||
return 0
|
return 0
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
" The binary fzf#exec() would choose, without its prompting or installing.
|
||||||
|
" Layout selection runs before fzf#exec() has resolved one
|
||||||
|
function! s:fzf_binary()
|
||||||
|
if exists('s:exec')
|
||||||
|
return s:exec
|
||||||
|
endif
|
||||||
|
let bins = filter(['fzf', s:fzf_go], 'executable(v:val)')
|
||||||
|
if empty(bins)
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
return len(bins) > 1 ? sort(bins, 's:compare_binary_versions')[-1] : bins[0]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:zellij_version()
|
||||||
|
if !exists('s:zellij_ver')
|
||||||
|
let output = systemlist('zellij --version')
|
||||||
|
let s:zellij_ver = v:shell_error || empty(output)
|
||||||
|
\ ? '' : matchstr(output[0], '[0-9.]\+')
|
||||||
|
endif
|
||||||
|
return s:zellij_ver
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" fzf decides on the running server, not on the version the tmux client
|
||||||
|
" reports, so ask it the same question rather than predicting the answer.
|
||||||
|
" See tmuxFloatingPaneInfo in src/tmux.go
|
||||||
|
function! s:tmux_floating_pane_info()
|
||||||
|
" fzf does not use a floating pane when it was not started from a pane
|
||||||
|
if empty($TMUX_PANE)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
let out = system('tmux display-message -p -t '.fzf#shellescape($TMUX_PANE)
|
||||||
|
\ .' ''#{window_width} #{window_height}'' '';'' list-commands new-pane')
|
||||||
|
" A server that does not know the command exits normally with no output
|
||||||
|
if v:shell_error || out !~# 'new-pane'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
" Too small for a floating pane of the minimum size
|
||||||
|
return str2nr(matchstr(out, '^\s*\zs\d\+')) >= 3
|
||||||
|
\ && str2nr(matchstr(out, '^\s*\d\+\s\+\zs\d\+')) >= 3
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Whether fzf will open a floating pane that can be left while fzf runs. A
|
||||||
|
" tmux popup below 3.7 is modal, and the fzf-tmux script that older tmux
|
||||||
|
" versions need does not accept a --popup value at all. Without a job to wait
|
||||||
|
" on fzf, s:execute_tmux() blocks on system() and the window stays visible but
|
||||||
|
" frozen, so the default keeps fzf inside Vim there
|
||||||
|
function! s:floating_pane()
|
||||||
|
return (has('nvim') || has('job'))
|
||||||
|
\ && s:tmux_enabled() && get(s:, 'tmux_floating', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:fzf_tmux(dict)
|
function! s:fzf_tmux(dict)
|
||||||
let size = get(a:dict, 'tmux', '')
|
let size = get(a:dict, 'tmux', '')
|
||||||
if empty(size)
|
if empty(size)
|
||||||
|
|||||||
@@ -102,9 +102,36 @@ Execute (fzf#run with dir option and autochdir when final cwd is same as dir):
|
|||||||
" Working directory changed due to &acd
|
" Working directory changed due to &acd
|
||||||
AssertEqual '/', getcwd()
|
AssertEqual '/', getcwd()
|
||||||
|
|
||||||
|
Execute (Default layout):
|
||||||
|
unlet! g:fzf_layout g:fzf_height
|
||||||
|
let layout_keys = ['window', 'popup', 'tmux', 'up', 'down', 'left', 'right']
|
||||||
|
|
||||||
|
let opts = fzf#wrap('foobar')
|
||||||
|
Log opts
|
||||||
|
let found = filter(copy(layout_keys), 'has_key(opts, v:val)')
|
||||||
|
AssertEqual 1, len(found)
|
||||||
|
if found[0] ==# 'tmux'
|
||||||
|
" Only where fzf opens a floating pane, which can be left while fzf runs
|
||||||
|
Assert !empty($TMUX) || !empty($ZELLIJ)
|
||||||
|
AssertEqual '90%,60%', opts.tmux
|
||||||
|
elseif found[0] ==# 'window'
|
||||||
|
AssertEqual 0.9, opts.window.width
|
||||||
|
else
|
||||||
|
" No popup support in this build
|
||||||
|
AssertEqual '~40%', opts.down
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Fullscreen strips it, whichever it was
|
||||||
|
let opts = fzf#wrap('foobar', {}, 1)
|
||||||
|
Log opts
|
||||||
|
AssertEqual [], filter(copy(layout_keys), 'has_key(opts, v:val)')
|
||||||
|
|
||||||
Execute (fzf#wrap):
|
Execute (fzf#wrap):
|
||||||
AssertThrows fzf#wrap({'foo': 'bar'})
|
AssertThrows fzf#wrap({'foo': 'bar'})
|
||||||
|
|
||||||
|
" Pin the layout so the assertions do not depend on the environment
|
||||||
|
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } }
|
||||||
|
|
||||||
let opts = fzf#wrap('foobar')
|
let opts = fzf#wrap('foobar')
|
||||||
Log opts
|
Log opts
|
||||||
AssertEqual 0.9, opts.window.width
|
AssertEqual 0.9, opts.window.width
|
||||||
|
|||||||
Reference in New Issue
Block a user