Copy code actions from old extension (until we have proper support)
This commit is contained in:
5
Makefile
5
Makefile
@@ -39,9 +39,14 @@ aoctest: newt.js
|
|||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
|
|
||||||
|
# build / install old vscode extension
|
||||||
vscode:
|
vscode:
|
||||||
cd newt-vscode && vsce package && code --install-extension *.vsix
|
cd newt-vscode && vsce package && code --install-extension *.vsix
|
||||||
|
|
||||||
|
# build / install new LSP vscode extension
|
||||||
|
vscode-lsp:
|
||||||
|
cd newt-vscode-lsp && vsce package && code --install-extension *.vsix
|
||||||
|
|
||||||
playground: .PHONY
|
playground: .PHONY
|
||||||
cd playground && ./build
|
cd playground && ./build
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ import {
|
|||||||
TransportKind
|
TransportKind
|
||||||
} from 'vscode-languageclient/node';
|
} from 'vscode-languageclient/node';
|
||||||
|
|
||||||
|
function getIndent(text: string) {
|
||||||
|
return text.match(/\S/)?.index ?? 0
|
||||||
|
}
|
||||||
|
|
||||||
// They put this at module level for deactivate below.
|
// They put this at module level for deactivate below.
|
||||||
let client: LanguageClient
|
let client: LanguageClient
|
||||||
|
|
||||||
@@ -86,6 +90,84 @@ 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;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user