diff --git a/src/calva-fmt/src/format.ts b/src/calva-fmt/src/format.ts index af4076f77..ec3674410 100644 --- a/src/calva-fmt/src/format.ts +++ b/src/calva-fmt/src/format.ts @@ -15,13 +15,13 @@ const FormatDepthDefaults = { defprotocol: 2, }; -export async function indentPosition(position: vscode.Position, document: vscode.TextDocument) { +export /*async*/ function indentPosition(position: vscode.Position, document: vscode.TextDocument) { const editor = util.getActiveTextEditor(); const pos = new vscode.Position(position.line, 0); const indent = getIndent( getDocument(document).model.lineInputModel, getDocumentOffset(document, position), - await config.getConfig(document) + config.getConfig(document) ); const newPosition = new vscode.Position(position.line, indent); const delta = document.lineAt(position.line).firstNonWhitespaceCharacterIndex - indent; @@ -97,7 +97,7 @@ export async function formatRange(document: vscode.TextDocument, range: vscode.R return vscode.workspace.applyEdit(wsEdit); } -export async function formatPositionInfo( +export /*async*/ function formatPositionInfo( editor: vscode.TextEditor, onType: boolean = false, extraConfig: CljFmtConfig = {} @@ -122,7 +122,7 @@ export async function formatPositionInfo( _convertEolNumToStringNotation(doc.eol), onType, { - ...(await config.getConfig()), + ...config.getConfig(), ...extraConfig, 'comment-form?': cursor.getFunctionName() === 'comment', } @@ -207,7 +207,7 @@ export async function formatPosition( extraConfig: CljFmtConfig = {} ): Promise { const doc: vscode.TextDocument = editor.document, - formattedInfo = await formatPositionInfo(editor, onType, extraConfig); + formattedInfo = formatPositionInfo(editor, onType, extraConfig); if (formattedInfo && formattedInfo.previousText != formattedInfo.formattedText) { return editor .edit( @@ -262,11 +262,11 @@ export function trimWhiteSpacePositionCommand(editor: vscode.TextEditor) { void formatPosition(editor, false, { 'remove-multiple-non-indenting-spaces?': true }); } -export async function formatCode(code: string, eol: number) { +export /*async*/ function formatCode(code: string, eol: number) { const d = { 'range-text': code, eol: _convertEolNumToStringNotation(eol), - config: await config.getConfig(), + config: config.getConfig(), }; const result = jsify(formatText(d)); if (!result['error']) { @@ -277,7 +277,7 @@ export async function formatCode(code: string, eol: number) { } } -async function _formatRange( +/*async*/ function _formatRange( rangeText: string, allText: string, range: number[], @@ -288,7 +288,7 @@ async function _formatRange( 'all-text': allText, range: range, eol: eol, - config: await config.getConfig(), + config: config.getConfig(), }; const result = jsify(formatTextAtRange(d)); if (!result['error']) { diff --git a/src/formatter-config.ts b/src/formatter-config.ts index 4c780c79a..d0a6a786d 100644 --- a/src/formatter-config.ts +++ b/src/formatter-config.ts @@ -40,28 +40,52 @@ function getConfigPath(workspaceConfig: vscode.WorkspaceConfiguration): string | export type FormatterConfig = Partial>>; -export async function getConfig( +let cachedLspConfig = undefined; + +async function getAndCacheLspConfig(documentUri: vscode.Uri) { + const clientProvider = lsp.getClientProvider(); + const client = clientProvider.getClientForDocumentUri(documentUri); + if (client && client.isRunning) { + lspFormatConfig = await lsp.api.getCljFmtConfig(client); + if (lspFormatConfig) { + cachedLspConfig = lspFormatConfig; + } else { + console.error( + 'Fetching formatting settings from clojure-lsp failed. Check that you are running a version of clojure-lsp that provides "cljfmt-raw" in serverInfo.' + ); + } + return lspFormatConfig; + } +} + +function getCachedLspConfig(documentUri: vscode.Uri) { + // The Uri ensures LSP config could be cached per-document, if that were necessary. + if (cachedLspConfig) { + return cachedLspConfig; + } else { + console.log( + 'LSP config is not cached yet, but I will get right on it. Try again in a little while.' + ); + void getAndCacheLspConfig(documentUri); + return {}; + } +} + +// To enable synchronous commands to get an instant configuration, +// might return undefined for LSP-based members until background query completes. +export function getConfig( document: vscode.TextDocument = vscode.window.activeTextEditor?.document -): Promise<{ +): { 'format-as-you-type': boolean; 'keep-comment-forms-trail-paren-on-own-line?': boolean; 'cljfmt-options-string': string; 'cljfmt-options': object; -}> { +} { const workspaceConfig = vscode.workspace.getConfiguration('calva.fmt'); const configPath: string | undefined = getConfigPath(workspaceConfig); if (configPath === LSP_CONFIG_KEY && document) { - const clientProvider = lsp.getClientProvider(); - const client = clientProvider.getClientForDocumentUri(document.uri); - if (client && client.isRunning) { - lspFormatConfig = await lsp.api.getCljFmtConfig(client); - if (!lspFormatConfig) { - console.error( - 'Fetching formatting settings from clojure-lsp failed. Check that you are running a version of clojure-lsp that provides "cljfmt-raw" in serverInfo.' - ); - } - } + lspFormatConfig = getCachedLspConfig(document.uri); } const cljfmtContent: string | undefined = configPath === LSP_CONFIG_KEY diff --git a/src/paredit/extension.ts b/src/paredit/extension.ts index b1b8f8073..4c1a99f76 100644 --- a/src/paredit/extension.ts +++ b/src/paredit/extension.ts @@ -453,7 +453,7 @@ const pareditCommands = [ { command: 'paredit.deleteBackward', handler: async (doc: EditableDocument) => { - await paredit.backspace(doc, await config.getConfig()); + await paredit.backspace(doc, config.getConfig()); }, }, {