@@ -22,6 +22,7 @@ import {
2222import { IntlShape } from "react-intl" ;
2323import {
2424 MarkupContent ,
25+ Position ,
2526 SignatureHelp ,
2627 SignatureHelpRequest ,
2728} from "vscode-languageserver-protocol" ;
@@ -53,6 +54,11 @@ class SignatureHelpState {
5354 */
5455 pos : number ;
5556
57+ /**
58+ * The LSP position for pos.
59+ */
60+ position : Position | null ;
61+
5662 /**
5763 * The latest result we want to display.
5864 *
@@ -61,11 +67,16 @@ class SignatureHelpState {
6167 */
6268 result : SignatureHelp | null ;
6369
64- constructor ( pos : number , result : SignatureHelp | null ) {
70+ constructor (
71+ pos : number ,
72+ position : Position | null ,
73+ result : SignatureHelp | null
74+ ) {
6575 if ( result && pos === - 1 ) {
6676 throw new Error ( "Invalid state" ) ;
6777 }
6878 this . pos = pos ;
79+ this . position = position ;
6980 this . result = result ;
7081 }
7182}
@@ -81,6 +92,16 @@ const signatureHelpToolTipBaseTheme = EditorView.baseTheme({
8192 } ,
8293} ) ;
8394
95+ const positionEq = ( a : Position | null , b : Position | null ) : boolean => {
96+ if ( a === null ) {
97+ return b === null ;
98+ }
99+ if ( b === null ) {
100+ return a === null ;
101+ }
102+ return a . character === b . character && a . line === b . line ;
103+ } ;
104+
84105const openSignatureHelp : Command = ( view : EditorView ) => {
85106 view . dispatch ( {
86107 effects : [
@@ -96,7 +117,7 @@ export const signatureHelp = (
96117 apiReferenceMap : ApiReferenceMap
97118) => {
98119 const signatureHelpTooltipField = StateField . define < SignatureHelpState > ( {
99- create : ( ) => new SignatureHelpState ( - 1 , null ) ,
120+ create : ( ) => new SignatureHelpState ( - 1 , null , null ) ,
100121 update ( state , tr ) {
101122 let { pos, result } = state ;
102123 for ( const effect of tr . effects ) {
@@ -139,11 +160,16 @@ export const signatureHelp = (
139160 } ) ;
140161 }
141162
142- if ( state . pos === pos && state . result === result ) {
163+ const position = pos === - 1 ? null : offsetToPosition ( tr . state . doc , pos ) ;
164+ if (
165+ state . pos === pos &&
166+ state . result === result &&
167+ positionEq ( state . position , position )
168+ ) {
143169 // Avoid pointless tooltip updates. If nothing else it makes e2e tests hard.
144170 return state ;
145171 }
146- return new SignatureHelpState ( pos , result ) ;
172+ return new SignatureHelpState ( pos , position , result ) ;
147173 } ,
148174 provide : ( f ) =>
149175 showTooltip . from ( f , ( val ) => {
@@ -187,7 +213,7 @@ export const signatureHelp = (
187213 implements PluginValue
188214 {
189215 private destroyed = false ;
190- private lastPos = - 1 ;
216+ private lastPosition : Position | null = null ;
191217
192218 constructor ( view : EditorView ) {
193219 super ( view ) ;
@@ -196,17 +222,17 @@ export const signatureHelp = (
196222 const { view, state } = update ;
197223 const uri = state . facet ( uriFacet ) ! ;
198224 const client = state . facet ( clientFacet ) ! ;
199- const { pos } = update . state . field ( signatureHelpTooltipField ) ;
200- if ( this . lastPos !== pos ) {
201- this . lastPos = pos ;
202- if ( this . lastPos !== - 1 ) {
225+ const { position } = update . state . field ( signatureHelpTooltipField ) ;
226+ if ( ! positionEq ( this . lastPosition , position ) ) {
227+ this . lastPosition = position ;
228+ if ( position !== null ) {
203229 ( async ( ) => {
204230 try {
205231 const result = await client . connection . sendRequest (
206232 SignatureHelpRequest . type ,
207233 {
208234 textDocument : { uri } ,
209- position : offsetToPosition ( state . doc , this . lastPos ) ,
235+ position,
210236 }
211237 ) ;
212238 if ( ! this . destroyed ) {
0 commit comments