find files by RegExp

This commit is contained in:
Oleh Lustenko 2022-09-18 09:11:05 +03:00
parent 7ddd6525c6
commit 7b7c672d6e
8 changed files with 89 additions and 41 deletions

10
main.ts
View File

@ -18,11 +18,7 @@ import {
} from './src/services/obsidian.service'; } from './src/services/obsidian.service';
import { renderPreviewFiles } from './src/components/RenderPreviewFiles'; import { renderPreviewFiles } from './src/components/RenderPreviewFiles';
import { createBackslash } from './src/components/RegExpBackslash'; import { createBackslash } from './src/components/RegExpBackslash';
import { import { RegExpFlag } from './src/constants/RegExpFlags';
REGEXP_FLAGS,
RegExpFlag,
RegExpFlags,
} from './src/constants/RegExpFlags';
import { RegExpFlagsSuggest } from './src/suggestions/RegExpFlagsSuggest'; import { RegExpFlagsSuggest } from './src/suggestions/RegExpFlagsSuggest';
interface BulkRenamePluginSettings { interface BulkRenamePluginSettings {
@ -31,7 +27,6 @@ interface BulkRenamePluginSettings {
existingSymbol: string; existingSymbol: string;
replacePattern: string; replacePattern: string;
tags: string[]; tags: string[];
userRegExp: string;
regExpState: { regExpState: {
regExp: string; regExp: string;
flags: RegExpFlag[]; flags: RegExpFlag[];
@ -44,7 +39,6 @@ const DEFAULT_SETTINGS: BulkRenamePluginSettings = {
fileNames: [], fileNames: [],
existingSymbol: '', existingSymbol: '',
replacePattern: '', replacePattern: '',
userRegExp: '',
regExpState: { regExpState: {
regExp: '', regExp: '',
flags: [], flags: [],
@ -196,7 +190,6 @@ export class BulkRenameSettingsTab extends PluginSettingTab {
.setName('Tag names ') .setName('Tag names ')
.setDesc('all files with the tags will be found') .setDesc('all files with the tags will be found')
.addSearch((cb) => { .addSearch((cb) => {
// @ts-ignore
cb.inputEl.addEventListener('keydown', (event) => { cb.inputEl.addEventListener('keydown', (event) => {
if (event.key !== 'Enter') { if (event.key !== 'Enter') {
return; return;
@ -267,6 +260,7 @@ export class BulkRenameSettingsTab extends PluginSettingTab {
.onChange((flag: RegExpFlag) => { .onChange((flag: RegExpFlag) => {
this.plugin.saveSettings(); this.plugin.saveSettings();
this.getFilesByRegExp(); this.getFilesByRegExp();
this.reRenderPreview();
}); });
cb.inputEl.addClass('bulk_regexp_flags'); cb.inputEl.addClass('bulk_regexp_flags');
}) })

65
package-lock.json generated
View File

@ -9,7 +9,8 @@
"version": "0.3.5", "version": "0.3.5",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@popperjs/core": "^2.11.2" "@popperjs/core": "^2.11.2",
"xregexp": "^5.1.1"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^28.1.8", "@types/jest": "^28.1.8",
@ -855,6 +856,18 @@
"source-map": "^0.6.0" "source-map": "^0.6.0"
} }
}, },
"node_modules/@babel/runtime-corejs3": {
"version": "7.19.1",
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.19.1.tgz",
"integrity": "sha512-j2vJGnkopRzH+ykJ8h68wrHnEUmtK//E723jjixiAl/PPf6FhqY/vYRcMVlNydRKQjQsTsYEjpx+DZMIvnGk/g==",
"dependencies": {
"core-js-pure": "^3.25.1",
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/template": { "node_modules/@babel/template": {
"version": "7.18.10", "version": "7.18.10",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
@ -3367,6 +3380,16 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/core-js-pure": {
"version": "3.25.1",
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.25.1.tgz",
"integrity": "sha512-7Fr74bliUDdeJCBMxkkIuQ4xfxn/SwrVg+HkJUAoNEXVqYLv55l6Af0dJ5Lq2YBUW9yKqSkLXaS5SYPK6MGa/A==",
"hasInstallScript": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
}
},
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@ -8421,6 +8444,11 @@
"node": ">= 4" "node": ">= 4"
} }
}, },
"node_modules/regenerator-runtime": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
},
"node_modules/regex-not": { "node_modules/regex-not": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
@ -10009,6 +10037,14 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0" "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
} }
}, },
"node_modules/xregexp": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/xregexp/-/xregexp-5.1.1.tgz",
"integrity": "sha512-fKXeVorD+CzWvFs7VBuKTYIW63YD1e1osxwQ8caZ6o1jg6pDAbABDG54LCIq0j5cy7PjRvGIq6sef9DYPXpncg==",
"dependencies": {
"@babel/runtime-corejs3": "^7.16.5"
}
},
"node_modules/y18n": { "node_modules/y18n": {
"version": "5.0.8", "version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
@ -10669,6 +10705,15 @@
} }
} }
}, },
"@babel/runtime-corejs3": {
"version": "7.19.1",
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.19.1.tgz",
"integrity": "sha512-j2vJGnkopRzH+ykJ8h68wrHnEUmtK//E723jjixiAl/PPf6FhqY/vYRcMVlNydRKQjQsTsYEjpx+DZMIvnGk/g==",
"requires": {
"core-js-pure": "^3.25.1",
"regenerator-runtime": "^0.13.4"
}
},
"@babel/template": { "@babel/template": {
"version": "7.18.10", "version": "7.18.10",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
@ -12606,6 +12651,11 @@
"integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==",
"dev": true "dev": true
}, },
"core-js-pure": {
"version": "3.25.1",
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.25.1.tgz",
"integrity": "sha512-7Fr74bliUDdeJCBMxkkIuQ4xfxn/SwrVg+HkJUAoNEXVqYLv55l6Af0dJ5Lq2YBUW9yKqSkLXaS5SYPK6MGa/A=="
},
"cross-spawn": { "cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@ -16376,6 +16426,11 @@
"source-map": "~0.6.1" "source-map": "~0.6.1"
} }
}, },
"regenerator-runtime": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
},
"regex-not": { "regex-not": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
@ -17596,6 +17651,14 @@
"signal-exit": "^3.0.7" "signal-exit": "^3.0.7"
} }
}, },
"xregexp": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/xregexp/-/xregexp-5.1.1.tgz",
"integrity": "sha512-fKXeVorD+CzWvFs7VBuKTYIW63YD1e1osxwQ8caZ6o1jg6pDAbABDG54LCIq0j5cy7PjRvGIq6sef9DYPXpncg==",
"requires": {
"@babel/runtime-corejs3": "^7.16.5"
}
},
"y18n": { "y18n": {
"version": "5.0.8", "version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",

View File

@ -15,7 +15,8 @@
"author": "", "author": "",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@popperjs/core": "^2.11.2" "@popperjs/core": "^2.11.2",
"xregexp": "^5.1.1"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^28.1.8", "@types/jest": "^28.1.8",

View File

@ -1,4 +1,4 @@
export const createBackslash = (textContent = '=> => => =>') => { export const createBackslash = (textContent = '/') => {
const previewLabel = window.document.createElement('div'); const previewLabel = window.document.createElement('div');
previewLabel.className = 'bulk_regexp_slash'; previewLabel.className = 'bulk_regexp_slash';
previewLabel.textContent = textContent; previewLabel.textContent = textContent;

View File

@ -1,26 +1,15 @@
export type RegExpFlag = export type RegExpFlag = 'g' | 'i' | 'm' | 'u' | 'y' | 'n' | 's' | 'x' | 'A';
| 'g'
| 'm'
| 'i'
| 'x'
| 's'
| 'u'
| 'U'
| 'A'
| 'J'
| 'D';
export const REGEXP_FLAGS = [ export const REGEXP_FLAGS = [
'g', 'g',
'm',
'i', 'i',
'x', 'm',
's',
'u', 'u',
'U', 'y',
'n',
's',
'x',
'A', 'A',
'J',
'D',
] as const; ] as const;
export type RegExpFlags = typeof REGEXP_FLAGS; export type RegExpFlags = typeof REGEXP_FLAGS;

View File

@ -1,5 +1,6 @@
import { App, Notice, TFile } from 'obsidian'; import { App, Notice, TFile } from 'obsidian';
import BulkRenamePlugin from '../../main'; import BulkRenamePlugin from '../../main';
import XRegExp from 'xregexp';
export const getFilesNamesInDirectory = (plugin: BulkRenamePlugin) => { export const getFilesNamesInDirectory = (plugin: BulkRenamePlugin) => {
const { fileNames } = plugin.settings; const { fileNames } = plugin.settings;
@ -77,9 +78,6 @@ export const renameFilesInObsidian = async (
new Notice('successfully renamed all files'); new Notice('successfully renamed all files');
}; };
let reRegExpChar = /[\\^$.*+?()[\]{}]/g,
reHasRegExpChar = RegExp(reRegExpChar.source);
export function escapeRegExp(s: string) { export function escapeRegExp(s: string) {
return s && reHasRegExpChar.test(s) ? s.replace(reRegExpChar, '\\$&') : s; return XRegExp.escape(s);
} }

View File

@ -1,5 +1,6 @@
import { App, TFile } from 'obsidian'; import { App, TFile } from 'obsidian';
import BulkRenamePlugin from '../../main'; import BulkRenamePlugin from '../../main';
import XRegExp from 'xregexp';
export const getObsidianFilesByFolderName = ( export const getObsidianFilesByFolderName = (
app: App, app: App,
@ -21,14 +22,19 @@ export const getObsidianFilesByRegExp = (
app: App, app: App,
plugin: BulkRenamePlugin, plugin: BulkRenamePlugin,
) => { ) => {
const { userRegExp } = plugin.settings; const { regExpState } = plugin.settings;
const regExp = XRegExp(regExpState.regExp, regExpState.flags.join(''));
const abstractFiles = app.vault.getAllLoadedFiles(); const abstractFiles = app.vault.getAllLoadedFiles();
const files = abstractFiles.filter( const matchedFileNames = abstractFiles.filter((file) => {
(file) => file instanceof TFile && file.parent.name.includes(userRegExp), if (file instanceof TFile && XRegExp.match(file.path, regExp)) {
) as TFile[]; return true;
}
}) as TFile[];
const filesSortedByName = sortFilesByName(files); const filesSortedByName = sortFilesByName(matchedFileNames);
return filesSortedByName; return filesSortedByName;
}; };

View File

@ -34,9 +34,6 @@ export class RegExpFlagsSuggest extends TextInputSuggest<RegExpFlag> {
} }
target.classList.toggle('bulk-flag-selected'); target.classList.toggle('bulk-flag-selected');
this.inputEl.value = regExpState.flags.join(''); this.inputEl.value = regExpState.flags.join('');
// this.inputEl.trigger('input'); this.inputEl.trigger('input');
// this.settings.plugin.settings.regExpState.flags.push(file);
// this.inputEl.trigger('input');
// this.close();
}; };
} }