diff --git a/manifest.json b/manifest.json index 67b876f..be6bec2 100644 --- a/manifest.json +++ b/manifest.json @@ -5,5 +5,5 @@ "author": "lazyloong", "minAppVersion": "1.0.0", - "version": "2.11.1" + "version": "2.12.0" } diff --git a/package.json b/package.json index 3bf390c..fa6efe9 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,8 @@ "devDependencies": { "builtin-modules": "^3.3.0", "obsidian": "github:obsidianmd/obsidian-api", - "templater": "github:SilentVoid13/Templater", "obsidian-plugin-cli": "^0.9.0", + "templater": "github:SilentVoid13/Templater", "typescript": "^4.9.5" } } diff --git a/src/fuzzyFolderModal.ts b/src/fuzzyFolderModal.ts index 81a0e65..538d6b5 100644 --- a/src/fuzzyFolderModal.ts +++ b/src/fuzzyFolderModal.ts @@ -4,6 +4,7 @@ import { PinyinIndex as PI, Item, MatchData, Pinyin } from "./utils"; import FuzzyChinesePinyinPlugin from "./main"; export default class FuzzyFolderModal extends FuzzyModal { + toMoveFiles: TAbstractFile | TFile[]; constructor(app: App, plugin: FuzzyChinesePinyinPlugin) { super(app, plugin); this.useInput = true; @@ -34,6 +35,7 @@ export default class FuzzyFolderModal extends FuzzyModal { let file = app.workspace.getActiveFile(); app.vault.rename(file, this.getChoosenItem().item.name + "/" + file.name); }); + this.toMoveFiles = null; } getEmptyInputSuggestions(): MatchData[] { let root = app.vault.getRoot(); @@ -61,10 +63,18 @@ export default class FuzzyFolderModal extends FuzzyModal { } return result.slice(0, 20); } - async onChooseSuggestion(matchData: MatchData, evt: MouseEvent | KeyboardEvent): Promise { + async onChooseSuggestion( + matchData: MatchData, + evt: MouseEvent | KeyboardEvent + ): Promise { if (matchData.score == -1) await app.vault.createFolder(matchData.item.name); - let file = app.workspace.getActiveFile(); - app.vault.rename(file, matchData.item.name + "/" + file.name); + if (!this.toMoveFiles) this.toMoveFiles = app.workspace.getActiveFile(); + if (Array.isArray(this.toMoveFiles)) + this.toMoveFiles.forEach((file) => + app.vault.rename(file, matchData.item.name + "/" + file.name) + ); + else app.vault.rename(this.toMoveFiles, matchData.item.name + "/" + this.toMoveFiles.name); + this.toMoveFiles = null; } } @@ -90,7 +100,9 @@ class PinyinIndex extends PI { iterate(root, new Pinyin("", this.plugin)); } initEvent() { - this.registerEvent(this.vault.on("rename", (folder, oldPath) => this.update("rename", folder, { oldPath }))); + this.registerEvent( + this.vault.on("rename", (folder, oldPath) => this.update("rename", folder, { oldPath })) + ); this.registerEvent(this.vault.on("create", (folder) => this.update("create", folder))); this.registerEvent(this.vault.on("delete", (folder) => this.update("delete", folder))); } @@ -99,14 +111,20 @@ class PinyinIndex extends PI { let folder = f as TFolder; switch (type) { case "create": - this.items.push({ name: folder.path, pinyin: new Pinyin(folder.path, this.plugin) }); + this.items.push({ + name: folder.path, + pinyin: new Pinyin(folder.path, this.plugin), + }); break; case "delete": this.items = this.items.filter((item) => item.name == folder.path); break; case "rename": this.items = this.items.filter((item) => item.name == data.oldPath); - this.items.push({ name: folder.path, pinyin: new Pinyin(folder.path, this.plugin) }); + this.items.push({ + name: folder.path, + pinyin: new Pinyin(folder.path, this.plugin), + }); break; } } diff --git a/src/main.ts b/src/main.ts index 9fb8994..8862a2e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,11 +1,11 @@ -import { Plugin, EditorSuggest } from "obsidian"; +import { Plugin, EditorSuggest, WorkspaceLeaf, Menu, TFile, TAbstractFile } from "obsidian"; import { fullPinyin2doublePinyin, Item, PinyinIndex, runOnLayoutReady } from "./utils"; import FuzzyModal from "./fuzzyModal"; import FuzzyFileModal from "./fuzzyFileModal"; import FuzzyFolderModal from "./fuzzyFolderModal"; import FuzzyCommandModal from "./fuzzyCommandModal"; import FileEditorSuggest from "./fileEditorSuggest"; -import TagEditorSuggest from "./tagEditorSuggest"; +import TagEditorSuggest, { addMetadataEditor } from "./tagEditorSuggest"; import FuzzySuggestModal from "./fuzzySuggestModal"; // 以下两个字典来源于:https://github.com/xmflswood/pinyin-match import SimplifiedDict from "./simplified_dict"; @@ -101,18 +101,6 @@ export default class FuzzyChinesePinyinPlugin extends Plugin { indexManager: IndexManager; editorSuggests: EditorSuggest[]; - loadPinyinDict() { - let PinyinKeys_ = this.settings.global.traditionalChineseSupport ? Object.keys(TraditionalDict) : Object.keys(SimplifiedDict); - let PinyinValues = this.settings.global.traditionalChineseSupport ? Object.values(TraditionalDict) : Object.values(SimplifiedDict); - let PinyinKeys = - this.settings.global.doublePinyin == "全拼" - ? PinyinKeys_ - : PinyinKeys_.map((p) => fullPinyin2doublePinyin(p, DoublePinyinDict[this.settings.global.doublePinyin])); - - // originalKeys 永远是全拼的拼音,keys 是转换后的拼音(可能也是全拼或双拼) - this.pinyinDict = { keys: PinyinKeys, values: PinyinValues, originalKeys: PinyinKeys_ }; - } - async onload() { await this.loadSettings(); @@ -123,7 +111,12 @@ export default class FuzzyChinesePinyinPlugin extends Plugin { this.fileEditorSuggest = new FileEditorSuggest(this.app, this); this.tagEditorSuggest = new TagEditorSuggest(this.app, this); - this.indexManager = new IndexManager(this, [this.folderModal, this.fileModal, this.commandModal, this.tagEditorSuggest]); + this.indexManager = new IndexManager(this, [ + this.folderModal, + this.fileModal, + this.commandModal, + this.tagEditorSuggest, + ]); this.editorSuggests = [this.fileEditorSuggest, this.tagEditorSuggest]; if (this.settings.file.useFileEditorSuggest) { @@ -133,6 +126,8 @@ export default class FuzzyChinesePinyinPlugin extends Plugin { this.app.workspace.editorSuggest.suggests.unshift(this.tagEditorSuggest); } + this.registerFileMenu(); + runOnLayoutReady(() => { if (this.settings.other.devMode) { this.indexManager.devLoad(); @@ -193,12 +188,15 @@ export default class FuzzyChinesePinyinPlugin extends Plugin { this.addSettingTab(new SettingTab(this.app, this)); this.api = { suggester: this.suggester, - search: (query: string, items: string[] | Item[]) => fuzzyPinyinSearch(query, items, this), + search: (query: string, items: string[] | Item[]) => + fuzzyPinyinSearch(query, items, this), stringArray2Items: stringArray2Items, }; } onunload() { - this.editorSuggests.forEach((editorSuggest) => this.app.workspace.editorSuggest.removeSuggest(editorSuggest)); + this.editorSuggests.forEach((editorSuggest) => + this.app.workspace.editorSuggest.removeSuggest(editorSuggest) + ); if (this.settings.other.devMode) { this.indexManager.devUnload(); } @@ -209,16 +207,68 @@ export default class FuzzyChinesePinyinPlugin extends Plugin { async saveSettings() { await this.saveData(this.settings); } + loadPinyinDict() { + let PinyinKeys_ = this.settings.global.traditionalChineseSupport + ? Object.keys(TraditionalDict) + : Object.keys(SimplifiedDict); + let PinyinValues = this.settings.global.traditionalChineseSupport + ? Object.values(TraditionalDict) + : Object.values(SimplifiedDict); + let PinyinKeys = + this.settings.global.doublePinyin == "全拼" + ? PinyinKeys_ + : PinyinKeys_.map((p) => + fullPinyin2doublePinyin( + p, + DoublePinyinDict[this.settings.global.doublePinyin] + ) + ); + + // originalKeys 永远是全拼的拼音,keys 是转换后的拼音(可能也是全拼或双拼) + this.pinyinDict = { keys: PinyinKeys, values: PinyinValues, originalKeys: PinyinKeys_ }; + } async suggester(text_items: string[], items: any[]): Promise { let modal = new FuzzySuggestModal(app, this, text_items, items); - const promise: Promise = new Promise((resolve: (value?: string) => void, reject) => modal.openAndGetValue(resolve, reject)); + const promise: Promise = new Promise((resolve: (value?: string) => void, reject) => + modal.openAndGetValue(resolve, reject) + ); return await promise; } + registerFileMenu() { + this.registerEvent( + this.app.workspace.on("file-menu", (menu: Menu, file: TAbstractFile) => { + let title = file instanceof TFile ? "文件" : "文件夹"; + menu.addItem((item) => { + item.setIcon("folder-tree") + .setTitle("FuzzyPinyin: 移动" + title) + .onClick(() => { + this.folderModal.toMoveFiles = file; + this.folderModal.open(); + }); + }); + }) + ); + this.registerEvent( + this.app.workspace.on("files-menu", (menu: Menu, files: TFile[]) => { + menu.addItem((item) => { + item.setIcon("folder-tree") + .setTitle(`FuzzyPinyin: 移动${files.length}个文件`) + .onClick(() => { + this.folderModal.toMoveFiles = files; + this.folderModal.open(); + }); + }); + }) + ); + } } class IndexManager extends Array> { plugin: FuzzyChinesePinyinPlugin; - constructor(plugin: FuzzyChinesePinyinPlugin, component: Array | EditorSuggest>) { + constructor( + plugin: FuzzyChinesePinyinPlugin, + component: Array | EditorSuggest> + ) { super(); component.forEach((p: any) => this.push(p.index)); this.plugin = plugin; @@ -230,9 +280,9 @@ class IndexManager extends Array> { let startTime = Date.now(); index.initIndex(); console.log( - `Fuzzy Chinese Pinyin: ${index.id} indexing completed, totaling ${index.items.length} items, taking ${ - (Date.now() - startTime) / 1000.0 - }s` + `Fuzzy Chinese Pinyin: ${index.id} indexing completed, totaling ${ + index.items.length + } items, taking ${(Date.now() - startTime) / 1000.0}s` ); } devLoad() { diff --git a/src/tagEditorSuggest.ts b/src/tagEditorSuggest.ts index d83b8ac..a06ee6a 100644 --- a/src/tagEditorSuggest.ts +++ b/src/tagEditorSuggest.ts @@ -1,6 +1,16 @@ -import { App, Editor, EditorPosition, EditorSuggest, EditorSuggestContext, EditorSuggestTriggerInfo, TFile } from "obsidian"; +import { + App, + Editor, + EditorPosition, + EditorSuggest, + EditorSuggestContext, + EditorSuggestTriggerInfo, + TFile, + WorkspaceLeaf, +} from "obsidian"; import { PinyinIndex as PI, HistoryMatchDataNode, Pinyin, MatchData, Item } from "./utils"; import FuzzyChinesePinyinPlugin from "./main"; +import { TextInputSuggest } from "templater/src/settings/suggesters/suggest"; export default class TagEditorSuggest extends EditorSuggest> { plugin: FuzzyChinesePinyinPlugin; @@ -18,7 +28,9 @@ export default class TagEditorSuggest extends EditorSuggest> { lineContent = editor.getLine(lineIndex), sub = lineContent.substr(0, cursor.ch); if ( - sub.match(/(^|\s)#[^\u2000-\u206F\u2E00-\u2E7F'!"#$%&()*+,.:;<=>?@^`{|}~\[\]\\\s]*$/g) && + sub.match( + /(^|\s)#[^\u2000-\u206F\u2E00-\u2E7F'!"#$%&()*+,.:;<=>?@^`{|}~\[\]\\\s]*$/g + ) && "#" !== lineContent.substr(cursor.ch, 1) ) { this.isYaml = false; @@ -36,7 +48,8 @@ export default class TagEditorSuggest extends EditorSuggest> { query: s, }; } - let frontmatterPosition = (app.metadataCache.getFileCache(file) as any)?.frontmatterPosition; + let frontmatterPosition = (app.metadataCache.getFileCache(file) as any) + ?.frontmatterPosition; if ( sub.match(/tags?: /) && frontmatterPosition &&