Update lsp
This commit is contained in:
parent
11e7c303e3
commit
7b1e9e063e
6
index.ts
6
index.ts
@ -1,6 +1,7 @@
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import process from 'process';
|
import process from 'process';
|
||||||
import { diagnosticsRequests, getDiagnostics, parseLsp } from './parser';
|
import { diagnosticsRequests, getDiagnostics, parseLsp } from './parser';
|
||||||
|
import { add_personal } from './languagetool';
|
||||||
|
|
||||||
if (process.argv.length !== 3) {
|
if (process.argv.length !== 3) {
|
||||||
console.log("Please provide only one pass");
|
console.log("Please provide only one pass");
|
||||||
@ -13,4 +14,7 @@ const res = parseLsp(file);
|
|||||||
|
|
||||||
fs.writeFileSync('./res', res.text);
|
fs.writeFileSync('./res', res.text);
|
||||||
|
|
||||||
console.log((await diagnosticsRequests(res)).map(a => a.replacements));
|
//const diag = await diagnosticsRequests(res);
|
||||||
|
const diag = await getDiagnostics(file);
|
||||||
|
|
||||||
|
//add_personal(['AutoML']);
|
||||||
|
22
languagetool.ts
Normal file
22
languagetool.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
export async function add_personal(words: string[]): Promise<void> {
|
||||||
|
console.log("adding " + JSON.stringify({ words }));
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch('https://api.languagetoolplus.com/enterprise/v1/dictionary/words?type=personal', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'authorization': process.env.AUTHORIZATION ?? '',
|
||||||
|
'content-type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
words
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(await res.text());
|
||||||
|
} catch (e) {
|
||||||
|
console.log("got error:" + e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
169
lsp.ts
169
lsp.ts
@ -1,9 +1,10 @@
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import * as process from 'process';
|
import * as process from 'process';
|
||||||
import { getDiagnostics } from './parser';
|
import { getDiagnostics, type GetDiagnosticsReturn } from './parser';
|
||||||
|
import { add_personal } from './languagetool';
|
||||||
|
|
||||||
export function log(str: string) {
|
export function log(str: string) {
|
||||||
fs.appendFileSync('/home/sylv/latex-lsp/test', str + "\n");
|
fs.appendFileSync('/tmp/latex-lsp-test', str + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function error(str: string) {
|
export function error(str: string) {
|
||||||
@ -26,11 +27,7 @@ type RPCRequest = {
|
|||||||
id: string;
|
id: string;
|
||||||
jsonrpc: string,
|
jsonrpc: string,
|
||||||
method: string,
|
method: string,
|
||||||
params: string,
|
params: any,
|
||||||
}
|
|
||||||
|
|
||||||
type InitRequest = RPCRequest & {
|
|
||||||
method: 'initialize',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ASSUMES that is has the right format
|
// ASSUMES that is has the right format
|
||||||
@ -91,6 +88,15 @@ type TextDocumentCodeAction = RPCRequest & {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type WorkspaceExecuteCommand = RPCRequest & {
|
||||||
|
method: 'workspace/executeCommand',
|
||||||
|
params: {
|
||||||
|
command: string,
|
||||||
|
arguments: any[]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
type Position = {
|
type Position = {
|
||||||
line: number,
|
line: number,
|
||||||
character: number
|
character: number
|
||||||
@ -105,6 +111,7 @@ export type Dialog = {
|
|||||||
range: Range,
|
range: Range,
|
||||||
message: string,
|
message: string,
|
||||||
severity: Severity,
|
severity: Severity,
|
||||||
|
data?: any,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum Severity {
|
export enum Severity {
|
||||||
@ -114,7 +121,36 @@ export enum Severity {
|
|||||||
Hint = 4,
|
Hint = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveRes: Record<string, (Dialog & {replacements: string[]})[]> = { };
|
let lastRequest: null | Date = null;
|
||||||
|
|
||||||
|
const saveRes: Record<string, GetDiagnosticsReturn[]> = {};
|
||||||
|
|
||||||
|
async function request(file: string, uri: string) {
|
||||||
|
if (lastRequest) {
|
||||||
|
if (((new Date()).getTime() - lastRequest.getTime()) <= 60 * 1000) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastRequest = new Date();
|
||||||
|
let diags = await getDiagnostics(file);
|
||||||
|
|
||||||
|
saveRes[uri] = diags;
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
uri: uri,
|
||||||
|
diagnostics: diags.map((a, i) => ({
|
||||||
|
message: a.message,
|
||||||
|
range: a.range,
|
||||||
|
severity: a.severity,
|
||||||
|
data: i,
|
||||||
|
}) as Dialog),
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyRPC('textDocument/publishDiagnostics', params);
|
||||||
|
|
||||||
|
return diags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async function handleJSON(req: RPCRequest) {
|
async function handleJSON(req: RPCRequest) {
|
||||||
log(`New Message entered: method: ${req.method}`);
|
log(`New Message entered: method: ${req.method}`);
|
||||||
@ -131,20 +167,7 @@ async function handleJSON(req: RPCRequest) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const diags = await getDiagnostics(reqO.params.textDocument.text);
|
request(reqO.params.textDocument.text, reqO.params.textDocument.uri);
|
||||||
|
|
||||||
saveRes[reqO.params.textDocument.uri] = diags;
|
|
||||||
|
|
||||||
const params = {
|
|
||||||
uri: reqO.params.textDocument.uri,
|
|
||||||
diagnostics: diags.map(a => ({
|
|
||||||
message: a.message,
|
|
||||||
range: a.range,
|
|
||||||
severity: a.severity,
|
|
||||||
}) as Dialog),
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyRPC('textDocument/publishDiagnostics', params);
|
|
||||||
|
|
||||||
//error(`TODO ${req.method}`);
|
//error(`TODO ${req.method}`);
|
||||||
} else if (req.method === 'textDocument/codeAction') {
|
} else if (req.method === 'textDocument/codeAction') {
|
||||||
@ -153,15 +176,104 @@ async function handleJSON(req: RPCRequest) {
|
|||||||
const diagRecord = saveRes[reqO.params.textDocument.uri];
|
const diagRecord = saveRes[reqO.params.textDocument.uri];
|
||||||
|
|
||||||
if (!diagRecord) {
|
if (!diagRecord) {
|
||||||
|
sendRPCMessage(req, [{
|
||||||
|
title: "File does not seam to be loaded"
|
||||||
|
}]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const saved = saveRes[req.params.textDocument.uri];
|
||||||
|
|
||||||
|
const character = req.params.range.start.character;
|
||||||
|
const line = req.params.range.start.line;
|
||||||
|
|
||||||
|
let item: GetDiagnosticsReturn | undefined = undefined;
|
||||||
|
|
||||||
|
console.log(JSON.stringify(req.params));
|
||||||
|
|
||||||
|
if (!req.params.context?.diagnostics || !req.params.context?.diagnostics[0] || typeof req.params.context?.diagnostics[0].data != 'number') {
|
||||||
|
for (const _item of saved) {
|
||||||
|
if (_item.range.end.line >= line && _item.range.start.line <= line) {
|
||||||
|
if (_item.range.end.character >= character && _item.range.start.character <= line) {
|
||||||
|
item = _item as GetDiagnosticsReturn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("Using " + req.params.context.diagnostics[0].data)
|
||||||
|
item = saved[req.params.context.diagnostics[0].data];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item === undefined) {
|
||||||
sendRPCMessage(req, [{
|
sendRPCMessage(req, [{
|
||||||
title: "No diagnostics found in this file"
|
title: "No diagnostics found in this file"
|
||||||
}]);
|
}]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item.replacements.length === 0) {
|
||||||
|
sendRPCMessage(req, [{
|
||||||
|
title: item.message,
|
||||||
|
}]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const items: {
|
||||||
|
title: string,
|
||||||
|
edit?: {
|
||||||
|
changes: Record<string, { range: Range, newText: string }[]>
|
||||||
|
},
|
||||||
|
command?: {
|
||||||
|
title: string,
|
||||||
|
command: string,
|
||||||
|
arguments?: any[]
|
||||||
|
},
|
||||||
|
}[] = item.replacements.map((value) => (
|
||||||
|
{
|
||||||
|
title: value,
|
||||||
|
edit: {
|
||||||
|
changes: {
|
||||||
|
[reqO.params.textDocument.uri]: [
|
||||||
|
{
|
||||||
|
range: item!.range,
|
||||||
|
newText: value
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
if (item.rule_id.startsWith("MORFOLOGIK_RULE")) {
|
||||||
|
items.push({
|
||||||
|
title: "Add to personal dictinoary",
|
||||||
|
command: {
|
||||||
|
title: "Add to personal dictionary",
|
||||||
|
command: "add_to_dic",
|
||||||
|
arguments: [
|
||||||
|
reqO.params.textDocument.uri,
|
||||||
|
item.word,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sendRPCMessage(req, items);
|
||||||
|
return;
|
||||||
|
} else if (req.method === 'workspace/executeCommand') {
|
||||||
|
let reqO: WorkspaceExecuteCommand = req as any;
|
||||||
|
|
||||||
log(JSON.stringify(req.params));
|
log(JSON.stringify(req.params));
|
||||||
|
|
||||||
error("TODO handle " + req.method);
|
if (reqO.params.command === 'add_to_dic') {
|
||||||
|
if (reqO.params.arguments[0] && reqO.params.arguments[1]) {
|
||||||
|
await add_personal([reqO.params.arguments[1]]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
error(`TODO Handle: ${req.method} ${JSON.stringify(req.params)}`);
|
||||||
} else {
|
} else {
|
||||||
error(`Handle: ${req.method} after init`);
|
error(`Handle: ${req.method} after init`);
|
||||||
}
|
}
|
||||||
@ -181,7 +293,16 @@ async function handleJSON(req: RPCRequest) {
|
|||||||
workspaceDiagnostics: false,
|
workspaceDiagnostics: false,
|
||||||
},
|
},
|
||||||
codeActionProvider: {
|
codeActionProvider: {
|
||||||
codeActionKinds: [ "quickfix" ]
|
codeActionKinds: ["quickfix"],
|
||||||
|
|
||||||
|
resolveSupport: {
|
||||||
|
properties: ["edit"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
executeCommandProvider: {
|
||||||
|
commands: [
|
||||||
|
"add_to_dic"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
serverInfo: {
|
serverInfo: {
|
||||||
|
105
parser.ts
105
parser.ts
@ -1,7 +1,8 @@
|
|||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
import process from 'process';
|
import process from 'process';
|
||||||
import { Severity, type Dialog } from './lsp';
|
import { Severity, type Dialog } from './lsp';
|
||||||
|
import { createSourceFile } from 'typescript';
|
||||||
|
|
||||||
|
|
||||||
type ParseResultConversion = {
|
type ParseResultConversion = {
|
||||||
@ -30,7 +31,8 @@ function parseComment(text: string, curPos: number): number {
|
|||||||
return text.length - curPos;
|
return text.length - curPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createPartition(text: string, startPos: number, curPos: number, result: string): [ParseResultConversion[], string] | null {
|
function createPartition(text: string, startPos: number, curPos: number, result: string, ignoreLast: number = 0): [ParseResultConversion[], string] | null {
|
||||||
|
curPos = curPos - ignoreLast;
|
||||||
if (startPos >= curPos || text.substring(startPos, curPos).match(/^\s*$/)) {
|
if (startPos >= curPos || text.substring(startPos, curPos).match(/^\s*$/)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -74,7 +76,7 @@ function createPartition(text: string, startPos: number, curPos: number, result:
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isChar(charCode: number): boolean {
|
function isChar(charCode: number): boolean {
|
||||||
return (charCode >= 92 && charCode <= 122) || (charCode >= 65 && charCode <= 90);
|
return (charCode >= 92 && charCode <= 122) || (charCode >= 65 && charCode <= 90) || charCode == 42;
|
||||||
}
|
}
|
||||||
function readBalanced(endChar: string, startChar: string, text: string, curPos: number): number {
|
function readBalanced(endChar: string, startChar: string, text: string, curPos: number): number {
|
||||||
let bal = 1;
|
let bal = 1;
|
||||||
@ -104,19 +106,26 @@ function parseCommand(text: string, curPos: number, result: string): [number, Pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (text[curPos + 1] === '\\') {
|
if (text[curPos + 1] === '\\') {
|
||||||
return [1, {
|
return [2, {
|
||||||
length: 1,
|
length: 1,
|
||||||
position: result.length,
|
position: result.length,
|
||||||
original_position: curPos + 1,
|
original_position: curPos + 1,
|
||||||
type: 'text'
|
type: 'text'
|
||||||
}, '\\'];
|
}, '\\'];
|
||||||
} else if (text[curPos + 1] === '%') {
|
} else if (text[curPos + 1] === '%') {
|
||||||
return [1, {
|
return [2, {
|
||||||
length: 1,
|
length: 1,
|
||||||
position: result.length,
|
position: result.length,
|
||||||
original_position: curPos + 1,
|
original_position: curPos + 1,
|
||||||
type: 'text'
|
type: 'text'
|
||||||
}, '%'];
|
}, '%'];
|
||||||
|
} else if (text[curPos + 1] === '_') {
|
||||||
|
return [2, {
|
||||||
|
length: 1,
|
||||||
|
position: result.length,
|
||||||
|
original_position: curPos + 1,
|
||||||
|
type: 'text'
|
||||||
|
}, '_'];
|
||||||
}
|
}
|
||||||
|
|
||||||
let commandName = "";
|
let commandName = "";
|
||||||
@ -166,7 +175,7 @@ function parseCommand(text: string, curPos: number, result: string): [number, Pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log(text.substring(i - 20, i + 20));
|
console.log(text.substring(i - 20, i + 20));
|
||||||
console.log('Char:', char.charCodeAt(0));
|
console.log('Char:' + char.charCodeAt(0));
|
||||||
throw new Error("TODO handle not char chars in the parse command function");
|
throw new Error("TODO handle not char chars in the parse command function");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,6 +184,9 @@ function parseCommand(text: string, curPos: number, result: string): [number, Pa
|
|||||||
throw new Error("Could not end of the command");
|
throw new Error("Could not end of the command");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//console.log("Parsed '" + text.substring(curPos, len) + "'")
|
||||||
|
//console.log("Ranged '" + text.substring(curPos - 5 , len + 5) + "'")
|
||||||
|
|
||||||
len = len - curPos;
|
len = len - curPos;
|
||||||
|
|
||||||
switch (commandName) {
|
switch (commandName) {
|
||||||
@ -195,11 +207,13 @@ function parseCommand(text: string, curPos: number, result: string): [number, Pa
|
|||||||
case 'includegraphics':
|
case 'includegraphics':
|
||||||
case 'appendix':
|
case 'appendix':
|
||||||
case 'printbibliography':
|
case 'printbibliography':
|
||||||
|
case 'subsection*':
|
||||||
|
case 'section*':
|
||||||
return [len];
|
return [len];
|
||||||
case 'title':
|
case 'title':
|
||||||
case 'author':
|
case 'author':
|
||||||
case 'end':
|
case 'end':
|
||||||
console.log("TODO: add way to check the", commandName)
|
console.log("TODO: add way to check the " + commandName)
|
||||||
return [len];
|
return [len];
|
||||||
|
|
||||||
case 'cite':
|
case 'cite':
|
||||||
@ -207,15 +221,49 @@ function parseCommand(text: string, curPos: number, result: string): [number, Pa
|
|||||||
return [len];
|
return [len];
|
||||||
|
|
||||||
case 'begin':
|
case 'begin':
|
||||||
case 'item':
|
|
||||||
console.log("TODO handle", commandName, ":", args)
|
switch (args[0]) {
|
||||||
|
|
||||||
|
case 'verbatim':
|
||||||
|
|
||||||
|
const find = '\end{verbatim}';
|
||||||
|
|
||||||
|
let endPos = text.indexOf(find, curPos) + find.length;
|
||||||
|
|
||||||
|
len = endPos - curPos;
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
console.log("Do not know how to handle " + args[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return [len];
|
return [len];
|
||||||
|
|
||||||
|
case 'item':
|
||||||
|
|
||||||
|
if (args[0]) {
|
||||||
|
return [len, {
|
||||||
|
length: 2 + args[0].length + 1,
|
||||||
|
original_length: len,
|
||||||
|
original_position: curPos + commandName.length,
|
||||||
|
position: result.length,
|
||||||
|
type: 'text'
|
||||||
|
}, "— " + args[0] + '\n'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [len, {
|
||||||
|
length: 2,
|
||||||
|
original_length: len,
|
||||||
|
original_position: curPos,
|
||||||
|
position: result.length,
|
||||||
|
type: 'text'
|
||||||
|
}, "— "];
|
||||||
|
|
||||||
case 'section':
|
case 'section':
|
||||||
return [len, {
|
return [len, {
|
||||||
length: args[0].length + 1,
|
length: args[0].length + 1,
|
||||||
original_length: len,
|
original_length: len,
|
||||||
original_position: curPos - commandName.length,
|
original_position: curPos + 2 + commandName.length,
|
||||||
position: result.length,
|
position: result.length,
|
||||||
type: 'h1',
|
type: 'h1',
|
||||||
}, args[0] + '\n']
|
}, args[0] + '\n']
|
||||||
@ -224,13 +272,13 @@ function parseCommand(text: string, curPos: number, result: string): [number, Pa
|
|||||||
return [len, {
|
return [len, {
|
||||||
length: args[0].length + 1,
|
length: args[0].length + 1,
|
||||||
original_length: len,
|
original_length: len,
|
||||||
original_position: curPos - commandName.length,
|
original_position: curPos + 2 + commandName.length,
|
||||||
position: result.length,
|
position: result.length,
|
||||||
type: 'h2',
|
type: 'h2',
|
||||||
}, args[0] + '\n']
|
}, args[0] + '\n']
|
||||||
|
|
||||||
default:
|
default:
|
||||||
console.log("Command name:", commandName, "options:", options, "args:", args);
|
console.log("Command name: " + commandName + " options: " + options + " args: " + args);
|
||||||
throw new Error("TODO handle this case");
|
throw new Error("TODO handle this case");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,7 +342,6 @@ export function parseLsp(text: string): ParseResult {
|
|||||||
const [len] = res;
|
const [len] = res;
|
||||||
i += len;
|
i += len;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
const [len, conv, toAdd] = res;
|
const [len, conv, toAdd] = res;
|
||||||
|
|
||||||
result.conversions.push(conv);
|
result.conversions.push(conv);
|
||||||
@ -309,7 +356,7 @@ export function parseLsp(text: string): ParseResult {
|
|||||||
throw new Error("Handle double math expression");
|
throw new Error("Handle double math expression");
|
||||||
}
|
}
|
||||||
|
|
||||||
const possiblePartition = createPartition(text, conversionStartPosition, i - 1, result.text);
|
const possiblePartition = createPartition(text, conversionStartPosition, i, result.text);
|
||||||
|
|
||||||
if (possiblePartition) {
|
if (possiblePartition) {
|
||||||
const [conv, toAdd] = possiblePartition;
|
const [conv, toAdd] = possiblePartition;
|
||||||
@ -319,6 +366,18 @@ export function parseLsp(text: string): ParseResult {
|
|||||||
|
|
||||||
const len = readUntil(text, '$', i + 1);
|
const len = readUntil(text, '$', i + 1);
|
||||||
|
|
||||||
|
let to_add = 'mathexpr' + (text[i + len + 1 + 1] === ' ' ? ' ' : '');
|
||||||
|
|
||||||
|
result.conversions = result.conversions.concat(
|
||||||
|
[{
|
||||||
|
length: to_add.length,
|
||||||
|
position: result.text.length,
|
||||||
|
original_position: i,
|
||||||
|
type: 'text',
|
||||||
|
}]
|
||||||
|
);
|
||||||
|
result.text += to_add;
|
||||||
|
|
||||||
i += len + 1;
|
i += len + 1;
|
||||||
|
|
||||||
conversionStartPosition = i + 1;
|
conversionStartPosition = i + 1;
|
||||||
@ -328,6 +387,8 @@ export function parseLsp(text: string): ParseResult {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.text = result.text.replace(/``/g, "''");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,6 +497,7 @@ export async function diagnosticsRequests(res: ParseResult): Promise < Match[] >
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (rawRes.status !== 200) {
|
if (rawRes.status !== 200) {
|
||||||
|
console.log("Error:" + (await (await rawRes.blob()).text()))
|
||||||
process.exit(2);
|
process.exit(2);
|
||||||
}
|
}
|
||||||
const body = await rawRes.json();
|
const body = await rawRes.json();
|
||||||
@ -443,10 +505,14 @@ export async function diagnosticsRequests(res: ParseResult): Promise < Match[] >
|
|||||||
return body.matches;
|
return body.matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDiagnostics(file: string): Promise<(Dialog & {replacements: string[]})[]> {
|
export type GetDiagnosticsReturn = (Dialog & { replacements: string[], rule_id: string, word?: string });
|
||||||
|
|
||||||
|
export async function getDiagnostics(file: string): Promise<GetDiagnosticsReturn[]> {
|
||||||
|
|
||||||
const res = parseLsp(file);
|
const res = parseLsp(file);
|
||||||
|
|
||||||
|
fs.writeFileSync('/tmp/latex-lsp-res', res.text)
|
||||||
|
|
||||||
const matches = await diagnosticsRequests(res);
|
const matches = await diagnosticsRequests(res);
|
||||||
|
|
||||||
const lineIndex = buildLineIndex(file);
|
const lineIndex = buildLineIndex(file);
|
||||||
@ -460,6 +526,13 @@ export async function getDiagnostics(file: string): Promise<(Dialog & {replaceme
|
|||||||
console.log("Could not find the original position")
|
console.log("Could not find the original position")
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let word: string | undefined = undefined;
|
||||||
|
|
||||||
|
if (match.rule.id.startsWith("MORFOLOGIK_RULE")) {
|
||||||
|
word = file.substring(original_position, original_position + match.length);
|
||||||
|
}
|
||||||
|
|
||||||
const [startLine, startChar] = getLineAndChar(lineIndex, original_position);
|
const [startLine, startChar] = getLineAndChar(lineIndex, original_position);
|
||||||
const [endLine, endChar] = getLineAndChar(lineIndex, original_position + match.length);
|
const [endLine, endChar] = getLineAndChar(lineIndex, original_position + match.length);
|
||||||
|
|
||||||
@ -473,6 +546,8 @@ export async function getDiagnostics(file: string): Promise<(Dialog & {replaceme
|
|||||||
severity: Severity.Error,
|
severity: Severity.Error,
|
||||||
message: match.message,
|
message: match.message,
|
||||||
replacements: match.replacements.map(a => a.value),
|
replacements: match.replacements.map(a => a.value),
|
||||||
|
rule_id: match.rule.id,
|
||||||
|
word,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user