Skip to content

Commit 86eafb2

Browse files
authored
Fix completion when wordbreak is first character (#526)
When a completion argument starts with a wordbreak character (e.g. "a :b"), argcomplete doesn't properly set `last_wordbreak_pos` and remove the wordbreak character from the results. This causes bash to add an extra wordbreak character (e.g. "a ::b") which then breaks any further completion. This commit properly sets `last_wordbreak_pos` in the _shlex parser, and adds a test case for a leading colon.
1 parent bb8d688 commit 86eafb2

File tree

3 files changed

+6
-1
lines changed

3 files changed

+6
-1
lines changed

argcomplete/finders.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ def quote_completions(
515515
# Bash mangles completions which contain characters in COMP_WORDBREAKS.
516516
# This workaround has the same effect as __ltrim_colon_completions in bash_completion
517517
# (extended to characters other than the colon).
518-
if last_wordbreak_pos:
518+
if last_wordbreak_pos is not None:
519519
completions = [c[last_wordbreak_pos + 1 :] for c in completions]
520520
special_chars += "();<>|&!`$* \t\n\"'"
521521
elif cword_prequote == '"':

argcomplete/packages/_shlex.py

+3
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ def read_token(self):
177177
elif self.whitespace_split:
178178
self.token = nextchar
179179
self.state = 'a'
180+
# Modified by argcomplete: Record last wordbreak position
181+
if nextchar in self.wordbreaks:
182+
self.last_wordbreak_pos = len(self.token) - 1
180183
else:
181184
self.token = nextchar
182185
if self.token or (self.posix and quoted):

test/test.py

+2
Original file line numberDiff line numberDiff line change
@@ -1041,10 +1041,12 @@ def test_punctuation(self):
10411041

10421042
def test_last_wordbreak_pos(self):
10431043
self.assertEqual(self.wordbreak("a"), None)
1044+
self.assertEqual(self.wordbreak("a :b"), 0)
10441045
self.assertEqual(self.wordbreak("a b:c"), 1)
10451046
self.assertEqual(self.wordbreak("a b:c=d"), 3)
10461047
self.assertEqual(self.wordbreak("a b:c=d "), None)
10471048
self.assertEqual(self.wordbreak("a b:c=d e"), None)
1049+
self.assertEqual(self.wordbreak('":b'), None)
10481050
self.assertEqual(self.wordbreak('"b:c'), None)
10491051
self.assertEqual(self.wordbreak('"b:c=d'), None)
10501052
self.assertEqual(self.wordbreak('"b:c=d"'), None)

0 commit comments

Comments
 (0)