m/fzf
1
0
mirror of https://github.com/junegunn/fzf.git synced 2025-11-14 22:33:47 -05:00

Compare commits

...

57 Commits

Author SHA1 Message Date
Junegunn Choi
2d61691bb2 0.16.7 2017-04-30 11:54:40 +09:00
Junegunn Choi
eba9e04e2e Export FZF_PREVIEW_HEIGHT instead of FZF_HEIGHT
https://github.com/junegunn/fzf.vim/issues/361
2017-04-30 11:36:23 +09:00
Junegunn Choi
33f32de690 Merge branch 'master' into devel 2017-04-30 11:23:42 +09:00
Junegunn Choi
93b8f61551 [vim] Export $FZF_HEIGHT for previewer scripts
Preview script cannot properly determine the height of fzf finder if
`--height` option is used.

https://github.com/junegunn/fzf.vim/issues/361
2017-04-30 11:18:56 +09:00
Junegunn Choi
7f17a9d1b4 Update mattn/go-shellwords 2017-04-30 00:47:44 +09:00
Junegunn Choi
d34e4cf698 Support CTRL-Z (SIGSTOP) 2017-04-28 22:58:08 +09:00
Junegunn Choi
6b592137b9 Add support for ctrl-alt-[a-z] key chords
Close #906
2017-04-28 02:36:36 +09:00
Junegunn Choi
d5e72bf55d Update README-VIM: options as list (#896) 2017-04-28 02:09:55 +09:00
Junegunn Choi
5677e5e133 [fish] Fix ~/.config/fish/functions/fish_user_key_bindings.fish
Install script will create the file with the proper function body only
if the file doesn't exist. If it already exists, it will try to append
`fzf_key_bindings` as before.

Close #851
2017-04-28 01:57:38 +09:00
Jan Edmund Lazo
7a11a06cbd [vim] Use backslash for Windows filepaths (#896)
- Fix shellescaping issues for filepaths
    - Supports both forward slashes or backslashes
    - Paths with spaces
- Use jobstart for neovim in s:execute (Windows)
    - https://github.com/neovim/neovim/pull/6497
- Make 2 s:fzf_shellescape functions
    - (Windows) Substitute \" with \\" to escape the last backslash
    - (Default) Regular shellescape
- Support list 'options'
- Add "@echo off" to the batchfile used to execute fzf
2017-04-22 11:30:51 +09:00
Junegunn Choi
a5862d4b9c [bash-completion] Use -o dirnames instead of -o plusdirs
Close #903
Related #135
2017-04-11 22:21:16 +09:00
Junegunn Choi
a50909e806 Correction: fzf no longer depends on ncurses 2017-04-06 02:08:49 +09:00
Kouki Higashikawa
7c8f7d3f20 [fzf-tmux] Close with exit code 130 when tmux pane is killed
Fix #796
2017-04-03 11:49:54 +09:00
Junegunn Choi
9078197446 Add --version to --help output and man page
Close #888
Close #894
2017-04-02 11:30:22 +09:00
Junegunn Choi
0fe07cf9fe Update README.md
Add PayPal donation button
2017-04-02 10:47:06 +09:00
Junegunn Choi
2216169ca1 Update doc/fzf.txt accordingly 2017-04-01 12:19:39 +09:00
Junegunn Choi
50e989ca85 Update example in README-VIM 2017-04-01 12:06:25 +09:00
Junegunn Choi
fa1fc3d855 Add vim doc
Close #893
2017-04-01 12:00:30 +09:00
五所和哉
bbe696e925 [fzf-tmux] Fix issue with zoomed pane on fish (#891) 2017-04-01 11:09:46 +09:00
Miodrag Milić
5d12f523a3 Add chocolatey upgrade instruction to Readme (#890) 2017-03-30 01:59:41 +09:00
Daniel Hahler
d295d20dc4 fzf#run: improve "is already running" message (#885)
This displays the buffer(s) in this case, which is useful when FZF got
stuck, and you have to manually remove the buffer.
2017-03-27 13:41:39 +09:00
Sam Van Den Berge
2ba10071c9 Add support for IPv6 addresses in ssh completion (#877)
Signed-off-by: Sam Van Den Berge <sam@drgt.net>
2017-03-21 01:06:13 +09:00
Christian Sturm
505dc0491b Make install script to work with non GNU tar (#871) 2017-03-10 23:22:37 +09:00
Junegunn Choi
54a4ab0f26 Add Chocolatey instruction
Thanks to @majkinetor. Close #869.
2017-03-07 23:03:14 +09:00
Junegunn Choi
e03e91477b 0.16.6 2017-03-05 03:05:06 +09:00
Junegunn Choi
88ac397158 Add test case for --no-clear 2017-03-04 14:26:47 +09:00
Junegunn Choi
6fd4be580b Use alternate screen only when the value of height is 100%
Do not automatically decide to use alternate screen when the value of
height exceeds the height of the terminal.

    # Use alternate screen
    fzf
    fzf --height 100%
    fzf --no-height

    # Still use current screen
    fzf --height 10000
2017-03-04 14:09:36 +09:00
Junegunn Choi
53348feb89 Add --no-clear option 2017-03-04 11:29:31 +09:00
Junegunn Choi
337cdbb37c [zsh] Use setopt noposixbuiltins instead of emulate -L zsh
Close #858
3a6af27586 (commitcomment-21135641)
2017-03-03 19:09:29 +09:00
Junegunn Choi
05fdf91fc5 Revert "[zsh] emulate -L zsh to avoid issues with incompatible options"
This reverts commit 3a6af27586.
2017-03-03 18:57:22 +09:00
Junegunn Choi
c387689d1c [shell] Enable sorting by default in CTRL-R
CTRL-R binding used to start with --no-sort to list the matched commands
in chronological order. However, it has been a constant source of
confusion. Let's enable it by default from now on. The sorted result
shouldn't be too confusing as we use --tiebreak=index.
2017-03-03 12:20:01 +09:00
Junegunn Choi
cb9238dc4e Display -S if sort is disabled and toggle-sort is used
This is to address a common confusion that one does not realize that
sorting is intentionally turned off by default and can be enabled by
a bind key.
2017-03-03 02:26:30 +09:00
Junegunn Choi
a484811f78 [vim] Capitalize exception messages 2017-03-02 14:17:59 +09:00
Junegunn Choi
111d1934c4 [vim] Throw error if g:fzf_layout is incorrectly used
https://github.com/junegunn/fzf.vim/issues/327
https://github.com/junegunn/fzf.vim/issues/317
2017-03-02 14:14:57 +09:00
Junegunn Choi
972fb1a29d Suppress ANSI colors in preview window if --no-color is set 2017-03-02 12:49:51 +09:00
Junegunn Choi
3a6af27586 [zsh] emulate -L zsh to avoid issues with incompatible options
Close #858
2017-03-01 16:07:04 +09:00
Junegunn Choi
c89ac341e4 Clear background even if background color is not set
This is needed when fzf is started from inside a program (e.g. Vim)
and it uses a different background color than the terminal.

- https://github.com/junegunn/fzf.vim/issues/325
- https://github.com/junegunn/fzf.vim/issues/300
2017-03-01 16:00:08 +09:00
Junegunn Choi
cd59e5d07b [neovim] Set 'dir' to the current direcotry
Close https://github.com/junegunn/fzf.vim/issues/308
2017-02-25 23:52:56 +09:00
Junegunn Choi
0b940e4b2b Redraw item if query string has changed 2017-02-24 02:30:11 +09:00
Junegunn Choi
b29375c844 [vim] Minor refactoring 2017-02-19 20:53:12 +09:00
Junegunn Choi
76d3f6d248 [vim] Escape ! when using :! to execute command
- call fzf#run({'source': "echo '!'"})
- call fzf#run({'source': "echo '!'", 'down': '40%'})

Close https://github.com/junegunn/fzf.vim/issues/315
2017-02-19 20:47:44 +09:00
Junegunn Choi
e87a85a179 0.16.5 2017-02-19 01:40:25 +09:00
Junegunn Choi
11407bf656 Exclude sysfs in find commands 2017-02-19 01:33:13 +09:00
Junegunn Choi
c82fb3c9b9 Add toggle-preview-wrap action 2017-02-18 23:49:00 +09:00
Junegunn Choi
309e1d8619 Properly truncate long query string 2017-02-18 23:17:29 +09:00
Junegunn Choi
c2db67c1c0 [vim] Prepend @echo off to $FZF_DEFAULT_COMMAND on Windows (#847) 2017-02-18 21:58:03 +09:00
Junegunn Choi
9526594905 [vim] Fix FZF_DEFAULT_COMMAND on Windows
Close #847. Patch submitted by @wontoncc.
2017-02-18 18:17:37 +09:00
Junegunn Choi
3d74d277aa Use cut instead of sed in the default command 2017-02-17 13:07:45 +09:00
Junegunn Choi
fc274c2ba4 [vim] Do not escape % when using system() instead of !
Close https://github.com/junegunn/fzf.vim/issues/309
2017-02-17 10:20:39 +09:00
Pierre Neidhardt
ce43ea9f42 [shell] Replace sed with -mindepth 1 and cut (#844) 2017-02-16 17:18:01 +09:00
Junegunn Choi
21da02fac2 Fix indentation 2017-02-14 22:30:09 +09:00
Junegunn Choi
19569bd5c5 Move cursor to the top-left when returning to alternate screen
Fix broken preview border. Reported by Thomas Sattler.

    fzf --bind 'enter:execute(date)' --preview=date --reverse
2017-02-14 22:28:04 +09:00
Daniel Gray
afa25d8c57 [zsh] Do not cd when cancelling alt+c keybind (#840) 2017-02-09 14:05:02 +09:00
Junegunn Choi
1ba7acf4bd [fzf-tmux] Fix race condition when using -l/-u on zoomed panes
Using a dummy command that works as the barrier.
2017-02-08 14:55:51 +09:00
Prabir Shrestha
a847fe8754 Use "type" instead of "cat" on windows (#836) 2017-02-07 14:42:08 +09:00
Junegunn Choi
5bb18b6441 Remove Dockerfiles and clean up Makefile
Due to the recent removal of ncurses dependency, we can cross-compile
binaries for different platforms without virtual machines.
2017-02-06 21:15:29 +09:00
Junegunn Choi
876c233a26 Remove Ruby version
Related #832
2017-02-06 21:06:12 +09:00
35 changed files with 818 additions and 1871 deletions

1
.gitignore vendored
View File

@@ -4,3 +4,4 @@ gopath
pkg
Gemfile.lock
.DS_Store
doc/tags

View File

@@ -1,6 +1,24 @@
CHANGELOG
=========
0.16.7
------
- Added support for `ctrl-alt-[a-z]` key chords
- CTRL-Z (SIGSTOP) now works with fzf
- fzf will export `$FZF_PREVIEW_WINDOW` so that the scripts can use it
- Bug fixes and improvements in Vim plugin and shell extensions
0.16.6
------
- Minor bug fixes and improvements
- Added `--no-clear` option for scripting purposes
0.16.5
------
- Minor bug fixes
- Added `toggle-preview-wrap` action
- Built with Go 1.8
0.16.4
------
- Added `--border` option to draw border above and below the finder

155
README-VIM.md Normal file
View File

@@ -0,0 +1,155 @@
FZF Vim integration
===================
This repository only enables basic integration with Vim. If you're looking for
more, check out [fzf.vim](https://github.com/junegunn/fzf.vim) project.
(Note: To use fzf in GVim, an external terminal emulator is required.)
`:FZF[!]`
---------
If you have set up fzf for Vim, `:FZF` command will be added.
```vim
" Look for files under current directory
:FZF
" Look for files under your home directory
:FZF ~
" With options
:FZF --no-sort --reverse --inline-info /tmp
" Bang version starts fzf in fullscreen mode
:FZF!
```
Similarly to [ctrlp.vim](https://github.com/kien/ctrlp.vim), use enter key,
`CTRL-T`, `CTRL-X` or `CTRL-V` to open selected files in the current window,
in new tabs, in horizontal splits, or in vertical splits respectively.
Note that the environment variables `FZF_DEFAULT_COMMAND` and
`FZF_DEFAULT_OPTS` also apply here.
### Configuration
- `g:fzf_action`
- Customizable extra key bindings for opening selected files in different ways
- `g:fzf_layout`
- Determines the size and position of fzf window (tmux pane or Neovim split)
- `g:fzf_colors`
- Customizes fzf colors to match the current color scheme
- `g:fzf_history_dir`
- Enables history feature
- `g:fzf_launcher`
- (Only in GVim) Terminal emulator to open fzf with
- `g:Fzf_launcher` for function reference
#### Examples
```vim
" This is the default extra key bindings
let g:fzf_action = {
\ 'ctrl-t': 'tab split',
\ 'ctrl-x': 'split',
\ 'ctrl-v': 'vsplit' }
" Default fzf layout
" - down / up / left / right
let g:fzf_layout = { 'down': '~40%' }
" In Neovim, you can set up fzf window using a Vim command
let g:fzf_layout = { 'window': 'enew' }
let g:fzf_layout = { 'window': '-tabnew' }
let g:fzf_layout = { 'window': '10split enew' }
" Customize fzf colors to match your color scheme
let g:fzf_colors =
\ { 'fg': ['fg', 'Normal'],
\ 'bg': ['bg', 'Normal'],
\ 'hl': ['fg', 'Comment'],
\ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'],
\ 'bg+': ['bg', 'CursorLine', 'CursorColumn'],
\ 'hl+': ['fg', 'Statement'],
\ 'info': ['fg', 'PreProc'],
\ 'prompt': ['fg', 'Conditional'],
\ 'pointer': ['fg', 'Exception'],
\ 'marker': ['fg', 'Keyword'],
\ 'spinner': ['fg', 'Label'],
\ 'header': ['fg', 'Comment'] }
" Enable per-command history.
" CTRL-N and CTRL-P will be automatically bound to next-history and
" previous-history instead of down and up. If you don't like the change,
" explicitly bind the keys to down and up in your $FZF_DEFAULT_OPTS.
let g:fzf_history_dir = '~/.local/share/fzf-history'
```
`fzf#run`
---------
For more advanced uses, you can use `fzf#run([options])` function with the
following options.
| Option name | Type | Description |
| -------------------------- | ------------- | ---------------------------------------------------------------- |
| `source` | string | External command to generate input to fzf (e.g. `find .`) |
| `source` | list | Vim list as input to fzf |
| `sink` | string | Vim command to handle the selected item (e.g. `e`, `tabe`) |
| `sink` | funcref | Reference to function to process each selected item |
| `sink*` | funcref | Similar to `sink`, but takes the list of output lines at once |
| `options` | string/list | Options to fzf |
| `dir` | string | Working directory |
| `up`/`down`/`left`/`right` | number/string | Use tmux pane with the given size (e.g. `20`, `50%`) |
| `window` (*Neovim only*) | string | Command to open fzf window (e.g. `vertical aboveleft 30new`) |
| `launcher` | string | External terminal emulator to start fzf with (GVim only) |
| `launcher` | funcref | Function for generating `launcher` string (GVim only) |
`options` entry can be either a string or a list. For simple cases, string
should suffice, but prefer to use list type if you're concerned about escaping
issues on different platforms.
```vim
call fzf#run({'options': '--reverse --prompt "C:\\Program Files\\"'})
call fzf#run({'options': ['--reverse', '--prompt', 'C:\Program Files\']})
```
`fzf#wrap`
----------
`fzf#wrap([name string,] [opts dict,] [fullscreen boolean])` is a helper
function that decorates the options dictionary so that it understands
`g:fzf_layout`, `g:fzf_action`, `g:fzf_colors`, and `g:fzf_history_dir` like
`:FZF`.
```vim
command! -bang MyStuff
\ call fzf#run(fzf#wrap('my-stuff', {'dir': '~/my-stuff'}, <bang>0))
```
GVim
----
In GVim, you need an external terminal emulator to start fzf with. `xterm`
command is used by default, but you can customize it with `g:fzf_launcher`.
```vim
" This is the default. %s is replaced with fzf command
let g:fzf_launcher = 'xterm -e bash -ic %s'
" Use urxvt instead
let g:fzf_launcher = 'urxvt -geometry 120x30 -e sh -c %s'
```
If you're running MacVim on OSX, I recommend you to use iTerm2 as the
launcher. Refer to the [this wiki page][macvim-iterm2] to see how to set up.
[macvim-iterm2]: https://github.com/junegunn/fzf/wiki/On-MacVim-with-iTerm2
[License](LICENSE)
------------------
The MIT License (MIT)
Copyright (c) 2017 Junegunn Choi

View File

@@ -1,4 +1,4 @@
<img src="https://raw.githubusercontent.com/junegunn/i/master/fzf.png" height="170" alt="fzf - a command-line fuzzy finder"> [![travis-ci](https://travis-ci.org/junegunn/fzf.svg?branch=master)](https://travis-ci.org/junegunn/fzf)
<img src="https://raw.githubusercontent.com/junegunn/i/master/fzf.png" height="170" alt="fzf - a command-line fuzzy finder"> [![travis-ci](https://travis-ci.org/junegunn/fzf.svg?branch=master)](https://travis-ci.org/junegunn/fzf) [![Donate via PayPal](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=EKYAW9PGKPD2N)
===
fzf is a general-purpose command-line fuzzy finder.
@@ -53,7 +53,7 @@ brew install fzf
/usr/local/opt/fzf/install
```
### Vim plugin
### As Vim plugin
You can manually add the directory to `&runtimepath` as follows,
@@ -74,10 +74,18 @@ Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
### Windows
Pre-built binaries for Windows can be downloaded [here][bin]. However, other
components of the project may not work on Windows. You might want to consider
installing fzf on [Windows Subsystem for Linux][wsl] where everything runs
flawlessly.
Pre-built binaries for Windows can be downloaded [here][bin]. fzf is also
available as a [Chocolatey package][choco].
[choco]: https://chocolatey.org/packages/fzf
```sh
choco install fzf
```
However, other components of the project may not work on Windows. You might
want to consider installing fzf on [Windows Subsystem for Linux][wsl] where
everything runs flawlessly.
[wsl]: https://blogs.msdn.microsoft.com/wsl/
@@ -90,6 +98,7 @@ method used.
- git: `cd ~/.fzf && git pull && ./install`
- brew: `brew update; brew reinstall fzf`
- chocolatey: `choco upgrade fzf`
- vim-plug: `:PlugUpdate fzf`
Building fzf
@@ -100,7 +109,7 @@ See [BUILD.md](BUILD.md).
Usage
-----
fzf will launch curses-based finder, read the list from STDIN, and write the
fzf will launch interactive finder, read the list from STDIN, and write the
selected item to STDOUT.
```sh
@@ -230,8 +239,8 @@ fish.
- Set `FZF_CTRL_T_COMMAND` to override the default command
- Set `FZF_CTRL_T_OPTS` to pass additional options
- `CTRL-R` - Paste the selected command from history onto the command line
- Sort is disabled by default to respect chronological ordering
- Press `CTRL-R` again to toggle sort
- If you want to see the commands in chronological order, press `CTRL-R`
again which toggles sorting by relevance
- Set `FZF_CTRL_R_OPTS` to pass additional options
- `ALT-C` - cd into the selected directory
- Set `FZF_ALT_C_COMMAND` to override the default command
@@ -336,75 +345,10 @@ commands as well like follows.
complete -F _fzf_file_completion -o default -o bashdefault doge
```
Usage as Vim plugin
-------------------
Vim plugin
----------
This repository only enables basic integration with Vim. If you're looking for
more, check out [fzf.vim](https://github.com/junegunn/fzf.vim) project.
(Note: To use fzf in GVim, an external terminal emulator is required.)
#### `:FZF[!]`
If you have set up fzf for Vim, `:FZF` command will be added.
```vim
" Look for files under current directory
:FZF
" Look for files under your home directory
:FZF ~
" With options
:FZF --no-sort --reverse --inline-info /tmp
" Bang version starts fzf in fullscreen mode
:FZF!
```
Similarly to [ctrlp.vim](https://github.com/kien/ctrlp.vim), use enter key,
`CTRL-T`, `CTRL-X` or `CTRL-V` to open selected files in the current window,
in new tabs, in horizontal splits, or in vertical splits respectively.
Note that the environment variables `FZF_DEFAULT_COMMAND` and
`FZF_DEFAULT_OPTS` also apply here. Refer to [the wiki page][fzf-config] for
customization.
[fzf-config]: https://github.com/junegunn/fzf/wiki/Configuring-Vim-plugin
#### `fzf#run`
For more advanced uses, you can use `fzf#run([options])` function with the
following options.
| Option name | Type | Description |
| -------------------------- | ------------- | ---------------------------------------------------------------- |
| `source` | string | External command to generate input to fzf (e.g. `find .`) |
| `source` | list | Vim list as input to fzf |
| `sink` | string | Vim command to handle the selected item (e.g. `e`, `tabe`) |
| `sink` | funcref | Reference to function to process each selected item |
| `sink*` | funcref | Similar to `sink`, but takes the list of output lines at once |
| `options` | string | Options to fzf |
| `dir` | string | Working directory |
| `up`/`down`/`left`/`right` | number/string | Use tmux pane with the given size (e.g. `20`, `50%`) |
| `window` (*Neovim only*) | string | Command to open fzf window (e.g. `vertical aboveleft 30new`) |
| `launcher` | string | External terminal emulator to start fzf with (GVim only) |
| `launcher` | funcref | Function for generating `launcher` string (GVim only) |
Examples can be found on [the wiki
page](https://github.com/junegunn/fzf/wiki/Examples-(vim)).
#### `fzf#wrap`
`fzf#wrap([name string,] [opts dict,] [fullscreen boolean])` is a helper
function that decorates the options dictionary so that it understands
`g:fzf_layout`, `g:fzf_action`, `g:fzf_colors`, and `g:fzf_history_dir` like
`:FZF`.
```vim
command! -bang MyStuff
\ call fzf#run(fzf#wrap('my-stuff', {'dir': '~/my-stuff'}, <bang>0))
```
See [README-VIM.md](README-VIM.md).
Tips
----

View File

@@ -121,7 +121,7 @@ args+=("--no-height")
if tmux list-panes -F '#F' | grep -q Z; then
zoomed=1
original_window=$(tmux display-message -p "#{window_id}")
tmp_window=$(tmux new-window -d -P -F "#{window_id}" "bash -c 'while :; do for c in \\| / - \\\\; do sleep 0.2; printf \"\\r\$c fzf-tmux is running\\r\"; done; done'")
tmp_window=$(tmux new-window -d -P -F "#{window_id}" "bash -c 'while :; do for c in \\| / - '\\;' do sleep 0.2; printf \"\\r\$c fzf-tmux is running\\r\"; done; done'")
tmux swap-pane -t $tmp_window \; select-window -t $tmp_window
fi
@@ -138,13 +138,18 @@ cleanup() {
# Remove temp window if we were zoomed
if [[ -n "$zoomed" ]]; then
tmux display-message -p "#{window_id}" > /dev/null
tmux swap-pane -t $original_window \; \
select-window -t $original_window \; \
kill-window -t $tmp_window \; \
resize-pane -Z
fi
if [ $# -gt 0 ]; then
exit 130
fi
}
trap cleanup EXIT SIGINT SIGTERM
trap 'cleanup 1' SIGUSR1
envs="env TERM=$TERM "
[[ -n "$FZF_DEFAULT_OPTS" ]] && envs="$envs FZF_DEFAULT_OPTS=$(printf %q "$FZF_DEFAULT_OPTS")"
@@ -163,18 +168,22 @@ for arg in "${args[@]}"; do
opts="$opts \"$arg\""
done
pppid=$$
trap_set="trap 'kill -SIGUSR1 $pppid' EXIT SIGINT SIGTERM"
trap_unset="trap - EXIT SIGINT SIGTERM"
if [[ -n "$term" ]] || [[ -t 0 ]]; then
cat <<< "\"$fzf\" $opts > $fifo2; echo \$? > $fifo3 $close" > $argsf
TMUX=$(echo $TMUX | cut -d , -f 1,2) tmux set-window-option synchronize-panes off \;\
set-window-option remain-on-exit off \;\
split-window $opt "cd $(printf %q "$PWD");$envs bash $argsf" $swap \
split-window $opt "$trap_set;cd $(printf %q "$PWD");$envs bash $argsf;$trap_unset" $swap \
> /dev/null 2>&1
else
mkfifo $fifo1
cat <<< "\"$fzf\" $opts < $fifo1 > $fifo2; echo \$? > $fifo3 $close" > $argsf
TMUX=$(echo $TMUX | cut -d , -f 1,2) tmux set-window-option synchronize-panes off \;\
set-window-option remain-on-exit off \;\
split-window $opt "$envs bash $argsf" $swap \
split-window $opt "$trap_set;$envs bash $argsf;$trap_unset" $swap \
> /dev/null 2>&1
cat <&0 > $fifo1 &
fi

182
doc/fzf.txt Normal file
View File

@@ -0,0 +1,182 @@
fzf.txt fzf Last change: April 28 2017
FZF - TABLE OF CONTENTS *fzf* *fzf-toc*
==============================================================================
FZF Vim integration
:FZF[!]
Configuration
Examples
fzf#run
fzf#wrap
GVim
License
FZF VIM INTEGRATION *fzf-vim-integration*
==============================================================================
This repository only enables basic integration with Vim. If you're looking for
more, check out {fzf.vim}{1} project.
(Note: To use fzf in GVim, an external terminal emulator is required.)
{1} https://github.com/junegunn/fzf.vim
:FZF[!]
==============================================================================
*:FZF*
If you have set up fzf for Vim, `:FZF` command will be added.
>
" Look for files under current directory
:FZF
" Look for files under your home directory
:FZF ~
" With options
:FZF --no-sort --reverse --inline-info /tmp
" Bang version starts fzf in fullscreen mode
:FZF!
<
Similarly to {ctrlp.vim}{2}, use enter key, CTRL-T, CTRL-X or CTRL-V to open
selected files in the current window, in new tabs, in horizontal splits, or in
vertical splits respectively.
Note that the environment variables `FZF_DEFAULT_COMMAND` and
`FZF_DEFAULT_OPTS` also apply here.
{2} https://github.com/kien/ctrlp.vim
< Configuration >_____________________________________________________________~
*fzf-configuration*
*g:fzf_action* *g:fzf_layout* *g:fzf_colors* *g:fzf_history_dir* *g:fzf_launcher*
*g:Fzf_launcher*
- `g:fzf_action`
- Customizable extra key bindings for opening selected files in different
ways
- `g:fzf_layout`
- Determines the size and position of fzf window (tmux pane or Neovim split)
- `g:fzf_colors`
- Customizes fzf colors to match the current color scheme
- `g:fzf_history_dir`
- Enables history feature
- `g:fzf_launcher`
- (Only in GVim) Terminal emulator to open fzf with
- `g:Fzf_launcher` for function reference
Examples~
*fzf-examples*
>
" This is the default extra key bindings
let g:fzf_action = {
\ 'ctrl-t': 'tab split',
\ 'ctrl-x': 'split',
\ 'ctrl-v': 'vsplit' }
" Default fzf layout
" - down / up / left / right
let g:fzf_layout = { 'down': '~40%' }
" In Neovim, you can set up fzf window using a Vim command
let g:fzf_layout = { 'window': 'enew' }
let g:fzf_layout = { 'window': '-tabnew' }
let g:fzf_layout = { 'window': '10split enew' }
" Customize fzf colors to match your color scheme
let g:fzf_colors =
\ { 'fg': ['fg', 'Normal'],
\ 'bg': ['bg', 'Normal'],
\ 'hl': ['fg', 'Comment'],
\ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'],
\ 'bg+': ['bg', 'CursorLine', 'CursorColumn'],
\ 'hl+': ['fg', 'Statement'],
\ 'info': ['fg', 'PreProc'],
\ 'prompt': ['fg', 'Conditional'],
\ 'pointer': ['fg', 'Exception'],
\ 'marker': ['fg', 'Keyword'],
\ 'spinner': ['fg', 'Label'],
\ 'header': ['fg', 'Comment'] }
" Enable per-command history.
" CTRL-N and CTRL-P will be automatically bound to next-history and
" previous-history instead of down and up. If you don't like the change,
" explicitly bind the keys to down and up in your $FZF_DEFAULT_OPTS.
let g:fzf_history_dir = '~/.local/share/fzf-history'
<
FZF#RUN *fzf#run*
==============================================================================
For more advanced uses, you can use `fzf#run([options])` function with the
following options.
---------------------------+---------------+--------------------------------------------------------------
Option name | Type | Description ~
---------------------------+---------------+--------------------------------------------------------------
`source` | string | External command to generate input to fzf (e.g. `find.` )
`source` | list | Vim list as input to fzf
`sink` | string | Vim command to handle the selected item (e.g. `e` , `tabe` )
`sink` | funcref | Reference to function to process each selected item
`sink*` | funcref | Similar to `sink` , but takes the list of output lines at once
`options` | string/list | Options to fzf
`dir` | string | Working directory
`up` / `down` / `left` / `right` | number/string | Use tmux pane with the given size (e.g. `20` , `50%` )
`window` (Neovim only) | string | Command to open fzf window (e.g. `verticalaboveleft30new` )
`launcher` | string | External terminal emulator to start fzf with (GVim only)
`launcher` | funcref | Function for generating `launcher` string (GVim only)
---------------------------+---------------+--------------------------------------------------------------
`options` entry can be either a string or a list. For simple cases, string
should suffice, but prefer to use list type if you're concerned about escaping
issues on different platforms.
>
call fzf#run({'options': '--reverse --prompt "C:\\Program Files\\"'})
call fzf#run({'options': ['--reverse', '--prompt', 'C:\Program Files\']})
<
FZF#WRAP *fzf#wrap*
==============================================================================
`fzf#wrap([namestring,][optsdict,][fullscreenboolean])` is a helper
function that decorates the options dictionary so that it understands
`g:fzf_layout`, `g:fzf_action`, `g:fzf_colors`, and `g:fzf_history_dir` like
`:FZF`.
>
command! -bang MyStuff
\ call fzf#run(fzf#wrap('my-stuff', {'dir': '~/my-stuff'}, <bang>0))
<
GVIM *fzf-gvim*
==============================================================================
In GVim, you need an external terminal emulator to start fzf with. `xterm`
command is used by default, but you can customize it with `g:fzf_launcher`.
>
" This is the default. %s is replaced with fzf command
let g:fzf_launcher = 'xterm -e bash -ic %s'
" Use urxvt instead
let g:fzf_launcher = 'urxvt -geometry 120x30 -e sh -c %s'
<
If you're running MacVim on OSX, I recommend you to use iTerm2 as the
launcher. Refer to the {this wiki page}{3} to see how to set up.
{3} https://github.com/junegunn/fzf/wiki/On-MacVim-with-iTerm2
LICENSE *fzf-license*
==============================================================================
The MIT License (MIT)
Copyright (c) 2017 Junegunn Choi
==============================================================================
vim:tw=78:sw=2:ts=2:ft=help:norl:nowrap:

1348
fzf

File diff suppressed because it is too large Load Diff

107
install
View File

@@ -2,7 +2,7 @@
set -u
version=0.16.4
version=0.16.7
auto_completion=
key_bindings=
update_config=2
@@ -99,11 +99,11 @@ link_fzf_in_path() {
}
try_curl() {
command -v curl > /dev/null && curl -fL $1 | tar -xz
command -v curl > /dev/null && curl -fL $1 | tar -xzf -
}
try_wget() {
command -v wget > /dev/null && wget -O - $1 | tar -xz
command -v wget > /dev/null && wget -O - $1 | tar -xzf -
}
download() {
@@ -158,80 +158,9 @@ case "$archi" in
FreeBSD\ *86) download fzf-$version-freebsd_${binary_arch:-386} ;;
OpenBSD\ *64) download fzf-$version-openbsd_${binary_arch:-amd64} ;;
OpenBSD\ *86) download fzf-$version-openbsd_${binary_arch:-386} ;;
*) binary_available=0 binary_error=1 ;;
*) binary_available=0 binary_error=1 ;;
esac
install_ruby_fzf() {
if [ -z "$allow_legacy" ]; then
ask "Do you want to install legacy Ruby version instead?" && exit 1
fi
echo "Installing legacy Ruby version ..."
# ruby executable
echo -n "Checking Ruby executable ... "
ruby=$(command -v ruby)
if [ $? -ne 0 ]; then
echo "ruby executable not found !!!"
exit 1
fi
# System ruby is preferred
system_ruby=/usr/bin/ruby
if [ -x $system_ruby ] && [ $system_ruby != "$ruby" ]; then
$system_ruby --disable-gems -rcurses -e0 2> /dev/null
[ $? -eq 0 ] && ruby=$system_ruby
fi
echo "OK ($ruby)"
# Curses-support
echo -n "Checking Curses support ... "
"$ruby" -rcurses -e0 2> /dev/null
if [ $? -eq 0 ]; then
echo "OK"
else
echo "Not found"
echo "Installing 'curses' gem ... "
if (( EUID )); then
/usr/bin/env gem install curses --user-install
else
/usr/bin/env gem install curses
fi
if [ $? -ne 0 ]; then
echo
echo "Failed to install 'curses' gem."
if [[ $(uname -r) =~ 'ARCH' ]]; then
echo "Make sure that base-devel package group is installed."
fi
exit 1
fi
fi
# Ruby version
echo -n "Checking Ruby version ... "
"$ruby" -e 'exit RUBY_VERSION >= "1.9"'
if [ $? -eq 0 ]; then
echo ">= 1.9"
"$ruby" --disable-gems -rcurses -e0 2> /dev/null
if [ $? -eq 0 ]; then
fzf_cmd="$ruby --disable-gems $fzf_base/fzf"
else
fzf_cmd="$ruby $fzf_base/fzf"
fi
else
echo "< 1.9"
fzf_cmd="$ruby $fzf_base/fzf"
fi
# Create fzf script
echo -n "Creating wrapper script for fzf ... "
rm -f "$fzf_base"/bin/fzf
echo "#!/bin/sh" > "$fzf_base"/bin/fzf
echo "$fzf_cmd \"\$@\"" >> "$fzf_base"/bin/fzf
chmod +x "$fzf_base"/bin/fzf
echo "OK"
}
cd "$fzf_base"
if [ -n "$binary_error" ]; then
if [ $binary_available -eq 0 ]; then
@@ -249,12 +178,12 @@ if [ -n "$binary_error" ]; then
echo "OK"
cp "$GOPATH/bin/fzf" "$fzf_base/bin/"
else
echo "Failed to build binary ..."
install_ruby_fzf
echo "Failed to build binary. Installation failed."
exit 1
fi
else
echo "go executable not found. Cannot build binary ..."
install_ruby_fzf
echo "go executable not found. Installation failed."
exit 1
fi
fi
@@ -368,6 +297,17 @@ append_line() {
set +e
}
create_file() {
local file="$1"
shift
echo "Create $file:"
for line in "$@"; do
echo " $line"
echo "$line" >> "$file"
done
echo
}
if [ $update_config -eq 2 ]; then
echo
ask "Do you want to update your shell configuration files?"
@@ -381,7 +321,14 @@ done
if [ $key_bindings -eq 1 ] && [ $has_fish -eq 1 ]; then
bind_file=~/.config/fish/functions/fish_user_key_bindings.fish
append_line $update_config "fzf_key_bindings" "$bind_file"
if [ ! -e "$bind_file" ]; then
create_file "$bind_file" \
'function fish_user_key_bindings' \
' fzf_key_bindings' \
'end'
else
append_line $update_config "fzf_key_bindings" "$bind_file"
fi
fi
if [ $update_config -eq 1 ]; then

View File

@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
..
.TH fzf-tmux 1 "Feb 2017" "fzf 0.16.4" "fzf-tmux - open fzf in tmux split pane"
.TH fzf-tmux 1 "Apr 2017" "fzf 0.16.7" "fzf-tmux - open fzf in tmux split pane"
.SH NAME
fzf-tmux - open fzf in tmux split pane

View File

@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
..
.TH fzf 1 "Feb 2017" "fzf 0.16.4" "fzf - a command-line fuzzy finder"
.TH fzf 1 "Apr 2017" "fzf 0.16.7" "fzf - a command-line fuzzy finder"
.SH NAME
fzf - a command-line fuzzy finder
@@ -339,6 +339,12 @@ Read input delimited by ASCII NUL characters instead of newline characters
.B "--print0"
Print output delimited by ASCII NUL characters instead of newline characters
.TP
.B "--no-clear"
Do not clear finder interface on exit. If fzf was started in full screen mode,
it will not switch back to the original screen, so you'll have to manually run
\fBtput rmcup\fR to return. This option can be used to avoid flickering of the
screen when your application needs to start fzf multiple times in order.
.TP
.B "--sync"
Synchronous search for multi-staged filtering. If specified, fzf will launch
ncurses finder only after the input stream is complete.
@@ -346,6 +352,9 @@ ncurses finder only after the input stream is complete.
.RS
e.g. \fBfzf --multi | fzf --sync\fR
.RE
.TP
.B "--version"
Display version information and exit
.SH ENVIRONMENT VARIABLES
.TP
@@ -430,6 +439,7 @@ e.g. \fBfzf --bind=ctrl-j:accept,ctrl-k:kill-line\fR
.B AVAILABLE KEYS: (SYNONYMS)
\fIctrl-[a-z]\fR
\fIctrl-space\fR
\fIctrl-alt-[a-z]\fR
\fIalt-[a-z]\fR
\fIalt-[0-9]\fR
\fIf[1-12]\fR
@@ -500,6 +510,7 @@ e.g. \fBfzf --bind=ctrl-j:accept,ctrl-k:kill-line\fR
\fBtoggle-in\fR (\fB--reverse\fR ? \fBtoggle+up\fR : \fBtoggle+down\fR)
\fBtoggle-out\fR (\fB--reverse\fR ? \fBtoggle+down\fR : \fBtoggle+up\fR)
\fBtoggle-preview\fR
\fBtoggle-preview-wrap\fR
\fBtoggle-sort\fR
\fBtoggle+up\fR \fIbtab (shift-tab)\fR
\fBunix-line-discard\fR \fIctrl-u\fR

View File

@@ -26,10 +26,56 @@ if exists('g:loaded_fzf')
endif
let g:loaded_fzf = 1
let s:is_win = has('win32') || has('win64')
if s:is_win && &shellslash
set noshellslash
let s:base_dir = expand('<sfile>:h:h')
set shellslash
else
let s:base_dir = expand('<sfile>:h:h')
endif
if s:is_win
function! s:fzf_call(fn, ...)
let shellslash = &shellslash
try
set noshellslash
return call(a:fn, a:000)
finally
let &shellslash = shellslash
endtry
endfunction
function! s:fzf_shellescape(path)
return substitute(s:fzf_call('shellescape', a:path), '[^\\]\zs\\"$', '\\\\"', '')
endfunction
else
function! s:fzf_call(fn, ...)
return call(a:fn, a:000)
endfunction
function! s:fzf_shellescape(path)
return shellescape(a:path)
endfunction
endif
function! s:fzf_getcwd()
return s:fzf_call('getcwd')
endfunction
function! s:fzf_fnamemodify(fname, mods)
return s:fzf_call('fnamemodify', a:fname, a:mods)
endfunction
function! s:fzf_expand(fmt)
return s:fzf_call('expand', a:fmt)
endfunction
function! s:fzf_tempname()
return s:fzf_call('tempname')
endfunction
let s:default_layout = { 'down': '~40%' }
let s:layout_keys = ['window', 'up', 'down', 'left', 'right']
let s:is_win = has('win32') || has('win64')
let s:base_dir = expand('<sfile>:h:h')
let s:fzf_go = s:base_dir.'/bin/fzf'
let s:fzf_tmux = s:base_dir.'/bin/fzf-tmux'
let s:install = s:base_dir.'/install'
@@ -41,7 +87,7 @@ set cpo&vim
function! s:fzf_exec()
if !exists('s:exec')
if executable(s:fzf_go)
let s:exec = s:fzf_go
let s:exec = s:fzf_expand(s:fzf_go)
elseif executable('fzf')
let s:exec = 'fzf'
elseif s:is_win
@@ -62,7 +108,7 @@ function! s:fzf_exec()
throw 'fzf executable not found'
endif
endif
return s:shellesc(s:exec)
return s:is_win ? s:exec : s:shellesc(s:exec)
endfunction
function! s:tmux_enabled()
@@ -133,7 +179,7 @@ function! s:has_any(dict, keys)
endfunction
function! s:open(cmd, target)
if stridx('edit', a:cmd) == 0 && fnamemodify(a:target, ':p') ==# expand('%:p')
if stridx('edit', a:cmd) == 0 && s:fzf_fnamemodify(a:target, ':p') ==# s:fzf_expand('%:p')
return
endif
execute a:cmd s:escape(a:target)
@@ -148,11 +194,11 @@ function! s:common_sink(action, lines) abort
if len(a:lines) > 1
augroup fzf_swap
autocmd SwapExists * let v:swapchoice='o'
\| call s:warn('fzf: E325: swap file exists: '.expand('<afile>'))
\| call s:warn('fzf: E325: swap file exists: '.s:fzf_expand('<afile>'))
augroup END
endif
try
let empty = empty(expand('%')) && line('$') == 1 && empty(getline(1)) && !&modified
let empty = empty(s:fzf_expand('%')) && line('$') == 1 && empty(getline(1)) && !&modified
let autochdir = &autochdir
set noautochdir
for item in a:lines
@@ -192,6 +238,21 @@ function! s:defaults()
return empty(colors) ? '' : ('--color='.colors)
endfunction
function! s:validate_layout(layout)
for key in keys(a:layout)
if index(s:layout_keys, key) < 0
throw printf('Invalid entry in g:fzf_layout: %s (allowed: %s)%s',
\ key, join(s:layout_keys, ', '), key == 'options' ? '. Use $FZF_DEFAULT_OPTS.' : '')
endif
endfor
return a:layout
endfunction
function! s:evaluate_opts(options)
return type(a:options) == type([]) ?
\ join(map(copy(a:options), 's:fzf_shellescape(v:val)')) : a:options
endfunction
" [name string,] [opts dict,] [fullscreen boolean]
function! fzf#wrap(...)
let args = ['', {}, 0]
@@ -200,7 +261,7 @@ function! fzf#wrap(...)
for arg in copy(a:000)
let tidx = index(expects, type(arg), tidx)
if tidx < 0
throw 'invalid arguments (expected: [name string] [opts dict] [fullscreen boolean])'
throw 'Invalid arguments (expected: [name string] [opts dict] [fullscreen boolean])'
endif
let args[tidx] = arg
let tidx += 1
@@ -223,20 +284,21 @@ function! fzf#wrap(...)
if !exists('g:fzf_layout') && exists('g:fzf_height')
let opts.down = g:fzf_height
else
let opts = extend(opts, get(g:, 'fzf_layout', s:default_layout))
let opts = extend(opts, s:validate_layout(get(g:, 'fzf_layout', s:default_layout)))
endif
endif
" Colors: g:fzf_colors
let opts.options = s:defaults() .' '. get(opts, 'options', '')
let opts.options = s:defaults() .' '. s:evaluate_opts(get(opts, 'options', ''))
" History: g:fzf_history_dir
if len(name) && len(get(g:, 'fzf_history_dir', ''))
let dir = expand(g:fzf_history_dir)
let dir = s:fzf_expand(g:fzf_history_dir)
if !isdirectory(dir)
call mkdir(dir, 'p')
endif
let opts.options = join(['--history', s:escape(dir.'/'.name), opts.options])
let history = s:is_win ? s:fzf_shellescape(dir.'\'.name) : s:escape(dir.'/'.name)
let opts.options = join(['--history', history, opts.options])
endif
" Action: g:fzf_action
@@ -252,19 +314,6 @@ function! fzf#wrap(...)
return opts
endfunction
function! fzf#shellescape(path)
if s:is_win
let shellslash = &shellslash
try
set noshellslash
return shellescape(a:path)
finally
let &shellslash = shellslash
endtry
endif
return shellescape(a:path)
endfunction
function! fzf#run(...) abort
try
let oshell = &shell
@@ -277,23 +326,30 @@ try
set shell=sh
endif
if has('nvim') && len(filter(range(1, bufnr('$')), 'bufname(v:val) =~# ";#FZF"'))
call s:warn('FZF is already running!')
return []
if has('nvim')
let running = filter(range(1, bufnr('$')), "bufname(v:val) =~# ';#FZF'")
if len(running)
call s:warn('FZF is already running (in buffer '.join(running, ', ').')!')
return []
endif
endif
let dict = exists('a:1') ? s:upgrade(a:1) : {}
let temps = { 'result': tempname() }
let optstr = get(dict, 'options', '')
let temps = { 'result': s:fzf_tempname() }
let optstr = s:evaluate_opts(get(dict, 'options', ''))
try
let fzf_exec = s:fzf_exec()
catch
throw v:exception
endtry
if has('nvim') && !has_key(dict, 'dir')
let dict.dir = s:fzf_getcwd()
endif
if !has_key(dict, 'source') && !empty($FZF_DEFAULT_COMMAND)
let temps.source = tempname()
call writefile(split($FZF_DEFAULT_COMMAND, "\n"), temps.source)
let dict.source = (empty($SHELL) ? &shell : $SHELL) . ' ' . s:shellesc(temps.source)
let temps.source = s:fzf_tempname().(s:is_win ? '.bat' : '')
call writefile((s:is_win ? ['@echo off'] : []) + split($FZF_DEFAULT_COMMAND, "\n"), temps.source)
let dict.source = (empty($SHELL) ? &shell : $SHELL) . (s:is_win ? ' /c ' : ' ') . s:shellesc(temps.source)
endif
if has_key(dict, 'source')
@@ -302,11 +358,11 @@ try
if type == 1
let prefix = source.'|'
elseif type == 3
let temps.input = tempname()
let temps.input = s:fzf_tempname()
call writefile(source, temps.input)
let prefix = 'cat '.s:shellesc(temps.input).'|'
let prefix = (s:is_win ? 'type ' : 'cat ').s:shellesc(temps.input).'|'
else
throw 'invalid source type'
throw 'Invalid source type'
endif
else
let prefix = ''
@@ -316,14 +372,15 @@ try
let use_height = has_key(dict, 'down') &&
\ !(has('nvim') || s:is_win || s:present(dict, 'up', 'left', 'right')) &&
\ executable('tput') && filereadable('/dev/tty')
let use_term = has('nvim')
let use_term = has('nvim') && !s:is_win
let use_tmux = (!use_height && !use_term || prefer_tmux) && s:tmux_enabled() && s:splittable(dict)
if prefer_tmux && use_tmux
let use_height = 0
let use_term = 0
endif
if use_height
let optstr .= ' --height='.s:calc_size(&lines, dict.down, dict)
let height = s:calc_size(&lines, dict.down, dict)
let optstr .= ' --height='.height
elseif use_term
let optstr .= ' --no-height'
endif
@@ -377,13 +434,13 @@ endfunction
function! s:pushd(dict)
if s:present(a:dict, 'dir')
let cwd = getcwd()
let cwd = s:fzf_getcwd()
if get(a:dict, 'prev_dir', '') ==# cwd
return 1
endif
let a:dict.prev_dir = cwd
execute 'lcd' s:escape(a:dict.dir)
let a:dict.dir = getcwd()
let a:dict.dir = s:fzf_getcwd()
return 1
endif
return 0
@@ -436,7 +493,7 @@ function! s:execute(dict, command, use_height, temps) abort
if has('unix') && !a:use_height
silent! !clear 2> /dev/null
endif
let escaped = escape(substitute(a:command, '\n', '\\n', 'g'), '%#')
let escaped = escape(substitute(a:command, '\n', '\\n', 'g'), '%#!')
if has('gui_running')
let Launcher = get(a:dict, 'launcher', get(g:, 'Fzf_launcher', get(g:, 'fzf_launcher', s:launcher)))
let fmt = type(Launcher) == 2 ? call(Launcher, []) : Launcher
@@ -445,7 +502,24 @@ function! s:execute(dict, command, use_height, temps) abort
endif
let command = printf(fmt, escaped)
else
let command = escaped
let command = a:use_height ? a:command : escaped
endif
if s:is_win
let batchfile = s:fzf_tempname().'.bat'
call writefile(['@echo off', command], batchfile)
let command = batchfile
if has('nvim')
let s:dict = a:dict
let s:temps = a:temps
let fzf = {}
function! fzf.on_exit(job_id, exit_status, event) dict
let lines = s:collect(s:temps)
call s:callback(s:dict, lines)
endfunction
let cmd = 'start /wait cmd /c '.command
call jobstart(cmd, fzf)
return []
endif
endif
if a:use_height
let stdin = has_key(a:dict, 'source') ? '' : '< /dev/tty'
@@ -658,19 +732,24 @@ let s:default_action = {
function! s:shortpath()
let short = pathshorten(fnamemodify(getcwd(), ':~:.'))
return empty(short) ? '~/' : short . (short =~ '/$' ? '' : '/')
let slash = (s:is_win && !&shellslash) ? '\' : '/'
return empty(short) ? '~'.slash : short . (short =~ slash.'$' ? '' : slash)
endfunction
function! s:cmd(bang, ...) abort
let args = copy(a:000)
let opts = { 'options': '--multi ' }
let opts = { 'options': ['--multi'] }
if len(args) && isdirectory(expand(args[-1]))
let opts.dir = substitute(substitute(remove(args, -1), '\\\(["'']\)', '\1', 'g'), '[/\\]*$', '/', '')
let opts.options .= ' --prompt '.fzf#shellescape(opts.dir)
if s:is_win && !&shellslash
let opts.dir = substitute(opts.dir, '/', '\\', 'g')
endif
let prompt = opts.dir
else
let opts.options .= ' --prompt '.fzf#shellescape(s:shortpath())
let prompt = s:shortpath()
endif
let opts.options .= ' '.join(args)
call extend(opts.options, ['--prompt', prompt])
call extend(opts.options, args)
call fzf#run(fzf#wrap('FZF', opts, a:bang))
endfunction

View File

@@ -234,7 +234,7 @@ _fzf_complete_telnet() {
_fzf_complete_ssh() {
_fzf_complete '+m' "$@" < <(
cat <(cat ~/.ssh/config /etc/ssh/ssh_config 2> /dev/null | command grep -i '^host' | command grep -v '*') \
<(command grep -oE '^[a-z0-9.,-]+' ~/.ssh/known_hosts | tr ',' '\n' | awk '{ print $1 " " $1 }') \
<(command grep -oE '^[a-z0-9.,:-]+' ~/.ssh/known_hosts | tr ',' '\n' | awk '{ print $1 " " $1 }') \
<(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') |
awk '{if (length($2) > 0) {print $2}}' | sort -u
)
@@ -304,7 +304,7 @@ done
# Directory
for cmd in $d_cmds; do
_fzf_defc "$cmd" _fzf_dir_completion "-o nospace -o plusdirs"
_fzf_defc "$cmd" _fzf_dir_completion "-o nospace -o dirnames"
done
unset _fzf_defc

View File

@@ -117,7 +117,7 @@ _fzf_complete_telnet() {
_fzf_complete_ssh() {
_fzf_complete '+m' "$@" < <(
command cat <(cat ~/.ssh/config /etc/ssh/ssh_config 2> /dev/null | command grep -i '^host' | command grep -v '*') \
<(command grep -oE '^[a-z0-9.,-]+' ~/.ssh/known_hosts | tr ',' '\n' | awk '{ print $1 " " $1 }') \
<(command grep -oE '^[a-z0-9.,:-]+' ~/.ssh/known_hosts | tr ',' '\n' | awk '{ print $1 " " $1 }') \
<(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') |
awk '{if (length($2) > 0) {print $2}}' | sort -u
)
@@ -143,7 +143,7 @@ _fzf_complete_unalias() {
fzf-completion() {
local tokens cmd prefix trigger tail fzf matches lbuf d_cmds
setopt localoptions noshwordsplit noksh_arrays
setopt localoptions noshwordsplit noksh_arrays noposixbuiltins
# http://zsh.sourceforge.net/FAQ/zshfaq03.html
# http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion-Flags

View File

@@ -1,7 +1,7 @@
# Key bindings
# ------------
__fzf_select__() {
local cmd="${FZF_CTRL_T_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
local cmd="${FZF_CTRL_T_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
-o -type f -print \
-o -type d -print \
-o -type l -print 2> /dev/null | cut -b3-"}"
@@ -46,8 +46,8 @@ fzf-file-widget() {
__fzf_cd__() {
local cmd dir
cmd="${FZF_ALT_C_COMMAND:-"command find -L . \\( -path '*/\\.*' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
-o -type d -print 2> /dev/null | sed 1d | cut -b3-"}"
cmd="${FZF_ALT_C_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
-o -type d -print 2> /dev/null | cut -b3-"}"
dir=$(eval "$cmd" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_ALT_C_OPTS" $(__fzfcmd) +m) && printf 'cd %q' "$dir"
}
@@ -56,7 +56,7 @@ __fzf_history__() (
shopt -u nocaseglob nocasematch
line=$(
HISTTIMEFORMAT= history |
FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS +s --tac -n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort $FZF_CTRL_R_OPTS +m" $(__fzfcmd) |
FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS --tac -n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort $FZF_CTRL_R_OPTS +m" $(__fzfcmd) |
command grep '^ *[0-9]') &&
if [[ $- =~ H ]]; then
sed 's/^ *\([0-9]*\)\** .*/!\1/' <<< "$line"

View File

@@ -2,7 +2,7 @@
# ------------
function fzf_key_bindings
# Store last token in $dir as root for the 'find' command
# Store current token in $dir as root for the 'find' command
function fzf-file-widget -d "List files and folders"
set -l dir (commandline -t)
# The commandline token might be escaped, we need to unescape it.
@@ -16,10 +16,10 @@ function fzf_key_bindings
# "-path \$dir'*/\\.*'" matches hidden files/folders inside $dir but not
# $dir itself, even if hidden.
set -q FZF_CTRL_T_COMMAND; or set -l FZF_CTRL_T_COMMAND "
command find -L \$dir -mindepth 1 \\( -path \$dir'*/\\.*' -o -fstype 'devfs' -o -fstype 'devtmpfs' \\) -prune \
command find -L \$dir -mindepth 1 \\( -path \$dir'*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' \\) -prune \
-o -type f -print \
-o -type d -print \
-o -type l -print 2> /dev/null | sed 's#^\./##'"
-o -type l -print 2> /dev/null | cut -b3-"
set -q FZF_TMUX_HEIGHT; or set FZF_TMUX_HEIGHT 40%
begin
@@ -45,7 +45,7 @@ function fzf_key_bindings
function fzf-history-widget -d "Show command history"
set -q FZF_TMUX_HEIGHT; or set FZF_TMUX_HEIGHT 40%
begin
set -lx FZF_DEFAULT_OPTS "--height $FZF_TMUX_HEIGHT $FZF_DEFAULT_OPTS +s --tiebreak=index --bind=ctrl-r:toggle-sort $FZF_CTRL_R_OPTS +m"
set -lx FZF_DEFAULT_OPTS "--height $FZF_TMUX_HEIGHT $FZF_DEFAULT_OPTS --tiebreak=index --bind=ctrl-r:toggle-sort $FZF_CTRL_R_OPTS +m"
history | eval (__fzfcmd) -q '(commandline)' | read -l result
and commandline -- $result
end
@@ -54,8 +54,8 @@ function fzf_key_bindings
function fzf-cd-widget -d "Change directory"
set -q FZF_ALT_C_COMMAND; or set -l FZF_ALT_C_COMMAND "
command find -L . \\( -path '*/\\.*' -o -fstype 'devfs' -o -fstype 'devtmpfs' \\) -prune \
-o -type d -print 2> /dev/null | sed 1d | cut -b3-"
command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' \\) -prune \
-o -type d -print 2> /dev/null | cut -b3-"
set -q FZF_TMUX_HEIGHT; or set FZF_TMUX_HEIGHT 40%
begin
set -lx FZF_DEFAULT_OPTS "--height $FZF_TMUX_HEIGHT --reverse $FZF_DEFAULT_OPTS $FZF_ALT_C_OPTS"

View File

@@ -4,7 +4,7 @@ if [[ $- == *i* ]]; then
# CTRL-T - Paste the selected file path(s) into the command line
__fsel() {
local cmd="${FZF_CTRL_T_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
local cmd="${FZF_CTRL_T_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
-o -type f -print \
-o -type d -print \
-o -type l -print 2> /dev/null | cut -b3-"}"
@@ -38,10 +38,15 @@ bindkey '^T' fzf-file-widget
# ALT-C - cd into the selected directory
fzf-cd-widget() {
local cmd="${FZF_ALT_C_COMMAND:-"command find -L . \\( -path '*/\\.*' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
-o -type d -print 2> /dev/null | sed 1d | cut -b3-"}"
local cmd="${FZF_ALT_C_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
-o -type d -print 2> /dev/null | cut -b3-"}"
setopt localoptions pipefail 2> /dev/null
cd "${$(eval "$cmd" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_ALT_C_OPTS" $(__fzfcmd) +m):-.}"
local dir="$(eval "$cmd" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse $FZF_DEFAULT_OPTS $FZF_ALT_C_OPTS" $(__fzfcmd) +m)"
if [[ -z "$dir" ]]; then
zle redisplay
return 0
fi
cd "$dir"
local ret=$?
zle reset-prompt
typeset -f zle-line-init >/dev/null && zle zle-line-init
@@ -53,9 +58,9 @@ bindkey '\ec' fzf-cd-widget
# CTRL-R - Paste the selected command from history into the command line
fzf-history-widget() {
local selected num
setopt localoptions noglobsubst pipefail 2> /dev/null
setopt localoptions noglobsubst noposixbuiltins pipefail 2> /dev/null
selected=( $(fc -l 1 |
FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS +s --tac -n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort $FZF_CTRL_R_OPTS --query=${(q)LBUFFER} +m" $(__fzfcmd)) )
FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS --tac -n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort $FZF_CTRL_R_OPTS --query=${(q)LBUFFER} +m" $(__fzfcmd)) )
local ret=$?
if [ -n "$selected" ]; then
num=$selected[1]
@@ -71,4 +76,3 @@ zle -N fzf-history-widget
bindkey '^R' fzf-history-widget
fi

View File

@@ -1,40 +0,0 @@
FROM ubuntu:14.04
MAINTAINER Junegunn Choi <junegunn.c@gmail.com>
# apt-get
RUN apt-get update && apt-get -y upgrade && \
apt-get install -y --force-yes git curl build-essential
# Install Go 1.4
RUN cd / && curl \
https://storage.googleapis.com/golang/go1.4.2.linux-amd64.tar.gz | \
tar -xz && mv go go1.4 && \
sed -i 's@#define PTHREAD_KEYS_MAX 128@@' /go1.4/src/runtime/cgo/gcc_android_arm.c
ENV GOROOT /go1.4
ENV PATH /go1.4/bin:$PATH
RUN cd / && \
curl -O http://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin && \
chmod 755 /android-ndk* && /android-ndk-r10e-linux-x86_64.bin && \
mv android-ndk-r10e /android-ndk
RUN cd /android-ndk && bash ./build/tools/make-standalone-toolchain.sh --platform=android-21 --install-dir=/ndk --arch=arm
ENV NDK_CC /ndk/bin/arm-linux-androideabi-gcc
RUN cd $GOROOT/src && \
CC_FOR_TARGET=$NDK_CC GOOS=android GOARCH=arm GOARM=7 ./make.bash
RUN cd / && curl \
http://ftp.gnu.org/gnu/ncurses/ncurses-5.9.tar.gz | \
tar -xz && cd /ncurses-5.9 && \
./configure CC=$NDK_CC CFLAGS="-fPIE -march=armv7-a -mfpu=neon -mhard-float -Wl,--no-warn-mismatch" LDFLAGS="-march=armv7-a -Wl,--no-warn-mismatch" --host=arm-linux --enable-overwrite --enable-const --without-cxx-binding --without-shared --without-debug --enable-widec --enable-ext-colors --enable-ext-mouse --enable-pc-files --with-pkg-config-libdir=$PKG_CONFIG_LIBDIR --without-manpages --without-ada --disable-shared --without-tests --prefix=/ndk/sysroot/usr --with-default-terminfo-dirs=/usr/share/terminfo --with-terminfo-dirs=/usr/share/terminfo ac_cv_header_locale_h=n ac_cv_func_getpwent=no ac_cv_func_getpwnam=no ac_cv_func_getpwuid=no && \
sed -i 's@#define HAVE_LOCALE_H 1@/* #undef HAVE_LOCALE_H */@' include/ncurses_cfg.h && \
make && \
sed -i '0,/echo.*/{s/echo.*/exit 0/}' misc/run_tic.sh && \
make install && \
mv /ndk/sysroot/usr/lib/libncursesw.a /ndk/sysroot/usr/lib/libncurses.a
# Default CMD
CMD cd /fzf/src && /bin/bash

View File

@@ -1,24 +0,0 @@
FROM base/archlinux:2014.07.03
MAINTAINER Junegunn Choi <junegunn.c@gmail.com>
# apt-get
RUN pacman-key --populate archlinux && pacman-key --refresh-keys
RUN pacman-db-upgrade && pacman -Syu --noconfirm base-devel git
# Install Go 1.4
RUN cd / && curl \
https://storage.googleapis.com/golang/go1.4.2.linux-amd64.tar.gz | \
tar -xz && mv go go1.4
ENV GOROOT /go1.4
ENV PATH /go1.4/bin:$PATH
# For i386 build
RUN echo '[multilib]' >> /etc/pacman.conf && \
echo 'Include = /etc/pacman.d/mirrorlist' >> /etc/pacman.conf && \
pacman-db-upgrade && yes | pacman -Sy gcc-multilib lib32-ncurses && \
cd $GOROOT/src && GOARCH=386 ./make.bash
# Default CMD
CMD cd /fzf/src && /bin/bash

View File

@@ -1,32 +0,0 @@
FROM centos:centos6
MAINTAINER Junegunn Choi <junegunn.c@gmail.com>
# yum
RUN yum install -y git gcc make tar glibc-devel glibc-devel.i686 \
ncurses-devel ncurses-static ncurses-devel.i686 \
gpm-devel gpm-static libgcc.i686
# Install Go 1.4
RUN cd / && curl \
https://storage.googleapis.com/golang/go1.4.2.linux-amd64.tar.gz | \
tar -xz && mv go go1.4
# Install Go 1.7
RUN cd / && curl \
https://storage.googleapis.com/golang/go1.7.linux-amd64.tar.gz | \
tar -xz && mv go go1.7
# Install RPMs for building static 32-bit binary
RUN curl ftp://ftp.pbone.net/mirror/ftp.centos.org/6.8/os/i386/Packages/ncurses-static-5.7-4.20090207.el6.i686.rpm -o rpm && rpm -i rpm && \
curl ftp://ftp.pbone.net/mirror/ftp.centos.org/6.8/os/i386/Packages/gpm-static-1.20.6-12.el6.i686.rpm -o rpm && rpm -i rpm
ENV GOROOT_BOOTSTRAP /go1.4
ENV GOROOT /go1.7
ENV PATH /go1.7/bin:$PATH
# For i386 build
RUN cd $GOROOT/src && GOARCH=386 ./make.bash
# Default CMD
CMD cd /fzf/src && /bin/bash

View File

@@ -1,22 +0,0 @@
FROM ubuntu:14.04
MAINTAINER Junegunn Choi <junegunn.c@gmail.com>
# apt-get
RUN apt-get update && apt-get -y upgrade && \
apt-get install -y --force-yes git curl build-essential libncurses-dev libgpm-dev
# Install Go 1.4
RUN cd / && curl \
https://storage.googleapis.com/golang/go1.4.2.linux-amd64.tar.gz | \
tar -xz && mv go go1.4
ENV GOROOT /go1.4
ENV PATH /go1.4/bin:$PATH
# For i386 build
RUN apt-get install -y lib32ncurses5-dev && \
cd $GOROOT/src && GOARCH=386 ./make.bash
# Default CMD
CMD cd /fzf/src && /bin/bash

View File

@@ -4,6 +4,8 @@ ifeq ($(UNAME_S),Darwin)
GOOS := darwin
else ifeq ($(UNAME_S),Linux)
GOOS := linux
else
$(error "$$GOOS is not defined.")
endif
endif
@@ -12,7 +14,6 @@ ROOTDIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
BINDIR := $(shell dirname $(ROOTDIR))/bin
GOPATH := $(shell dirname $(ROOTDIR))/gopath
SRCDIR := $(GOPATH)/src/github.com/junegunn/fzf/src
DOCKEROPTS := -i -t -v $(ROOTDIR):/fzf/src
BINARY32 := fzf-$(GOOS)_386
BINARY64 := fzf-$(GOOS)_amd64
BINARYARM5 := fzf-$(GOOS)_arm5
@@ -86,12 +87,6 @@ deps: $(SRCDIR) $(SOURCES)
cd $(SRCDIR) && go get -tags "$(TAGS)"
./deps
android-build: $(SRCDIR)
cd $(SRCDIR) && GOARCH=arm GOARM=7 CGO_ENABLED=1 go get
cd $(SRCDIR)/fzf && GOARCH=arm GOARM=7 CGO_ENABLED=1 go build -a -ldflags="-w -extldflags=-pie" -o $(BINARYARM7)
cd $(SRCDIR)/fzf && cp $(BINARYARM7) $(RELEASEARM7) && tar -czf $(RELEASEARM7).tgz $(RELEASEARM7) && \
rm -f $(RELEASEARM7)
test: deps
SHELL=/bin/sh GOOS= go test -v -tags "$(TAGS)" ./...
@@ -129,42 +124,4 @@ $(BINDIR)/fzf: fzf/$(BINARY) | $(BINDIR)
$(BINDIR):
mkdir -p $@
docker-arch:
docker build -t junegunn/arch-sandbox - < Dockerfile.arch
docker-ubuntu:
docker build -t junegunn/ubuntu-sandbox - < Dockerfile.ubuntu
docker-centos:
docker build -t junegunn/centos-sandbox - < Dockerfile.centos
docker-android:
docker build -t junegunn/android-sandbox - < Dockerfile.android
arch: docker-arch
docker run $(DOCKEROPTS) junegunn/$@-sandbox \
sh -c 'cd /fzf/src; /bin/bash'
ubuntu: docker-ubuntu
docker run $(DOCKEROPTS) junegunn/$@-sandbox \
sh -c 'cd /fzf/src; /bin/bash'
centos: docker-centos
docker run $(DOCKEROPTS) junegunn/$@-sandbox \
sh -c 'cd /fzf/src; /bin/bash'
linux: docker-centos
docker run $(DOCKEROPTS) junegunn/centos-sandbox \
/bin/bash -ci 'cd /fzf/src; make TAGS=static release'
ubuntu-android: docker-android
docker run $(DOCKEROPTS) junegunn/android-sandbox \
sh -c 'cd /fzf/src; /bin/bash'
android: docker-android
docker run $(DOCKEROPTS) junegunn/android-sandbox \
/bin/bash -ci 'cd /fzf/src; GOOS=android make android-build'
.PHONY: all deps release test install uninstall clean \
linux arch ubuntu centos docker-arch docker-ubuntu docker-centos \
android-build docker-android ubuntu-android android
.PHONY: all deps release release-all test install uninstall clean

View File

@@ -8,7 +8,7 @@ import (
const (
// Current version
version = "0.16.4"
version = "0.16.7"
// Core
coordinatorDelayMax time.Duration = 100 * time.Millisecond
@@ -18,10 +18,9 @@ const (
readerBufferSize = 64 * 1024
// Terminal
initialDelay = 20 * time.Millisecond
initialDelayTac = 100 * time.Millisecond
spinnerDuration = 200 * time.Millisecond
maxPatternLength = 100
initialDelay = 20 * time.Millisecond
initialDelayTac = 100 * time.Millisecond
spinnerDuration = 200 * time.Millisecond
// Matcher
numPartitionsMultiplier = 8

View File

@@ -4,5 +4,5 @@ package fzf
const (
// Reader
defaultCommand = `find -L . -path '*/\.*' -prune -o -type f -print -o -type l -print 2> /dev/null | sed s/^..//`
defaultCommand = `command find -L . -mindepth 1 \( -path '*/\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \) -prune -o -type f -print -o -type l -print 2> /dev/null | cut -b3-`
)

View File

@@ -14,5 +14,5 @@ reset() (
reset github.com/junegunn/go-isatty 66b8e73f3f5cda9f96b69efd03dd3d7fc4a5cdb8
reset github.com/junegunn/go-runewidth 14207d285c6c197daabb5c9793d63e7af9ab2d50
reset github.com/junegunn/go-shellwords 33bd8f1ebe16d6e5eb688cc885749a63059e9167
reset github.com/junegunn/go-shellwords 02e3cf038dcea8290e44424da473dd12be796a8a
reset golang.org/x/crypto abc5fa7ad02123a41f02bf1391c9760f7586e608

View File

@@ -86,6 +86,7 @@ const usage = `usage: fzf [options]
--read0 Read input delimited by ASCII NUL characters
--print0 Print output delimited by ASCII NUL characters
--sync Synchronous search for multi-staged filtering
--version Display version information and exit
Environment variables
FZF_DEFAULT_COMMAND Default command to use when input is tty
@@ -186,6 +187,7 @@ type Options struct {
Margin [4]sizeSpec
Bordered bool
Tabstop int
ClearOnExit bool
Version bool
}
@@ -234,6 +236,7 @@ func defaultOptions() *Options {
HeaderLines: 0,
Margin: defaultMargin(),
Tabstop: 8,
ClearOnExit: true,
Version: false}
}
@@ -398,7 +401,7 @@ func parseKeyChords(str string, message string) map[int]string {
case "ctrl-space":
chord = tui.CtrlSpace
case "alt-enter", "alt-return":
chord = tui.AltEnter
chord = tui.CtrlAltM
case "alt-space":
chord = tui.AltSpace
case "alt-/":
@@ -434,7 +437,9 @@ func parseKeyChords(str string, message string) map[int]string {
case "f12":
chord = tui.F12
default:
if len(key) == 6 && strings.HasPrefix(lkey, "ctrl-") && isAlphabet(lkey[5]) {
if len(key) == 10 && strings.HasPrefix(lkey, "ctrl-alt-") && isAlphabet(lkey[9]) {
chord = tui.CtrlAltA + int(lkey[9]) - 'a'
} else if len(key) == 6 && strings.HasPrefix(lkey, "ctrl-") && isAlphabet(lkey[5]) {
chord = tui.CtrlA + int(lkey[5]) - 'a'
} else if len(key) == 5 && strings.HasPrefix(lkey, "alt-") && isAlphabet(lkey[4]) {
chord = tui.AltA + int(lkey[4]) - 'a'
@@ -723,6 +728,8 @@ func parseKeymap(keymap map[int][]action, str string) {
appendAction(actNextHistory)
case "toggle-preview":
appendAction(actTogglePreview)
case "toggle-preview-wrap":
appendAction(actTogglePreviewWrap)
case "toggle-sort":
appendAction(actToggleSort)
case "preview-up":
@@ -1097,6 +1104,10 @@ func parseOptions(opts *Options, allArgs []string) {
nextString(allArgs, &i, "margin required (TRBL / TB,RL / T,RL,B / T,R,B,L)"))
case "--tabstop":
opts.Tabstop = nextInt(allArgs, &i, "tab stop required")
case "--clear":
opts.ClearOnExit = true
case "--no-clear":
opts.ClearOnExit = false
case "--version":
opts.Version = true
default:

View File

@@ -125,14 +125,14 @@ func TestIrrelevantNth(t *testing.T) {
}
func TestParseKeys(t *testing.T) {
pairs := parseKeyChords("ctrl-z,alt-z,f2,@,Alt-a,!,ctrl-G,J,g,ALT-enter,alt-SPACE", "")
pairs := parseKeyChords("ctrl-z,alt-z,f2,@,Alt-a,!,ctrl-G,J,g,ctrl-alt-a,ALT-enter,alt-SPACE", "")
check := func(i int, s string) {
if pairs[i] != s {
t.Errorf("%s != %s", pairs[i], s)
}
}
if len(pairs) != 11 {
t.Error(11)
if len(pairs) != 12 {
t.Error(12)
}
check(tui.CtrlZ, "ctrl-z")
check(tui.AltZ, "alt-z")
@@ -143,7 +143,8 @@ func TestParseKeys(t *testing.T) {
check(tui.CtrlA+'g'-'a', "ctrl-G")
check(tui.AltZ+'J', "J")
check(tui.AltZ+'g', "g")
check(tui.AltEnter, "ALT-enter")
check(tui.CtrlAltA, "ctrl-alt-a")
check(tui.CtrlAltM, "ALT-enter")
check(tui.AltSpace, "alt-SPACE")
// Synonyms

View File

@@ -46,6 +46,7 @@ type itemLine struct {
current bool
selected bool
label string
queryLen int
width int
result Result
}
@@ -58,6 +59,7 @@ type Terminal struct {
inlineInfo bool
prompt string
reverse bool
fullscreen bool
hscroll bool
hscrollOff int
wordRubout string
@@ -140,6 +142,7 @@ const (
reqList
reqJump
reqRefresh
reqReinit
reqRedraw
reqClose
reqPrintQuery
@@ -199,6 +202,7 @@ const (
actPrintQuery
actToggleSort
actTogglePreview
actTogglePreviewWrap
actPreviewUp
actPreviewDown
actPreviewPageUp
@@ -208,6 +212,7 @@ const (
actExecute
actExecuteSilent
actExecuteMulti // Deprecated
actSigStop
)
func toActions(types ...actionType) []action {
@@ -244,6 +249,9 @@ func defaultKeymap() map[int][]action {
keymap[tui.CtrlU] = toActions(actUnixLineDiscard)
keymap[tui.CtrlW] = toActions(actUnixWordRubout)
keymap[tui.CtrlY] = toActions(actYank)
if !util.IsWindows() {
keymap[tui.CtrlZ] = toActions(actSigStop)
}
keymap[tui.AltB] = toActions(actBackwardWord)
keymap[tui.SLeft] = toActions(actBackwardWord)
@@ -293,7 +301,15 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
strongAttr = tui.AttrRegular
}
var renderer tui.Renderer
if opts.Height.size > 0 {
fullscreen := opts.Height.size == 0 || opts.Height.percent && opts.Height.size == 100
if fullscreen {
if tui.HasFullscreenRenderer() {
renderer = tui.NewFullscreenRenderer(opts.Theme, opts.Black, opts.Mouse)
} else {
renderer = tui.NewLightRenderer(opts.Theme, opts.Black, opts.Mouse, opts.Tabstop, opts.ClearOnExit,
true, func(h int) int { return h })
}
} else {
maxHeightFunc := func(termHeight int) int {
var maxHeight int
if opts.Height.percent {
@@ -314,12 +330,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
}
return util.Min(termHeight, util.Max(maxHeight, effectiveMinHeight))
}
renderer = tui.NewLightRenderer(opts.Theme, opts.Black, opts.Mouse, opts.Tabstop, maxHeightFunc)
} else if tui.HasFullscreenRenderer() {
renderer = tui.NewFullscreenRenderer(opts.Theme, opts.Black, opts.Mouse)
} else {
renderer = tui.NewLightRenderer(opts.Theme, opts.Black, opts.Mouse, opts.Tabstop,
func(h int) int { return h })
renderer = tui.NewLightRenderer(opts.Theme, opts.Black, opts.Mouse, opts.Tabstop, opts.ClearOnExit, false, maxHeightFunc)
}
wordRubout := "[^[:alnum:]][[:alnum:]]"
wordNext := "[[:alnum:]][^[:alnum:]]|(.$)"
@@ -333,6 +344,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
inlineInfo: opts.InlineInfo,
prompt: opts.Prompt,
reverse: opts.Reverse,
fullscreen: fullscreen,
hscroll: opts.Hscroll,
hscrollOff: opts.HscrollOff,
wordRubout: wordRubout,
@@ -568,6 +580,7 @@ func (t *Terminal) resizeWindows() {
pwidth += 1
}
t.pwindow = t.tui.NewWindow(y+1, x+2, pwidth, h-2, tui.BorderNone)
os.Setenv("FZF_PREVIEW_HEIGHT", strconv.Itoa(h-2))
}
switch t.preview.position {
case posUp:
@@ -598,11 +611,12 @@ func (t *Terminal) resizeWindows() {
width,
height, tui.BorderNone)
}
if !t.tui.IsOptimized() && t.theme != nil && t.theme.HasBg() {
if !t.tui.IsOptimized() {
for i := 0; i < t.window.Height(); i++ {
t.window.MoveAndClear(i, 0)
}
}
t.truncateQuery()
}
func (t *Terminal) move(y int, x int, clear bool) {
@@ -628,13 +642,19 @@ func (t *Terminal) printPrompt() {
}
func (t *Terminal) printInfo() {
pos := 0
if t.inlineInfo {
t.move(0, t.displayWidth([]rune(t.prompt))+t.displayWidth(t.input)+1, true)
pos = t.displayWidth([]rune(t.prompt)) + t.displayWidth(t.input) + 1
if pos+len(" < ") > t.window.Width() {
return
}
t.move(0, pos, true)
if t.reading {
t.window.CPrint(tui.ColSpinner, t.strong, " < ")
} else {
t.window.CPrint(tui.ColPrompt, t.strong, " < ")
}
pos += len(" < ")
} else {
t.move(1, 0, true)
if t.reading {
@@ -643,14 +663,15 @@ func (t *Terminal) printInfo() {
t.window.CPrint(tui.ColSpinner, t.strong, _spinner[idx])
}
t.move(1, 2, false)
pos = 2
}
output := fmt.Sprintf("%d/%d", t.merger.Length(), t.count)
if t.toggleSort {
if t.sort {
output += "/S"
output += " +S"
} else {
output += " "
output += " -S"
}
}
if t.multi && len(t.selected) > 0 {
@@ -659,7 +680,9 @@ func (t *Terminal) printInfo() {
if t.progress > 0 && t.progress < 100 {
output += fmt.Sprintf(" (%d%%)", t.progress)
}
t.window.CPrint(tui.ColInfo, 0, output)
if pos+len(output) <= t.window.Width() {
t.window.CPrint(tui.ColInfo, 0, output)
}
}
func (t *Terminal) printHeader() {
@@ -726,11 +749,13 @@ func (t *Terminal) printItem(result *Result, line int, i int, current bool) {
}
// Avoid unnecessary redraw
newLine := itemLine{current: current, selected: selected, label: label, result: *result, width: 0}
newLine := itemLine{current: current, selected: selected, label: label,
result: *result, queryLen: len(t.input), width: 0}
prevLine := t.prevLines[i]
if prevLine.current == newLine.current &&
prevLine.selected == newLine.selected &&
prevLine.label == newLine.label &&
prevLine.queryLen == newLine.queryLen &&
prevLine.result == newLine.result {
return
}
@@ -944,7 +969,7 @@ func (t *Terminal) printPreview() {
trimmed, _ = t.trimRight(trimmed, maxWidth-t.pwindow.X())
}
str, _ = t.processTabs(trimmed, 0)
if ansi != nil && ansi.colored() {
if t.theme != nil && ansi != nil && ansi.colored() {
fillRet = t.pwindow.CFill(ansi.fg, ansi.bg, ansi.attr, str)
} else {
fillRet = t.pwindow.Fill(str)
@@ -1154,6 +1179,12 @@ func replacePlaceholder(template string, stripAnsi bool, delimiter Delimiter, fo
})
}
func (t *Terminal) redraw() {
t.tui.Clear()
t.tui.Refresh()
t.printAll()
}
func (t *Terminal) executeCommand(template string, forcePlus bool, background bool) {
valid, list := t.buildPlusList(template, forcePlus)
if !valid {
@@ -1165,12 +1196,10 @@ func (t *Terminal) executeCommand(template string, forcePlus bool, background bo
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
t.tui.Pause()
t.tui.Pause(true)
cmd.Run()
if t.tui.Resume() {
t.tui.Clear()
t.printAll()
}
t.tui.Resume(true)
t.redraw()
t.refresh()
} else {
cmd.Run()
@@ -1210,6 +1239,12 @@ func (t *Terminal) buildPlusList(template string, forcePlus bool) (bool, []*Item
return true, sels
}
func (t *Terminal) truncateQuery() {
maxPatternLength := util.Max(1, t.window.Width()-t.displayWidth([]rune(t.prompt))-1)
t.input, _ = t.trimRight(t.input, maxPatternLength)
t.cx = util.Constrain(t.cx, 0, len(t.input))
}
// Loop is called to start Terminal I/O
func (t *Terminal) Loop() {
// prof := profile.Start(profile.ProfilePath("/tmp/"))
@@ -1222,6 +1257,15 @@ func (t *Terminal) Loop() {
t.reqBox.Set(reqQuit, nil)
}()
contChan := make(chan os.Signal, 1)
notifyOnCont(contChan)
go func() {
for {
<-contChan
t.reqBox.Set(reqReinit, nil)
}
}()
resizeChan := make(chan os.Signal, 1)
notifyOnResize(resizeChan) // Non-portable
go func() {
@@ -1330,10 +1374,11 @@ func (t *Terminal) Loop() {
t.printHeader()
case reqRefresh:
t.suppress = false
case reqReinit:
t.tui.Resume(t.fullscreen)
t.redraw()
case reqRedraw:
t.tui.Clear()
t.tui.Refresh()
t.printAll()
t.redraw()
case reqClose:
t.tui.Close()
if t.output() {
@@ -1443,6 +1488,11 @@ func (t *Terminal) Loop() {
}
req(reqList, reqInfo, reqHeader)
}
case actTogglePreviewWrap:
if t.hasPreviewWindow() {
t.preview.wrap = !t.preview.wrap
req(reqPreviewRefresh)
}
case actToggleSort:
t.sort = !t.sort
t.eventBox.Set(EvtSearchNew, t.sort)
@@ -1627,6 +1677,15 @@ func (t *Terminal) Loop() {
t.input = []rune(t.history.next())
t.cx = len(t.input)
}
case actSigStop:
p, err := os.FindProcess(os.Getpid())
if err == nil {
t.tui.Clear()
t.tui.Pause(t.fullscreen)
notifyStop(p)
t.mutex.Unlock()
return false
}
case actMouse:
me := event.MouseEvent
mx, my := me.X, me.Y
@@ -1688,11 +1747,7 @@ func (t *Terminal) Loop() {
if !doActions(actions, mapkey) {
continue
}
// Truncate the query if it's too long
if len(t.input) > maxPatternLength {
t.input = t.input[:maxPatternLength]
t.cx = util.Constrain(t.cx, 0, maxPatternLength)
}
t.truncateQuery()
changed = string(previousInput) != string(t.input)
} else {
if mapkey == tui.Rune {

View File

@@ -11,3 +11,11 @@ import (
func notifyOnResize(resizeChan chan<- os.Signal) {
signal.Notify(resizeChan, syscall.SIGWINCH)
}
func notifyStop(p *os.Process) {
p.Signal(syscall.SIGSTOP)
}
func notifyOnCont(resizeChan chan<- os.Signal) {
signal.Notify(resizeChan, syscall.SIGCONT)
}

View File

@@ -9,3 +9,11 @@ import (
func notifyOnResize(resizeChan chan<- os.Signal) {
// TODO
}
func notifyStop(p *os.Process) {
// NOOP
}
func notifyOnCont(resizeChan chan<- os.Signal) {
// NOOP
}

View File

@@ -25,13 +25,13 @@ const (
Reverse = Attr(1 << 6)
)
func (r *FullscreenRenderer) Init() {}
func (r *FullscreenRenderer) Pause() {}
func (r *FullscreenRenderer) Clear() {}
func (r *FullscreenRenderer) Refresh() {}
func (r *FullscreenRenderer) Close() {}
func (r *FullscreenRenderer) Init() {}
func (r *FullscreenRenderer) Pause(bool) {}
func (r *FullscreenRenderer) Resume(bool) {}
func (r *FullscreenRenderer) Clear() {}
func (r *FullscreenRenderer) Refresh() {}
func (r *FullscreenRenderer) Close() {}
func (r *FullscreenRenderer) Resume() bool { return false }
func (r *FullscreenRenderer) DoesAutoWrap() bool { return false }
func (r *FullscreenRenderer) IsOptimized() bool { return false }
func (r *FullscreenRenderer) GetChar() Event { return Event{} }

View File

@@ -74,6 +74,7 @@ type LightRenderer struct {
theme *ColorTheme
mouse bool
forceBlack bool
clearOnExit bool
prevDownTime time.Time
clickY []int
ttyin *os.File
@@ -106,15 +107,16 @@ type LightWindow struct {
bg Color
}
func NewLightRenderer(theme *ColorTheme, forceBlack bool, mouse bool, tabstop int, maxHeightFunc func(int) int) Renderer {
func NewLightRenderer(theme *ColorTheme, forceBlack bool, mouse bool, tabstop int, clearOnExit bool, fullscreen bool, maxHeightFunc func(int) int) Renderer {
r := LightRenderer{
theme: theme,
forceBlack: forceBlack,
mouse: mouse,
clearOnExit: clearOnExit,
ttyin: openTtyIn(),
yoffset: 0,
tabstop: tabstop,
fullscreen: false,
fullscreen: fullscreen,
upOneLine: false,
maxHeightFunc: maxHeightFunc}
return &r
@@ -174,11 +176,7 @@ func (r *LightRenderer) Init() {
}
r.origState = origState
terminal.MakeRaw(fd)
terminalHeight, capHeight := r.updateTerminalSize()
if capHeight == terminalHeight {
r.fullscreen = true
r.height = terminalHeight
}
r.updateTerminalSize()
initTheme(r.theme, r.defaultTheme(), r.forceBlack)
if r.fullscreen {
@@ -240,20 +238,15 @@ func getEnv(name string, defaultValue int) int {
return atoi(env, defaultValue)
}
func (r *LightRenderer) updateTerminalSize() (int, int) {
func (r *LightRenderer) updateTerminalSize() {
width, height, err := terminal.GetSize(r.fd())
if err == nil {
r.width = width
if r.fullscreen {
r.height = height
} else {
r.height = r.maxHeightFunc(height)
}
r.height = r.maxHeightFunc(height)
} else {
r.width = getEnv("COLUMNS", defaultWidth)
r.height = r.maxHeightFunc(getEnv("LINES", defaultHeight))
}
return height, r.height
}
func (r *LightRenderer) getch(nonblock bool) (int, bool) {
@@ -351,9 +344,10 @@ func (r *LightRenderer) escSequence(sz *int) Event {
return Event{ESC, 0, nil}
}
*sz = 2
if r.buffer[1] >= 1 && r.buffer[1] <= 'z'-'a'+1 {
return Event{int(CtrlAltA + r.buffer[1] - 1), 0, nil}
}
switch r.buffer[1] {
case 13:
return Event{AltEnter, 0, nil}
case 32:
return Event{AltSpace, 0, nil}
case 47:
@@ -528,30 +522,41 @@ func (r *LightRenderer) rmcup() {
r.csi("?1049l")
}
func (r *LightRenderer) Pause() {
func (r *LightRenderer) Pause(clear bool) {
terminal.Restore(r.fd(), r.origState)
if r.fullscreen {
r.rmcup()
} else {
r.smcup()
r.csi("H")
if clear {
if r.fullscreen {
r.rmcup()
} else {
r.smcup()
r.csi("H")
}
r.flush()
}
r.flush()
}
func (r *LightRenderer) Resume() bool {
func (r *LightRenderer) Resume(clear bool) {
terminal.MakeRaw(r.fd())
if r.fullscreen {
r.smcup()
} else {
r.rmcup()
if clear {
if r.fullscreen {
r.smcup()
} else {
r.rmcup()
}
r.flush()
} else if !r.fullscreen && r.mouse {
// NOTE: Resume(false) is only called on SIGCONT after SIGSTOP.
// And It's highly likely that the offset we obtained at the beginning will
// no longer be correct, so we simply disable mouse input.
r.csi("?1000l")
r.mouse = false
}
r.flush()
// Should redraw
return true
}
func (r *LightRenderer) Clear() {
if r.fullscreen {
r.csi("H")
}
// r.csi("u")
r.origin()
r.csi("J")
@@ -568,14 +573,20 @@ func (r *LightRenderer) Refresh() {
func (r *LightRenderer) Close() {
// r.csi("u")
if r.fullscreen {
r.rmcup()
} else {
r.origin()
if r.upOneLine {
r.csi("A")
if r.clearOnExit {
if r.fullscreen {
r.rmcup()
} else {
r.origin()
if r.upOneLine {
r.csi("A")
}
r.csi("J")
}
r.csi("J")
} else if r.fullscreen {
r.csi("G")
} else {
r.move(r.height, 0)
}
if r.mouse {
r.csi("?1000l")
@@ -593,7 +604,7 @@ func (r *LightRenderer) MaxY() int {
}
func (r *LightRenderer) DoesAutoWrap() bool {
return true
return false
}
func (r *LightRenderer) IsOptimized() bool {

View File

@@ -176,12 +176,11 @@ func initPairs(theme *ColorTheme) {
}
}
func (r *FullscreenRenderer) Pause() {
func (r *FullscreenRenderer) Pause(bool) {
C.endwin()
}
func (r *FullscreenRenderer) Resume() bool {
return false
func (r *FullscreenRenderer) Resume(bool) {
}
func (r *FullscreenRenderer) Close() {
@@ -353,7 +352,7 @@ func escSequence() Event {
case C.ERR:
return Event{ESC, 0, nil}
case CtrlM:
return Event{AltEnter, 0, nil}
return Event{CtrlAltM, 0, nil}
case '/':
return Event{AltSlash, 0, nil}
case ' ':

View File

@@ -221,61 +221,68 @@ func (r *FullscreenRenderer) GetChar() Event {
// process keyboard:
case *tcell.EventKey:
alt := (ev.Modifiers() & tcell.ModAlt) > 0
keyfn := func(r rune) int {
if alt {
return CtrlAltA - 'a' + int(r)
}
return CtrlA - 'a' + int(r)
}
switch ev.Key() {
case tcell.KeyCtrlA:
return Event{CtrlA, 0, nil}
return Event{keyfn('a'), 0, nil}
case tcell.KeyCtrlB:
return Event{CtrlB, 0, nil}
return Event{keyfn('b'), 0, nil}
case tcell.KeyCtrlC:
return Event{CtrlC, 0, nil}
return Event{keyfn('c'), 0, nil}
case tcell.KeyCtrlD:
return Event{CtrlD, 0, nil}
return Event{keyfn('d'), 0, nil}
case tcell.KeyCtrlE:
return Event{CtrlE, 0, nil}
return Event{keyfn('e'), 0, nil}
case tcell.KeyCtrlF:
return Event{CtrlF, 0, nil}
return Event{keyfn('f'), 0, nil}
case tcell.KeyCtrlG:
return Event{CtrlG, 0, nil}
return Event{keyfn('g'), 0, nil}
case tcell.KeyCtrlH:
return Event{keyfn('h'), 0, nil}
case tcell.KeyCtrlI:
return Event{keyfn('i'), 0, nil}
case tcell.KeyCtrlJ:
return Event{CtrlJ, 0, nil}
return Event{keyfn('j'), 0, nil}
case tcell.KeyCtrlK:
return Event{CtrlK, 0, nil}
return Event{keyfn('k'), 0, nil}
case tcell.KeyCtrlL:
return Event{CtrlL, 0, nil}
return Event{keyfn('l'), 0, nil}
case tcell.KeyCtrlM:
if alt {
return Event{AltEnter, 0, nil}
}
return Event{CtrlM, 0, nil}
return Event{keyfn('m'), 0, nil}
case tcell.KeyCtrlN:
return Event{CtrlN, 0, nil}
return Event{keyfn('n'), 0, nil}
case tcell.KeyCtrlO:
return Event{CtrlO, 0, nil}
return Event{keyfn('o'), 0, nil}
case tcell.KeyCtrlP:
return Event{CtrlP, 0, nil}
return Event{keyfn('p'), 0, nil}
case tcell.KeyCtrlQ:
return Event{CtrlQ, 0, nil}
return Event{keyfn('q'), 0, nil}
case tcell.KeyCtrlR:
return Event{CtrlR, 0, nil}
return Event{keyfn('r'), 0, nil}
case tcell.KeyCtrlS:
return Event{CtrlS, 0, nil}
return Event{keyfn('s'), 0, nil}
case tcell.KeyCtrlT:
return Event{CtrlT, 0, nil}
return Event{keyfn('t'), 0, nil}
case tcell.KeyCtrlU:
return Event{CtrlU, 0, nil}
return Event{keyfn('u'), 0, nil}
case tcell.KeyCtrlV:
return Event{CtrlV, 0, nil}
return Event{keyfn('v'), 0, nil}
case tcell.KeyCtrlW:
return Event{CtrlW, 0, nil}
return Event{keyfn('w'), 0, nil}
case tcell.KeyCtrlX:
return Event{CtrlX, 0, nil}
return Event{keyfn('x'), 0, nil}
case tcell.KeyCtrlY:
return Event{CtrlY, 0, nil}
return Event{keyfn('y'), 0, nil}
case tcell.KeyCtrlZ:
return Event{CtrlZ, 0, nil}
return Event{keyfn('z'), 0, nil}
case tcell.KeyCtrlSpace:
return Event{CtrlSpace, 0, nil}
case tcell.KeyBackspace, tcell.KeyBackspace2:
case tcell.KeyBackspace2:
if alt {
return Event{AltBS, 0, nil}
}
@@ -301,8 +308,6 @@ func (r *FullscreenRenderer) GetChar() Event {
case tcell.KeyPgDn:
return Event{PgDn, 0, nil}
case tcell.KeyTab:
return Event{Tab, 0, nil}
case tcell.KeyBacktab:
return Event{BTab, 0, nil}
@@ -359,13 +364,12 @@ func (r *FullscreenRenderer) GetChar() Event {
return Event{Invalid, 0, nil}
}
func (r *FullscreenRenderer) Pause() {
func (r *FullscreenRenderer) Pause(bool) {
_screen.Fini()
}
func (r *FullscreenRenderer) Resume() bool {
func (r *FullscreenRenderer) Resume(bool) {
r.initScreen()
return true
}
func (r *FullscreenRenderer) Close() {

View File

@@ -75,7 +75,6 @@ const (
F11
F12
AltEnter
AltSpace
AltSlash
AltBS
@@ -90,7 +89,9 @@ const ( // Reset iota
AltD
AltE
AltF
AltZ = AltA + 'z' - 'a'
AltZ = AltA + 'z' - 'a'
CtrlAltA = AltZ + 1
CtrlAltM = CtrlAltA + 'm' - 'a'
)
const (
@@ -205,8 +206,8 @@ const (
type Renderer interface {
Init()
Pause()
Resume() bool
Pause(clear bool)
Resume(clear bool)
Clear()
RefreshWindows(windows []Window)
Refresh()

View File

@@ -513,11 +513,11 @@ class TestGoFZF < TestBase
tmux.send_keys "seq 1 111 | #{fzf "-m +s --tac #{opt} -q11"}", :Enter
tmux.until { |lines| lines[-3].include? '> 111' }
tmux.send_keys :Tab
tmux.until { |lines| lines[-2].include? '4/111 (1)' }
tmux.until { |lines| lines[-2].include? '4/111 -S (1)' }
tmux.send_keys 'C-R'
tmux.until { |lines| lines[-3].include? '> 11' }
tmux.send_keys :Tab
tmux.until { |lines| lines[-2].include? '4/111/S (2)' }
tmux.until { |lines| lines[-2].include? '4/111 +S (2)' }
tmux.send_keys :Enter
assert_equal ['111', '11'], readonce.split($/)
end
@@ -1296,6 +1296,14 @@ class TestGoFZF < TestBase
tmux.until { |lines| lines[4] == '> 3' }
tmux.until { |_| %w[1 2 3] == File.readlines(tempname).map(&:chomp) }
end
def test_no_clear
tmux.send_keys 'seq 100 | fzf --no-clear --inline-info --height 5', :Enter
prompt = '> < 100/100'
tmux.until { |lines| lines[-1] == prompt }
tmux.send_keys :Enter
tmux.until { |lines| lines[-2] == prompt && lines[-1] == '1' }
end
end
module TestShell
@@ -1408,6 +1416,7 @@ module TestShell
tmux.send_keys 'C-r'
tmux.until { |lines| lines.item_count > 0 }
end
tmux.send_keys 'C-r'
tmux.send_keys '3d'
tmux.until { |lines| lines[-3].end_with? 'echo 3rd' }
tmux.send_keys :Enter