Skip to content

Commit b8cc3f9

Browse files
authored
Merge pull request #2
2 parents 2a194f2 + e9bb150 commit b8cc3f9

File tree

6 files changed

+223
-16
lines changed

6 files changed

+223
-16
lines changed

README.md

+11-2
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,17 @@ The default binding to select an entry is the key \<TAB\> ( you already have you
8989

9090
Like the original [fzf](https://github.com/junegunn/fzf) completion script, you could use recursive search with some bash complete functions by adding `**` at the end of your path, then hit key \<TAB\> to recursively looking for corresponding files / path / directories.
9191

92-
- **Only _filedir function works with globs right now( cd, ls, and many others) , vi use _filedir_xspec and is not globs compatible right now (need to add it)**.
93-
- **If there is no results, you will be aware by seeing the \** removed from your current search**
92+
- **Works with complete functions who use for path/files lookup :**
93+
- **_filedir**
94+
- cd
95+
- ls
96+
- and more than 400 commands
97+
- **_filedir_xspec**
98+
- vi(m)
99+
- bunzip2
100+
- lynx
101+
- and more than 140 commands
102+
- **If there is no results, you will be aware by seeing the "\*\*" removed from your current search**
94103
- **Be cautious that using this capability on huge directories could freeze your shell for ages without be able to cancel it with CTRL-C (need to fix it)**
95104
- **The bindings with globs are different ( \<TAB\>, \<SHIFT-TAB\> are used to (un)select multiples results and \<ENTER\> to validate )**
96105

bash_completion.d/_filedir

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ __fzf_obc_trap__filedir()
3232
if [[ "$1" != -d ]]; then
3333
# With an extension filter
3434
if [[ -n "$1" ]];then
35-
COMPREPLY+=( $(__fzf_obc_search "files" "$1") )
35+
local xspec=${1:+"!*.@($1|${1^^})"};
36+
COMPREPLY+=( $(__fzf_obc_search "files" "${xspec}") )
3637
else
3738
# Without extension filter
3839
COMPREPLY+=( $(__fzf_obc_search "paths") )

bash_completion.d/_filedir_xspec

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env bash
2+
__fzf_obc_trap__filedir_xspec()
3+
{
4+
local last_status=$1
5+
shift
6+
local IFS=$'\n'
7+
# Add / for directories to the original COMPREPLY
8+
# Exclude from COMPREPLY directories listed into FZF_OBC_EXCLUDE_PATH
9+
local i reply_expand exclude_arr exclude exclude_expand
10+
IFS=':' read -r -a exclude_arr <<< "${FZF_OBC_EXCLUDE_PATH}"
11+
for i in "${!COMPREPLY[@]}";do
12+
reply_expand="${COMPREPLY[$i]}"
13+
__fzf_obc_expand_tilde_by_ref reply_expand
14+
for exclude in "${exclude_arr[@]}";do
15+
exclude_expand=${exclude}
16+
__fzf_obc_expand_tilde_by_ref exclude_expand
17+
if [[ "${reply_expand}" == "${exclude_expand}" ]] || [[ "${reply_expand}" == *"/${exclude_expand}" ]];then
18+
unset "COMPREPLY[$i]" && continue 2
19+
fi
20+
done
21+
if test -d "${reply_expand}";then
22+
COMPREPLY[$i]=${COMPREPLY[$i]}/
23+
fi
24+
done
25+
26+
# Add to COMPREPLY our own results
27+
# Add recursivity to native _filedir
28+
if [[ "${cur}" == *"**" ]];then
29+
cur=${cur/\*\*/}
30+
__fzf_obc_tilde "$cur" || return
31+
local xspec
32+
# shellcheck disable=SC2154
33+
xspec="${_xspecs[${1##*/}]}"
34+
local matchop=!;
35+
if [[ $xspec == !* ]]; then
36+
xspec=${xspec#!};
37+
matchop=@;
38+
fi;
39+
xspec="$matchop($xspec|${xspec^^})";
40+
COMPREPLY+=( $(__fzf_obc_search "files" "${xspec}") )
41+
cur="${cur}**"
42+
fi
43+
return "${last_status}"
44+
}

bash_completion.d/_fzf_obc_functions

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ __fzf_obc_search() {
3333
local type xspec
3434
type="${1}"
3535
shift
36-
xspec=${1:+"*.@($1|${1^^})"}
36+
xspec=${1}
3737

3838
local cur_expanded=${cur:-./}
3939
__fzf_obc_expand_tilde_by_ref cur_expanded

test/lib/ttytest_addons.rb

+4-3
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,14 @@ def clear_screen
7171
sleep 0.05
7272
end
7373
end
74-
driver.tmux(*%W[send-keys -Rt #{name}], 'Escape')
75-
driver.tmux(*%W[send-keys -Rt #{name}], 'Escape')
7674
driver.tmux(*%W[send-keys -Rt #{name}], 'C-c')
75+
sleep TTYtest.send_keys_delay
7776
driver.tmux(*%W[send-keys -Rt #{name}], 'C-c')
78-
driver.tmux(*%W[send-keys -Rt #{name}], 'Enter')
77+
sleep TTYtest.send_keys_delay
7978
driver.tmux(*%W[send-keys -Rt #{name}], 'printf "\\033c"')
79+
sleep TTYtest.send_keys_delay
8080
driver.tmux(*%W[send-keys -Rt #{name}], 'Enter')
81+
sleep TTYtest.send_keys_delay
8182
end
8283
end
8384
end

test/test-fzf-obc.rb

+161-9
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@
2121

2222
puts "\nChecking for binaries required for those tests\n\n"
2323

24-
check_cmds('fzf,git')
24+
check_cmds(%w{
25+
fzf
26+
git
27+
insmod
28+
vi
29+
})
2530

2631

2732
class FzfObcTest < Minitest::Test
@@ -30,17 +35,10 @@ class FzfObcTest < Minitest::Test
3035

3136
def setup
3237
prepare_tmux
38+
cleanup
3339
@@tty.clear_screen()
3440
end
3541

36-
def teardown
37-
if !TTYtest.debug
38-
Dir.chdir BASE
39-
FileUtils.rm_rf "#{TEST_DIR}"
40-
FileUtils.rm_rf "#{ENV['HOME']}/#{HOME_TEST_DIR}"
41-
end
42-
end
43-
4442
def prepare_tmux
4543
return if @@prepare_tmux_done
4644
@@prepare_tmux_done = true
@@ -140,6 +138,24 @@ def files_glob_creation
140138
files_creation
141139
end
142140

141+
def create_files_dirs(
142+
dest: TEST_DIR,
143+
subdirs: %w{},
144+
files: %w{}
145+
)
146+
dest = File.expand_path(dest)
147+
FileUtils.mkdir_p "#{dest}"
148+
for file in files
149+
FileUtils.touch "#{dest}/#{file}"
150+
end
151+
for dir in subdirs
152+
FileUtils.mkdir_p "#{dest}/#{dir}"
153+
for file in files
154+
FileUtils.touch "#{dest}/#{dir}/#{file}"
155+
end
156+
end
157+
end
158+
143159
def files_home_completion
144160
FileUtils.mkdir_p "#{ENV['HOME']}/#{HOME_TEST_DIR}"
145161
FileUtils.touch "#{ENV['HOME']}/#{HOME_TEST_DIR}/fzf-obc.test"
@@ -302,4 +318,140 @@ def test_files_home_glob_completion
302318
TTY
303319
end
304320

321+
def test__filedir_with_insmod
322+
# insmod use _filedir with extension filter
323+
puts "\nDebug: inside " + __method__.to_s + "\n" if TTYtest.debug
324+
create_files_dirs(
325+
subdirs: %w{d1},
326+
files: %w{
327+
test.ko.gz
328+
test\ 1.ko.gz
329+
test.log
330+
test.mp3
331+
}
332+
)
333+
@@tty.send_keys(<<~EOF)
334+
insmod #{TEST_DIR}/
335+
#{TAB}
336+
EOF
337+
@@tty.assert_matches(<<~EOF)
338+
$ insmod #{TEST_DIR}/
339+
>
340+
3/3
341+
> #{TEST_DIR}/test.ko.gz
342+
#{TEST_DIR}/test 1.ko.gz
343+
#{TEST_DIR}/d1/
344+
EOF
345+
end
346+
347+
def test__filedir_with_insmod_in_home
348+
# insmod use _filedir with extension filter
349+
puts "\nDebug: inside " + __method__.to_s + "\n" if TTYtest.debug
350+
create_files_dirs(
351+
dest: "~/#{HOME_TEST_DIR}",
352+
subdirs: %w{d1},
353+
files: %w{
354+
test.ko.gz
355+
test\ 1.ko.gz
356+
test.log
357+
test.mp3
358+
}
359+
)
360+
@@tty.send_keys(<<~EOF)
361+
insmod ~/#{HOME_TEST_DIR}/
362+
#{TAB}
363+
EOF
364+
@@tty.assert_matches(<<~EOF)
365+
$ insmod ~/#{HOME_TEST_DIR}/
366+
>
367+
3/3
368+
> ~/#{HOME_TEST_DIR}/test.ko.gz
369+
~/#{HOME_TEST_DIR}/test 1.ko.gz
370+
~/#{HOME_TEST_DIR}/d1/
371+
EOF
372+
end
373+
374+
def test__filedir_xspec_with_vi
375+
# vi use _filedir_xspec with extension filter
376+
puts "\nDebug: inside " + __method__.to_s + "\n" if TTYtest.debug
377+
create_files_dirs(
378+
subdirs: %w{d1},
379+
files: %w{
380+
test.conf
381+
test\ 1.conf
382+
test.class
383+
test.mp3
384+
}
385+
)
386+
@@tty.send_keys(<<~EOF)
387+
vi #{TEST_DIR}/
388+
#{TAB}
389+
EOF
390+
@@tty.assert_matches(<<~EOF)
391+
$ vi #{TEST_DIR}/
392+
>
393+
3/3
394+
> #{TEST_DIR}/test.conf
395+
#{TEST_DIR}/test 1.conf
396+
#{TEST_DIR}/d1/
397+
EOF
398+
end
399+
400+
def test__filedir_xspec_with_vi_in_home
401+
# vi use _filedir_xspec with extension filter
402+
puts "\nDebug: inside " + __method__.to_s + "\n" if TTYtest.debug
403+
create_files_dirs(
404+
dest: "~/#{HOME_TEST_DIR}",
405+
subdirs: %w{d1},
406+
files: %w{
407+
test.conf
408+
test\ 1.conf
409+
test.class
410+
test.mp3
411+
}
412+
)
413+
@@tty.send_keys(<<~EOF)
414+
vi ~/#{HOME_TEST_DIR}/
415+
#{TAB}
416+
EOF
417+
@@tty.assert_matches(<<~EOF)
418+
$ vi ~/#{HOME_TEST_DIR}/
419+
>
420+
3/3
421+
> ~/#{HOME_TEST_DIR}/test.conf
422+
~/#{HOME_TEST_DIR}/test 1.conf
423+
~/#{HOME_TEST_DIR}/d1/
424+
EOF
425+
426+
# With globs
427+
@@tty.clear_screen()
428+
@@tty.send_keys(<<~EOF)
429+
vi ~/#{HOME_TEST_DIR}/**
430+
#{TAB}
431+
EOF
432+
@@tty.assert_matches(<<~EOF)
433+
$ vi ~/#{HOME_TEST_DIR}/**
434+
>
435+
4/4
436+
> ~/#{HOME_TEST_DIR}/test.conf
437+
~/#{HOME_TEST_DIR}/test 1.conf
438+
~/#{HOME_TEST_DIR}/d1/test.conf
439+
~/#{HOME_TEST_DIR}/d1/test 1.conf
440+
EOF
441+
442+
end
443+
444+
end
445+
446+
def cleanup
447+
Dir.chdir BASE
448+
FileUtils.rm_rf "#{TEST_DIR}"
449+
FileUtils.rm_rf "#{ENV['HOME']}/#{HOME_TEST_DIR}"
450+
end
451+
452+
MiniTest.after_run do
453+
if !TTYtest.debug
454+
# Don't cleanup in debug mode to keep the last test structure
455+
cleanup
456+
end
305457
end

0 commit comments

Comments
 (0)