diff --git a/manifest.json b/manifest.json index 886d7f5..fd57f0b 100644 --- a/manifest.json +++ b/manifest.json @@ -5,5 +5,5 @@ "author": "lazyloong", "minAppVersion": "1.0.0", - "version": "2.17.3" + "version": "2.18.0" } diff --git a/src/editorSuggest/tagEditorSuggest.ts b/src/editorSuggest/tagEditorSuggest.ts index 0b6377a..786639c 100644 --- a/src/editorSuggest/tagEditorSuggest.ts +++ b/src/editorSuggest/tagEditorSuggest.ts @@ -148,7 +148,6 @@ export default class TagEditorSuggest extends EditorSuggest> { return matchData; } renderSuggestion(matchData: MatchData, el: HTMLElement) { - el.addClass("fz-item"); new SuggestionRenderer(el).render(matchData); } selectSuggestion(matchData: MatchData): void { diff --git a/src/main.ts b/src/main.ts index 7f61fc8..51c94c0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -14,6 +14,7 @@ import FuzzyFileModal from "@/modal/fileModal"; import FuzzyFolderModal from "@/modal/folderModal"; import FuzzyCommandModal from "@/modal/commandModal"; import FuzzySuggestModal from "@/modal/suggestModal"; +import FuzzyHeadingModal from "@/modal/headingModal"; import FileEditorSuggest from "@/editorSuggest/fileEditorSuggest"; import TagEditorSuggest from "@/editorSuggest/tagEditorSuggest"; // 以下两个字典来源于:https://github.com/xmflswood/pinyin-match @@ -36,6 +37,7 @@ export default class FuzzyChinesePinyinPlugin extends Plugin { fileModal: FuzzyFileModal; folderModal: FuzzyFolderModal; commandModal: FuzzyCommandModal; + headingModal: FuzzyHeadingModal; fileEditorSuggest: FileEditorSuggest; tagEditorSuggest: TagEditorSuggest; indexManager: IndexManager; @@ -49,6 +51,7 @@ export default class FuzzyChinesePinyinPlugin extends Plugin { this.fileModal = new FuzzyFileModal(this.app, this); this.folderModal = new FuzzyFolderModal(this.app, this); this.commandModal = new FuzzyCommandModal(this.app, this); + this.headingModal = new FuzzyHeadingModal(this.app, this); this.fileEditorSuggest = new FileEditorSuggest(this.app, this); this.tagEditorSuggest = new TagEditorSuggest(this.app, this); @@ -149,6 +152,18 @@ export default class FuzzyChinesePinyinPlugin extends Plugin { return true; }, }); + this.addCommand({ + id: "search-heading", + name: "Search Heading", + checkCallback: (checking: boolean) => { + if (!checking) { + const file = this.app.workspace.getActiveFile(); + this.headingModal.setFile(file); + this.headingModal.open(); + } + return true; + }, + }); } onunload() { if (this.settings.other.devMode) { diff --git a/src/modal/commandModal.ts b/src/modal/commandModal.ts index 792795a..bd09209 100644 --- a/src/modal/commandModal.ts +++ b/src/modal/commandModal.ts @@ -141,8 +141,6 @@ export default class FuzzyCommandModal extends FuzzyModal { this.app.commands.executeCommand(matchData.item.command); } renderSuggestion(matchData: MatchData, el: HTMLElement): void { - el.addClass("fz-item"); - let renderer = new SuggestionRenderer(el); renderer.render(matchData); diff --git a/src/modal/fileModal.ts b/src/modal/fileModal.ts index 960f7d9..4b0e969 100644 --- a/src/modal/fileModal.ts +++ b/src/modal/fileModal.ts @@ -239,7 +239,6 @@ export default class FuzzyFileModal extends FuzzyModal { } renderSuggestion(matchData: MatchData, el: HTMLElement) { - el.addClass("fz-item"); let renderer = new SuggestionRenderer(el); if (matchData.item.file) renderer.setNote(matchData.item.path); if (matchData.usePath) renderer.setToHighlightEl("note"); diff --git a/src/modal/headingModal.ts b/src/modal/headingModal.ts new file mode 100644 index 0000000..5d63a8b --- /dev/null +++ b/src/modal/headingModal.ts @@ -0,0 +1,51 @@ +import { App, TFile } from "obsidian"; +import FuzzyChinesePinyinPlugin from "@/main"; +import { MatchData, Pinyin, SuggestionRenderer, Item as uItem } from "@/utils"; +import FuzzyModal from "./modal"; + +interface Item extends uItem { + level: number; +} + +export default class FuzzyHeadingModal extends FuzzyModal { + file: TFile; + constructor(app: App, plugin: FuzzyChinesePinyinPlugin) { + super(app, plugin); + this.index = {} as any; + } + setFile(file: TFile) { + this.file = file; + let heading = app.metadataCache.getFileCache(file)?.headings; + if (!heading) return; + if (!this.plugin.settings.heading.showFirstLevelHeading) + heading = heading.filter((h) => h.level > 1); + this.index.items = heading.map((h) => ({ + name: h.heading, + pinyin: new Pinyin(h.heading, this.plugin), + level: h.level, + })) as Item[]; + } + getEmptyInputSuggestions(): MatchData[] { + return this.index.items.map((p) => ({ + item: p, + score: -1, + range: null, + })); + } + onChooseSuggestion(matchData: MatchData, evt: KeyboardEvent | MouseEvent): void { + const leaf = app.workspace.getMostRecentLeaf(); + leaf.openLinkText("#" + matchData.item.name, this.file.path); + } + renderSuggestion(matchData: MatchData, el: HTMLElement): void { + let renderer = new SuggestionRenderer(el); + renderer.render(matchData); + renderer.addIcon("heading-" + matchData.item.level); + if (this.plugin.settings.heading.headingIndent) { + let indent = this.plugin.settings.heading.showFirstLevelHeading + ? matchData.item.level - 1 + : matchData.item.level - 2; + indent *= 15; + renderer.titleEl.style.marginLeft = indent + "px"; + } + } +} diff --git a/src/modal/modal.ts b/src/modal/modal.ts index f17c21a..27b37de 100644 --- a/src/modal/modal.ts +++ b/src/modal/modal.ts @@ -86,7 +86,6 @@ export default abstract class FuzzyModal extends SuggestModal, el: HTMLElement) { - el.addClass("fz-item"); new SuggestionRenderer(el).render(matchData); } onNoSuggestion(value?: MatchData): void { diff --git a/src/settingTab.ts b/src/settingTab.ts index 7f75232..6eeef05 100644 --- a/src/settingTab.ts +++ b/src/settingTab.ts @@ -14,6 +14,7 @@ export default class SettingTab extends PluginSettingTab { this.containerEl.createEl("h1", { text: "设置" }); this.addGlobalSetting(); this.addFileSetting(); + this.addHeadingSetting(); this.addCommandSettings(); this.addOtherSetting(); } @@ -158,6 +159,23 @@ export default class SettingTab extends PluginSettingTab { ); }); } + addHeadingSetting() { + this.containerEl.createEl("h2", { text: "标题搜索" }); + new Setting(this.containerEl).setName("显示第一级标题").addToggle((cb) => + cb + .setValue(this.plugin.settings.heading.showFirstLevelHeading) + .onChange(async (value) => { + this.plugin.settings.heading.showFirstLevelHeading = value; + await this.plugin.saveSettings(); + }) + ); + new Setting(this.containerEl).setName("搜索结果缩进").addToggle((cb) => + cb.setValue(this.plugin.settings.heading.headingIndent).onChange(async (value) => { + this.plugin.settings.heading.headingIndent = value; + await this.plugin.saveSettings(); + }) + ); + } addCommandSettings() { this.containerEl.createEl("h2", { text: "命令" }); this.addPinnedCommands(); @@ -178,7 +196,12 @@ export default class SettingTab extends PluginSettingTab { }); } addPinnedCommands() { - this.plugin.settings.command.pinnedCommands.forEach((command, index) => { + const { pinnedCommands } = this.plugin.settings.command; + if (pinnedCommands.length === 0) { + new Setting(this.containerEl).setName("没有置顶命令"); + return; + } + pinnedCommands.forEach((command, index) => { new Setting(this.containerEl) .setName(command) .addExtraButton((cb) => @@ -274,6 +297,10 @@ export interface FuzyyChinesePinyinSettings { showTags: boolean; searchWithTag: boolean; }; + heading: { + showFirstLevelHeading: boolean; + headingIndent: boolean; + }; command: { pinnedCommands: Array; }; @@ -323,6 +350,10 @@ export const DEFAULT_SETTINGS: FuzyyChinesePinyinSettings = { showTags: false, searchWithTag: true, }, + heading: { + showFirstLevelHeading: true, + headingIndent: true, + }, command: { pinnedCommands: [], }, diff --git a/src/utils.ts b/src/utils.ts index d5fe445..fb310a8 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -278,6 +278,7 @@ export class SuggestionRenderer { note: string = ""; hasIcon: boolean = false; constructor(containerEl: HTMLElement) { + containerEl.addClass("fz-item"); this.containerEl = containerEl; this.contentEl = this.containerEl.createEl("div", { cls: "fz-suggestion-content" }); this.titleEl = this.contentEl.createEl("div", { cls: "fz-suggestion-title" });