When the start parameter is missing, the behabiour is arbitary
It seems that the behaviour of the start parameter being missing is server (or perhaps a specific client) dependent. The specification clearely says that it should be inserted at the column of the original request, but the servers clearly expect either for that column to be the beginning of an identifier or for the client to ignore the spec and request from that position anyway. Reading the VSCode code, we see that the 'word' before the cursor is guessed, and if only if BOTH 'start' AND 'length' are supplied, then they are used to determine where insertion starts, otherwise the current 'word' is used. Unclear what 'word' means in the specific contexts, but we're relying on iskeyword.
This commit is contained in:
parent
3aa949431e
commit
2710ee2bfa
2 changed files with 50 additions and 10 deletions
|
|
@ -19,6 +19,13 @@ let s:save_cpo = &cpoptions
|
|||
set cpoptions&vim
|
||||
" }}}
|
||||
|
||||
function! s:Debug( ... )
|
||||
py3 <<EOF
|
||||
if _vimspector_session is not None:
|
||||
_vimspector_session._logger.debug( *vim.eval( 'a:000' ) )
|
||||
EOF
|
||||
endfunction
|
||||
|
||||
|
||||
let s:enabled = vimspector#internal#state#Reset()
|
||||
|
||||
|
|
@ -271,28 +278,37 @@ function! vimspector#CompleteFuncSync( prompt, find_start, query ) abort
|
|||
|
||||
let line = getline( line( '.' ) )[ len( a:prompt ) : ]
|
||||
let col = col( '.' ) - len( a:prompt )
|
||||
|
||||
" It seems that most servers don't implement the 'start' parameter, which is
|
||||
" clearly necessary, as they all seem to assume a specific behaviour, which
|
||||
" is undocumented.
|
||||
|
||||
let s:latest_completion_request.items =
|
||||
\ py3eval( '_vimspector_session.GetCompletionsSync( '
|
||||
\.' vim.eval( "line" ), '
|
||||
\.' int( vim.eval( "col" ) ) )' )
|
||||
|
||||
let s:latest_completion_request.line = line
|
||||
let s:latest_completion_request.col = col
|
||||
|
||||
let prev_non_keyword_char = match( line[ 0 : col - 1 ], '\k*$' ) + 1
|
||||
let query_len = col - prev_non_keyword_char
|
||||
|
||||
let start_pos = col
|
||||
for item in s:latest_completion_request.items
|
||||
if !has_key( item, 'start' )
|
||||
let item.start = col
|
||||
if !has_key( item, 'start' ) || !has_key( item, 'length' )
|
||||
" The specification states that if start is not supplied, isertion
|
||||
" should be at the requested column. But about 0 of the servers actually
|
||||
" implement that
|
||||
" (https://github.com/microsoft/debug-adapter-protocol/issues/138)
|
||||
let item.start = prev_non_keyword_char
|
||||
let item.length = query_len
|
||||
else
|
||||
" For some reason, the returned start value is 0-indexed even though we
|
||||
" use columnsStartAt1
|
||||
" TODO need to check this with the other servers that exist
|
||||
let item.start += 1
|
||||
endif
|
||||
" TODO/FIXME. I don't think it's possible to implement the 'length'
|
||||
" parameter, using vim's completion system
|
||||
" if !has_key( item, 'length' )
|
||||
" let item.length = 0
|
||||
" endif
|
||||
|
||||
if !has_key( item, 'text' )
|
||||
let item.text = item.label
|
||||
endif
|
||||
|
|
@ -305,6 +321,14 @@ function! vimspector#CompleteFuncSync( prompt, find_start, query ) abort
|
|||
let s:latest_completion_request.start_pos = start_pos
|
||||
let s:latest_completion_request.prompt = a:prompt
|
||||
|
||||
call s:Debug( 'FindStart: %s', {
|
||||
\ 'line': line,
|
||||
\ 'col': col,
|
||||
\ 'prompt': len( a:prompt ),
|
||||
\ 'start_pos': start_pos,
|
||||
\ 'returning': ( start_pos + len( a:prompt ) ) - 1,
|
||||
\ } )
|
||||
|
||||
" start_pos is 1-based and the return of findstart is 0-based
|
||||
return ( start_pos + len( a:prompt ) ) - 1
|
||||
else
|
||||
|
|
@ -316,11 +340,18 @@ function! vimspector#CompleteFuncSync( prompt, find_start, query ) abort
|
|||
" that would be erased by the fixed-up earlier start position)
|
||||
"
|
||||
" both start_pos and item.start are 1-based
|
||||
let item.text = s:latest_completion_request.text[
|
||||
let item.text = s:latest_completion_request.line[
|
||||
\ s:latest_completion_request.start_pos + pfxlen - 1 :
|
||||
\ item.start + pfxlen - 1 ] . item.text
|
||||
endif
|
||||
|
||||
if item.length > len( a:query )
|
||||
call s:Debug( 'Rejecting %s, length is greater than %s',
|
||||
\ item,
|
||||
\ len( a:query ) )
|
||||
continue
|
||||
endif
|
||||
|
||||
call add( items, { 'word': item.text,
|
||||
\ 'abbr': item.label,
|
||||
\ 'menu': get( item, 'type', '' ),
|
||||
|
|
@ -328,6 +359,8 @@ function! vimspector#CompleteFuncSync( prompt, find_start, query ) abort
|
|||
\ } )
|
||||
endfor
|
||||
let s:latest_completion_request = {}
|
||||
|
||||
call s:Debug( 'Items: %s', items )
|
||||
return { 'words': items, 'refresh': 'always' }
|
||||
endif
|
||||
endfunction
|
||||
|
|
|
|||
|
|
@ -1,3 +1,10 @@
|
|||
var msg = 'Hello, world!'
|
||||
|
||||
console.log( "OK stuff happened" )
|
||||
var obj = {
|
||||
test: 'testing',
|
||||
toast: function() {
|
||||
return 'toasty' . this.test;
|
||||
}
|
||||
}
|
||||
|
||||
console.log( "OK stuff happened " + obj.toast() )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue