Skip to content
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

277 separate configuration to enable only some features to work when formatting on save #281

Draft
wants to merge 6 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 50 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,59 @@ At the moment we implemented formatting logic for these language features:

We implemented extensive settings configuration to allow users to easly tailor the experience to their needs. This might not be the case in the future.

### Settings
### Extension Settings

### Formatting on save
TODO: list of extension settings
TODO: link to a separate settings documentation

TODO: link a separate file with settings
### VSCode Settings

TODO

### Formatting On Save

> In case you want to use formatting on save

VSCode provides default `editor.formatOnSaveMode` which enables file formatting on save using configured formatter.

### Formatting On Save With Alternate Settings

> In case you want to use formatting on save, but with less features enabled, you can use `AblFormatter.formatOnSave` setting

If `AblFormatter.formatOnSave` is set, then durring save current file is formatted using `./ablformatter/settings.json` file which structure folows the same logic as VSCode settings file. The only difference is that these settings are explicit e.g. if setting is not writen, the formatter presumes that the value is false. File example:

```json
{
"AblFormatter.usingFormatting": true,
"AblFormatter.variableDefinitionFormatting": true
}
```

In this case only two explicitly enabled formatters will be enabled.

### Diferent Settings For A File

> In case you need specific settings for 1 file

There is a possiblity to have specific formatter settings for a given file. This was implemented for simplier functional testing, but can be used by end users too. It works by writing OpenEdge comments on the top of the file. The first comment should be `/* formatterSettingsOverride */`. The second should contain settings json content. Example:

```prolog
/* formatterSettingsOverride */
/* { "AblFormatter.blockFormatting": true,
"AblFormatter.forFormatting": true
}*/

for each Customer:
Customer.var += 1.
end.
```

