replace full path during replacement

This commit is contained in:
Oleg 2022-08-27 12:06:35 +03:00
parent 2eef8f00b1
commit 3e30b9b546
7 changed files with 28 additions and 159 deletions

View File

@ -1,35 +0,0 @@
import { Notice } from 'obsidian';
export class TemplaterError extends Error {
constructor(msg: string, public console_msg?: string) {
super(msg);
this.name = this.constructor.name;
Error.captureStackTrace(this, this.constructor);
}
}
export function log_error(e: Error | TemplaterError): void {
const notice = new Notice('', 8000);
if (e instanceof TemplaterError && e.console_msg) {
// TODO: Find a better way for this
// @ts-ignore
notice.noticeEl.innerHTML = `<b>Templater Error</b>:<br/>${e.message}<br/>Check console for more information`;
console.error(`Templater Error:`, e.message, '\n', e.console_msg);
} else {
// @ts-ignore
notice.noticeEl.innerHTML = `<b>Templater Error</b>:<br/>${e.message}`;
}
}
export function errorWrapperSync<T>(fn: () => T, msg: string): T {
try {
return fn();
} catch (e) {
log_error(new TemplaterError(msg, e.message));
return null;
}
}
export enum FileSuggestMode {
TemplateFiles,
ScriptFiles,
}

View File

@ -1,43 +0,0 @@
import {
App,
normalizePath,
TAbstractFile,
TFile,
TFolder,
Vault,
} from 'obsidian';
import { TemplaterError } from '../errors/errors';
export function resolveFolder(app: App, folder_str: string): TFolder {
folder_str = normalizePath(folder_str);
const folder = app.vault.getAbstractFileByPath(folder_str);
if (!folder) {
throw new TemplaterError(`Folder "${folder_str}" doesn't exist`);
}
if (!(folder instanceof TFolder)) {
throw new TemplaterError(`${folder_str} is a file, not a folder`);
}
return folder;
}
export function getFilesFromTheFolder(
app: App,
folder_str: string,
): Array<TFile> {
const folder = resolveFolder(app, folder_str);
const files: Array<TFile> = [];
Vault.recurseChildren(folder, (file: TAbstractFile) => {
if (file instanceof TFile) {
files.push(file);
}
});
files.sort((a, b) => {
return a.basename.localeCompare(b.basename);
});
return files;
}

47
main.ts
View File

