-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhance LSP for multi-editor support #38
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,44 @@ | ||
import * as prettier from 'prettier'; | ||
import { workspace, ExtensionContext, Range, TextDocument, TextEdit } from 'vscode'; | ||
import * as path from 'path'; | ||
import { TextEdit, Range } from 'vscode-languageserver-types'; | ||
import { TextDocument } from 'vscode-languageserver-textdocument'; | ||
|
||
export function formatDocument(document: TextDocument, context: ExtensionContext): TextEdit[] | undefined { | ||
const rootPath = workspace.getWorkspaceFolder(document.uri)?.name; | ||
|
||
const ignoreOptions = { ignorePath: path.join(rootPath ? rootPath: "", '.prettierignore') }; | ||
|
||
const fileInfo = prettier.getFileInfo.sync(document.uri.fsPath, ignoreOptions); | ||
|
||
if (!fileInfo.ignored) { | ||
const source = document.getText(); | ||
// @TODO create npm module later | ||
const pluginPath = path.join(context.extensionPath, 'out', 'prettier-plugin-tact', 'prettier-plugin-tact.js'); // 'node_modules', | ||
const options = { | ||
export function formatDocument(document: TextDocument, rootPath: string): TextEdit[] | undefined { | ||
|
||
if (rootPath) { | ||
const ignoreOptions = { ignorePath: path.join(rootPath, '.prettierignore') }; | ||
const fileInfo = prettier.getFileInfo.sync(document.uri, ignoreOptions); | ||
if (fileInfo.ignored) return; | ||
} | ||
|
||
const lspPath = __dirname; | ||
|
||
const source = document.getText(); | ||
// @TODO create npm module later | ||
const pluginPath = path.join(lspPath, 'prettier-plugin-tact', 'prettier-plugin-tact.js'); // 'node_modules', | ||
const options = { | ||
'parser': 'tact-parser', | ||
'pluginSearchDirs': [context.extensionPath], | ||
'pluginSearchDirs': [lspPath], | ||
'plugins': [pluginPath], | ||
}; | ||
// | ||
const config = prettier.resolveConfig.sync(document.uri.fsPath); | ||
if (config !== null) { | ||
}; | ||
|
||
const config = prettier.resolveConfig.sync(document.uri); | ||
|
||
if (config !== null) { | ||
prettier.clearConfigCache(); | ||
} | ||
Object.assign(options, config); | ||
|
||
const firstLine = document.lineAt(0); | ||
const lastLine = document.lineAt(document.lineCount - 1); | ||
const fullTextRange = new Range(firstLine.range.start, lastLine.range.end); | ||
let formatted = ""; | ||
try { | ||
} | ||
Object.assign(options, config); | ||
|
||
const startIndex = document.positionAt(0); | ||
const endIndex = document.positionAt(document.getText().length); | ||
|
||
const fullTextRange = Range.create(startIndex, endIndex); | ||
let formatted = ""; | ||
try { | ||
formatted = prettier.format(source, options); | ||
} catch(e) { | ||
} catch (e) { | ||
formatted = source; | ||
console.log(e); | ||
} | ||
return [TextEdit.replace(fullTextRange, formatted)]; | ||
} | ||
return [TextEdit.replace(fullTextRange, formatted)]; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ import { HoverService } from './hoverService'; | |
import { RefactorService } from './refactorService'; | ||
import { TactCompiler } from './tactCompiler'; | ||
import { URI } from 'vscode-uri'; | ||
import { formatDocument } from './formatter'; | ||
|
||
interface Settings { | ||
tact: TactSettings; | ||
|
@@ -40,7 +41,7 @@ const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument); | |
let rootPath: string | undefined; | ||
let tactCompiler: TactCompiler; | ||
|
||
let enabledAsYouTypeErrorCheck = false; | ||
let enabledAsYouTypeErrorCheck = true; | ||
let validationDelay = 1500; | ||
|
||
// flags to avoid trigger concurrent validations (compiling is slow) | ||
|
@@ -68,12 +69,12 @@ async function validate(document: TextDocument) { | |
let newDocumentsWithErrors: any = []; | ||
for (let fileName in compileErrorDiagnostics) { | ||
newDocumentsWithErrors.push(URI.file(fileName).path); | ||
connection.sendDiagnostics({diagnostics: compileErrorDiagnostics[fileName], uri: URI.file(fileName).path}); | ||
connection.sendDiagnostics({diagnostics: compileErrorDiagnostics[fileName], uri: "file://"+URI.file(fileName).path}); | ||
} | ||
let difference = documentsWithErrors.filter((x: any) => !newDocumentsWithErrors.includes(x)); | ||
// if an error is resolved, we must to send empty diagnostics for the URI contained it; | ||
for(let item in difference) { | ||
connection.sendDiagnostics({diagnostics: [], uri: difference[item]}); | ||
connection.sendDiagnostics({diagnostics: [], uri: "file://"+difference[item]}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as "file://" above. |
||
} | ||
documentsWithErrors = newDocumentsWithErrors; | ||
} | ||
|
@@ -213,7 +214,8 @@ connection.onInitialize((result): InitializeResult => { | |
codeActionProvider: { | ||
resolveProvider: true | ||
}, | ||
textDocumentSync: TextDocumentSyncKind.Full, | ||
documentFormattingProvider: true, | ||
textDocumentSync: TextDocumentSyncKind.Incremental, | ||
}, | ||
}; | ||
}); | ||
|
@@ -250,6 +252,14 @@ connection.onRenameRequest((params) => { | |
return provider.rename(documents.get(params.textDocument.uri) as TextDocument, params.position, params.newName); | ||
}); | ||
|
||
connection.onDocumentFormatting((params) => { | ||
const document = documents.get(params.textDocument.uri); | ||
if (document == undefined) { | ||
return []; | ||
} | ||
return formatDocument(document as any, rootPath as string); | ||
}); | ||
|
||
// Make the text document manager listen on the connection | ||
// for open, change and close text document events | ||
documents.listen(connection); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,14 +39,23 @@ export class TactCompiler { | |
} | ||
|
||
const pathKey = path.relative( this.rootPath, args.file).replaceAll('\\','/'); | ||
|
||
let rootPath = this.rootPath; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we change There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes that would be a better. |
||
|
||
// If the root path is not set, which occurs when a single file is opened separately, set the root path to the directory containing the file. | ||
if(!this.isRootPathSet()) { | ||
rootPath = path.dirname(args.file); | ||
} | ||
|
||
const pathContent = fs.readFileSync(pathKey); | ||
const fsObject = {} as any; | ||
fsObject[pathKey] = pathContent.toString('base64'); | ||
for (let pathKey in args.sources) { | ||
fsObject[path.relative( this.rootPath, pathKey).replaceAll('\\','/')] = Buffer.from(args.sources[pathKey].content).toString('base64'); | ||
const fileContent = args.sources[pathKey].content || args.sources[pathKey]; | ||
fsObject[path.relative( rootPath, pathKey).replaceAll('\\','/')] = Buffer.from(fileContent).toString('base64'); | ||
} | ||
const result: CheckResult = check({ project: createVirtualFileSystem(path.resolve(this.rootPath).replaceAll('\\','/'), fsObject), | ||
entrypoint: path.relative( this.rootPath, args.file).replaceAll('\\','/') | ||
const result: CheckResult = check({ project: createVirtualFileSystem(path.resolve(rootPath).replaceAll('\\','/'), fsObject), | ||
entrypoint: path.relative( rootPath, args.file).replaceAll('\\','/') | ||
}); | ||
return result; | ||
} | ||
|
@@ -92,4 +101,4 @@ export class TactCompiler { | |
return []; | ||
} | ||
|
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure about this. Will it work for web version? What for should we need add "file://"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the web version, similar to the Monaco editor, a few additional changes are required. I'll push those by this weekend.