Contrary to [On save](#formatting-on-save-with-alternate-settings) settings, File settings are implicit and just overrides VSCode settings.

Priority:

1. File Settings
2. VSCode Settings

## Installation

Expand All @@ -60,7 +106,7 @@ Alowed file extensions:
- **.i**
- **.w**

Commands:
Standard VSCode Commands:

- **Format Document**: Formats the entire ABL document.
- **Format Selection**: Formats only the selected lines of code.
Expand Down
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "abl-formatter",
"displayName": "Abl Formatter",
"description": "Progress OpenEdge (ABL) code formatter",
"version": "0.0.2",
"version": "0.0.4",
"icon": "resources/Formatter_LOGO.png",
"repository": {
"url": "https://github.com/BalticAmadeus/AblFormatter"
Expand Down Expand Up @@ -38,6 +38,12 @@
"configuration": {
"title": "AblFormatter",
"properties": {
"AblFormatter.formatOnSave": {
"order": 10,
"type": "boolean",
"default": "false",
"markdownDescription": "Enable/disable Formatting on save."
},
"AblFormatter.assignFormatting": {
"order": 100,
"type": "boolean",
Expand Down
1 change: 1 addition & 0 deletions resources/ade
Submodule ade added at 2e350f
7 changes: 7 additions & 0 deletions resources/samples/.ablformatter/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"AblFormatter.blockFormatting": true,
"AblFormatter.caseFormatting": true,
"abl.completion.upperCase": false,
"AblFormatter.ifFormatting": true,
"AblFormatter.ifFormattingThenLocation": "New"
}
13 changes: 12 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,31 @@ import { AblDebugHoverProvider } from "./providers/AblDebugHoverProvider";
import { ConfigurationManager2 } from "./utils/ConfigurationManager";
import { enableFormatterDecorators } from "./v2/formatterFramework/enableFormatterDecorators";
import { DebugManager } from "./providers/DebugManager";
import { GlobalSettings } from "./utils/GlobalSettings";

export async function activate(context: vscode.ExtensionContext) {
const debugManager = DebugManager.getInstance(context);

await Parser.init().then(() => {});

ConfigurationManager2.getInstance();
const configurationManager = ConfigurationManager2.getInstance();
enableFormatterDecorators();

const parserHelper = new AblParserHelper(
context.extensionPath,
debugManager
);
const formatter = new AblFormatterProvider(parserHelper);
const globalSettings = new GlobalSettings(configurationManager);

vscode.workspace.onWillSaveTextDocument((e) => {
if (
globalSettings.formatOnSave() &&
e.document.languageId === Constants.ablId
) {
formatter.formatDocumentOnSave(e.document);
}
});

vscode.languages.registerDocumentRangeFormattingEditProvider(
Constants.ablId,
Expand Down
80 changes: 34 additions & 46 deletions src/providers/AblFormatterProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,69 +11,61 @@ export class AblFormatterProvider
vscode.DocumentRangeFormattingEditProvider,
vscode.DocumentFormattingEditProvider
{
private parserHelper: IParserHelper;
private readonly parserHelper: IParserHelper;
private readonly configurationManager: ConfigurationManager2 =
ConfigurationManager2.getInstance();

public constructor(parserHelper: IParserHelper) {
this.parserHelper = parserHelper;
}

public provideDocumentFormattingEdits(
document: vscode.TextDocument,
options: vscode.FormattingOptions
): vscode.ProviderResult<vscode.TextEdit[]> {
console.log("AblFormatterProvider.provideDocumentFormattingEdits");
public formatDocumentOnSave(document: vscode.TextDocument): void {
const options: vscode.FormattingOptions = {
insertSpaces: true,
tabSize: 4, //TODO fix
};

const configurationManager = ConfigurationManager2.getInstance();
const debugManager = DebugManager.getInstance();
this.configurationManager.setTabSize(options.tabSize);

configurationManager.setTabSize(options.tabSize);
this.configurationManager.useOnSaveSettings(true);

try {
const codeFormatter = new FormattingEngine(
this.parserHelper,
new FileIdentifier(document.fileName, document.version),
configurationManager,
debugManager
);

const str = codeFormatter.formatText(
document.getText(),
new EOL(document.eol)
);

const editor = vscode.window.activeTextEditor;
editor!.edit(
(edit: vscode.TextEditorEdit) => {
edit.replace(
new vscode.Range(
new vscode.Position(0, 0),
new vscode.Position(10000000, 10000000)
),
str
);
},
{ undoStopBefore: false, undoStopAfter: false }
);
this.provideDocumentFormattingEdits(document, options);
} catch (e) {
console.log(e);
return;
} finally {
this.configurationManager.useOnSaveSettings(false);
}
}

public provideDocumentRangeFormattingEdits(
public provideDocumentFormattingEdits(
document: vscode.TextDocument,
range: vscode.Range
options: vscode.FormattingOptions
): vscode.ProviderResult<vscode.TextEdit[]> {
console.log("AblFormatterProvider.provideDocumentFormattingEdits");
const fullRange = new vscode.Range(
new vscode.Position(0, 0),
new vscode.Position(10000000, 10000000)
);

this.provideDocumentRangeFormattingEdits(document, fullRange, options);

const configurationManager = ConfigurationManager2.getInstance();
return [];
}

public provideDocumentRangeFormattingEdits(
document: vscode.TextDocument,
range: vscode.Range,
options: vscode.FormattingOptions
): vscode.ProviderResult<vscode.TextEdit[]> {
const debugManager = DebugManager.getInstance();

this.configurationManager.setTabSize(options.tabSize);

try {
const codeFormatter = new FormattingEngine(
this.parserHelper,
new FileIdentifier(document.fileName, document.version),
configurationManager,
this.configurationManager,
debugManager
);

Expand All @@ -100,18 +92,14 @@ export class AblFormatterProvider
ranges: vscode.Range[],
options: vscode.FormattingOptions
): vscode.ProviderResult<vscode.TextEdit[]> {
console.log(
"AblFormatterProvider.provideDocumentFormattingEdits2",
ranges
);

switch (ranges.length) {
case 0:
return [];
case 1:
return this.provideDocumentRangeFormattingEdits(
document,
ranges[0]
ranges[0],
options
);
default:
// for now, just format whole document, if there is more than one range
Expand Down
7 changes: 7 additions & 0 deletions src/utils/ASettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { IConfigurationManager } from "./IConfigurationManager";

export abstract class ASettings {
public constructor(
protected readonly configurationManager: IConfigurationManager
) {}
}
61 changes: 51 additions & 10 deletions src/utils/ConfigurationManager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { commands, window, workspace, WorkspaceConfiguration } from "vscode";
import { IConfigurationManager } from "./IConfigurationManager";
import * as fs from "fs";

export class ConfigurationManager2 implements IConfigurationManager {
private static instance: ConfigurationManager2;
Expand All @@ -8,9 +9,12 @@ export class ConfigurationManager2 implements IConfigurationManager {
private configuration: WorkspaceConfiguration | undefined = undefined;
private externalConfiguration: WorkspaceConfiguration | undefined =
undefined;
private overridingSettings: any | undefined;
private overridingSettings: any;
private tabSize: number | undefined;

private shouldUseOnSaveSettings: boolean = false;
private onSaveConfig: any;

private constructor() {
workspace.onDidChangeConfiguration((e) => {
if (e.affectsConfiguration("AblFormatter")) {
Expand All @@ -27,6 +31,31 @@ export class ConfigurationManager2 implements IConfigurationManager {
);
}
});

this.readOnSaveSettingsFile();
this.createOnSaveListener();
}

private createOnSaveListener() {
workspace
.createFileSystemWatcher("**/.ablformatter/settings.json")
.onDidChange((e) => {
window.showInformationMessage(
"ABL On Save settings were changed!"
);

this.readOnSaveSettingsFile();
});
}

private readOnSaveSettingsFile(): void {
workspace.findFiles("**/.ablformatter/settings.json").then((files) => {
if (files.length > 0) {
this.onSaveConfig = JSON.parse(
fs.readFileSync(files[0].fsPath, "utf-8")
);
}
});
}

public static getInstance(): ConfigurationManager2 {
Expand All @@ -49,7 +78,7 @@ export class ConfigurationManager2 implements IConfigurationManager {
}

public getTabSize(): number {
return this.tabSize || 4; // Default to 4 if not set
return this.tabSize ?? 4; // Default to 4 if not set
}

public getCasing() {
Expand All @@ -75,14 +104,10 @@ export class ConfigurationManager2 implements IConfigurationManager {
"Settings"
)
.then((selection) => {
switch (selection) {
case "Settings":
commands.executeCommand(
"workbench.action.openWorkspaceSettingsFile"
);
return;
default:
return;
if (selection === "Settings") {
commands.executeCommand(
"workbench.action.openWorkspaceSettingsFile"
);
}
});
}
Expand All @@ -102,6 +127,18 @@ export class ConfigurationManager2 implements IConfigurationManager {
private getConfig(name: string): any {
const config = this.configuration?.get(name);

if (this.shouldUseOnSaveSettings) {
if (this.onSaveConfig === undefined) {
window.showWarningMessage("On save config was not found!");
} else {
const config = this.onSaveConfig["AblFormatter." + name];
if (config === undefined) {
return false;
}
return config;
}
}

if (this.overridingSettings !== undefined) {
const overridingConfig =
this.overridingSettings["AblFormatter." + name];
Expand All @@ -113,4 +150,8 @@ export class ConfigurationManager2 implements IConfigurationManager {
}
return config;
}

public useOnSaveSettings(shouldUseOnSaveSettings: boolean): void {
this.shouldUseOnSaveSettings = shouldUseOnSaveSettings;
}
}
7 changes: 7 additions & 0 deletions src/utils/GlobalSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { ASettings } from "./ASettings";

export class GlobalSettings extends ASettings {
public formatOnSave() {
return this.configurationManager.get("formatOnSave") === true;
}
}
11 changes: 11 additions & 0 deletions src/v2/formatters/AFormatterSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ASettings } from "../../utils/ASettings";

export abstract class AFormatterSettings extends ASettings {
public tabSize() {
return this.configurationManager.getTabSize();
}

public casing() {
return this.configurationManager.getCasing();
}
}
Loading
Loading