@@ -37,11 +37,8 @@ let s:completion_status_failed = 'failed'
37
37
let s: completion_status_pending = ' pending'
38
38
39
39
let s: is_user_data_support = has (' patch-8.0.1493' )
40
- let s: user_data_key = ' vim-lsp/textEdit'
41
- let s: user_data_additional_edits_key = ' vim-lsp/additionalTextEdits'
42
- let s: user_data_insert_start_key = ' vim-lsp/insertStart'
43
- let s: user_data_insert_format_key = ' vim-lsp/insertFormat'
44
- let s: user_data_filtertext_key = ' vim-lsp/filterText'
40
+ let s: managed_user_data_key_base = 0
41
+ let s: managed_user_data_map = {}
45
42
46
43
" }}}
47
44
@@ -80,10 +77,11 @@ function! lsp#omni#complete(findstart, base) abort
80
77
endfunction
81
78
82
79
function ! s: get_insertion_point (item, current_line, typed_pattern) abort
83
- if ! has_key (a: item , ' user_data' )
84
- let l: insert_start = -1
85
- else
86
- let l: insert_start = get (json_decode (a: item [' user_data' ]), s: user_data_insert_start_key , -1 )
80
+ let l: insert_start = -1
81
+
82
+ let l: user_data = lsp#omni#get_managed_user_data_from_completed_item (a: item )
83
+ if has_key (l: user_data , ' completion_item' ) && has_key (l: user_data [' completion_item' ], ' textEdit' )
84
+ let l: insert_start = l: user_data [' completion_item' ][' textEdit' ][' range' ][' start' ][' character' ]
87
85
endif
88
86
89
87
if l: insert_start >= 0
@@ -94,12 +92,11 @@ function! s:get_insertion_point(item, current_line, typed_pattern) abort
94
92
endfunction
95
93
96
94
function ! s: get_filter_label (item) abort
97
- if ! has_key (a: item , ' user_data' )
98
- return trim (a: item [' word' ])
95
+ let l: user_data = lsp#omni#get_managed_user_data_from_completed_item (a: item )
96
+ if has_key (l: user_data , ' completion_item' ) && has_key (l: user_data [' completion_item' ], ' filterText' )
97
+ return trim (l: user_data [' completion_item' ][' filterText' ])
99
98
endif
100
-
101
- let l: user_data = json_decode (a: item [' user_data' ])
102
- return trim (get (l: user_data , s: user_data_filtertext_key , a: item [' word' ]))
99
+ return trim (a: item [' word' ])
103
100
endfunction
104
101
105
102
function ! s: prefix_filter (item, last_typed_word) abort
@@ -252,12 +249,6 @@ function! lsp#omni#default_get_vim_completion_item(item, ...) abort
252
249
let l: abbr = a: item [' label' ]
253
250
endif
254
251
255
- if has_key (a: item , ' insertTextFormat' ) && a: item [' insertTextFormat' ] == 2
256
- let l: word = substitute (l: word , ' \<\$[0-9]\+\|\${[^}]\+}\>' , ' ' , ' g' )
257
- endif
258
-
259
- let l: kind = lsp#omni#get_kind_text (a: item , l: server_name )
260
-
261
252
let l: completion = {
262
253
\ ' word' : l: word ,
263
254
\ ' abbr' : l: abbr ,
@@ -266,7 +257,8 @@ function! lsp#omni#default_get_vim_completion_item(item, ...) abort
266
257
\ ' icase' : 1 ,
267
258
\ ' dup' : 1 ,
268
259
\ ' empty' : 1 ,
269
- \ ' kind' : l: kind }
260
+ \ ' kind' : lsp#omni#get_kind_text (a: item , l: server_name )
261
+ \ }
270
262
271
263
" check support user_data.
272
264
" if not support but g:lsp_text_edit_enabled enabled,
@@ -277,38 +269,9 @@ function! lsp#omni#default_get_vim_completion_item(item, ...) abort
277
269
call lsp#log (l: no_support_error_message )
278
270
endif
279
271
280
- let l: user_data = {}
281
-
282
- " Use '-1' to signal "no specific insertion point" set.
283
- let l: user_data [s: user_data_insert_start_key ] = -1
284
-
285
- " add user_data in completion item, when
286
- " 1. provided user_data
287
- " 2. provided textEdit or additionalTextEdits
288
- " 3. textEdit value is Dictionary or additionalTextEdits is non-empty list
289
- if g: lsp_text_edit_enabled
290
- let l: text_edit = get (a: item , ' textEdit' , v: null )
291
- let l: additional_text_edits = get (a: item , ' additionalTextEdits' , v: null )
292
-
293
- " type check
294
- if type (l: text_edit ) == type ({})
295
- let l: user_data [s: user_data_key ] = l: text_edit
296
- let l: user_data [s: user_data_insert_start_key ] = l: text_edit [' range' ][' start' ][' character' ]
297
- let l: user_data [s: user_data_insert_format_key ] = get (a: item , ' insertTextFormat' , 0 )
298
- endif
299
-
300
- if type (l: additional_text_edits ) == type ([]) && ! empty (l: additional_text_edits )
301
- let l: user_data [s: user_data_additional_edits_key ] = l: additional_text_edits
302
- endif
303
- endif
304
-
305
- " Store filterText in user_data
306
- if s: is_user_data_support && has_key (a: item , ' filterText' )
307
- let l: user_data [s: user_data_filtertext_key ] = a: item [' filterText' ]
308
- endif
309
-
310
- if ! empty (l: user_data )
311
- let l: completion [' user_data' ] = json_encode (l: user_data )
272
+ " Add user_data.
273
+ if s: is_user_data_support
274
+ let l: completion [' user_data' ] = s: create_user_data (a: item , l: server_name )
312
275
endif
313
276
314
277
if has_key (a: item , ' detail' ) && ! empty (a: item [' detail' ])
@@ -332,139 +295,42 @@ function! lsp#omni#get_vim_completion_item(...) abort
332
295
return call (g: lsp_get_vim_completion_item [0 ], a: 000 )
333
296
endfunction
334
297
335
- augroup lsp_completion_item_text_edit
336
- autocmd !
337
- autocmd CompleteDone * call <SID> apply_text_edits ()
338
- augroup END
339
-
340
- function ! s: apply_text_edits () abort
341
- " textEdit support function(callin from CompleteDone).
342
- "
343
- " expected user_data structure:
344
- " v:completed_item['user_data']: {
345
- " 'vim-lsp/textEdit': {
346
- " 'range': { ...(snip) },
347
- " 'newText': 'yyy'
348
- " },
349
- " 'vim-lsp/additionalTextEdits': [
350
- " {
351
- " 'range': { ...(snip) },
352
- " 'newText': 'yyy'
353
- " },
354
- " ...
355
- " ],
356
- " }
357
- if ! g: lsp_text_edit_enabled
358
- doautocmd User lsp_complete_done
359
- return
360
- endif
361
-
362
- " completion faild or not select complete item
363
- if empty (v: completed_item )
364
- doautocmd User lsp_complete_done
365
- return
366
- endif
367
-
368
- " check user_data
369
- if ! has_key (v: completed_item , ' user_data' )
370
- doautocmd User lsp_complete_done
371
- return
372
- endif
373
-
374
- " check user_data type is Dictionary and user_data['vim-lsp/textEdit']
375
- try
376
- let l: user_data = json_decode (v: completed_item [' user_data' ])
377
- catch
378
- " do nothing if user_data is not json type string.
379
- doautocmd User lsp_complete_done
380
- return
381
- endtry
382
-
383
- if type (l: user_data ) != type ({})
384
- doautocmd User lsp_complete_done
385
- return
386
- endif
387
-
388
- let l: all_text_edits = []
389
-
390
- " if newText contains snippet markers, remove all them.
391
- let l: snippet_marker_pos = -1
392
-
393
- " expand textEdit range, for omni complet inserted text.
394
- let l: text_edit = get (l: user_data , s: user_data_key , {})
395
- if ! empty (l: text_edit )
396
- let l: expanded_text_edit = s: expand_range (l: text_edit , strchars (v: completed_item [' word' ]))
397
- " InsertTextFormat: Snippet
398
- if get (l: user_data , s: user_data_insert_format_key , 0 ) == 2
399
- let l: new_text = l: expanded_text_edit [' newText' ]
400
- let l: marker_pattern = ' \<\$[0-9]\+\|\${[^}]\+}\>'
401
- let l: snippet_marker_pos = matchstrpos (l: new_text , l: marker_pattern )[1 ] - 1
402
- let l: expanded_text_edit [' newText' ] = substitute (l: new_text , l: marker_pattern , ' ' , ' g' )
403
- endif
404
- call add (l: all_text_edits , l: expanded_text_edit )
405
- endif
406
-
407
- if has_key (l: user_data , s: user_data_additional_edits_key )
408
- let l: all_text_edits += l: user_data [s: user_data_additional_edits_key ]
409
- endif
410
-
411
- " save cursor position in a mark, vim will move it appropriately when
412
- " applying edits
413
- let l: saved_mark = getpos (" 'a" )
414
- " move to end of newText but in two steps (as column may not exist yet)
415
- let [l: pos , l: col_offset ] = s: get_cursor_pos_and_edit_length (l: text_edit )
416
- call setpos (" 'a" , l: pos )
417
-
418
- " apply textEdits
419
- if ! empty (l: all_text_edits )
420
- call lsp#utils#text_edit#apply_text_edits (lsp#utils#get_buffer_uri (), l: all_text_edits )
421
- " When user typed something character while popup menu is shwon, vim
422
- " insert typed-character after CompleteDone occured. but the character
423
- " should not be duplicated since the textEdit include the character.
424
- " this remove the following character.
425
- if l: snippet_marker_pos != -1
426
- let l: oldpos = line (' .' )
427
- let l: oldline = getline (' .' )
428
- call timer_start (1 , {_- > [
429
- \ setline (l: oldpos , l: oldline ),
430
- \ execute (' redraw' , 1 ),
431
- \ execute (' doautocmd User lsp_complete_done' , 1 ),
432
- \] })
433
- endif
434
- return
435
- endif
436
-
437
- let l: pos = getpos (" 'a" )
438
- if l: snippet_marker_pos >= 0
439
- let l: pos [2 ] += l: snippet_marker_pos
440
- else
441
- let l: pos [2 ] += l: col_offset
442
- endif
443
- call setpos (" 'a" , l: saved_mark )
444
- call setpos (' .' , l: pos )
445
-
446
- doautocmd User lsp_complete_done
298
+ "
299
+ " Clear internal user_data map.
300
+ "
301
+ " This function should call at `CompleteDone` only if not empty `v:completed_item`.
302
+ "
303
+ function ! lsp#omni#_clear_managed_user_data_map () abort
304
+ let s: managed_user_data_key_base = 0
305
+ let s: managed_user_data_map = {}
447
306
endfunction
448
307
449
- function ! s: expand_range (text_edit, expand_length) abort
450
- let l: expanded_text_edit = a: text_edit
451
- let l: expanded_text_edit [' range' ][' end' ][' character' ] += a: expand_length
452
-
453
- return l: expanded_text_edit
308
+ "
309
+ " create item's user_data.
310
+ "
311
+ function ! s: create_user_data (completion_item, server_name) abort
312
+ let l: user_data_key = ' vim-lsp/key/' . string (s: managed_user_data_key_base )
313
+ let s: managed_user_data_map [l: user_data_key ] = {
314
+ \ ' server_name' : a: server_name ,
315
+ \ ' completion_item' : a: completion_item
316
+ \ }
317
+ let s: managed_user_data_key_base += 1
318
+ return l: user_data_key
454
319
endfunction
455
320
456
- function ! s: get_cursor_pos_and_edit_length (text_edit) abort
457
- if ! empty (a: text_edit )
458
- let l: start = a: text_edit [' range' ][' start' ]
459
- let [l: line , l: col ] = lsp#utils#position#_lsp_to_vim (' %' , l: start )
460
- let l: length = len (a: text_edit [' newText' ])
461
- let l: pos = [0 , l: line , l: col , 0 ]
462
- else
463
- let l: length = 0
464
- let l: pos = getpos (' .' )
321
+ function ! lsp#omni#get_managed_user_data_from_completed_item (completed_item) abort
322
+ " the item has no user_data.
323
+ if ! has_key (a: completed_item , ' user_data' )
324
+ return {}
325
+ endif
326
+
327
+ " Check managed user_data.
328
+ let l: user_data_key = get (a: completed_item , ' user_data' , ' ' )
329
+ if ! has_key (s: managed_user_data_map , l: user_data_key )
330
+ return {}
465
331
endif
466
332
467
- return [l: pos , l: length ]
333
+ return s: managed_user_data_map [l: user_data_key ]
468
334
endfunction
469
335
470
336
function ! lsp#omni#get_completion_item_kinds () abort
0 commit comments