Reduce hint size for in intellisense signature requests (#2489)

This commit is contained in:
Jonatan Kłosko 2024-02-16 21:17:49 +01:00 committed by GitHub
parent bfc6ae7f04
commit 26d73af7e5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 61 additions and 13 deletions

View file

@ -52,6 +52,7 @@ import CollabClient from "./live_editor/collab_client";
import { languages } from "./live_editor/codemirror/languages";
import { exitMulticursor } from "./live_editor/codemirror/commands";
import { highlight } from "./live_editor/highlight";
import { ancestorNode, closestNode } from "./live_editor/codemirror/tree_utils";
/**
* Mounts cell source editor with real-time collaboration mechanism.
@ -513,7 +514,7 @@ export default class LiveEditor {
/** @private */
signatureSource({ state, pos }) {
const textUntilCursor = state.doc.sliceString(0, pos);
const textUntilCursor = this.getSignatureHint(state, pos);
return this.connection
.intellisenseRequest("signature", {
@ -528,6 +529,33 @@ export default class LiveEditor {
.catch(() => null);
}
/** @private */
getSignatureHint(state, pos) {
// By default we send all text until cursor as signature hint.
// We use the local AST to limit the hint to the relevanat call
// expression.
const tree = syntaxTree(state);
const node = tree.resolve(pos);
if (node && this.language === "elixir") {
let callNode = closestNode(node, [
"Call",
"FunctionDefinitionCall",
"KernelCall",
]);
if (callNode) {
const pipeNode = ancestorNode(callNode, ["Right", "PipeOperator"]);
const boundaryNode = pipeNode || callNode;
return state.doc.sliceString(boundaryNode.from, pos);
}
}
return state.doc.sliceString(0, pos);
}
formatterSource(doc) {
return this.connection
.intellisenseRequest("format", { code: doc.toString() })
@ -560,15 +588,3 @@ export default class LiveEditor {
this.initialWidgets = {};
}
}
function closestNode(node, names) {
while (node) {
if (names.includes(node.type.name)) {
return node;
}
node = node.parent;
}
return null;
}

View file

@ -0,0 +1,32 @@
/**
* Finds the closest node with the given name (parent or self).
*/
export function closestNode(node, names) {
while (node) {
if (names.includes(node.type.name)) return node;
node = node.parent;
}
return null;
}
/**
* Goes up the tree using the given path.
*
* Path is a list of parent node names, from innermost to outermost.
* Returns the alst node on the path, but only if the path matches
* exactly.
*/
export function ancestorNode(node, path) {
let i = 0;
while (i < path.length && node.parent) {
if (node.parent.type.name !== path[i]) return null;
node = node.parent;
i++;
}
return i === path.length && node ? node : null;
}