add suggestions for regExp flags, mark selected flags, make regExp field looks pretty
This commit is contained in:
parent
470dd8176d
commit
7ddd6525c6
54
main.ts
54
main.ts
|
@ -17,6 +17,13 @@ import {
|
|||
getObsidianFilesWithTagName,
|
||||
} from './src/services/obsidian.service';
|
||||
import { renderPreviewFiles } from './src/components/RenderPreviewFiles';
|
||||
import { createBackslash } from './src/components/RegExpBackslash';
|
||||
import {
|
||||
REGEXP_FLAGS,
|
||||
RegExpFlag,
|
||||
RegExpFlags,
|
||||
} from './src/constants/RegExpFlags';
|
||||
import { RegExpFlagsSuggest } from './src/suggestions/RegExpFlagsSuggest';
|
||||
|
||||
interface BulkRenamePluginSettings {
|
||||
folderName: string;
|
||||
|
@ -25,6 +32,10 @@ interface BulkRenamePluginSettings {
|
|||
replacePattern: string;
|
||||
tags: string[];
|
||||
userRegExp: string;
|
||||
regExpState: {
|
||||
regExp: string;
|
||||
flags: RegExpFlag[];
|
||||
};
|
||||
viewType: 'tags' | 'folder' | 'regexp';
|
||||
}
|
||||
|
||||
|
@ -34,6 +45,10 @@ const DEFAULT_SETTINGS: BulkRenamePluginSettings = {
|
|||
existingSymbol: '',
|
||||
replacePattern: '',
|
||||
userRegExp: '',
|
||||
regExpState: {
|
||||
regExp: '',
|
||||
flags: [],
|
||||
},
|
||||
tags: [],
|
||||
viewType: 'folder',
|
||||
};
|
||||
|
@ -158,7 +173,7 @@ export class BulkRenameSettingsTab extends PluginSettingTab {
|
|||
.setName('Folder location')
|
||||
.setDesc('Find files within the folder')
|
||||
.addSearch((cb) => {
|
||||
new FolderSuggest(this.app, cb.inputEl);
|
||||
new FolderSuggest(this.app, cb.inputEl, this.plugin);
|
||||
cb.setPlaceholder('Example: folder1/')
|
||||
.setValue(this.plugin.settings.folderName)
|
||||
.onChange((newFolder) => {
|
||||
|
@ -212,7 +227,9 @@ export class BulkRenameSettingsTab extends PluginSettingTab {
|
|||
new Setting(this.containerEl)
|
||||
.setName('RegExp')
|
||||
.setDesc('all files by titles will be found')
|
||||
.addSearch((cb) => {
|
||||
.addText((cb) => {
|
||||
const backslash = createBackslash('/');
|
||||
cb.inputEl.insertAdjacentElement('beforebegin', backslash);
|
||||
// @ts-ignore
|
||||
cb.inputEl.addEventListener('keydown', (event) => {
|
||||
if (event.key !== 'Enter') {
|
||||
|
@ -220,21 +237,40 @@ export class BulkRenameSettingsTab extends PluginSettingTab {
|
|||
}
|
||||
const target = event.target as HTMLInputElement;
|
||||
|
||||
this.plugin.settings.userRegExp = target.value;
|
||||
this.plugin.settings.regExpState.regExp = target.value;
|
||||
this.plugin.saveSettings();
|
||||
});
|
||||
cb.setPlaceholder('Example: #tag, #tag2')
|
||||
.setValue(this.plugin.settings.userRegExp)
|
||||
cb.setPlaceholder('Put your RegExp here')
|
||||
.setValue(this.plugin.settings.regExpState.regExp)
|
||||
.onChange((newFolder) => {
|
||||
this.plugin.settings.userRegExp = newFolder;
|
||||
this.plugin.settings.regExpState.regExp = newFolder;
|
||||
this.plugin.saveSettings();
|
||||
this.getFilesByRegExp();
|
||||
});
|
||||
// @ts-ignore
|
||||
cb.containerEl.addClass('bulk_regexp');
|
||||
cb.inputEl.addClass('bulk_input');
|
||||
cb.inputEl.addClass('bulk_regexp');
|
||||
cb.inputEl.onblur = this.reRenderPreview;
|
||||
});
|
||||
})
|
||||
.addText((cb) => {
|
||||
new RegExpFlagsSuggest(this.app, cb.inputEl, this.plugin);
|
||||
const backslash = createBackslash('/');
|
||||
cb.inputEl.insertAdjacentElement('beforebegin', backslash);
|
||||
cb.inputEl.addEventListener('keydown', (event) => {
|
||||
// @ts-ignore
|
||||
event.stopPropagation();
|
||||
event.stopImmediatePropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
cb.setPlaceholder('flags here')
|
||||
// .setDisabled(true)
|
||||
.setValue(this.plugin.settings.regExpState.flags.join(''))
|
||||
.onChange((flag: RegExpFlag) => {
|
||||
this.plugin.saveSettings();
|
||||
this.getFilesByRegExp();
|
||||
});
|
||||
cb.inputEl.addClass('bulk_regexp_flags');
|
||||
})
|
||||
.controlEl.addClass('bulk_regexp_control');
|
||||
}
|
||||
|
||||
renderReplaceSymbol() {
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
export const createBackslash = (textContent = '=> => => =>') => {
|
||||
const previewLabel = window.document.createElement('div');
|
||||
previewLabel.className = 'bulk_regexp_slash';
|
||||
previewLabel.textContent = textContent;
|
||||
return previewLabel;
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
export type RegExpFlag =
|
||||
| 'g'
|
||||
| 'm'
|
||||
| 'i'
|
||||
| 'x'
|
||||
| 's'
|
||||
| 'u'
|
||||
| 'U'
|
||||
| 'A'
|
||||
| 'J'
|
||||
| 'D';
|
||||
|
||||
export const REGEXP_FLAGS = [
|
||||
'g',
|
||||
'm',
|
||||
'i',
|
||||
'x',
|
||||
's',
|
||||
'u',
|
||||
'U',
|
||||
'A',
|
||||
'J',
|
||||
'D',
|
||||
] as const;
|
||||
|
||||
export type RegExpFlags = typeof REGEXP_FLAGS;
|
|
@ -0,0 +1,42 @@
|
|||
// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes
|
||||
|
||||
import { TextInputSuggest } from './suggest';
|
||||
import { REGEXP_FLAGS, RegExpFlag } from '../constants/RegExpFlags';
|
||||
|
||||
export class RegExpFlagsSuggest extends TextInputSuggest<RegExpFlag> {
|
||||
// @ts-ignore TODO refactor types types
|
||||
getSuggestions() {
|
||||
return REGEXP_FLAGS;
|
||||
}
|
||||
|
||||
renderSuggestion = (flag: RegExpFlag, el: HTMLElement) => {
|
||||
const { regExpState } = this.plugin.settings;
|
||||
const hasFlag = regExpState.flags.includes(flag);
|
||||
if (hasFlag) {
|
||||
el.addClass('bulk-flag-selected');
|
||||
} else {
|
||||
el.removeClass('bulk-flag-selected');
|
||||
}
|
||||
el.setText(flag);
|
||||
};
|
||||
|
||||
selectSuggestion = (flag: RegExpFlag, event: MouseEvent | KeyboardEvent) => {
|
||||
const { regExpState } = this.plugin.settings;
|
||||
const target = event.target as HTMLDivElement;
|
||||
|
||||
const hasFlag = regExpState.flags.includes(flag);
|
||||
if (hasFlag) {
|
||||
regExpState.flags = regExpState.flags.filter((existingFlag) => {
|
||||
return existingFlag !== flag;
|
||||
});
|
||||
} else {
|
||||
regExpState.flags = [...regExpState.flags, flag];
|
||||
}
|
||||
target.classList.toggle('bulk-flag-selected');
|
||||
this.inputEl.value = regExpState.flags.join('');
|
||||
// this.inputEl.trigger('input');
|
||||
// this.settings.plugin.settings.regExpState.flags.push(file);
|
||||
// this.inputEl.trigger('input');
|
||||
// this.close();
|
||||
};
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import { App, ISuggestOwner, Scope } from 'obsidian';
|
||||
import { createPopper, Instance as PopperInstance } from '@popperjs/core';
|
||||
import BulkRenamePlugin from '../../main';
|
||||
|
||||
const wrapAround = (value: number, size: number): number => {
|
||||
return ((value % size) + size) % size;
|
||||
|
@ -104,6 +105,7 @@ class Suggest<T> {
|
|||
|
||||
export abstract class TextInputSuggest<T> implements ISuggestOwner<T> {
|
||||
protected app: App;
|
||||
protected plugin: BulkRenamePlugin;
|
||||
protected inputEl: HTMLInputElement | HTMLTextAreaElement;
|
||||
|
||||
private popper: PopperInstance;
|
||||
|
@ -111,7 +113,12 @@ export abstract class TextInputSuggest<T> implements ISuggestOwner<T> {
|
|||
private suggestEl: HTMLElement;
|
||||
private suggest: Suggest<T>;
|
||||
|
||||
constructor(app: App, inputEl: HTMLInputElement | HTMLTextAreaElement) {
|
||||
constructor(
|
||||
app: App,
|
||||
inputEl: HTMLInputElement | HTMLTextAreaElement,
|
||||
plugin: BulkRenamePlugin,
|
||||
) {
|
||||
this.plugin = plugin;
|
||||
this.app = app;
|
||||
this.inputEl = inputEl;
|
||||
this.scope = new Scope();
|
||||
|
@ -191,7 +198,7 @@ export abstract class TextInputSuggest<T> implements ISuggestOwner<T> {
|
|||
this.suggestEl.detach();
|
||||
}
|
||||
|
||||
abstract getSuggestions(inputStr: string): T[];
|
||||
abstract getSuggestions(inputStr?: string): T[];
|
||||
abstract renderSuggestion(item: T, el: HTMLElement): void;
|
||||
abstract selectSuggestion(item: T): void;
|
||||
abstract selectSuggestion(item: T, evt: MouseEvent | KeyboardEvent): void;
|
||||
}
|
||||
|
|
41
styles.css
41
styles.css
|
@ -24,35 +24,28 @@
|
|||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.bulk_regexp {
|
||||
.bulk_regexp_control {
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
}
|
||||
|
||||
.bulk_regexp_control > input {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.bulk_regexp,
|
||||
.bulk_regexp_flags {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bulk_regexp > input {
|
||||
color: green;
|
||||
padding: 0 28px 0 14px;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
.bulk_regexp_flags {
|
||||
caret-color: transparent;
|
||||
}
|
||||
|
||||
.bulk_regexp:before {
|
||||
content: '/';
|
||||
top: 2px;
|
||||
left: -15px;
|
||||
.bulk_regexp_slash {
|
||||
font-size: 1.5em;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.bulk_regexp:after {
|
||||
content: '/';
|
||||
bottom: 5px;
|
||||
right: -15px;
|
||||
}
|
||||
|
||||
.bulk_regexp:before,
|
||||
.bulk_regexp:after {
|
||||
color: #000080;
|
||||
font-size: 30px;
|
||||
/*background-color: #cccccc;*/
|
||||
display: block;
|
||||
/*text-align: center;*/
|
||||
position: absolute;
|
||||
.bulk-flag-selected {
|
||||
background-color: lavender !important;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue