Skip to content

Commit cfb2ffc

Browse files
authored
Merge pull request platers#1231 from pjkaufman/master
Feat: Add Ability to Enable/Disable Custom Commands and Custom Replacements
2 parents 5063adb + 4f9bf49 commit cfb2ffc

File tree

11 files changed

+86
-32
lines changed

11 files changed

+86
-32
lines changed

__integration__/custom-commands.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const customCommandTestCases: IntegrationTestCase[] = [
1313
plugin.plugin.settings.lintCommands = [{
1414
'id': 'table-editor-obsidian:format-all-tables',
1515
'name': 'Format all tables in this file',
16+
'enabled': true,
1617
}];
1718
},
1819
},

__tests__/rules-runner.test.ts

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {Command} from 'obsidian';
22
import {RulesRunner} from '../src/rules-runner';
33
import {CustomReplace} from '../src/ui/linter-components/custom-replace-option';
44
import dedent from 'ts-dedent';
5+
import {LintCommand} from 'src/ui/linter-components/custom-command-option';
56

67
const rulesRunner = new RulesRunner();
78
const appCommandsMock = {
@@ -31,7 +32,7 @@ const appCommandsMock = {
3132

3233
type CustomCommandTestCase = {
3334
testName: string,
34-
listOfCommands: Command[],
35+
listOfCommands: LintCommand[],
3536
expectedCommandCount: Map<string, number>;
3637
expectedNumberOfCommandsRun: number;
3738
skipFileValue: boolean
@@ -48,8 +49,8 @@ const customCommandTestCases: CustomCommandTestCase[] = [
4849
{
4950
testName: 'When an app lint command is run it should be executed',
5051
listOfCommands: [
51-
{id: 'first id', name: 'command name'},
52-
{id: 'second id', name: 'command name 2'},
52+
{id: 'first id', name: 'command name', enabled: true},
53+
{id: 'second id', name: 'command name 2', enabled: true},
5354
],
5455
expectedCommandCount: new Map([
5556
['first id', 1],
@@ -61,7 +62,7 @@ const customCommandTestCases: CustomCommandTestCase[] = [
6162
{
6263
testName: 'A lint command with an empty id should not get run',
6364
listOfCommands: [
64-
{id: '', name: ''},
65+
{id: '', name: '', enabled: true},
6566
],
6667
expectedCommandCount: new Map([
6768
['', 0],
@@ -72,8 +73,8 @@ const customCommandTestCases: CustomCommandTestCase[] = [
7273
{
7374
testName: 'When custom commands are run with two of the same command, the second command instance is skipped',
7475
listOfCommands: [
75-
{id: 'first id', name: 'command name'},
76-
{id: 'first id', name: 'command name'},
76+
{id: 'first id', name: 'command name', enabled: true},
77+
{id: 'first id', name: 'command name', enabled: true},
7778
],
7879
expectedCommandCount: new Map([
7980
['first id', 1],
@@ -84,13 +85,23 @@ const customCommandTestCases: CustomCommandTestCase[] = [
8485
{
8586
testName: 'When the file is listed to be skipped, no custom commands are run',
8687
listOfCommands: [
87-
{id: 'first id', name: 'command name'},
88-
{id: 'second id', name: 'command name 2'},
88+
{id: 'first id', name: 'command name', enabled: true},
89+
{id: 'second id', name: 'command name 2', enabled: true},
8990
],
9091
expectedCommandCount: new Map<string, number>(),
9192
expectedNumberOfCommandsRun: 0,
9293
skipFileValue: true,
9394
},
95+
{
96+
testName: 'When the custom commands are not enabled, nothing gets run',
97+
listOfCommands: [
98+
{id: 'first id', name: 'command name', enabled: false},
99+
{id: 'second id', name: 'command name 2', enabled: false},
100+
],
101+
expectedCommandCount: new Map<string, number>(),
102+
expectedNumberOfCommandsRun: 0,
103+
skipFileValue: false,
104+
},
94105
];
95106

96107

@@ -106,7 +117,7 @@ const customReplaceTestCases: CustomReplaceTestCase[] = [
106117
testName: 'A custom replace with no find value does not affect the text',
107118
listOfRegexReplacements: [
108119
{
109-
label: '', find: '', replace: 'hello', flags: 'g',
120+
label: '', find: '', replace: 'hello', flags: 'g', enabled: true,
110121
},
111122
],
112123
before: dedent`
@@ -122,10 +133,10 @@ const customReplaceTestCases: CustomReplaceTestCase[] = [
122133
testName: 'A custom replace with a null or undefined find value does not affect the text',
123134
listOfRegexReplacements: [
124135
{
125-
label: '', find: 'How', replace: null, flags: '',
136+
label: '', find: 'How', replace: null, flags: '', enabled: true,
126137
},
127138
{
128-
label: 'Replace 2', find: 'look', replace: undefined, flags: '',
139+
label: 'Replace 2', find: 'look', replace: undefined, flags: '', enabled: true,
129140
},
130141
],
131142
before: dedent`
@@ -141,7 +152,7 @@ const customReplaceTestCases: CustomReplaceTestCase[] = [
141152
testName: 'A custom replace searching for multiple blank lines in a row works (has proper escaping of a slash)',
142153
listOfRegexReplacements: [
143154
{
144-
label: 'condense multiple blanks into 1', find: '\n{3,}', replace: '\n\n', flags: 'g',
155+
label: 'condense multiple blanks into 1', find: '\n{3,}', replace: '\n\n', flags: 'g', enabled: true,
145156
},
146157
],
147158
before: dedent`
@@ -160,7 +171,7 @@ const customReplaceTestCases: CustomReplaceTestCase[] = [
160171
testName: 'A custom replace using capture groups works',
161172
listOfRegexReplacements: [
162173
{
163-
label: 'Remove a question mark proceeded by a k or an e', find: '(k|e)(\\?)', replace: '$1', flags: 'g',
174+
label: 'Remove a question mark proceeded by a k or an e', find: '(k|e)(\\?)', replace: '$1', flags: 'g', enabled: true,
164175
},
165176
],
166177
before: dedent`
@@ -176,7 +187,7 @@ const customReplaceTestCases: CustomReplaceTestCase[] = [
176187
testName: 'A custom replace using ^ and $ works',
177188
listOfRegexReplacements: [
178189
{
179-
label: 'Replace Did at the start of a line or look? at the end of a line', find: '(^Did)|(look\\?$)', replace: 'swapped', flags: 'gm',
190+
label: 'Replace Did at the start of a line or look? at the end of a line', find: '(^Did)|(look\\?$)', replace: 'swapped', flags: 'gm', enabled: true,
180191
},
181192
],
182193
before: dedent`
@@ -192,7 +203,7 @@ const customReplaceTestCases: CustomReplaceTestCase[] = [
192203
testName: 'A custom replace should respect linter ignore ranges',
193204
listOfRegexReplacements: [
194205
{
195-
label: 'Replace Did at the start of a line or look? at the end of a line', find: '(^Did)|(look\\?$)', replace: 'swapped', flags: 'gm',
206+
label: 'Replace Did at the start of a line or look? at the end of a line', find: '(^Did)|(look\\?$)', replace: 'swapped', flags: 'gm', enabled: true,
196207
},
197208
],
198209
before: dedent`
@@ -212,23 +223,23 @@ const customReplaceTestCases: CustomReplaceTestCase[] = [
212223
testName: 'A custom replace with an undefined label should still run.',
213224
listOfRegexReplacements: [
214225
{
215-
label: undefined, find: 'lobo', replace: 'hello', flags: 'g',
226+
label: undefined, find: 'lobo', replace: 'hello', flags: 'g', enabled: true,
216227
},
217228
],
218229
before: dedent`
219-
How does this look?
230+
How does this lobo?
220231
Did it stay the same?
221232
`,
222233
after: dedent`
223-
How does this look?
234+
How does this hello?
224235
Did it stay the same?
225236
`,
226237
},
227238
{ // relates for https://github.com/platers/obsidian-linter/issues/1121
228239
testName: 'A custom replace should respect linter ignore ranges that use the Obsidian comment format',
229240
listOfRegexReplacements: [
230241
{
231-
label: 'Replace Did at the start of a line or look? at the end of a line', find: '(^Did)|(look\\?$)', replace: 'swapped', flags: 'gm',
242+
label: 'Replace Did at the start of a line or look? at the end of a line', find: '(^Did)|(look\\?$)', replace: 'swapped', flags: 'gm', enabled: true,
232243
},
233244
],
234245
before: dedent`
@@ -244,6 +255,22 @@ const customReplaceTestCases: CustomReplaceTestCase[] = [
244255
%% linter-enable %%
245256
`,
246257
},
258+
{
259+
testName: 'A custom replace that is not enabled should not run',
260+
listOfRegexReplacements: [
261+
{
262+
label: undefined, find: 'lobo', replace: 'hello', flags: 'g', enabled: false,
263+
},
264+
],
265+
before: dedent`
266+
How does this look?
267+
Did it stay the same?
268+
`,
269+
after: dedent`
270+
How does this look?
271+
Did it stay the same?
272+
`,
273+
},
247274
];
248275

249276
describe('Rules Runner', () => {
49 Bytes
Loading
4 Bytes
Loading

src/main.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,22 @@ export default class LinterPlugin extends Plugin {
675675
}
676676
}
677677

678+
// make sure that all custom replacements have the enabled property
679+
for (const customReplace of this.settings.customRegexes) {
680+
if (!Object.hasOwn(customReplace, 'enabled')) {
681+
customReplace.enabled = true;
682+
updateMade = true;
683+
}
684+
}
685+
686+
// make sure that all custom commands have the enabled property
687+
for (const customCommand of this.settings.lintCommands) {
688+
if (!Object.hasOwn(customCommand, 'enabled')) {
689+
customCommand.enabled = true;
690+
updateMade = true;
691+
}
692+
}
693+
678694
if (updateMade) {
679695
await this.saveSettings();
680696
}
@@ -1074,7 +1090,7 @@ export default class LinterPlugin extends Plugin {
10741090

10751091
private updateHasCustomCommandStatus() {
10761092
for (const customCommand of this.settings.lintCommands) {
1077-
if (customCommand.id && customCommand.id.trim() != '') {
1093+
if (customCommand.id && customCommand.id.trim() != '' && customCommand.enabled) {
10781094
this.hasCustomCommands = true;
10791095
return;
10801096
}

src/rules-runner.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ export class RulesRunner {
219219
logDebug(getTextInLanguage('logs.running-custom-lint-command'));
220220
const commandsRun = new Set<string>();
221221
for (const commandInfo of lintCommands) {
222-
if (!commandInfo.id) {
222+
if (!commandInfo.id || !commandInfo.enabled) {
223223
continue;
224224
} else if (commandsRun.has(commandInfo.id)) {
225225
logWarn(getTextInLanguage('logs.custom-lint-duplicate-warning').replace('{COMMAND_NAME}', commandInfo.name));
@@ -244,7 +244,7 @@ export class RulesRunner {
244244
for (const eachRegex of customRegexes) {
245245
const findIsEmpty = eachRegex.find === undefined || eachRegex.find == '' || eachRegex.find === null;
246246
const replaceIsEmpty = eachRegex.replace === undefined || eachRegex.replace === null;
247-
if (findIsEmpty || replaceIsEmpty) {
247+
if (findIsEmpty || replaceIsEmpty || !eachRegex.enabled) {
248248
continue;
249249
}
250250

src/ui/linter-components/auto-correct-files-picker-option.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export class AutoCorrectFilesPickerOption extends AddCustomRefreshableRow {
101101
}
102102
})
103103
.addExtraButton((cb) => {
104-
cb.setIcon('cross')
104+
cb.setIcon('trash')
105105
.setTooltip(getTextInLanguage('options.custom-auto-correct.delete-tooltip'))
106106
.onClick(() => {
107107
this.filesPicked.splice(index, 1);

src/ui/linter-components/custom-command-option.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {getTextInLanguage} from 'src/lang/helpers';
33
import {AddCustomRow} from '../components/add-custom-row';
44
import CommandSuggester from '../suggesters/command-suggester';
55

6-
export type LintCommand = { id: string, name: string };
6+
export type LintCommand = { id: string, name: string, enabled: boolean };
77

88
export class CustomCommandOption extends AddCustomRow {
99
constructor(containerEl: HTMLElement, public lintCommands: LintCommand[], app: App, saveSettings: () => void) {
@@ -15,7 +15,7 @@ export class CustomCommandOption extends AddCustomRow {
1515
app,
1616
saveSettings,
1717
() => {
18-
const newCommand = {id: '', name: ''};
18+
const newCommand = {id: '', name: '', enabled: true};
1919
this.lintCommands.push(newCommand);
2020
this.saveSettings();
2121
this.addCommand(newCommand, this.lintCommands.length - 1, true);
@@ -37,7 +37,7 @@ export class CustomCommandOption extends AddCustomRow {
3737
cb.setPlaceholder(getTextInLanguage('options.custom-command.command-search-placeholder-text'))
3838
.setValue(command.name)
3939
.onChange((newCommandName) => {
40-
const newCommand = {id: cb.inputEl.getAttribute('commandId'), name: newCommandName};
40+
const newCommand = {id: cb.inputEl.getAttribute('commandId'), name: newCommandName, enabled: command.enabled};
4141

4242
// make sure that the command is valid before making any attempt to save the value
4343
if (newCommand.name && newCommand.id) {
@@ -75,13 +75,18 @@ export class CustomCommandOption extends AddCustomRow {
7575
});
7676
})
7777
.addExtraButton((cb) => {
78-
cb.setIcon('cross')
78+
cb.setIcon('trash')
7979
.setTooltip(getTextInLanguage('options.custom-command.delete-tooltip'))
8080
.onClick(() => {
8181
this.lintCommands.splice(index, 1);
8282
this.saveSettings();
8383
this.resetInputEls();
8484
});
85+
}).addToggle((cb) => {
86+
cb.setValue(command.enabled)
87+
.onChange((status: boolean) => {
88+
command.enabled = status;
89+
});
8590
});
8691
}
8792

src/ui/linter-components/custom-replace-option.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {App, Setting} from 'obsidian';
22
import {getTextInLanguage} from 'src/lang/helpers';
33
import {AddCustomRow} from '../components/add-custom-row';
4-
export type CustomReplace = {label: string, find: string, replace: string, flags: string};
4+
export type CustomReplace = {label: string, find: string, replace: string, flags: string, enabled: boolean};
55

66
const defaultFlags = 'gm';
77

@@ -16,7 +16,7 @@ export class CustomReplaceOption extends AddCustomRow {
1616
app,
1717
saveSettings,
1818
()=>{
19-
const newRegex = {label: '', find: '', replace: '', flags: defaultFlags};
19+
const newRegex = {label: '', find: '', replace: '', flags: defaultFlags, enabled: true};
2020
this.regexes.push(newRegex);
2121
this.saveSettings();
2222
this.addRegex(newRegex, this.regexes.length - 1, true);
@@ -101,13 +101,18 @@ export class CustomReplaceOption extends AddCustomRow {
101101
this.resetInputEls();
102102
});
103103
}).addExtraButton((cb)=>{
104-
cb.setIcon('cross')
104+
cb.setIcon('trash')
105105
.setTooltip(getTextInLanguage('options.custom-replace.delete-tooltip'))
106106
.onClick(()=>{
107107
this.regexes.splice(index, 1);
108108
this.saveSettings();
109109
this.resetInputEls();
110110
});
111+
}).addToggle((cb) => {
112+
cb.setValue(regex.enabled)
113+
.onChange((status: boolean) => {
114+
regex.enabled = status;
115+
});
111116
});
112117

113118
setting.settingEl.addClass('linter-custom-regex-replacement-row2');

src/ui/linter-components/files-to-ignore-option.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export class FilesToIgnoreOption extends AddCustomRow {
6464

6565
cb.inputEl.addClass('linter-files-to-ignore-flags');
6666
}).addExtraButton((cb)=>{
67-
cb.setIcon('cross')
67+
cb.setIcon('trash')
6868
.setTooltip(getTextInLanguage('tabs.general.files-to-ignore.delete-tooltip'))
6969
.onClick(()=>{
7070
this.filesToIgnore.splice(index, 1);

0 commit comments

Comments
 (0)