@@ -78,6 +78,8 @@ local definitions = {
7878 kind = cmp .lsp .CompletionItemKind .Variable ,
7979 isIncomplete = true ,
8080 exec = function (option , arglead , cmdline , force )
81+ -- Any edits we produce are relative to the whole command line.
82+ local cmdline_length = # cmdline
8183 -- Ignore range only cmdline. (e.g.: 4, '<,'>)
8284 if not force and ONLY_RANGE_REGEX :match_str (cmdline ) then
8385 return {}
@@ -115,18 +117,21 @@ local definitions = {
115117 -- In this case, the `vim.fn.getcompletion` will return only `get_query` for `vim.treesitter.get_|`.
116118 -- We should detect `vim.treesitter.` and `get_query` separately.
117119 -- TODO: The `\h\w*` was choosed by huristic. We should consider more suitable detection.
118- local fixed_input
119- do
120- local suffix_pos = vim .regex ([[ \h\w*$]] ):match_str (arglead )
121- fixed_input = string.sub (arglead , 1 , suffix_pos or # arglead )
122- end
120+ local fixed_input = arglead
123121
124122 -- The `vim.fn.getcompletion` does not return `*no*cursorline` option.
125123 -- cmp-cmdline corrects `no` prefix for option name.
126124 local is_option_name_completion = OPTION_NAME_COMPLETION_REGEX :match_str (cmdline ) ~= nil
127125
128126 local items = {}
129127 local escaped = cmdline :gsub ([[ \\]] , [[ \\\\]] );
128+ local is_magic_file = false
129+ local input_start = string.sub (fixed_input , 1 , 1 )
130+ if input_start == ' %' then
131+ is_magic_file = true
132+ elseif input_start == ' #' then
133+ is_magic_file = true
134+ end
130135 for _ , word_or_item in ipairs (vim .fn .getcompletion (escaped , ' cmdline' )) do
131136 local word = type (word_or_item ) == ' string' and word_or_item or word_or_item .word
132137 local item = { label = word }
@@ -139,9 +144,25 @@ local definitions = {
139144 end
140145 end
141146 for _ , item in ipairs (items ) do
142- if not string.find (item .label , fixed_input , 1 , true ) then
147+ if not is_magic_file and not string.find (item .label , fixed_input , 1 , true ) then
143148 item .label = fixed_input .. item .label
144149 end
150+ if is_magic_file then
151+ local replace_range = {
152+ start = {
153+ character = cmdline_length - # fixed_input - 1
154+ },
155+ [' end' ] = {
156+ character = cmdline_length - 1
157+ }
158+ }
159+ item .textEdit = {
160+ replace = replace_range ,
161+ range = replace_range ,
162+ newText = item .label
163+ }
164+ item .label = fixed_input .. ' → ' .. item .label
165+ end
145166 end
146167 return items
147168 end
@@ -196,6 +217,20 @@ source.complete = function(self, params, callback)
196217 for _ , item in ipairs (items ) do
197218 item .kind = kind
198219 labels [item .label ] = true
220+ if item [' textEdit' ] ~= nil then
221+ local new_range = {
222+ start = {
223+ character = item .textEdit .range .start .character ,
224+ line = params .context .cursor .line
225+ },
226+ [' end' ] = {
227+ character = item .textEdit .range [' end' ].character ,
228+ line = params .context .cursor .line
229+ }
230+ }
231+ item .textEdit .replace = new_range
232+ item .textEdit .range = new_range
233+ end
199234 end
200235
201236 -- `vim.fn.getcompletion` does not handle fuzzy matches. So, we must return all items, including items that were matched in the previous input.
0 commit comments