add missing and case split for lsp

This commit is contained in:
2026-02-17 22:01:58 -08:00
parent fa0eb3a26d
commit cd31156404
13 changed files with 238 additions and 142 deletions

View File

@@ -90,86 +90,6 @@ export function activate(context: vscode.ExtensionContext) {
}
}
});
// HACK Temporarily copied from non-LSP version, until code actions are implemented
context.subscriptions.push(
vscode.languages.registerCodeActionsProvider(
{ language: "newt" },
{
provideCodeActions(document, range, context, token) {
const actions: vscode.CodeAction[] = [];
for (const diagnostic of context.diagnostics) {
let {message,range} = diagnostic;
let m = message.match(/missing cases: \[(.*)\]/);
if (m) {
// A lot of this logic would also apply to case split.
let cons = m[1].split(', ');
let line = range.start.line;
let lineText = document.lineAt(line).text;
// this isn't going to work for let.
// and I think I relaxed the indent for `|`
const indent = getIndent(lineText)
let m2 = lineText.match(/(.*=>?)/);
if (!m2) continue;
let s = range.start.character;
let e = range.end.character;
let a = lineText.slice(0,s);
let b = lineText.slice(e,m2[0].length);
let parens = a.endsWith('(') && b.startsWith(')');
let lines = cons.map(con =>
!parens && con.includes('_')
? `${a}(${con})${b} ?`
: `${a}${con}${b} ?`);
const fix = new vscode.CodeAction(
"Add missing cases",
vscode.CodeActionKind.QuickFix
);
fix.edit = new vscode.WorkspaceEdit();
// skip indented lines
while (1) {
line = line + 1
lineText = document.lineAt(line).text
if (!lineText.trim() || getIndent(lineText) <= indent) break
}
const insertPos = new vscode.Position(line, 0);
let text = lines.join('\n') + '\n';
if (insertPos.line === document.lineCount) {
text = "\n" + text;
}
fix.edit.insert(document.uri, insertPos, text);
fix.diagnostics = [diagnostic];
fix.isPreferred = true;
actions.push(fix);
}
m = message.match(/try importing: (.*)/);
if (m) {
let mods = m[1].split(', ')
let insertLine = 0;
for (let i = 0; i < document.lineCount; i++) {
const line = document.lineAt(i).text;
if (/^(import|module)\b/.test(line)) insertLine = i + 1;
}
const insertPos = new vscode.Position(insertLine, 0);
for (let mod of mods) {
const fix = new vscode.CodeAction(
`Import ${mod}`,
vscode.CodeActionKind.QuickFix
);
fix.edit = new vscode.WorkspaceEdit();
fix.edit.insert(document.uri, insertPos, `import ${mod}\n`);
fix.diagnostics = [diagnostic];
// fix.isPreferred = true; // they're all preferred?
actions.push(fix);
}
}
}
return actions;
}
}
)
);
return;
}
export function deactivate() {

View File

@@ -5,7 +5,7 @@
* vscode LSP server module.
*/
import { LSP_checkFile, LSP_updateFile, LSP_hoverInfo } from './newt.js'
import { LSP_checkFile, LSP_updateFile, LSP_hoverInfo, LSP_codeActionInfo } from './newt.js'
import {
createConnection,
@@ -105,14 +105,21 @@ connection.onDefinition((params): Location | null => {
return value.location
})
connection.onCodeAction(({textDocument, range}) => {
let actions = LSP_codeActionInfo(textDocument.uri, range.start.line, range.start.character);
console.log('ACTIONS is ', JSON.stringify(actions,null,' '))
return actions
})
connection.onInitialize((_params: InitializeParams): InitializeResult => ({
capabilities: {
textDocumentSync: TextDocumentSyncKind.Incremental,
hoverProvider: true,
definitionProvider: true,
codeActionProvider: true,
},
}));
documents.listen(connection);
connection.listen();
console.log('STARTED')
console.log('STARTED')

View File

@@ -1,4 +1,4 @@
import { Diagnostic, Location } from "vscode-languageserver";
import { CodeAction, Diagnostic, Location } from "vscode-languageserver";
export function LSP_updateFile(name: string, content: string): (eta: any) => any;
export function LSP_checkFile(name: string): Diagnostic[];
@@ -7,3 +7,4 @@ interface HoverResult {
location: Location
}
export function LSP_hoverInfo(name: string, row: number, col: number): HoverResult|null;
export function LSP_codeActionInfo(name: string, row: number, col: number): CodeAction[]|null;