Compare commits

...

37 Commits
0.1.0 ... 0.3.1

Author SHA1 Message Date
Junegunn Choi
ff34c6b272 Merge pull request #5 from Vifon/zsh-widgets
new zsh widgets
2013-11-10 16:11:29 -08:00
Wojciech Siewierski
b2ac52462c zsh widget fix
* fzf-cd-widget properly escapes the special characters
2013-11-10 18:57:47 +01:00
Wojciech Siewierski
a6f7caf20d new zsh widgets
+ new fzf-cd-widget for running cd

* fzf-file-widget now properly escapes the special characters and supports
  multi-selection

* fzf-history-widget replaces the current line instead of appending to it
2013-11-10 18:28:59 +01:00
Junegunn Choi
1e9e597837 Merge pull request #4 from Vifon/patch-1
superfluous backslash in zle widget removed
2013-11-10 06:34:21 -08:00
Wojciech Siewierski
0dc725d09c superfluous backslash in zle widget removed 2013-11-10 15:31:10 +01:00
Junegunn Choi
1eceb6a4b9 FZF_DEFAULT_SORT 2013-11-10 20:22:57 +09:00
Junegunn Choi
8777a495bc Shift-TAB on multi-select mode 2013-11-10 20:19:57 +09:00
Junegunn Choi
83825dbbd3 Add Tips section 2013-11-10 20:03:38 +09:00
Junegunn Choi
1ac19a2097 Update README 2013-11-10 11:53:13 +09:00
Junegunn Choi
833c6e1eeb Update example 2013-11-10 04:00:27 +09:00
Junegunn Choi
8a0a3f9bf5 Do not sort the result if query is empty 2013-11-10 03:57:10 +09:00
Junegunn Choi
ddf6e5ef1e Implement multi-select mode (#3) 2013-11-10 03:56:18 +09:00
Junegunn Choi
11a1010e9e Add zsh widget examples 2013-11-09 01:16:39 +09:00
Junegunn Choi
75b666bf54 Update README (replace backticks with $())
As reported in #2, backticks on oh-my-zsh (with TERM=xterm*)
makes fzf run twice. This should be a bug of oh-my-zsh,
but for now using $() seems to be a quick workaround.
2013-11-06 20:54:02 +09:00
Junegunn Choi
3f73554a9e Fix FZF_DEFAULT_COMMAND 2013-11-05 21:05:34 +09:00
Junegunn Choi
dc67420319 Make fzf.vim separately installable 2013-11-05 13:45:23 +09:00
Junegunn Choi
f2d8e7e3ee Update README 2013-11-05 00:11:06 +09:00
Junegunn Choi
de8116b1cf Fix error on Linux with Ruby 1.8 2013-11-04 10:38:16 +09:00
Junegunn Choi
1460e0a10b 0.2.0 2013-11-03 22:51:00 +09:00
Junegunn Choi
c46dad465f Fix invalid return when query string is empty 2013-11-03 22:49:12 +09:00
Junegunn Choi
0df647b2a7 Strip null bytes in the string 2013-11-03 22:15:52 +09:00
Junegunn Choi
69d6b58f88 Do not block on --no-sort 2013-11-03 22:01:25 +09:00
Junegunn Choi
8e305edcf2 Add --no-color (+c) option 2013-11-03 11:45:14 +09:00
Junegunn Choi
c326e363eb Premature optimization is root of all fun 2013-11-03 10:43:48 +09:00
Junegunn Choi
d1298b8fff Reduce memory footprint 2013-11-03 04:05:32 +09:00
Junegunn Choi
2a0e0ded2a Remove Gemfile 2013-11-03 01:11:36 +09:00
Junegunn Choi
7cecf648eb Optimize left/right trimming 2013-11-03 00:06:50 +09:00
Junegunn Choi
c3c94ea889 Fix long item display 2013-11-02 20:58:23 +09:00
Junegunn Choi
94f0c3d22b Bump up gem version to 0.1.3 2013-11-02 20:41:29 +09:00
Junegunn Choi
d717096ee3 Update README 2013-11-02 20:40:25 +09:00
Junegunn Choi
1629fe079a Improve display
- CJK wide character support
- Progress reporting for long-running queries (> 0.5sec)
2013-11-02 20:12:39 +09:00
Junegunn Choi
6a9970c98e FZF_DEFAULT_COMMAND 2013-11-02 12:56:43 +09:00
Junegunn Choi
682583e88f 0.1.1 2013-11-01 16:13:12 +09:00
Junegunn Choi
fd2472d11c Ignore empty file path 2013-11-01 16:07:46 +09:00
Junegunn Choi
311c4a36e2 Remove initial delay 2013-11-01 02:02:00 +09:00
Junegunn Choi
b98fba4cf1 Gradually increase delay upto 0.2 seconds 2013-11-01 01:59:23 +09:00
Junegunn Choi
a03b5c8c42 gem install fzf 2013-11-01 01:12:46 +09:00
5 changed files with 287 additions and 134 deletions

View File

@@ -1,4 +0,0 @@
source 'https://rubygems.org'
# Specify your gem's dependencies in fzf.gemspec
gemspec

119
README.md
View File

@@ -16,7 +16,8 @@ fzf requires Ruby (>= 1.8.5).
Installation
------------
Download fzf executable and put it somewhere in your search $PATH.
Download [fzf executable](https://raw.github.com/junegunn/fzf/master/fzf) and
put it somewhere in your search $PATH.
```sh
mkdir -p ~/bin
@@ -38,15 +39,21 @@ Make sure that ~/bin is included in $PATH.
export PATH=$PATH:~/bin
```
Install as Vim plugin
---------------------
### Install as Ruby gem
fzf was not designed to be a Vim plugin, but you can use it as one. The only
reason one might consider using fzf in Vim is its speed. For a very large list
of files, fzf is significantly faster than native Vim plugins.
fzf can be installed as a Ruby gem
You can use any Vim plugin manager to install fzf as a Vim plugin. If you don't
use one, I recommend you try [vim-plug](https://github.com/junegunn/vim-plug).
```
gem install fzf
```
It's a bit easier to install and update the script but the Ruby gem version
takes slightly longer to start.
### Install as Vim plugin
You can use any Vim plugin manager to install fzf for Vim. If you don't use one,
I recommend you try [vim-plug](https://github.com/junegunn/vim-plug).
1. [Install vim-plug](https://github.com/junegunn/vim-plug#usage)
2. Edit your .vimrc
@@ -64,9 +71,11 @@ Usage
```
usage: fzf [options]
-m, --multi Enable multi-select
-s, --sort=MAX Maximum number of matched items to sort. Default: 500
+s, --no-sort Keep the sequence unchanged.
+s, --no-sort Do not sort the result. Keep the sequence unchanged.
+i Case-sensitive match
+c, --no-color Disable colors
```
fzf will launch curses-based finder, read the list from STDIN, and write the
@@ -77,10 +86,11 @@ find * -type f | fzf > selected
```
Without STDIN pipe, fzf will use find command to fetch the list of
files (excluding hidden ones).
files excluding hidden ones. (You can override the default command with
`FZF_DEFAULT_COMMAND`)
```sh
vim `fzf`
vim $(fzf)
```
If you want to preserve the exact sequence of the input, provide `--no-sort` (or
@@ -101,6 +111,9 @@ The following readline key bindings should also work as expected.
- CTRL-B / CTRL-F
- CTRL-W / CTRL-U
If you enable multi-select mode with `-m` option, you can select multiple items
with TAB or Shift-TAB key.
Usage as Vim plugin
-------------------
@@ -117,23 +130,27 @@ You can override the command which produces input to fzf.
let g:fzf_command = 'find . -type f'
```
Most of the time, you will prefer native Vim plugins with better integration
with Vim. The only reason one might consider using fzf in Vim is its speed. For
a very large list of files, fzf is significantly faster and it does not block.
Useful bash examples
--------------------
```sh
# vimf - Open selected file in Vim
vimf() {
FILE=`fzf` && vim "$FILE"
FILE=$(fzf) && vim "$FILE"
}
# fd - cd to selected directory
fd() {
DIR=`find ${1:-*} -path '*/\.*' -prune -o -type d -print 2> /dev/null | fzf` && cd "$DIR"
DIR=$(find ${1:-*} -path '*/\.*' -prune -o -type d -print 2> /dev/null | fzf) && cd "$DIR"
}
# fda - including hidden directories
fda() {
DIR=`find ${1:-*} -type d 2> /dev/null | fzf` && cd "$DIR"
DIR=$(find ${1:-*} -type d 2> /dev/null | fzf) && cd "$DIR"
}
# fh - repeat history
@@ -143,14 +160,84 @@ fh() {
# fkill - kill process
fkill() {
ps -ef | sed 1d | fzf | awk '{print $2}' | xargs kill -${1:-9}
ps -ef | sed 1d | fzf -m | awk '{print $2}' | xargs kill -${1:-9}
}
# CTRL-T - Open fuzzy finder and paste the selected item to the command line
# (Assuming you don't use the default CTRL-T and CTRL-R)
# CTRL-T - Paste the selected file path into the command line
bind '"\er": redraw-current-line'
bind '"\C-t": " \C-u \C-a\C-k$(fzf)\e\C-e\C-y\C-a\C-y\ey\C-h\C-e\er"'
# CTRL-R - Paste the selected command from history into the command line
bind '"\C-r": " \C-e\C-u$(history | fzf +s | sed \"s/ *[0-9]* *//\")\e\C-e\er"'
```
zsh widgets
-----------
```sh
# CTRL-T - Paste the selected file(s) path into the command line
fzf-file-widget() {
local FILES
local IFS="
"
FILES=($(
find * -path '*/\.*' -prune \
-o -type f -print \
-o -type l -print 2> /dev/null | fzf -m))
unset IFS
FILES=$FILES:q
LBUFFER="${LBUFFER%% #} $FILES"
zle redisplay
}
zle -N fzf-file-widget
bindkey '^T' fzf-file-widget
# ALT-C - cd into the selected directory
fzf-cd-widget() {
cd "${$(find * -path '*/\.*' -prune \
-o -type d -print 2> /dev/null | fzf):-.}"
zle reset-prompt
}
zle -N fzf-cd-widget
bindkey '\ec' fzf-cd-widget
# CTRL-R - Paste the selected command from history into the command line
fzf-history-widget() {
LBUFFER=$(history | fzf +s | sed "s/ *[0-9]* *//")
zle redisplay
}
zle -N fzf-history-widget
bindkey '^R' fzf-history-widget
```
Tips
----
### Faster startup with `--disable-gems` options
If you're running Ruby 1.9 or above, you can improve the startup time with
`--disable-gems` option to Ruby.
- `time ruby ~/bin/fzf -h`
- 0.077 sec
- `time ruby --disable-gems ~/bin/fzf -h`
- 0.025 sec
Define fzf alias with the option as follows:
```sh
alias fzf='ruby --disable-gems ~/bin/fzf'
```
### Incorrect display on Ruby 1.8
It is reported that the output of fzf can become unreadable on some terminals
when it's running on Ruby 1.8. If you experience the problem, upgrade your Ruby
to 1.9 or above. Ruby 1.9 or above is also required for displaying Unicode
characters.
License
-------

288
fzf
View File

@@ -10,7 +10,7 @@
# URL: https://github.com/junegunn/fzf
# Author: Junegunn Choi
# License: MIT
# Last update: October 29, 2013
# Last update: November 10, 2013
#
# Copyright (c) 2013 Junegunn Choi
#
@@ -38,9 +38,11 @@
def usage x
puts %[usage: fzf [options]
-m, --multi Enable multi-select
-s, --sort=MAX Maximum number of matched items to sort. Default: 500.
+s, --no-sort Do not sort the result. Keep the sequence unchanged.
+i Case-sensitive match]
+i Case-sensitive match
+c, --no-color Disable colors]
exit x
end
@@ -49,7 +51,10 @@ $stdout.reopen($stderr)
usage 0 unless (%w[--help -h] & ARGV).empty?
@rxflag = ARGV.delete('+i') ? 0 : Regexp::IGNORECASE
@sort = (ARGV.delete('+s') || ARGV.delete('--no-sort')) ? nil : 500
@sort = %w[+s --no-sort].map { |e| ARGV.delete e }.compact.empty? ?
ENV.fetch('FZF_DEFAULT_SORT', 500).to_i : nil
@color = %w[+c --no-color].map { |e| ARGV.delete e }.compact.empty?
@multi = !%w[-m --multi].map { |e| ARGV.delete e }.compact.empty?
rest = ARGV.join ' '
if sort = rest.match(/(-s|--sort=?) ?([0-9]+)/)
usage 1 unless @sort
@@ -72,6 +77,7 @@ require 'curses'
@cursor_x = 0
@vcursor = 0
@events = {}
@selects = {} # ordered >= 1.9
case RUBY_PLATFORM
when /darwin/
@@ -104,8 +110,8 @@ when /darwin/
ret
end
def self.nfc str, offset
ret = ''
def self.nfc str, b = 0, e = 0
ret = ''
omap = []
pend = []
str.split(//).each_with_index do |c, idx|
@@ -132,7 +138,7 @@ when /darwin/
ret << c
end
end
return [ret, offset.map { |o| omap[o] || (omap.last + 1) }]
return [ret, omap[b] || 0, omap[e] || ((omap.last || 0) + 1)]
end
end
@@ -165,7 +171,7 @@ def max_items; C.lines - 2; end
def cursor_y; C.lines - 1; end
def cprint str, col
C.attron(col) do
C.addstr str
C.addstr str.gsub("\0", '')
end if str
end
@@ -178,7 +184,7 @@ def print_input
end
end
def print_info progress = true, msg = nil
def print_info selected, msg = nil
@fan ||= '-\|/-\|/'.split(//)
C.setpos cursor_y - 1, 0
C.clrtoeol
@@ -191,14 +197,14 @@ def print_info progress = true, msg = nil
' '
end
C.attron color(:info, false) do
progress &&= "#{prefix}#{@matches.length}/#{@count}"
C.addstr progress if progress
C.addstr "#{prefix}#{@matches.length}/#{@count}"
C.addstr " (#{selected})" if selected > 0
C.addstr msg if msg
end
end
def refresh
C.setpos cursor_y, 2 + ulen(@query[0, @cursor_x])
C.setpos cursor_y, 2 + width(@query[0, @cursor_x])
C.refresh
end
@@ -207,15 +213,35 @@ def ctrl char
end
if RUBY_VERSION.split('.').map { |e| e.rjust(3, '0') }.join > '001009'
def ulen str
@urx ||= Regexp.new '\p{Han}|\p{Katakana}|\p{Hiragana}|\p{Hangul}'
str.gsub(@urx, ' ').length
@wrx = Regexp.new '\p{Han}|\p{Katakana}|\p{Hiragana}|\p{Hangul}'
def width str
str.gsub(@wrx, ' ').length
end
def trim str, len, left
width = width str
diff = 0
while width > len
width -= (left ? str[0, 1] : str[-1, 1]) =~ @wrx ? 2 : 1
str = left ? str[1..-1] : str[0...-1]
diff += 1
end
[str, diff]
end
else
def ulen str
def width str
str.length
end
def trim str, len, left
diff = str.length - len
if diff > 0
[left ? str[diff..-1] : str[0...-diff], diff]
else
[str, 0]
end
end
class String
def ord
self.unpack('c').first
@@ -240,35 +266,53 @@ dbg =
end
C.raw
C.noecho
if C.can_change_color?
fg = ENV.fetch('FZF_FG', 252).to_i
bg = ENV.fetch('FZF_BG', 236).to_i
C.init_pair 1, 110, dbg
C.init_pair 2, 108, dbg
C.init_pair 3, fg + 2, bg
C.init_pair 4, 151, bg
C.init_pair 5, 148, dbg
C.init_pair 6, 144, dbg
C.init_pair 7, 161, bg
else
C.init_pair 1, C::COLOR_BLUE, dbg
C.init_pair 2, C::COLOR_GREEN, dbg
C.init_pair 3, C::COLOR_YELLOW, C::COLOR_BLACK
C.init_pair 4, C::COLOR_GREEN, C::COLOR_BLACK
C.init_pair 5, C::COLOR_GREEN, dbg
C.init_pair 6, C::COLOR_WHITE, dbg
C.init_pair 7, C::COLOR_RED, C::COLOR_BLACK
end
def color sym, bold = false
C.color_pair([:blue, :match, :chosen,
:match!, :fan, :info, :red].index(sym) + 1) |
(bold ? C::A_BOLD : 0)
if @color
if C.can_change_color?
fg = ENV.fetch('FZF_FG', 252).to_i
bg = ENV.fetch('FZF_BG', 236).to_i
C.init_pair 1, 110, dbg
C.init_pair 2, 108, dbg
C.init_pair 3, fg + 2, bg
C.init_pair 4, 151, bg
C.init_pair 5, 148, dbg
C.init_pair 6, 144, dbg
C.init_pair 7, 161, bg
else
C.init_pair 1, C::COLOR_BLUE, dbg
C.init_pair 2, C::COLOR_GREEN, dbg
C.init_pair 3, C::COLOR_YELLOW, C::COLOR_BLACK
C.init_pair 4, C::COLOR_GREEN, C::COLOR_BLACK
C.init_pair 5, C::COLOR_GREEN, dbg
C.init_pair 6, C::COLOR_WHITE, dbg
C.init_pair 7, C::COLOR_RED, C::COLOR_BLACK
end
def color sym, bold = false
C.color_pair([:blue, :match, :chosen,
:match!, :fan, :info, :red].index(sym) + 1) |
(bold ? C::A_BOLD : 0)
end
else
def color sym, bold = false
case sym
when :chosen
bold ? C::A_REVERSE : 0
when :match
C::A_UNDERLINE
when :match!
C::A_REVERSE | C::A_UNDERLINE
else
0
end | (bold ? C::A_BOLD : 0)
end
end
@read =
if $stdin.tty?
if !`which find`.empty?
if default_command = ENV['FZF_DEFAULT_COMMAND']
IO.popen(default_command)
elsif !`which find`.empty?
IO.popen("find * -path '*/\\.*' -prune -o -type f -print -o -type l -print 2> /dev/null")
else
exit 1
@@ -290,20 +334,18 @@ searcher = Thread.new {
events = {}
fcache = {}
matches = []
selects = {}
mcount = 0 # match count
plcount = 0 # prev list count
q = ''
vcursor = 0
zz = [0, 0]
started = false
delay = -5
begin
while true
wait_for_completion = nil
@mtx.synchronize do
while true
events.merge! @events
wait_for_completion = !@sort && !events[:loaded]
if @events.empty? # No new events
@cv.wait @mtx
@@ -313,52 +355,57 @@ searcher = Thread.new {
break
end
if !wait_for_completion && events[:new]
if events[:new]
@lists << [@new, {}]
@count += @new.length
@new = []
fcache = {}
end
if events[:select]
selects = @selects.dup
end
end#mtx
if wait_for_completion
@smtx.synchronize do
print_info false, " +#{@new.length}"
print_input
refresh
sleep 0.1
end
next
end
new_search = events[:key] || events[:new]
user_input = events[:key] || events[:vcursor]
new_search = events[:key] || events.delete(:new)
user_input = events[:key] || events[:vcursor] || events.delete(:select)
progress = 0
started_at = Time.now
if new_search && !@lists.empty?
events.delete :new
q = events.delete(:key) || q
regexp = q.empty? ? nil :
Regexp.new(convert_query(q).inject('') { |sum, e|
unless q.empty?
q = q.downcase if @rxflag != 0
regexp = Regexp.new(convert_query(q).inject('') { |sum, e|
e = Regexp.escape e
sum << "#{e}[^#{e}]*?"
}, @rxflag)
end
matches = fcache[q] ||=
begin
@smtx.synchronize do
print_info true, ' ..'
print_input
refresh
end unless q.empty?
found = []
skip = false
cnt = 0
@lists.each do |pair|
@mtx.synchronize { skip = @events[:key] }
list, cache = pair
cnt += list.length
@mtx.synchronize {
skip = @events[:key]
progress = (100 * cnt / @count)
}
break if skip
list, cache = pair
found.concat(cache[q] ||= begin
found.concat(cache[q] ||= q.empty? ? list : begin
if progress < 100 && Time.now - started_at > 0.5
@smtx.synchronize do
print_info selects.length, " (#{progress}%)"
refresh
end
end
prefix, suffix = @query[0, @cursor_x], @query[@cursor_x..-1] || ''
prefix_cache = suffix_cache = nil
@@ -372,13 +419,9 @@ searcher = Thread.new {
partial_cache = [prefix_cache, suffix_cache].compact.sort_by { |e| e.length }.first
(partial_cache ? partial_cache.map { |e| e.first } : list).map { |line|
if regexp
# Ignore errors: e.g. invalid byte sequence in UTF-8
md = line.match(regexp) rescue nil
md ? [line, md.offset(0)] : nil
else
[line, zz]
end
# Ignore errors: e.g. invalid byte sequence in UTF-8
md = line.match(regexp) rescue nil
md && [line, *md.offset(0)]
}.compact
end)
end
@@ -387,19 +430,16 @@ searcher = Thread.new {
end
mcount = matches.length
if @sort && mcount <= @sort
matches.replace matches.sort_by { |pair|
line, offset = pair
[offset.last - offset.first, line.length, line]
if @sort && mcount <= @sort && !q.empty?
matches.replace matches.sort_by { |triple|
line, b, e = triple
[b ? (e - b) : 0, line.length, line]
}
end
end#new_search
# This small delay reduces the number of partial lists
if started && !user_input
sleep 0.2
end
started = true
sleep((delay = [20, delay + 5].min) * 0.01) unless user_input
if events.delete(:vcursor) || new_search
@mtx.synchronize do
@@ -419,38 +459,45 @@ searcher = Thread.new {
end
end
maxc = C.cols - 5
maxc = C.cols - 3
matches[0, max_items].each_with_index do |item, idx|
next if !new_search && !((vcursor-1)..(vcursor+1)).include?(idx)
line, offset = convert_item item
line, b, e = convert_item item
b ||= 0
e ||= 0
row = cursor_y - idx - 2
chosen = idx == vcursor
b, e = offset
if line.length > maxc
diff = e - (maxc - 2)
if diff > 2
line = '..' + line[diff..-1]
b -= diff - 2
b = [2, b].max
# Overflow
if width(line) > maxc
ewidth = width(line[0...e])
# Stri..
if ewidth <= maxc - 2
line, _ = trim line, maxc - 2, false
line << '..'
# ..ring
else
line = line[0, maxc] + '..'
# ..ri..
line = line[0...e] + '..' if ewidth < width(line) - 2
line, diff = trim line, maxc - 2, true
b += 2 - diff
e += 2 - diff
b = [2, b].max
line = '..' + line
end
end
if line.length > maxc
line = line[0, maxc] + '..'
end
C.setpos row, 0
C.clrtoeol
cprint chosen ? '>' : ' ', color(:red, true)
cprint ' ', chosen ? color(:chosen) : 0
selected = selects.include?([*item][0])
cprint selected ? '>' : ' ',
chosen ? color(:chosen) : (selected ? color(:red, true) : 0)
C.attron color(:chosen, true) if chosen
e = [e, maxc].min
if b < maxc && b < e
if b < e
C.addstr line[0, b]
cprint line[b...e], color(chosen ? :match! : :match, chosen)
C.attron color(:chosen, true) if chosen
@@ -461,11 +508,10 @@ searcher = Thread.new {
C.attroff color(:chosen, true) if chosen
end
print_info if !@lists.empty? || events[:loaded]
print_input
print_info selects.length if !@lists.empty? || events[:loaded]
refresh
end
end
end#while
rescue Exception => e
main.raise e
end
@@ -482,7 +528,7 @@ begin
ctrl(:d) => proc { exit 1 if input.empty? },
ctrl(:m) => proc {
@mtx.synchronize do
got = @matches.fetch(@vcursor, [])[0]
got = [*@matches.fetch(@vcursor, [])][0]
end
exit 0
},
@@ -497,6 +543,18 @@ begin
cursor = ridx
},
127 => proc { input[cursor -= 1] = '' if cursor > 0 },
9 => proc { |o|
emit(:select) {
if sel = [*@matches.fetch(@vcursor, [])][0]
if @selects.has_key? sel
@selects.delete sel
else
@selects[sel] = 1
end
@vcursor = [0, @vcursor + (o == :stab ? 1 : -1)].max
end
} if @multi
},
:left => proc { cursor = [0, cursor - 1].max },
:right => proc { cursor = [input.length, cursor + 1].min },
}
@@ -505,8 +563,16 @@ begin
actions[ctrl(:h)] = actions[127]
actions[ctrl(:n)] = actions[ctrl(:j)]
actions[ctrl(:p)] = actions[ctrl(:k)]
actions[:stab] = actions[9]
while true
# Update user input
@smtx.synchronize do
@cursor_x = cursor
print_input
refresh
end
ord = tty.getc.ord
if ord == 27
ord = tty.getc.ord
@@ -516,6 +582,7 @@ begin
when 67 then :right
when 66 then ctrl(:j)
when 65 then ctrl(:k)
when 90 then :stab
else :nop
end
end
@@ -531,16 +598,15 @@ begin
# Dispatch key event
emit(:key) { @query = input.dup }
# Update user input
@smtx.synchronize do
@cursor_x = cursor
print_input
refresh
end
end
ensure
C.close_screen
stdout.puts got if got
if got
@selects.delete got
@selects.each do |sel, _|
stdout.puts sel
end
stdout.puts got
end
end

View File

@@ -1,7 +1,7 @@
# coding: utf-8
Gem::Specification.new do |spec|
spec.name = 'fzf'
spec.version = '0.1.0'
spec.version = '0.3.1'
spec.authors = ['Junegunn Choi']
spec.email = ['junegunn.c@gmail.com']
spec.description = %q{Fuzzy finder for your shell}

View File

@@ -27,9 +27,13 @@ function! s:fzf(args)
try
let tf = tempname()
let prefix = exists('g:fzf_command') ? g:fzf_command.'|' : ''
execute "silent !".prefix."/usr/bin/env ruby ".s:exec." ".a:args." > ".tf
let fzf = executable(s:exec) ? s:exec : 'fzf'
execute "silent !".prefix.fzf." ".a:args." > ".tf
if !v:shell_error
execute 'silent e '.join(readfile(tf), '')
let file = join(readfile(tf), '')
if !empty(file)
execute 'silent e '.file
endif
endif
finally
silent! call delete(tf)