Match filenames, expanding ~USER type strings. Most of the seemingly convoluted logic in this completer is an attempt to handle filenames with spaces in them. And yet it's not quite perfect, because Python's readline doesn't expose all of the GNU readline details ne
(self, context: CompletionContext)
| 2194 | |
| 2195 | @context_matcher() |
| 2196 | def file_matcher(self, context: CompletionContext) -> SimpleMatcherResult: |
| 2197 | """Match filenames, expanding ~USER type strings. |
| 2198 | |
| 2199 | Most of the seemingly convoluted logic in this completer is an |
| 2200 | attempt to handle filenames with spaces in them. And yet it's not |
| 2201 | quite perfect, because Python's readline doesn't expose all of the |
| 2202 | GNU readline details needed for this to be done correctly. |
| 2203 | |
| 2204 | For a filename with a space in it, the printed completions will be |
| 2205 | only the parts after what's already been typed (instead of the |
| 2206 | full completions, as is normally done). I don't think with the |
| 2207 | current (as of Python 2.3) Python readline it's possible to do |
| 2208 | better. |
| 2209 | """ |
| 2210 | # TODO: add a heuristic for suppressing (e.g. if it has OS-specific delimiter, |
| 2211 | # starts with `/home/`, `C:\`, etc) |
| 2212 | |
| 2213 | text = context.token |
| 2214 | code_until_cursor = self._extract_code(context.text_until_cursor) |
| 2215 | completion_type = self._determine_completion_context(code_until_cursor) |
| 2216 | in_cli_context = self._is_completing_in_cli_context(code_until_cursor) |
| 2217 | if ( |
| 2218 | completion_type == self._CompletionContextType.ATTRIBUTE |
| 2219 | and not in_cli_context |
| 2220 | ): |
| 2221 | return { |
| 2222 | "completions": [], |
| 2223 | "suppress": False, |
| 2224 | } |
| 2225 | |
| 2226 | # chars that require escaping with backslash - i.e. chars |
| 2227 | # that readline treats incorrectly as delimiters, but we |
| 2228 | # don't want to treat as delimiters in filename matching |
| 2229 | # when escaped with backslash |
| 2230 | if text.startswith('!'): |
| 2231 | text = text[1:] |
| 2232 | text_prefix = u'!' |
| 2233 | else: |
| 2234 | text_prefix = u'' |
| 2235 | |
| 2236 | text_until_cursor = self.text_until_cursor |
| 2237 | # track strings with open quotes |
| 2238 | open_quotes = has_open_quotes(text_until_cursor) |
| 2239 | |
| 2240 | if '(' in text_until_cursor or '[' in text_until_cursor: |
| 2241 | lsplit = text |
| 2242 | else: |
| 2243 | try: |
| 2244 | # arg_split ~ shlex.split, but with unicode bugs fixed by us |
| 2245 | lsplit = arg_split(text_until_cursor)[-1] |
| 2246 | except ValueError: |
| 2247 | # typically an unmatched ", or backslash without escaped char. |
| 2248 | if open_quotes: |
| 2249 | lsplit = text_until_cursor.split(open_quotes)[-1] |
| 2250 | else: |
| 2251 | return { |
| 2252 | "completions": [], |
| 2253 | "suppress": False, |
nothing calls this directly
no test coverage detected