Skip to content

Commit

Permalink
v2.3.9
Browse files Browse the repository at this point in the history
  • Loading branch information
RobertOstermann committed Jul 27, 2023
1 parent f08231e commit 0c90d49
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 36 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

All notable changes to the "sqlfluff" extension will be documented in this file.

Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
## [2.3.9] - 2023-07-26

- Update the `sqlfluff.format.languages` to accept objects containing formatting settings for the languages to address this [Feature Request](https://github.com/sqlfluff/vscode-sqlfluff/issues/94)
- Format selection now can format while preserving the whitespace (based on first line)
- `SQLFluff Format Selection` now can be placed in the context menu.

## [2.3.8] - 2023-07-16

Expand Down
52 changes: 47 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "vscode-sqlfluff",
"displayName": "sqlfluff",
"version": "2.3.8",
"version": "2.3.9",
"description": "A linter and auto-formatter for SQLfluff, a popular linting tool for SQL and dbt.",
"publisher": "dorzey",
"icon": "images/icon.png",
Expand Down Expand Up @@ -38,17 +38,22 @@
{
"command": "sqlfluff.debug",
"title": "SQLFluff Debug Extension",
"when": "extensionLangId == sql || extensionLangId == sql-bigquery || extensionLangId == jinja-sql || extensionLangId == postgres || extensionLangId == snowflake-sql"
"enablement": "editorLangId in sqlfluff.formatLanguages"
},
{
"command": "sqlfluff.fix",
"title": "SQLFluff Fix",
"when": "extensionLangId == sql || extensionLangId == sql-bigquery || extensionLangId == jinja-sql || extensionLangId == postgres || extensionLangId == snowflake-sql"
"enablement": "editorLangId in sqlfluff.formatLanguages"
},
{
"command": "sqlfluff.format.selection",
"title": "SQLFluff Format Selection",
"enablement": "editorLangId in sqlfluff.formatLanguages && editorHasSelection"
},
{
"command": "sqlfluff.lint",
"title": "SQLFluff Lint",
"when": "extensionLangId == sql || extensionLangId == sql-bigquery || extensionLangId == jinja-sql || extensionLangId == postgres || extensionLangId == snowflake-sql"
"enablement": "editorLangId in sqlfluff.formatLanguages"
},
{
"command": "sqlfluff.lintProject",
Expand All @@ -57,9 +62,18 @@
{
"command": "sqlfluff.showOutputChannel",
"title": "SQLFluff Show Output Channel",
"when": "extensionLangId == sql || extensionLangId == sql-bigquery || extensionLangId == jinja-sql || extensionLangId == postgres || extensionLangId == snowflake-sql"
"enablement": "editorLangId in sqlfluff.formatLanguages"
}
],
"menus": {
"editor/context": [
{
"command": "sqlfluff.format.selection",
"group": "1_modification@10",
"when": "editorLangId in sqlfluff.formatLanguages && editorHasSelection"
}
]
},
"configuration": {
"properties": {
"sqlfluff.config": {
Expand Down Expand Up @@ -262,6 +276,34 @@
"postgres",
"snowflake-sql"
],
"items": {
"type": [
"string",
"object"
],
"additionalProperties": false,
"required": [
"language",
"contextMenuFormatOptions",
"preserveLeadingWhitespace"
],
"properties": {
"language": {
"type": "string",
"markdownDescription": "The language to enable formatting for."
},
"contextMenuFormatOptions": {
"type": "boolean",
"default": false,
"markdownDescription": "Show a SQLFluff option in the context menu."
},
"preserveLeadingWhitespace": {
"type": "boolean",
"default": false,
"markdownDescription": "Only works with `Format on Selection`. Preserve whitespace based on the first line of the selection."
}
}
},
"description": "The languages formatting is enabled for."
},
"sqlfluff.experimental.format.executeInTerminal": {
Expand Down
51 changes: 39 additions & 12 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Configuration from "./features/helper/configuration";
import Utilities from "./features/helper/utilities";
import LinterProvider from "./features/linter";
import Debug from "./features/providers/debug";
import { FormatSelectionProvider } from "./features/providers/formatter/rangeFormat";
import HoverProvider from "./features/providers/linter/actions/hover";
import QuickFixProvider from "./features/providers/linter/actions/quickFix";

Expand Down Expand Up @@ -51,54 +52,80 @@ export const activate = (context: vscode.ExtensionContext) => {
context.subscriptions.push(hoverProvider);
});

vscode.commands.executeCommand("setContext", "sqlfluff.formatLanguages", formatSelectors)

context.subscriptions.push(vscode.commands.registerCommand(EXCLUDE_RULE, ExcludeRules.toggleRule));
context.subscriptions.push(vscode.commands.registerCommand(EXCLUDE_RULE_WORKSPACE, ExcludeRules.toggleRuleWorkspace));
context.subscriptions.push(vscode.commands.registerCommand(VIEW_DOCUMENTATION, Documentation.showDocumentation));

const lintCommand = "sqlfluff.lint";
const lintCommandHandler = () => {
if (vscode.window.activeTextEditor) {
const currentDocument = vscode.window.activeTextEditor.document;
if (currentDocument) {
lintingProvider.doLint(currentDocument, true);
const document = vscode.window.activeTextEditor.document;
if (document) {
lintingProvider.doLint(document, true);
}
}
};
context.subscriptions.push(vscode.commands.registerCommand(lintCommand, lintCommandHandler));

const lintProjectCommand = "sqlfluff.lintProject";
const lintProjectCommandHandler = () => {
if (vscode.window.activeTextEditor) {
const currentDocument = vscode.window.activeTextEditor.document;
if (currentDocument) {
const document = vscode.window.activeTextEditor.document;
if (document) {
lintingProvider.lintProject(true);
}
}
};
context.subscriptions.push(vscode.commands.registerCommand(lintProjectCommand, lintProjectCommandHandler));

const fixCommand = "sqlfluff.fix";
const fixCommandHandler = () => {
if (vscode.window.activeTextEditor) {
const currentDocument = vscode.window.activeTextEditor.document;
if (currentDocument) {
const document = vscode.window.activeTextEditor.document;
if (document) {
vscode.commands.executeCommand("editor.action.formatDocument");
}
}
};
context.subscriptions.push(vscode.commands.registerCommand(fixCommand, fixCommandHandler));

const formatSelection = "sqlfluff.format.selection";
const formatSelectionHandler = async () => {
if (vscode.window.activeTextEditor) {
// Check if available language
const document = vscode.window.activeTextEditor.document;
const range = new vscode.Range(
vscode.window.activeTextEditor.selection.start,
vscode.window.activeTextEditor.selection.end,
)

const textEdits = await FormatSelectionProvider.provideTextEdits(
document,
range,
);

textEdits.forEach((textEdit) => {
const workspaceEdit = new vscode.WorkspaceEdit();
workspaceEdit.replace(document.uri, textEdit.range, textEdit.newText);

vscode.workspace.applyEdit(workspaceEdit);
})
}
};
context.subscriptions.push(vscode.commands.registerCommand(formatSelection, formatSelectionHandler));

const debugCommand = "sqlfluff.debug";
const debugCommandHandler = async () => {
Debug.debug();
};
context.subscriptions.push(vscode.commands.registerCommand(debugCommand, debugCommandHandler));

const showOutputChannelCommand = "sqlfluff.showOutputChannel";
const showOutputChannelCommandHandler = async () => {
Utilities.outputChannel.show();
};

context.subscriptions.push(vscode.commands.registerCommand(lintCommand, lintCommandHandler));
context.subscriptions.push(vscode.commands.registerCommand(lintProjectCommand, lintProjectCommandHandler));
context.subscriptions.push(vscode.commands.registerCommand(fixCommand, fixCommandHandler));
context.subscriptions.push(vscode.commands.registerCommand(debugCommand, debugCommandHandler));
context.subscriptions.push(vscode.commands.registerCommand(showOutputChannelCommand, showOutputChannelCommandHandler));
};

Expand Down
31 changes: 30 additions & 1 deletion src/features/helper/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { DiagnosticSeverity } from "vscode";

import DiagnosticSetting from "./types/diagnosticSetting";
import EnvironmentVariable from "./types/environmentVariable";
import FormatLanguageSettings from "./types/formatLanguageSettings";
import RunTrigger from "./types/runTrigger";
import Variables from "./types/variables";
import Utilities from "./utilities";
Expand Down Expand Up @@ -233,13 +234,41 @@ export default class Configuration {
}

public static formatLanguages(): string[] {
const languages: any = vscode.workspace
const languageSettings: (FormatLanguageSettings | string)[] | undefined = vscode.workspace
.getConfiguration("sqlfluff.format")
.get("languages");


const languages: string[] = [];
languageSettings?.forEach((languageSetting: FormatLanguageSettings | string) => {
if (typeof languageSetting === "string") {
languages.push(languageSetting);
} else {
languages.push(languageSetting.language)
}
})

return languages;
}

public static formatLanguageSetting(languageId: string): FormatLanguageSettings | undefined {
const languageSettings: (FormatLanguageSettings | string)[] | undefined = vscode.workspace
.getConfiguration("sqlfluff.format")
.get("languages");

const setting = languageSettings?.find((languageSetting: FormatLanguageSettings | string) => {
if (typeof languageSettings === "string") return false;

const typedSetting = languageSetting as unknown as FormatLanguageSettings;
if (typedSetting.language === languageId) return true;

return false;
});

if (typeof setting === "string") return undefined
return setting;
}

public static executeInTerminal(): boolean {
return vscode.workspace
.getConfiguration("sqlfluff.experimental.format")
Expand Down
5 changes: 5 additions & 0 deletions src/features/helper/types/formatLanguageSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default interface FormatLanguageSettings {
language: string;
contextMenuFormatOptions: boolean;
preserveLeadingWhitespace: boolean;
}
24 changes: 23 additions & 1 deletion src/features/providers/formatter/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,28 @@ export default class FormatHelper {
return undefined;
}

return lines;
const parsedLines = lines[0].split(/\r?\n|\r|\n/g);
return parsedLines;
}

public static addLeadingWhitespace(lines: string[], languageId: string, leadingWhitespace: number): string[] | undefined {
const formatSettings = Configuration.formatLanguageSetting(languageId)
let linesWithWhitespace: string[] = [];

if (formatSettings?.preserveLeadingWhitespace) {
lines.forEach((line) => {
const emptySpace = new Array(leadingWhitespace).join(" ");
const whitespaceLine = line === "" ? line : emptySpace.concat(line);
linesWithWhitespace.push(whitespaceLine);
})
} else {
linesWithWhitespace = lines;
}

if (linesWithWhitespace.length > 0 && linesWithWhitespace.slice(-1)[0] === "") {
linesWithWhitespace.pop();
}

return linesWithWhitespace;
}
}
31 changes: 26 additions & 5 deletions src/features/providers/formatter/rangeFormat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,36 @@ export class RangeFormattingProvider implements vscode.DocumentRangeFormattingEd
range: vscode.Range,
options: vscode.FormattingOptions,
token: vscode.CancellationToken,
): Promise<vscode.TextEdit[]> {
const textEdits = await FormatSelectionProvider.provideTextEdits(document, range);

return textEdits;
}
}

export class FormatSelectionProvider {
static async provideTextEdits(
document: vscode.TextDocument,
range: vscode.Range,
): Promise<vscode.TextEdit[]> {
const filePath = Utilities.normalizePath(document.fileName);
const workspaceFolder = vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders[0].uri.fsPath : undefined;
const rootPath = workspaceFolder ? Utilities.normalizePath(workspaceFolder) : undefined;
const workingDirectory = Configuration.workingDirectory(rootPath);
const textEdits: vscode.TextEdit[] = [];

const endCharacter = document.lineAt(range.end.line).range.end.character;
const lineRange = new vscode.Range(
new vscode.Position(range.start.line, 0),
new vscode.Position(range.end.line, endCharacter),
);

if (workingDirectory?.includes("${")) {
return [];
}

Utilities.appendHyphenatedLine();
Utilities.outputChannel.appendLine(`Range (Lines ${range.start.line} to ${range.end.line}) Format triggered for ${filePath}`);
Utilities.outputChannel.appendLine(`Range (Lines ${lineRange.start.line} to ${lineRange.end.line}) Format triggered for ${filePath}`);

if (!Configuration.formatEnabled()) {
const message = "Format not enabled in the settings. Skipping Format.";
Expand All @@ -53,7 +69,7 @@ export class RangeFormattingProvider implements vscode.DocumentRangeFormattingEd

const commandOptions: CommandOptions = {
filePath: filePath,
fileContents: document.getText(range),
fileContents: document.getText(lineRange),
};

const result = await SQLFluff.run(
Expand All @@ -67,13 +83,18 @@ export class RangeFormattingProvider implements vscode.DocumentRangeFormattingEd
throw new Error("Command failed to execute, check logs for details");
}

const lines = FormatHelper.parseLines(result.lines);
let lines = FormatHelper.parseLines(result.lines);

const leadingWhitespace = document.lineAt(range.start.line).firstNonWhitespaceCharacterIndex;
lines = lines ? FormatHelper.addLeadingWhitespace(lines, document.languageId, leadingWhitespace) : undefined;

if (lines === undefined) return [];

if (lines.length > 1 || lines[0] !== "") {
const eol = document.eol;
textEdits.push(vscode.TextEdit.replace(
range,
lines.join("\n"),
lineRange,
eol === vscode.EndOfLine.LF ? lines.join("\n") : lines.join("\r\n"),
));
}

Expand Down
12 changes: 6 additions & 6 deletions test/.vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
"sqlfluff.dialect": "postgres",
"sqlfluff.format.languages": [
"sql",
"sql-bigquery",
"jinja-sql",
"postgres",
"snowflake-sql",
"markdown"
{
"language": "markdown" ,
"contextMenuFormatOptions": false,
"preserveLeadingWhitespace": true
}
],

/* Linter */
Expand All @@ -30,6 +30,6 @@
"sqlfluff.executablePath": "sqlfluff",
// "sqlfluff.shell": true,
// "sqlfluff.shell": "C:/Program Files/Git/bin/bash.exe",
"sqlfluff.workingDirectory": "${fileDirname}",
"sqlfluff.workingDirectory": "${fileDirname}"
// "sqlfluff.workingDirectory": "broken",
}
Loading

0 comments on commit 0c90d49

Please sign in to comment.