Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
F
fzf
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to JiHu GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
KMSCAKKSCFKA AKFACAMADCAS
fzf
Commits
76a3ef8c
Commit
76a3ef8c
authored
10 years ago
by
Junegunn Choi
Browse files
Options
Downloads
Patches
Plain Diff
Add --with-nth option (#102)
parent
6fd6fff3
No related branches found
No related tags found
No related merge requests found
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
.travis.yml
+9
-0
9 additions, 0 deletions
.travis.yml
README.md
+25
-24
25 additions, 24 deletions
README.md
Rakefile
+1
-0
1 addition, 0 deletions
Rakefile
fzf
+84
-53
84 additions, 53 deletions
fzf
test/test_fzf.rb
+32
-2
32 additions, 2 deletions
test/test_fzf.rb
with
151 additions
and
79 deletions
.travis.yml
0 → 100644
+
9
−
0
View file @
76a3ef8c
language
:
ruby
rvm
:
-
"
1.8.7"
-
"
1.9.3"
-
"
2.0.0"
-
"
2.1.1"
install
:
gem install curses minitest
This diff is collapsed.
Click to expand it.
README.md
+
25
−
24
View file @
76a3ef8c
...
...
@@ -65,38 +65,39 @@ Usage
usage: fzf [options]
Search
-x, --extended Extended-search mode
-e, --extended-exact Extended-search mode (exact match)
-i Case-insensitive match (default: smart-case match)
+i Case-sensitive match
-n, --nth=N[,..] Comma-separated list of field index expressions
for limiting search scope. Each can be a non-zero
integer or a range expression ([BEGIN]..[END])
-d, --delimiter=STR Field delimiter regex for --nth (default: AWK-style)
-x, --extended Extended-search mode
-e, --extended-exact Extended-search mode (exact match)
-i Case-insensitive match (default: smart-case match)
+i Case-sensitive match
-n, --nth=N[,..] Comma-separated list of field index expressions
for limiting search scope. Each can be a non-zero
integer or a range expression ([BEGIN]..[END])
--with-nth=N[,..] Transform the item using index expressions for search
-d, --delimiter=STR Field delimiter regex for --nth (default: AWK-style)
Search result
-s, --sort=MAX Maximum number of matched items to sort (default: 1000)
+s, --no-sort Do not sort the result. Keep the sequence unchanged.
-s, --sort=MAX
Maximum number of matched items to sort (default: 1000)
+s, --no-sort
Do not sort the result. Keep the sequence unchanged.
Interface
-m, --multi Enable multi-select with tab/shift-tab
--no-mouse Disable mouse
+c, --no-color Disable colors
+2, --no-256 Disable 256-color
--black Use black background
--reverse Reverse orientation
--prompt=STR Input prompt (default: '> ')
-m, --multi
Enable multi-select with tab/shift-tab
--no-mouse
Disable mouse
+c, --no-color
Disable colors
+2, --no-256
Disable 256-color
--black
Use black background
--reverse
Reverse orientation
--prompt=STR
Input prompt (default: '> ')
Scripting
-q, --query=STR Start the finder with the given query
-1, --select-1 Automatically select the only match
-0, --exit-0 Exit immediately when there's no match
-f, --filter=STR Filter mode. Do not start interactive finder.
--print-query Print query as the first line
-q, --query=STR
Start the finder with the given query
-1, --select-1
Automatically select the only match
-0, --exit-0
Exit immediately when there's no match
-f, --filter=STR
Filter mode. Do not start interactive finder.
--print-query
Print query as the first line
Environment variables
FZF_DEFAULT_COMMAND Default command to use when input is tty
FZF_DEFAULT_OPTS Defaults options. (e.g. "-x -m --sort 10000")
FZF_DEFAULT_COMMAND
Default command to use when input is tty
FZF_DEFAULT_OPTS
Defaults options. (e.g. "-x -m --sort 10000")
```
fzf will launch curses-based finder, read the list from STDIN, and write the
...
...
This diff is collapsed.
Click to expand it.
Rakefile
+
1
−
0
View file @
76a3ef8c
...
...
@@ -6,3 +6,4 @@ Rake::TestTask.new(:test) do |test|
test
.
verbose
=
true
end
task
:default
=>
:test
This diff is collapsed.
Click to expand it.
fzf
+
84
−
53
View file @
76a3ef8c
...
...
@@ -7,7 +7,7 @@
# / __/ / /_/ __/
# /_/ /___/_/ Fuzzy finder for your shell
#
# Version: 0.8.
7
(
Aug
1
7
, 2014)
# Version: 0.8.
8
(
Nov
1, 2014)
#
# Author: Junegunn Choi
# URL: https://github.com/junegunn/fzf
...
...
@@ -53,11 +53,34 @@ unless String.method_defined? :force_encoding
end
end
class
String
attr_accessor
:orig
def
tokenize
delim
,
nth
unless
delim
# AWK default
prefix_length
=
(
index
(
/\S/
)
||
0
)
rescue
0
tokens
=
scan
(
/\S+\s*/
)
rescue
[]
else
prefix_length
=
0
tokens
=
scan
(
delim
)
rescue
[]
end
nth
.
map
{
|
n
|
if
n
.
begin
==
0
&&
n
.
end
==
-
1
[
prefix_length
,
tokens
.
join
]
elsif
part
=
tokens
[
n
]
[
prefix_length
+
(
tokens
[
0
...
(
n
.
begin
)]
||
[]).
join
.
length
,
part
.
join
]
end
}.
compact
end
end
class
FZF
C
=
Curses
attr_reader
:rxflag
,
:sort
,
:nth
,
:color
,
:black
,
:ansi256
,
:reverse
,
:prompt
,
:mouse
,
:multi
,
:query
,
:select1
,
:exit0
,
:filter
,
:extended
,
:print_query
:print_query
,
:with_nth
def
sync
@shr_mtx
.
synchronize
{
yield
}
...
...
@@ -95,6 +118,7 @@ class FZF
@exit0
=
false
@filter
=
nil
@nth
=
nil
@with_nth
=
nil
@delim
=
nil
@reverse
=
false
@prompt
=
'> '
...
...
@@ -148,6 +172,11 @@ class FZF
@nth
=
parse_nth
nth
when
/^-n([0-9,-\.]+)$/
,
/^--nth=([0-9,-\.]+)$/
@nth
=
parse_nth
$1
when
'--with-nth'
usage
1
,
'field expression required'
unless
nth
=
argv
.
shift
@with_nth
=
parse_nth
nth
when
/^--with-nth=([0-9,-\.]+)$/
@with_nth
=
parse_nth
$1
when
'-d'
,
'--delimiter'
usage
1
,
'delimiter required'
unless
delim
=
argv
.
shift
@delim
=
FZF
.
build_delim_regex
delim
...
...
@@ -181,6 +210,7 @@ class FZF
@queue
=
Queue
.
new
@pending
=
nil
@rev_dir
=
@reverse
?
-
1
:
1
@stdout
=
$stdout
.
clone
unless
@filter
# Shared variables: needs protection
...
...
@@ -200,7 +230,7 @@ class FZF
end
def
parse_nth
nth
nth
.
split
(
','
).
map
{
|
expr
|
ranges
=
nth
.
split
(
','
).
map
{
|
expr
|
x
=
proc
{
usage
1
,
"invalid field expression:
#{
expr
}
"
}
first
,
second
=
expr
.
split
(
'..'
,
2
)
x
.
call
if
!
first
.
empty?
&&
first
.
to_i
==
0
||
...
...
@@ -215,6 +245,7 @@ class FZF
Range
.
new
(
*
[
first
,
second
].
map
{
|
e
|
e
>
0
?
e
-
1
:
e
})
}
ranges
==
[
0
..-
1
]
?
nil
:
ranges
end
def
FZF
.
build_delim_regex
delim
...
...
@@ -222,6 +253,10 @@ class FZF
Regexp
.
compile
"(?:.*?
#{
delim
}
)|(?:.+?$)"
end
def
burp
string
@stdout
.
puts
(
string
.
orig
||
string
)
end
def
start
if
@filter
start_reader
.
join
...
...
@@ -236,7 +271,7 @@ class FZF
if
loaded
if
@select1
&&
len
==
1
puts
@query
if
@print_query
puts
empty
?
matches
.
first
:
matches
.
first
.
first
burp
(
empty
?
matches
.
first
:
matches
.
first
.
first
)
exit
0
elsif
@exit0
&&
len
==
0
puts
@query
if
@print_query
...
...
@@ -312,39 +347,40 @@ class FZF
$stderr
.
puts
%[usage: fzf [options]
Search
-x, --extended Extended-search mode
-e, --extended-exact Extended-search mode (exact match)
-i Case-insensitive match (default: smart-case match)
+i Case-sensitive match
-n, --nth=N[,..] Comma-separated list of field index expressions
for limiting search scope. Each can be a non-zero
integer or a range expression ([BEGIN]..[END])
-d, --delimiter=STR Field delimiter regex for --nth (default: AWK-style)
-x, --extended Extended-search mode
-e, --extended-exact Extended-search mode (exact match)
-i Case-insensitive match (default: smart-case match)
+i Case-sensitive match
-n, --nth=N[,..] Comma-separated list of field index expressions
for limiting search scope. Each can be a non-zero
integer or a range expression ([BEGIN]..[END])
--with-nth=N[,..] Transform the item using index expressions for search
-d, --delimiter=STR Field delimiter regex for --nth (default: AWK-style)
Search result
-s, --sort=MAX Maximum number of matched items to sort (default: 1000)
+s, --no-sort Do not sort the result. Keep the sequence unchanged.
-s, --sort=MAX
Maximum number of matched items to sort (default: 1000)
+s, --no-sort
Do not sort the result. Keep the sequence unchanged.
Interface
-m, --multi Enable multi-select with tab/shift-tab
--no-mouse Disable mouse
+c, --no-color Disable colors
+2, --no-256 Disable 256-color
--black Use black background
--reverse Reverse orientation
--prompt=STR Input prompt (default: '> ')
-m, --multi
Enable multi-select with tab/shift-tab
--no-mouse
Disable mouse
+c, --no-color
Disable colors
+2, --no-256
Disable 256-color
--black
Use black background
--reverse
Reverse orientation
--prompt=STR
Input prompt (default: '> ')
Scripting
-q, --query=STR Start the finder with the given query
-1, --select-1 Automatically select the only match
-0, --exit-0 Exit immediately when there's no match
-f, --filter=STR Filter mode. Do not start interactive finder.
--print-query Print query as the first line
-q, --query=STR
Start the finder with the given query
-1, --select-1
Automatically select the only match
-0, --exit-0
Exit immediately when there's no match
-f, --filter=STR
Filter mode. Do not start interactive finder.
--print-query
Print query as the first line
Environment variables
FZF_DEFAULT_COMMAND Default command to use when input is tty
FZF_DEFAULT_OPTS Defaults options. (e.g. "-x -m --sort 10000")]
+
$/
+
$/
exit
x
FZF_DEFAULT_COMMAND
Default command to use when input is tty
FZF_DEFAULT_OPTS
Defaults options. (e.g. "-x -m --sort 10000")]
+
$/
+
$/
exit
x
end
def
emit
event
...
...
@@ -520,7 +556,6 @@ class FZF
end
def
init_screen
@stdout
=
$stdout
.
clone
$stdout
.
reopen
(
$stderr
)
C
.
init_screen
...
...
@@ -595,14 +630,28 @@ class FZF
end
Thread
.
new
do
while
line
=
stream
.
gets
emit
(
:new
)
{
@new
<<
line
.
chomp
}
if
@with_nth
while
line
=
stream
.
gets
emit
(
:new
)
{
@new
<<
transform
(
line
)
}
end
else
while
line
=
stream
.
gets
emit
(
:new
)
{
@new
<<
line
.
chomp
}
end
end
emit
(
:loaded
)
{
true
}
@spinner
.
clear
if
@spinner
end
end
def
transform
line
line
=
line
.
chomp
mut
=
(
line
=~
/ $/
?
line
:
line
+
' '
).
tokenize
(
@delim
,
@with_nth
).
map
{
|
e
|
e
.
last
}.
join
(
''
).
sub
(
/ *$/
,
''
)
mut
.
orig
=
line
mut
end
def
start_search
&
callback
Thread
.
new
do
lists
=
[]
...
...
@@ -1080,10 +1129,10 @@ class FZF
@stdout
.
puts
q
if
@print_query
if
got
if
selects
.
empty?
@stdout
.
puts
got
burp
got
else
selects
.
each
do
|
sel
,
_
|
@stdout
.
puts
sel
burp
sel
end
end
end
...
...
@@ -1108,25 +1157,7 @@ class FZF
end
def
tokenize
str
@tokens_cache
[
str
]
||=
begin
unless
@delim
# AWK default
prefix_length
=
(
str
.
index
(
/\S/
)
||
0
)
rescue
0
tokens
=
str
.
scan
(
/\S+\s*/
)
rescue
[]
else
prefix_length
=
0
tokens
=
str
.
scan
(
@delim
)
rescue
[]
end
@nth
.
map
{
|
n
|
if
n
.
begin
==
0
&&
n
.
end
==
-
1
[
prefix_length
,
tokens
.
join
]
elsif
part
=
tokens
[
n
]
[
prefix_length
+
(
tokens
[
0
...
(
n
.
begin
)]
||
[]).
join
.
length
,
part
.
join
]
end
}.
compact
end
@tokens_cache
[
str
]
||=
str
.
tokenize
(
@delim
,
@nth
)
end
def
do_match
str
,
pat
...
...
This diff is collapsed.
Click to expand it.
test/test_fzf.rb
+
32
−
2
View file @
76a3ef8c
#!/usr/bin/env ruby
# encoding: utf-8
require
'rubygems'
require
'curses'
require
'timeout'
require
'stringio'
...
...
@@ -25,6 +26,7 @@ class TestFZF < MiniTest::Unit::TestCase
assert_equal
nil
,
fzf
.
rxflag
assert_equal
true
,
fzf
.
mouse
assert_equal
nil
,
fzf
.
nth
assert_equal
nil
,
fzf
.
with_nth
assert_equal
true
,
fzf
.
color
assert_equal
false
,
fzf
.
black
assert_equal
true
,
fzf
.
ansi256
...
...
@@ -47,7 +49,7 @@ class TestFZF < MiniTest::Unit::TestCase
ENV
[
'FZF_DEFAULT_OPTS'
]
=
'-x -m -s 10000 -q " hello world " +c +2 --select-1 -0 '
<<
'--no-mouse -f "goodbye world" --black --nth=3,-1,2 --reverse --print-query'
'--no-mouse -f "goodbye world" --black
--with-nth=3,-3..,2
--nth=3,-1,2 --reverse --print-query'
fzf
=
FZF
.
new
[]
assert_equal
10000
,
fzf
.
sort
assert_equal
' hello world '
,
...
...
@@ -65,13 +67,14 @@ class TestFZF < MiniTest::Unit::TestCase
assert_equal
true
,
fzf
.
reverse
assert_equal
true
,
fzf
.
print_query
assert_equal
[
2
..
2
,
-
1
..-
1
,
1
..
1
],
fzf
.
nth
assert_equal
[
2
..
2
,
-
3
..-
1
,
1
..
1
],
fzf
.
with_nth
end
def
test_option_parser
# Long opts
fzf
=
FZF
.
new
%w[--sort=2000 --no-color --multi +i --query hello --select-1
--exit-0 --filter=howdy --extended-exact
--no-mouse --no-256 --nth=1 --reverse --prompt (hi)
--no-mouse --no-256 --nth=1
--with-nth=..
--reverse --prompt (hi)
--print-query]
assert_equal
2000
,
fzf
.
sort
assert_equal
true
,
fzf
.
multi
...
...
@@ -86,6 +89,7 @@ class TestFZF < MiniTest::Unit::TestCase
assert_equal
'howdy'
,
fzf
.
filter
assert_equal
:exact
,
fzf
.
extended
assert_equal
[
0
..
0
],
fzf
.
nth
assert_equal
nil
,
fzf
.
with_nth
assert_equal
true
,
fzf
.
reverse
assert_equal
'(hi)'
,
fzf
.
prompt
assert_equal
true
,
fzf
.
print_query
...
...
@@ -638,6 +642,32 @@ class TestFZF < MiniTest::Unit::TestCase
assert_fzf_output
%w[--exit-0]
,
''
,
''
end
def
test_with_nth
source
=
"hello world
\n
batman"
assert_fzf_output
%w[-0 -1 --with-nth=2,1 -x -q ^worl]
,
source
,
'hello world'
assert_fzf_output
%w[-0 -1 --with-nth=2,1 -x -q llo$]
,
source
,
'hello world'
assert_fzf_output
%w[-0 -1 --with-nth=.. -x -q llo$]
,
source
,
''
assert_fzf_output
%w[-0 -1 --with-nth=2,2,2,..,1 -x -q worlworlworlhellworlhell]
,
source
,
'hello world'
assert_fzf_output
%w[-0 -1 --with-nth=1,1,-1,1 -x -q batbatbatbat]
,
source
,
'batman'
end
def
test_with_nth_transform
fzf
=
FZF
.
new
%w[--with-nth 2..,1]
assert_equal
'my world hello'
,
fzf
.
transform
(
'hello my world'
)
assert_equal
'my world hello'
,
fzf
.
transform
(
'hello my world'
)
assert_equal
'my world hello'
,
fzf
.
transform
(
'hello my world '
)
fzf
=
FZF
.
new
%w[--with-nth 2,-1,2]
assert_equal
'my world my'
,
fzf
.
transform
(
'hello my world'
)
assert_equal
'world world world'
,
fzf
.
transform
(
'hello world'
)
assert_equal
'world world world'
,
fzf
.
transform
(
'hello world '
)
end
def
test_ranking_overlap_match_regions
list
=
[
'1 3 4 2'
,
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment