@@ -148,7 +148,6 @@ def __init__(
148148 self .rel_fnames = rel_fnames
149149 self .encoding = encoding
150150 self .abs_read_only_fnames = abs_read_only_fnames or []
151- self .post_filter_commands = ["/add" ]
152151
153152 fname_to_rel_fnames = defaultdict (list )
154153 for rel_fname in addable_rel_fnames :
@@ -214,22 +213,47 @@ def tokenize(self):
214213
215214 def get_command_completions (self , document , complete_event , text , words ):
216215 if len (words ) == 1 and not text [- 1 ].isspace ():
216+ # Handle command completion (e.g., typing "/ad" should complete to "/add")
217217 partial = words [0 ].lower ()
218+ # Strip leading '/' if present for comparison with command names
219+ if partial .startswith ("/" ):
220+ partial = partial [1 :]
218221 candidates = [cmd for cmd in self .command_names if cmd .startswith (partial )]
219222 for candidate in sorted (candidates ):
220- yield Completion (candidate , start_position = - len (words [- 1 ]))
223+ # Add back the leading '/' for the completion
224+ yield Completion ("/" + candidate , start_position = - len (words [- 1 ]))
221225 return
222226
223- if len (words ) <= 1 or text [- 1 ].isspace ():
224- return
227+ # Handle command followed by space: trigger auto-completion with empty partial
228+ if text [- 1 ].isspace ():
229+ # We have a command followed by space, trigger auto-completion with empty string
230+ if len (words ) == 1 :
231+ # Command with no arguments yet, just a trailing space
232+ partial = ""
233+ # We need to get the command name without the trailing space
234+ # The command is words[0] but might have leading '/'
235+ cmd_text = words [0 ]
236+ else :
237+ # Command with arguments and trailing space
238+ partial = ""
239+ cmd_text = text .rstrip () # Remove trailing space for matching
240+ else :
241+ # No trailing space
242+ if len (words ) <= 1 :
243+ return
244+ partial = words [- 1 ].lower ()
245+ cmd_text = text
225246
226- cmd = words [0 ]
227- partial = words [- 1 ].lower ()
247+ # Pass the text (without trailing space if present) to matching_commands
248+ matches , matched_cmd , _ = self .commands .matching_commands (cmd_text .rstrip ())
249+ if not matches :
250+ return
228251
229- matches , _ , _ = self .commands .matching_commands (cmd )
230252 if len (matches ) == 1 :
231253 cmd = matches [0 ]
232- elif cmd not in matches :
254+ elif matched_cmd in matches :
255+ cmd = matched_cmd
256+ else :
233257 return
234258
235259 raw_completer = self .commands .get_raw_completions (cmd )
@@ -242,11 +266,14 @@ def get_command_completions(self, document, complete_event, text, words):
242266 if candidates is None :
243267 return
244268
245- if cmd in self .post_filter_commands :
246- candidates = [word for word in candidates if partial in word .lower ()]
269+ candidates = [word for word in candidates if partial in word .lower ()]
247270
248271 for candidate in sorted (candidates ):
249- yield Completion (candidate , start_position = - len (words [- 1 ]))
272+ # Calculate start position based on partial, not words[-1]
273+ # When partial is empty (trailing space), start_position should be 0
274+ # When partial is not empty, replace that many characters
275+ start_position = - len (partial ) if partial else 0
276+ yield Completion (candidate , start_position = start_position )
250277
251278 def get_completions (self , document , complete_event ):
252279 self .tokenize ()
@@ -256,8 +283,9 @@ def get_completions(self, document, complete_event):
256283 if not words :
257284 return
258285
259- if text and text [- 1 ].isspace ():
260- # don't keep completing after a space
286+ if text and text [- 1 ].isspace () and not text .startswith ("/" ):
287+ # don't keep completing after a space for non-commands
288+ # For commands, we want to allow completion with empty string partial
261289 return
262290
263291 if text [0 ] == "/" :
0 commit comments