Skip to content

Commit

Permalink
[core/completion] Support scalar COMPREPLY with compgen -F (#2212)
Browse files Browse the repository at this point in the history
i.e. value.Str
  • Loading branch information
akinomyoga authored Jan 2, 2025
1 parent 3775f6a commit eadacc6
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 15 deletions.
40 changes: 25 additions & 15 deletions core/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from _devbuild.gen.runtime_asdl import (scope_e, comp_action_e, comp_action_t)
from _devbuild.gen.types_asdl import redir_arg_type_e
from _devbuild.gen.value_asdl import (value, value_e)
from core import bash_impl
from core import error
from core import pyos
from core import state
Expand All @@ -51,7 +52,7 @@
from frontend import location
from frontend import reader
from mycpp import mylib
from mycpp.mylib import print_stderr, iteritems, log
from mycpp.mylib import iteritems, log, print_stderr, tagswitch
from osh.string_ops import ShellQuoteB
from osh import word_
from pylib import os_path
Expand Down Expand Up @@ -619,25 +620,34 @@ def Matches(self, comp):
# Read the response. (The name 'COMP_REPLY' would be more consistent with others.)
val = self.cmd_ev.mem.GetValue('COMPREPLY', scope_e.GlobalOnly)

if val.tag() == value_e.Undef:
# We set it above, so this error would only happen if the user unset it.
# Not changing it means there were no completions.
# TODO: This writes over the command line; it would be better to use an
# error object.
print_stderr('osh error: Ran function %r but COMPREPLY was unset' %
self.func.name)
return
UP_val = val
with tagswitch(val) as case:
if case(value_e.Undef):
# We set it above, so this error would only happen if the user
# unset it. Not changing it means there were no completions.
# TODO: This writes over the command line; it would be better
# to use an error object.
print_stderr('osh error: Ran function %r but COMPREPLY was unset' %
self.func.name)
return

if val.tag() != value_e.BashArray:
print_stderr('osh error: COMPREPLY should be an array, got %s' %
ui.ValType(val))
return
elif case(value_e.Str):
val = cast(value.Str, UP_val)
strs = [val.s]

elif case(value_e.BashArray):
val = cast(value.BashArray, UP_val)
strs = bash_impl.BashArray_GetValues(val)

else:
print_stderr('osh error: COMPREPLY should be an array or a string, got %s' %
ui.ValType(val))
return

if 0:
self.debug('> %r' % val) # CRASHES in C++

array_val = cast(value.BashArray, val)
for s in array_val.strs:
for s in strs:
#self.debug('> %r' % s)
yield s

Expand Down
13 changes: 13 additions & 0 deletions spec/builtin-completion.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -625,3 +625,16 @@ argv.py "${words[@]}"

## N-I bash STDOUT:
## END


#### compgen -F with scalar COMPREPLY

_comp_cmd_test() {
unset -v COMPREPLY
COMPREPLY=hello
}
compgen -F _comp_cmd_test

## STDOUT:
hello
## END

0 comments on commit eadacc6

Please sign in to comment.