Skip to content

Commit f51d393

Browse files
committed
Improve completion with '~/...' arguments.
1 parent f573f2f commit f51d393

4 files changed

Lines changed: 105 additions & 2 deletions

File tree

src/completion-scripts_.toit

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,16 @@ bash-completion-script_ --program-path/string -> string:
7272
local IFS=\$'\\n'
7373
shopt -s extglob 2>/dev/null
7474
75+
# Expand tildes (e.g. ~/foo -> /home/user/foo) so the program
76+
# receives real filesystem paths it can open.
77+
local -a expanded_words
78+
local _w
79+
for _w in "\${COMP_WORDS[@]:1:\$COMP_CWORD}"; do
80+
expanded_words+=("\${_w/#\\~/\$HOME}")
81+
done
82+
7583
local completions
76-
completions=\$("$program-path" __complete -- "\${COMP_WORDS[@]:1:\$COMP_CWORD}")
84+
completions=\$("$program-path" __complete -- "\${expanded_words[@]}")
7785
if [ \$? -ne 0 ]; then
7886
return
7987
fi
@@ -149,8 +157,16 @@ zsh-completion-script_ --program-path/string -> string:
149157
local -a completions
150158
local directive_line directive extensions=""
151159
160+
# Expand tildes (e.g. ~/foo -> /home/user/foo) so the program
161+
# receives real filesystem paths it can open.
162+
local -a expanded_words
163+
local _w
164+
for _w in "\${words[@]:1:\$((CURRENT-1))}"; do
165+
expanded_words+=("\${_w/#\\~/\$HOME}")
166+
done
167+
152168
local output
153-
output=\$("$program-path" __complete -- "\${words[@]:1:\$((CURRENT-1))}" 2>/dev/null)
169+
output=\$("$program-path" __complete -- "\${expanded_words[@]}" 2>/dev/null)
154170
if [ \$? -ne 0 ]; then
155171
return
156172
fi

tests/completion_shell_bash_test.toit

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,33 @@ test-bash binary/string tmpdir/string:
9999
expect (content.contains "beta")
100100
tmux.cancel
101101

102+
// Tilde expansion: the "lookup" command opens the file given as the
103+
// first rest arg and offers fixed candidates for the second arg.
104+
// When the file path uses ~, the shell must expand the tilde so
105+
// the program can open the file.
106+
// Find an existing file in $HOME to avoid creating test artifacts.
107+
tmux.send-line "for f in .profile .bashrc .zshrc .zshenv .bash_profile .config; do test -e ~/\$f && echo tilde-found:\$f && break; done"
108+
tmux.wait-for "tilde-found:"
109+
tilde-file := ""
110+
lines := (tmux.capture).split "\n"
111+
lines.do: | line/string |
112+
if line.contains "tilde-found:" and tilde-file == "":
113+
tilde-file = ((line.trim).split ":").last
114+
115+
expect (tilde-file != "")
116+
117+
// Re-source with absolute path.
118+
tmux.send-line "source <($binary completion bash) && echo re-sourced2"
119+
tmux.wait-for "re-sourced2"
120+
121+
// Complete the entry arg using a tilde path for the file.
122+
tmux.send-keys ["$binary lookup ~/$(tilde-file) ", "Tab", "Tab"]
123+
tmux.wait-for "tilde-ok-alpha"
124+
content = tmux.capture
125+
expect (content.contains "tilde-ok-bravo")
126+
expect (content.contains "tilde-ok-charlie")
127+
tmux.cancel
128+
102129
print " All bash tests passed."
103130
finally:
104131
tmux.close

tests/completion_shell_test_app.toit

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// shell completion end-to-end via tmux.
77
88
import cli show *
9+
import host.file
910

1011
KNOWN-DEVICES ::= {
1112
"d3b07384-d113-4ec6-a7d2-8c6b2ab3e8f5": "Living Room Sensor",
@@ -51,4 +52,36 @@ main arguments:
5152
]
5253
--run=:: null
5354

55+
// "lookup" command: opens a file (first rest arg) and, if successful,
56+
// offers fixed completion candidates for the second rest arg. This
57+
// exercises tilde expansion: the shell must expand ~/... before the
58+
// program tries to open the file.
59+
root.add
60+
Command "lookup"
61+
--help="Look up an entry in a file."
62+
--rest=[
63+
OptionPath "file" --help="Input file." --required,
64+
Option "entry"
65+
--help="Entry to look up."
66+
--completion=:: | ctx/CompletionContext |
67+
file-values := ctx.seen-options.get "file"
68+
if not file-values or file-values.is-empty:
69+
[]
70+
else:
71+
opened := false
72+
catch:
73+
file.read-contents file-values.first
74+
opened = true
75+
if not opened:
76+
[]
77+
else:
78+
result := []
79+
candidates := ["tilde-ok-alpha", "tilde-ok-bravo", "tilde-ok-charlie"]
80+
candidates.do: | c/string |
81+
if c.starts-with ctx.prefix:
82+
result.add (CompletionCandidate c)
83+
result,
84+
]
85+
--run=:: null
86+
5487
root.run arguments

tests/completion_shell_zsh_test.toit

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,33 @@ test-zsh binary/string tmpdir/string:
8989
expect (content.contains "beta")
9090
tmux.cancel
9191

92+
// Tilde expansion: the "lookup" command opens the file given as the
93+
// first rest arg and offers fixed candidates for the second arg.
94+
// When the file path uses ~, the shell must expand the tilde so
95+
// the program can open the file.
96+
// Find an existing file in $HOME to avoid creating test artifacts.
97+
tmux.send-line "for f in .profile .bashrc .zshrc .zshenv .bash_profile .config; do test -e ~/\$f && echo tilde-found:\$f && break; done"
98+
tmux.wait-for "tilde-found:"
99+
tilde-file := ""
100+
lines := (tmux.capture).split "\n"
101+
lines.do: | line/string |
102+
if line.contains "tilde-found:" and tilde-file == "":
103+
tilde-file = ((line.trim).split ":").last
104+
105+
expect (tilde-file != "")
106+
107+
// Re-source with absolute path (original binary).
108+
tmux.send-line "source <($binary completion zsh) && echo re-sourced2"
109+
tmux.wait-for "re-sourced2"
110+
111+
// Complete the entry arg using a tilde path for the file.
112+
tmux.send-keys ["$binary lookup ~/$(tilde-file) ", "Tab"]
113+
tmux.wait-for "tilde-ok-alpha"
114+
content = tmux.capture
115+
expect (content.contains "tilde-ok-bravo")
116+
expect (content.contains "tilde-ok-charlie")
117+
tmux.cancel
118+
92119
print " All zsh tests passed."
93120
finally:
94121
tmux.close

0 commit comments

Comments
 (0)