-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #38 from chrispahm/add-lsp-features
fAdd lsp features
- Loading branch information
Showing
11 changed files
with
269 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
src/provideGAMSCompletionItems.js → src/lsp/gmsCompletionItemsProvider.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
const vscode = require("vscode"); | ||
|
||
module.exports = function gmsDeclarationProvider(document, position, state) { | ||
// get the word at the current position | ||
const wordRange = document.getWordRangeAtPosition(position); | ||
const word = document.getText(wordRange); | ||
const referenceTree = state.get("referenceTree"); | ||
let matchingRef = referenceTree?.find( | ||
(item) => item.name?.toLowerCase() === word?.toLowerCase() | ||
); | ||
|
||
if (matchingRef && matchingRef.declared) { | ||
const { file, line, column } = matchingRef.declared; | ||
const uri = vscode.Uri.file(file); | ||
return new vscode.Location(uri, new vscode.Position(line - 1, column - 1)); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
const vscode = require("vscode"); | ||
|
||
module.exports = function gmsDefinitionProvider(document, position, state) { | ||
// get the word at the current position | ||
const wordRange = document.getWordRangeAtPosition(position); | ||
const word = document.getText(wordRange); | ||
const referenceTree = state.get("referenceTree"); | ||
let matchingRef = referenceTree?.find( | ||
(item) => item.name?.toLowerCase() === word?.toLowerCase() | ||
); | ||
|
||
if (matchingRef && matchingRef.defined) { | ||
const { file, line, column } = matchingRef.defined; | ||
const uri = vscode.Uri.file(file); | ||
return new vscode.Location(uri, new vscode.Position(line-1, column-1)); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
const vscode = require("vscode"); | ||
|
||
function createDocumentSymbol(symbol, detail) { | ||
let symbolKind = vscode.SymbolKind.Variable; | ||
if (symbol.type === "SET") { | ||
symbolKind = vscode.SymbolKind.Array; | ||
} else if (symbol.type === "EQU") { | ||
symbolKind = vscode.SymbolKind.Function; | ||
} else if (symbol.type === "PARAM") { | ||
symbolKind = vscode.SymbolKind.Constant; | ||
} else if (symbol.type === "MODEL") { | ||
symbolKind = vscode.SymbolKind.Class; | ||
} | ||
const symbolRange = new vscode.Range( | ||
new vscode.Position(symbol.line-1, symbol.column-1), | ||
new vscode.Position(symbol.line-1, symbol.column) | ||
); | ||
return new vscode.DocumentSymbol( | ||
symbol.name, | ||
detail, | ||
symbolKind, | ||
symbolRange, | ||
symbolRange | ||
); | ||
} | ||
|
||
// Implements "go to document symbols" | ||
module.exports = function gmsDocumentSymbolsProvider(document, state) { | ||
const referenceTree = state.get("referenceTree"); | ||
const symbolsInFile = referenceTree.reduce((acc, symbol) => { | ||
// check if the smybol is declared, defined, references or assigned | ||
// in this file | ||
if (!symbol || !symbol.name) return acc; | ||
const { declared, defined, ref, assigned } = symbol; | ||
if (declared?.file === document.fileName) { | ||
// add to symbols | ||
acc.push(createDocumentSymbol(symbol, "declared")); | ||
} | ||
if (defined?.file === document.fileName) { | ||
// add to symbols | ||
acc.push(createDocumentSymbol(symbol, "defined")); | ||
} | ||
ref?.forEach((ref) => { | ||
if (ref.file === document.fileName) { | ||
// add to symbols | ||
acc.push(createDocumentSymbol(symbol, "referenced")); | ||
} | ||
}); | ||
assigned?.forEach((ref) => { | ||
if (ref.file === document.fileName) { | ||
// add to symbols | ||
acc.push(createDocumentSymbol(symbol, "assigned")); | ||
} | ||
}); | ||
|
||
return acc; | ||
}, []); | ||
return symbolsInFile; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
const vscode = require("vscode"); | ||
|
||
module.exports = function gmsHoverProvider(document, position, state) { | ||
// get the word at the current position | ||
const wordRange = document.getWordRangeAtPosition(position); | ||
const word = document.getText(wordRange); | ||
const referenceTree = state.get("referenceTree"); | ||
let matchingRef = referenceTree?.find( | ||
(item) => item.name?.toLowerCase() === word?.toLowerCase() | ||
); | ||
|
||
if (matchingRef) { | ||
let hoverContent = new vscode.MarkdownString(`(${matchingRef.type.toLowerCase()}) **${matchingRef.name}**${matchingRef.description ? "\n\n" + matchingRef.description : ""}`); | ||
if (matchingRef.domain) { | ||
hoverContent = new vscode.MarkdownString(`(${matchingRef.type.toLowerCase()}) **${matchingRef.name}**(${matchingRef.domain.map(d => d.name).join(", ")})${matchingRef.description ? "\n\n" + matchingRef.description : ""}`); | ||
} | ||
return new vscode.Hover( | ||
hoverContent, | ||
wordRange | ||
); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
const vscode = require("vscode"); | ||
|
||
// Implements "go to implementations" | ||
module.exports = function gmsReferenceProvider(document, position, state) { | ||
// get the word at the current position | ||
const wordRange = document.getWordRangeAtPosition(position); | ||
const word = document.getText(wordRange); | ||
const referenceTree = state.get("referenceTree"); | ||
let matchingRef = referenceTree?.find( | ||
(item) => item.name?.toLowerCase() === word?.toLowerCase() | ||
); | ||
|
||
if (matchingRef && matchingRef.assigned) { | ||
return matchingRef.assigned.map((ref) => { | ||
const { file, line, column } = ref; | ||
const uri = vscode.Uri.file(file); | ||
return new vscode.Location(uri, new vscode.Position(line-1, column-1)); | ||
}); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
const vscode = require("vscode"); | ||
|
||
// Implements "go to references" | ||
module.exports = function gmsReferenceProvider(document, position, state) { | ||
// get the word at the current position | ||
const wordRange = document.getWordRangeAtPosition(position); | ||
const word = document.getText(wordRange); | ||
const referenceTree = state.get("referenceTree"); | ||
let matchingRef = referenceTree?.find( | ||
(item) => item.name?.toLowerCase() === word?.toLowerCase() | ||
); | ||
|
||
if (matchingRef && matchingRef.ref) { | ||
return matchingRef.ref.map((ref) => { | ||
const { file, line, column } = ref; | ||
const uri = vscode.Uri.file(file); | ||
return new vscode.Location(uri, new vscode.Position(line-1, column-1)); | ||
}); | ||
} | ||
}; |
2 changes: 1 addition & 1 deletion
2
src/provideGAMSSignatureHelp.js → src/lsp/gmsSignatureHelpProvider.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
const vscode = require("vscode"); | ||
const gmsDeclarationProvider = require("./gmsDeclarationProvider.js"); | ||
const gmsDefinitionProvider = require("./gmsDefinitionProvider.js"); | ||
const gmsHoverProvider = require("./gmsHoverProvider.js"); | ||
const gmsReferenceProvider = require("./gmsReferenceProvider.js"); | ||
const gmsImplementationProvider = require("./gmsImplementationProvider.js"); | ||
const gmsDocumentSymbolsProvider = require("./gmsDocumentSymbolsProvider.js"); | ||
const gmsCompletionItemsProvider = require("./gmsCompletionItemsProvider.js"); | ||
const gmsSignatureHelpProvider = require("./gmsSignatureHelpProvider.js"); | ||
|
||
module.exports = function implementLSPMethods(context, state) { | ||
// Register the GAMS declaration provider | ||
context.subscriptions.push( | ||
vscode.languages.registerDeclarationProvider( | ||
{ scheme: "file", language: "gams" }, | ||
{ | ||
provideDeclaration: (document, position) => { | ||
return gmsDeclarationProvider(document, position, state); | ||
}, | ||
} | ||
) | ||
); | ||
|
||
// Register the GAMS definition provider | ||
context.subscriptions.push( | ||
vscode.languages.registerDefinitionProvider( | ||
{ scheme: "file", language: "gams" }, | ||
{ | ||
provideDefinition: (document, position) => { | ||
return gmsDefinitionProvider(document, position, state); | ||
}, | ||
} | ||
) | ||
); | ||
|
||
// Register the GAMS hover provider | ||
context.subscriptions.push( | ||
vscode.languages.registerHoverProvider( | ||
{ scheme: "file", language: "gams" }, | ||
{ | ||
provideHover: (document, position) => { | ||
return gmsHoverProvider(document, position, state); | ||
}, | ||
} | ||
) | ||
); | ||
|
||
// Register the GAMS reference provider | ||
context.subscriptions.push( | ||
vscode.languages.registerReferenceProvider( | ||
{ scheme: "file", language: "gams" }, | ||
{ | ||
provideReferences: (document, position) => { | ||
return gmsReferenceProvider(document, position, state); | ||
}, | ||
} | ||
) | ||
); | ||
|
||
// Register the GAMS implementation provider | ||
context.subscriptions.push( | ||
vscode.languages.registerImplementationProvider( | ||
{ scheme: "file", language: "gams" }, | ||
{ | ||
provideImplementation: (document, position) => { | ||
return gmsImplementationProvider(document, position, state); | ||
}, | ||
} | ||
) | ||
); | ||
|
||
// Register the GAMS document symbol provider | ||
/* | ||
TODO: VSCode seems to query symbols quite often, so this can be | ||
a performance bottleneck. Caching symbols may not make sense, as they have | ||
to be re-calculated when the source code changes. | ||
context.subscriptions.push( | ||
vscode.languages.registerDocumentSymbolProvider( | ||
{ scheme: "file", language: "gams" }, | ||
{ | ||
provideDocumentSymbols: (document) => { | ||
return gmsDocumentSymbolsProvider(document, state); | ||
}, | ||
} | ||
) | ||
); | ||
*/ | ||
// provide auto-completeion | ||
context.subscriptions.push( | ||
vscode.languages.registerCompletionItemProvider("gams", { | ||
provideCompletionItems(document, position) { | ||
return gmsCompletionItemsProvider(document, position, state); | ||
} | ||
}, " ", ",", "(", "[", "{", ":", ">", "<", "=", "+", "-", "*", "/", "^", "!", "&", "|", ">", "<", "\t") | ||
); | ||
|
||
// provide signature help | ||
context.subscriptions.push( | ||
vscode.languages.registerSignatureHelpProvider("gams", { | ||
provideSignatureHelp(document, position) { | ||
return gmsSignatureHelpProvider(document, position, state); | ||
} | ||
}, "(", ",") | ||
); | ||
}; |