@ -1,13 +1,5 @@
import { import { App, Plugin, PluginSettingTab, Setting, TFile } from 'obsidian';
App, import { FolderSuggest } from './suggestions/folderSuggest';
FileManager,
Plugin,
PluginSettingTab,
Setting,
TAbstractFile,
TFile,
} from 'obsidian';
import { FolderSuggest } from './suggest/folderSuggest';
interface MyPluginSettings { interface MyPluginSettings {
folderName: string; folderName: string;
@ -95,6 +87,7 @@ class BulkRenameSettingsTab extends PluginSettingTab {
}); });
}); });
} }
renderFileLocation() { renderFileLocation() {
const { settings } = this.plugin; const { settings } = this.plugin;
new Setting(this.containerEl) new Setting(this.containerEl)
@ -133,12 +126,14 @@ class BulkRenameSettingsTab extends PluginSettingTab {
text.setDisabled(true); text.setDisabled(true);
const previewLabel = createPreviewElement(); const previewLabel = createPreviewElement();
text.inputEl.insertAdjacentElement('afterend', previewLabel); text.inputEl.insertAdjacentElement('afterend', previewLabel);
text.inputEl.addClass('templater_cmd');
}) })
.addTextArea((text) => { .addTextArea((text) => {
replacedPreviewTextArea = text.inputEl; replacedPreviewTextArea = text.inputEl;
const value = getRenderedFileNamesReplaced(this.plugin); const value = getRenderedFileNamesReplaced(this.plugin);
text.setValue(value); text.setValue(value);
text.setDisabled(true); text.setDisabled(true);
text.inputEl.addClass('templater_cmd');
}) })
.then((setting) => { .then((setting) => {
syncScrolls(existingFilesTextArea, replacedPreviewTextArea, this.state); syncScrolls(existingFilesTextArea, replacedPreviewTextArea, this.state);
@ -146,7 +141,6 @@ class BulkRenameSettingsTab extends PluginSettingTab {
} }
renderRenameFiles() { renderRenameFiles() {
const { settings } = this.plugin;
new Setting(this.containerEl) new Setting(this.containerEl)
.setName('Replace pattern') .setName('Replace pattern')
.setDesc('Files in this folder will be available renamed.') .setDesc('Files in this folder will be available renamed.')
@ -154,12 +148,19 @@ class BulkRenameSettingsTab extends PluginSettingTab {
button.setButtonText('Rename'); button.setButtonText('Rename');
button.onClick(() => { button.onClick(() => {
const { replacePattern, existingSymbol } = this.plugin.settings; const { replacePattern, existingSymbol } = this.plugin.settings;
const firstFile = this.plugin.settings.fileNames[0]; if (!replacePattern || !existingSymbol) {
console.log(firstFile); return;
}
this.plugin.settings.fileNames.forEach((fileName) => {
this.app.fileManager.renameFile(
fileName,
replaceFilePath(this.plugin, fileName),
);
});
}); });
}) })
.addText((cb) => {}); .addText((cb) => {});
const fileManager = new FileManager();
this.plugin.settings.fileNames; this.plugin.settings.fileNames;
} }
} }
@ -188,24 +189,30 @@ const prepareFileNameString = (filesNames: TFile[]) => {
filesNames.forEach((fileName, index) => { filesNames.forEach((fileName, index) => {
const isLast = index + 1 === filesNames.length; const isLast = index + 1 === filesNames.length;
if (isLast) { if (isLast) {
return (value += fileName.name); return (value += fileName.path);
} }
value += fileName.name + '\r\n'; value += fileName.path + '\r\n';
}); });
return value; return value;
}; };
const getRenderedFileNamesReplaced = (plugin: MyPlugin) => { const getRenderedFileNamesReplaced = (plugin: MyPlugin) => {
const { fileNames, replacePattern, existingSymbol } = plugin.settings; const { fileNames } = plugin.settings;
const newFiles = fileNames.map((file) => { const newFiles = fileNames.map((file) => {
return { return {
...file, ...file,
name: file.name.replaceAll(existingSymbol, replacePattern), path: replaceFilePath(plugin, file),
}; };
}); });
return prepareFileNameString(newFiles); return prepareFileNameString(newFiles);
}; };
const replaceFilePath = (plugin: MyPlugin, file: TFile) => {
const { replacePattern, existingSymbol } = plugin.settings;
return file.path.replaceAll(existingSymbol, replacePattern);
};
const createPreviewElement = () => { const createPreviewElement = () => {
const previewLabel = window.document.createElement('span'); const previewLabel = window.document.createElement('span');
previewLabel.className = 'previewLabel'; previewLabel.className = 'previewLabel';
@ -220,14 +227,14 @@ const syncScrolls = (
state: State, state: State,
) => { ) => {
existingFilesArea.addEventListener('scroll', (event) => { existingFilesArea.addEventListener('scroll', (event) => {
const target = event.target; const target = event.target as HTMLTextAreaElement;
if (target.scrollTop !== state.previewScroll) { if (target.scrollTop !== state.previewScroll) {
previewArea.scrollTop = target.scrollTop; previewArea.scrollTop = target.scrollTop;
state.previewScroll = target.scrollTop; state.previewScroll = target.scrollTop;
} }
}); });
previewArea.addEventListener('scroll', (event) => { previewArea.addEventListener('scroll', (event) => {
const target = event.target; const target = event.target as HTMLTextAreaElement;
if (target.scrollTop !== state.filesScroll) { if (target.scrollTop !== state.filesScroll) {
existingFilesArea.scrollTop = target.scrollTop; existingFilesArea.scrollTop = target.scrollTop;
state.filesScroll = target.scrollTop; state.filesScroll = target.scrollTop;

View File

@ -1,6 +1,6 @@
{ {
"name": "obsidian-bulk-rename", "name": "obsidian-bulk-rename",
"version": "1.0.0", "version": "0.0.1",
"description": "Purpose of this plugin rename files based on pattern", "description": "Purpose of this plugin rename files based on pattern",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {

View File

@ -1,60 +0,0 @@
// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes
import { App, TAbstractFile, TextAreaComponent, TFile } from 'obsidian';
import { TextInputSuggest } from './suggest';
import TemplaterPlugin from 'main';
import { errorWrapperSync } from '../errors/errors';
import { getFilesFromTheFolder } from '../files/files';
export class FileSuggest extends TextInputSuggest<TFile> {
constructor(
public app: App,
public inputEl: any,
private plugin: TemplaterPlugin,
) {
super(app, inputEl);
}
getFolder(): string {
return this.plugin.settings.mySetting;
}
get_error_msg(): string {
return `Templates folder doesn't exist`;
}
getSuggestions(input_str: string): TFile[] {
const all_files = errorWrapperSync(
() => getFilesFromTheFolder(this.app, this.getFolder()),
this.get_error_msg(),
);
if (!all_files) {
return [];
}
const files: TFile[] = [];
const lower_input_str = input_str.toLowerCase();
all_files.forEach((file: TAbstractFile) => {
if (
file instanceof TFile &&
file.extension === 'md' &&
file.path.toLowerCase().contains(lower_input_str)
) {
files.push(file);
}
});
return files;
}
renderSuggestion(file: TFile, el: HTMLElement): void {
el.setText(file.path);
}
selectSuggestion(file: TFile): void {
this.inputEl.value = file.path;
this.inputEl.trigger('input');
this.close();
}
}