11import { walkGherkinDocument } from '@cucumber/gherkin-utils'
2- import { CompletionItem , CompletionItemKind , InsertTextFormat } from 'vscode-languageserver-types'
2+ import {
3+ CompletionItem ,
4+ CompletionItemKind ,
5+ InsertTextFormat ,
6+ Position ,
7+ } from 'vscode-languageserver-types'
38
49import { parseGherkinDocument } from '../gherkin/parseGherkinDocument.js'
510import { Index } from '../index/index.js'
@@ -8,7 +13,7 @@ import { lspCompletionSnippet } from './snippet/lspCompletionSnippet.js'
813// https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#textDocument_completion
914export function getGherkinCompletionItems (
1015 gherkinSource : string ,
11- line : number ,
16+ position : Position ,
1217 index : Index
1318) : readonly CompletionItem [ ] {
1419 const { gherkinDocument } = parseGherkinDocument ( gherkinSource )
@@ -20,7 +25,7 @@ export function getGherkinCompletionItems(
2025 let endCharacter : number
2126 walkGherkinDocument ( gherkinDocument , undefined , {
2227 step ( step ) {
23- if ( step . location . line === line + 1 && step . location . column !== undefined ) {
28+ if ( step . location . line === position . line + 1 && step . location . column !== undefined ) {
2429 text = step . text
2530 startCharacter = step . location . column + step . keyword . length - 1
2631 endCharacter = startCharacter + text . length
@@ -29,28 +34,40 @@ export function getGherkinCompletionItems(
2934 } )
3035 if ( text === undefined ) return [ ]
3136 const suggestions = index ( text )
32- return suggestions . map ( ( suggestion ) => {
37+ // https://github.com/microsoft/language-server-protocol/issues/898#issuecomment-593968008
38+ return suggestions . map ( ( suggestion , i ) => {
39+ // The index has already sorted the syggestions by match score.
40+ // We're moving suggestions that are from undefined steps to the bottom
41+ const sortText = ( suggestion . matched ? i + 1000 : i + 2000 ) . toString ( )
3342 const item : CompletionItem = {
3443 label : suggestion . label ,
3544 insertTextFormat : InsertTextFormat . Snippet ,
3645 kind : CompletionItemKind . Text ,
3746 labelDetails : {
3847 ...( suggestion . matched ? { } : { detail : ' (undefined step)' } ) ,
3948 } ,
49+ // VSCode will only display suggestions that literally match the label.
50+ // We're overriding this behaviour by setting filterText to what the user has typed,
51+ // so that the suggestions are always displayed
52+ filterText : text ,
53+ sortText,
4054 textEdit : {
4155 newText : lspCompletionSnippet ( suggestion . segments ) ,
4256 range : {
4357 start : {
44- line,
58+ line : position . line ,
4559 character : startCharacter ,
4660 } ,
4761 end : {
48- line,
62+ line : position . line ,
4963 character : endCharacter ,
5064 } ,
5165 } ,
5266 } ,
5367 }
68+ const { label } = item
69+ console . log ( { label, sortText } )
70+ console . log ( )
5471 return item
5572 } )
5673}
0 commit comments