Skip to content

Commit b7d5667

Browse files
Calculate line/column immediately
I'm not sure this is necessary but it feels obviously correct / straightforward which is a win in this code.
1 parent 1f3d6f6 commit b7d5667

File tree

1 file changed

+36
-10
lines changed

1 file changed

+36
-10
lines changed

src/editor/codemirror/language-server/signatureHelp.ts

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
import { IntlShape } from "react-intl";
2323
import {
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+
84105
const 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

Comments
 (0)