From ee75e93fc38eddcd64c6f51c7eeaa5b7633c35f3 Mon Sep 17 00:00:00 2001 From: RavenHogWarts Date: Sun, 23 Mar 2025 18:19:17 +0800 Subject: [PATCH] Add more replication type matches. --- src/i18n.ts | 50 ++++- src/main.ts | 523 +++++++++++++++++++--------------------------- src/settingTab.ts | 151 +++++++++++++ src/type.ts | 55 +++++ 4 files changed, 457 insertions(+), 322 deletions(-) create mode 100644 src/settingTab.ts create mode 100644 src/type.ts diff --git a/src/i18n.ts b/src/i18n.ts index f512858..a3c88c3 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -7,16 +7,19 @@ export enum Language { // 定义翻译键值类型 export type TranslationKey = - | 'no-file' | 'no-content' | 'inline-code-copied' | 'block-id-copied' - | 'note-link-copied' | 'heading-copied' | 'format' - | 'add-to-menu' | 'add-to-menu-desc' | 'show-notice' | 'show-notice-desc' - | 'use-heading-as-display' | 'use-heading-as-display-desc' | 'link-format' - | 'link-format-desc' | 'markdown-link' | 'wiki-link' | 'contextual-copy' - | 'target' | 'enable-bold' | 'enable-bold-desc' | 'enable-highlight' - | 'enable-highlight-desc' | 'enable-italic' | 'enable-italic-desc' - | 'bold-copied' | 'highlight-copied' | 'italic-copied' - | 'customize-targets' | 'customize-targets-desc' | 'enable-inline-code' - | 'enable-inline-code-desc'; + | 'no-file' | 'no-content' + | 'inline-code-copied' | 'block-id-copied' | 'note-link-copied' | 'heading-copied' | 'strikethrough-copied' | 'inline-latex-copied' | 'link-copied' | 'bold-copied' | 'highlight-copied' | 'italic-copied' + | 'format' | 'add-to-menu' | 'add-to-menu-desc' | 'show-notice' | 'show-notice-desc' + | 'use-heading-as-display' | 'use-heading-as-display-desc' + | 'link-format'| 'link-format-desc' | 'markdown-link' | 'wiki-link' | 'contextual-copy' + | 'target' | 'customize-targets' | 'customize-targets-desc' + | 'enable-bold' | 'enable-bold-desc' + | 'enable-highlight'| 'enable-highlight-desc' + | 'enable-italic' | 'enable-italic-desc' + | 'enable-inline-code' | 'enable-inline-code-desc' + | 'enable-strikethrough' | 'enable-strikethrough-desc' + | 'enable-inline-latex' | 'enable-inline-latex-desc' + | 'enable-link' | 'enable-link-desc'; // 本地化翻译字典 export const translations: Record> = { @@ -31,6 +34,9 @@ export const translations: Record> = { 'bold-copied': 'Bold text copied!', 'highlight-copied': 'Highlighted text copied!', 'italic-copied': 'Italic text copied!', + 'inline-latex-copied': 'Inline LaTeX copied!', + 'strikethrough-copied': 'Strikethrough text copied!', + 'link-copied': 'Link copied!', // 设置界面 'format': 'Format', @@ -55,6 +61,12 @@ export const translations: Record> = { 'enable-highlight-desc': 'Enable copying highlighted text like ==highlight example==', 'enable-italic': 'Enable italic text', 'enable-italic-desc': 'Enable copying italic text like *italic example*', + 'enable-strikethrough': 'Enable strikethrough text', + 'enable-strikethrough-desc': 'Enable copying strikethrough text like ~~strikethrough example~~', + 'enable-inline-latex': 'Enable inline LaTeX', + 'enable-inline-latex-desc': 'Enable copying inline LaTeX like $latex example$', + 'enable-link': 'Enable link', + 'enable-link-desc': 'Enable copying link like [linktitle example](linkurl example)', // 命令名称 'contextual-copy': 'Contextual Copy' @@ -70,6 +82,9 @@ export const translations: Record> = { 'bold-copied': '加粗文本已复制!', 'highlight-copied': '高亮文本已复制!', 'italic-copied': '斜体文本已复制!', + 'inline-latex-copied': '行内LaTeX已复制!', + 'strikethrough-copied': '删除线文本已复制!', + 'link-copied': '链接已复制!', // 设置界面 'format': '格式', @@ -94,6 +109,12 @@ export const translations: Record> = { 'enable-highlight-desc': '启用复制高亮文本,如 ==高亮示例==', 'enable-italic': '启用斜体文本', 'enable-italic-desc': '启用复制斜体文本,如 *斜体示例*', + 'enable-strikethrough': '启用删除线文本', + 'enable-strikethrough-desc': '启用复制删除线文本,如 ~~删除线示例~~', + 'enable-inline-latex': '启用行内LaTeX', + 'enable-inline-latex-desc': '启用复制行内LaTeX,如 $latex 示例$', + 'enable-link': '启用链接', + 'enable-link-desc': '启用复制链接,如 [链接标题 示例](链接地址 示例)', // 命令名称 'contextual-copy': '智能复制' @@ -109,6 +130,9 @@ export const translations: Record> = { 'bold-copied': '加粗文本已複製!', 'highlight-copied': '高亮文本已複製!', 'italic-copied': '斜體文本已複製!', + 'inline-latex-copied': '行內LaTeX已複製!', + 'strikethrough-copied': '刪除線文本已複製!', + 'link-copied': '連結已複製!', // 設置界面 'format': '格式', @@ -133,6 +157,12 @@ export const translations: Record> = { 'enable-highlight-desc': '啟用複製高亮文本,如 ==高亮示例==', 'enable-italic': '啟用斜體文本', 'enable-italic-desc': '啟用複製斜體文本,如 *斜體示例*', + 'enable-strikethrough': '啟用刪除線文本', + 'enable-strikethrough-desc': '啟用複製刪除線文本,如 ~~刪除線示例~~', + 'enable-inline-latex': '啟用行內LaTeX', + 'enable-inline-latex-desc': '啟用複製行內LaTeX,如 $latex 示例$', + 'enable-link': '啟用連結', + 'enable-link-desc': '啟用複製連結,如 [連結標題 示例](連結地址 示例)', // 命令名称 'contextual-copy': '智能複製' diff --git a/src/main.ts b/src/main.ts index c5325a6..3b4f8e6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,34 +1,7 @@ -import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting, Menu } from 'obsidian'; +import { Editor, MarkdownView, Notice, Plugin, Menu } from 'obsidian'; import { Language, TranslationKey, I18n } from './i18n'; - -enum LinkFormat { - MDLINK = 'markdown-link', - WIKILINK = 'wiki-link' -} - -interface EasyCopySettings { - addToMenu: boolean; - showNotice: boolean; - useHeadingAsDisplayText: boolean; - linkFormat: LinkFormat; - customizeTargets: boolean; - enableInlineCode: boolean; - enableBold: boolean; - enableHighlight: boolean; - enableItalic: boolean; -} - -const DEFAULT_SETTINGS: EasyCopySettings = { - addToMenu: true, - showNotice: true, - useHeadingAsDisplayText: true, - linkFormat: LinkFormat.WIKILINK, - customizeTargets: false, - enableInlineCode: true, - enableBold: true, - enableHighlight: true, - enableItalic: false -} +import { ContextData, ContextType, DEFAULT_SETTINGS, EasyCopySettings, LinkFormat } from './type'; +import { EasyCopySettingTab } from './settingTab'; export default class EasyCopy extends Plugin { settings: EasyCopySettings; @@ -115,6 +88,140 @@ export default class EasyCopy extends Plugin { return this.i18n.t(key); } + /** + * 获取当前行的上下文类型 + * @param editor + * @param view + * @returns ContextData + */ + private determineContextType(editor: Editor, view: MarkdownView): ContextData { + // 获取当前文件和光标信息 + const file = view.file; + if (!file) { + new Notice(this.t('no-file')); + return { type: ContextType.NULL, curLine: '', match: null, range: null }; + } + + const cursor = editor.getCursor(); + const curLine = editor.getLine(cursor.line); + const curCh = cursor.ch; + + // 根据光标位置解析内容类型 + const beforeCursor = curLine.slice(0, curCh); // 光标前的内容 + const afterCursor = curLine.slice(curCh); // 光标后的内容 + + // 匹配优先级:加粗 > 斜体 > 高亮 > 删除线 > 行内代码 > 行内Latex > 块ID + const matchers = [ + { type: ContextType.BOLD, regex: /\*\*([^*]+)\*\*/g , enable: this.settings.enableBold}, + // 使用前后断言 (?= matchStart && beforeCursor.length <= matchEnd) { + return { + content: match[1], // 返回内容,不包括语法 + range: [matchStart, matchEnd], + }; + } + } + return null; + } + + private isCursorInLink(beforeCursor: string, afterCursor: string): {type: ContextType.LINKTITLE | ContextType.LINEURL, content: string, range: [number, number]} | null { + // 匹配链接的正则表达式 + const linkRegex = /\[([^\]]*?)\]\(([^)]*?)\)/g; + + const fullText = beforeCursor + afterCursor; + let match: RegExpExecArray | null; + while ((match = linkRegex.exec(fullText)) !== null) { + const linkStart = match.index; // 链接的起始位置 + const linkEnd = linkStart + match[0].length; // 链接的结束位置 + + // 光标位置 + const cursorPos = beforeCursor.length; + + // 判断光标是否在当前链接范围内 + if (cursorPos >= linkStart && cursorPos <= linkEnd) { + const bracketStart = linkStart + 1; // `[` 后的位置 + const bracketEnd = linkStart + match[1].length + 1; // `]` 的位置 + const parenStart = bracketEnd + 2; // `(` 后的位置 + const parenEnd = parenStart + match[2].length; // `)` 的位置 + + // 判断光标在 [] 还是 () + if (cursorPos >= bracketStart && cursorPos <= bracketEnd) { + return { type: ContextType.LINKTITLE, content: match[1], range: [bracketStart, bracketEnd] }; + } else if (cursorPos >= parenStart && cursorPos <= parenEnd) { + return { type: ContextType.LINEURL, content: match[2], range: [parenStart, parenEnd] }; + } + } + } + + // 如果光标不在任何链接中,返回 null + return null; + } + /** * 智能复制功能:根据光标位置复制不同类型的内容 * 支持复制行内代码、块ID链接和标题链接 @@ -126,141 +233,111 @@ export default class EasyCopy extends Plugin { new Notice(this.t('no-file')); return; } - - const cursor = editor.getCursor(); - const curLine = editor.getLine(cursor.line); - const curCh = cursor.ch; // 获取文件名(去除.md后缀) const filename = file.basename; - - // 1. 检查是否是标题行 - if (curLine.startsWith('#')) { - this.copyHeadingLink(curLine, filename); + + // 获取当前行的上下文类型 + const contextType = this.determineContextType(editor, view); + console.log('contextType:', contextType); + if (contextType.type == ContextType.NULL) { + new Notice(this.t('no-content')); return; } - - // 2. 检查是否包含行内代码 - if ((!this.settings.customizeTargets || this.settings.enableInlineCode) && curLine.includes('`')) { - // 尝试提取行内代码 - const inlineCode = this.getInlineCode(curLine, curCh); - if (inlineCode) { - navigator.clipboard.writeText(inlineCode); - if (this.settings.showNotice) { - new Notice(this.t('inline-code-copied')); - } - return; - } - } - - // 3. 检查是否包含块ID - if (curLine.includes('^')) { - // 尝试提取块ID - const blockId = this.getBlockId(curLine); - if (blockId) { - const blockIdLink = this.settings.linkFormat === LinkFormat.WIKILINK - ? `[[${filename}#^${blockId}]]` - : `[${blockId}](${filename}#^${blockId})`; - - navigator.clipboard.writeText(blockIdLink); - if (this.settings.showNotice) { - new Notice(this.t('block-id-copied')); - } - return; - } - } - - // 4. 检查是否包含加粗文本 - if ((!this.settings.customizeTargets || this.settings.enableBold) && curLine.includes('**')) { - const boldText = this.getBoldText(curLine, curCh); - if (boldText) { - navigator.clipboard.writeText(boldText); + + switch (contextType.type) { + case ContextType.BOLD: + navigator.clipboard.writeText(contextType.match!); if (this.settings.showNotice) { new Notice(this.t('bold-copied')); } return; - } - } - - // 5. 检查是否包含高亮文本 - if ((!this.settings.customizeTargets || this.settings.enableHighlight) && curLine.includes('==')) { - const highlightText = this.getHighlightText(curLine, curCh); - if (highlightText) { - navigator.clipboard.writeText(highlightText); - if (this.settings.showNotice) { - new Notice(this.t('highlight-copied')); - } - return; - } - } - - // 6. 检查是否包含斜体文本 - if ((!this.settings.customizeTargets || this.settings.enableItalic) && (curLine.includes('*') || curLine.includes('_'))) { - const italicText = this.getItalicText(curLine, curCh); - if (italicText) { - navigator.clipboard.writeText(italicText); + case ContextType.ITALIC: + navigator.clipboard.writeText(contextType.match!); if (this.settings.showNotice) { new Notice(this.t('italic-copied')); } return; - } + case ContextType.HIGHLIGHT: + navigator.clipboard.writeText(contextType.match!); + if (this.settings.showNotice) { + new Notice(this.t('highlight-copied')); + } + return; + case ContextType.STRIKETHROUGH: + navigator.clipboard.writeText(contextType.match!); + if (this.settings.showNotice) { + new Notice(this.t('strikethrough-copied')); + } + return; + case ContextType.INLINECODE: + navigator.clipboard.writeText(contextType.match!); + if (this.settings.showNotice) { + new Notice(this.t('inline-code-copied')); + } + return; + case ContextType.INLINELATEX: + navigator.clipboard.writeText(contextType.match!); + if (this.settings.showNotice) { + new Notice(this.t('inline-latex-copied')); + } + return; + + case ContextType.LINKTITLE: + case ContextType.LINEURL: + // 复制链接标题或链接地址 + navigator.clipboard.writeText(contextType.match!); + if (this.settings.showNotice) { + new Notice(this.t('link-copied')); + } + return; + case ContextType.BLOCKID: + { + const blockIdLink = this.settings.linkFormat === LinkFormat.WIKILINK + ? `[[${filename}#^${contextType.match!}]]` + : `[${contextType.match!}](${filename}#^${contextType.match!})`; + navigator.clipboard.writeText(blockIdLink); + } + if (this.settings.showNotice) { + new Notice(this.t('block-id-copied')); + } + return; + case ContextType.HEADING: + this.copyHeadingLink(contextType.match!, filename); + return; + default: + break; } - - // 如果没有找到可复制的内容 - new Notice(this.t('no-content')); - } - - /** - * 提取行内代码 - */ - private getInlineCode(str: string, cursor: number): string | null { - const start = str.lastIndexOf('`', cursor - 1); - const end = str.indexOf('`', cursor); - - if (start === -1 || end === -1) { - return null; - } - - return str.substring(start + 1, end); - } - - /** - * 提取块ID - */ - private getBlockId(str: string): string | null { - // 提取当前光标所在行的像是 ^block-id-123 这样的 block id - const regex = /(?:^|\s+)\^([a-zA-Z0-9_-]+)(?:\s*|$)/; - const match = str.match(regex); - - if (match) { - return match[1]; - } - - return null; } /** * 复制标题链接 */ - private copyHeadingLink(headingLine: string, filename: string): void { + private copyHeadingLink(content: string, filename: string): void { // 提取标题文本和级别 - const selectedHeading = headingLine.replace(/#+\s+/, "#"); - const linkAlias = selectedHeading.replace(/#+\s*/, ""); - + let selectedHeading = content; + // 如果内容是[[内容]],移除[[]] + if (selectedHeading.startsWith('[[') && selectedHeading.endsWith(']]')) { + selectedHeading = selectedHeading.slice(2, -2); + } + const linkAlias = selectedHeading; + let noteFlag = 0; + let headingReferenceLink = ""; // 根据设置选择链接格式 if (this.settings.linkFormat === LinkFormat.WIKILINK) { // Wiki链接格式 - headingReferenceLink = `[[${filename}${selectedHeading}|${linkAlias}]]`; + headingReferenceLink = `[[${filename}#${selectedHeading}|${linkAlias}]]`; // 处理同名标题的特殊情况 if (this.settings.useHeadingAsDisplayText && filename === linkAlias) { headingReferenceLink = `[[${filename}]]`; + noteFlag = 1; } } else { // Markdown链接格式 - headingReferenceLink = `[${linkAlias}](${filename}${selectedHeading})`; + headingReferenceLink = `[${linkAlias}](${filename}#${selectedHeading})`; } // 复制到剪贴板 @@ -268,7 +345,7 @@ export default class EasyCopy extends Plugin { // 显示通知 if (this.settings.showNotice) { - if (headingLine.startsWith("# ")) { + if (noteFlag) { new Notice(this.t('note-link-copied')); } else { new Notice(this.t('heading-copied')); @@ -276,68 +353,6 @@ export default class EasyCopy extends Plugin { } } - /** - * 提取加粗文本 - */ - private getBoldText(str: string, cursor: number): string | null { - // 查找光标前后的 ** 标记 - const start = str.lastIndexOf('**', cursor - 1); - const end = str.indexOf('**', cursor); - - if (start === -1 || end === -1) { - return null; - } - - return str.substring(start + 2, end); - } - - /** - * 提取高亮文本 - */ - private getHighlightText(str: string, cursor: number): string | null { - // 查找光标前后的 == 标记 - const start = str.lastIndexOf('==', cursor - 1); - const end = str.indexOf('==', cursor); - - if (start === -1 || end === -1) { - return null; - } - - return str.substring(start + 2, end); - } - - /** - * 提取斜体文本 - */ - private getItalicText(str: string, cursor: number): string | null { - // 尝试查找使用 * 的斜体 - let start = str.lastIndexOf('*', cursor - 1); - if (start > 0 && str.charAt(start - 1) === '*') { - // 这可能是加粗文本的一部分,跳过 - start = str.lastIndexOf('*', start - 2); - } - - let end = str.indexOf('*', cursor); - if (end > 0 && end + 1 < str.length && str.charAt(end + 1) === '*') { - // 这可能是加粗文本的一部分,跳过 - end = str.indexOf('*', end + 2); - } - - if (start !== -1 && end !== -1) { - return str.substring(start + 1, end); - } - - // 尝试查找使用 _ 的斜体 - start = str.lastIndexOf('_', cursor - 1); - end = str.indexOf('_', cursor); - - if (start !== -1 && end !== -1) { - return str.substring(start + 1, end); - } - - return null; - } - /** * 初始化国际化设置,使用Obsidian的语言设置 */ @@ -371,119 +386,3 @@ export default class EasyCopy extends Plugin { return lang; } } - -class EasyCopySettingTab extends PluginSettingTab { - plugin: EasyCopy; - - constructor(app: App, plugin: EasyCopy) { - super(app, plugin); - this.plugin = plugin; - } - - display(): void { - const {containerEl} = this; - - containerEl.empty(); - - new Setting(containerEl) - .setName(this.plugin.t('add-to-menu')) - .setDesc(this.plugin.t('add-to-menu-desc')) - .addToggle(toggle => toggle - .setValue(this.plugin.settings.addToMenu) - .onChange(async (value) => { - this.plugin.settings.addToMenu = value; - await this.plugin.saveSettings(); - })); - - new Setting(containerEl) - .setName(this.plugin.t('show-notice')) - .setDesc(this.plugin.t('show-notice-desc')) - .addToggle(toggle => toggle - .setValue(this.plugin.settings.showNotice) - .onChange(async (value) => { - this.plugin.settings.showNotice = value; - await this.plugin.saveSettings(); - })); - - containerEl.createEl('h2', {text: this.plugin.t('format')}); - - new Setting(containerEl) - .setName(this.plugin.t('use-heading-as-display')) - .setDesc(this.plugin.t('use-heading-as-display-desc')) - .addToggle(toggle => toggle - .setValue(this.plugin.settings.useHeadingAsDisplayText) - .onChange(async (value) => { - this.plugin.settings.useHeadingAsDisplayText = value; - await this.plugin.saveSettings(); - })); - - new Setting(containerEl) - .setName(this.plugin.t('link-format')) - .setDesc(this.plugin.t('link-format-desc')) - .addDropdown(dropdown => dropdown - .addOption(LinkFormat.MDLINK, this.plugin.t('markdown-link')) - .addOption(LinkFormat.WIKILINK, this.plugin.t('wiki-link')) - .setValue(this.plugin.settings.linkFormat) - .onChange(async (value) => { - this.plugin.settings.linkFormat = value as LinkFormat; - await this.plugin.saveSettings(); - })); - - containerEl.createEl('h2', {text: this.plugin.t('target')}); - - new Setting(containerEl) - .setName(this.plugin.t('customize-targets')) - .setDesc(this.plugin.t('customize-targets-desc')) - .addToggle(toggle => toggle - .setValue(this.plugin.settings.customizeTargets) - .onChange(async (value) => { - this.plugin.settings.customizeTargets = value; - await this.plugin.saveSettings(); - // 重新渲染设置界面以显示或隐藏目标选项 - this.display(); - })); - - // 只有当自定义复制对象选项开启时才显示具体的复制对象选项 - if (this.plugin.settings.customizeTargets) { - new Setting(containerEl) - .setName(this.plugin.t('enable-inline-code')) - .setDesc(this.plugin.t('enable-inline-code-desc')) - .addToggle(toggle => toggle - .setValue(this.plugin.settings.enableInlineCode) - .onChange(async (value) => { - this.plugin.settings.enableInlineCode = value; - await this.plugin.saveSettings(); - })); - - new Setting(containerEl) - .setName(this.plugin.t('enable-bold')) - .setDesc(this.plugin.t('enable-bold-desc')) - .addToggle(toggle => toggle - .setValue(this.plugin.settings.enableBold) - .onChange(async (value) => { - this.plugin.settings.enableBold = value; - await this.plugin.saveSettings(); - })); - - new Setting(containerEl) - .setName(this.plugin.t('enable-highlight')) - .setDesc(this.plugin.t('enable-highlight-desc')) - .addToggle(toggle => toggle - .setValue(this.plugin.settings.enableHighlight) - .onChange(async (value) => { - this.plugin.settings.enableHighlight = value; - await this.plugin.saveSettings(); - })); - - new Setting(containerEl) - .setName(this.plugin.t('enable-italic')) - .setDesc(this.plugin.t('enable-italic-desc')) - .addToggle(toggle => toggle - .setValue(this.plugin.settings.enableItalic) - .onChange(async (value) => { - this.plugin.settings.enableItalic = value; - await this.plugin.saveSettings(); - })); - } - } -} diff --git a/src/settingTab.ts b/src/settingTab.ts new file mode 100644 index 0000000..d94585e --- /dev/null +++ b/src/settingTab.ts @@ -0,0 +1,151 @@ +import { App, PluginSettingTab, Setting } from "obsidian"; +import EasyCopy from "./main"; +import { LinkFormat } from "./type"; + + +export class EasyCopySettingTab extends PluginSettingTab { + plugin: EasyCopy; + + constructor(app: App, plugin: EasyCopy) { + super(app, plugin); + this.plugin = plugin; + } + + display(): void { + const {containerEl} = this; + + containerEl.empty(); + + new Setting(containerEl) + .setName(this.plugin.t('add-to-menu')) + .setDesc(this.plugin.t('add-to-menu-desc')) + .addToggle(toggle => toggle + .setValue(this.plugin.settings.addToMenu) + .onChange(async (value) => { + this.plugin.settings.addToMenu = value; + await this.plugin.saveSettings(); + })); + + new Setting(containerEl) + .setName(this.plugin.t('show-notice')) + .setDesc(this.plugin.t('show-notice-desc')) + .addToggle(toggle => toggle + .setValue(this.plugin.settings.showNotice) + .onChange(async (value) => { + this.plugin.settings.showNotice = value; + await this.plugin.saveSettings(); + })); + + containerEl.createEl('h2', {text: this.plugin.t('format')}); + + new Setting(containerEl) + .setName(this.plugin.t('use-heading-as-display')) + .setDesc(this.plugin.t('use-heading-as-display-desc')) + .addToggle(toggle => toggle + .setValue(this.plugin.settings.useHeadingAsDisplayText) + .onChange(async (value) => { + this.plugin.settings.useHeadingAsDisplayText = value; + await this.plugin.saveSettings(); + })); + + new Setting(containerEl) + .setName(this.plugin.t('link-format')) + .setDesc(this.plugin.t('link-format-desc')) + .addDropdown(dropdown => dropdown + .addOption(LinkFormat.MDLINK, this.plugin.t('markdown-link')) + .addOption(LinkFormat.WIKILINK, this.plugin.t('wiki-link')) + .setValue(this.plugin.settings.linkFormat) + .onChange(async (value) => { + this.plugin.settings.linkFormat = value as LinkFormat; + await this.plugin.saveSettings(); + })); + + containerEl.createEl('h2', {text: this.plugin.t('target')}); + + new Setting(containerEl) + .setName(this.plugin.t('customize-targets')) + .setDesc(this.plugin.t('customize-targets-desc')) + .addToggle(toggle => toggle + .setValue(this.plugin.settings.customizeTargets) + .onChange(async (value) => { + this.plugin.settings.customizeTargets = value; + await this.plugin.saveSettings(); + // 重新渲染设置界面以显示或隐藏目标选项 + this.display(); + })); + + // 只有当自定义复制对象选项开启时才显示具体的复制对象选项 + if (this.plugin.settings.customizeTargets) { + new Setting(containerEl) + .setName(this.plugin.t('enable-inline-code')) + .setDesc(this.plugin.t('enable-inline-code-desc')) + .addToggle(toggle => toggle + .setValue(this.plugin.settings.enableInlineCode) + .onChange(async (value) => { + this.plugin.settings.enableInlineCode = value; + await this.plugin.saveSettings(); + })); + + new Setting(containerEl) + .setName(this.plugin.t('enable-bold')) + .setDesc(this.plugin.t('enable-bold-desc')) + .addToggle(toggle => toggle + .setValue(this.plugin.settings.enableBold) + .onChange(async (value) => { + this.plugin.settings.enableBold = value; + await this.plugin.saveSettings(); + })); + + new Setting(containerEl) + .setName(this.plugin.t('enable-highlight')) + .setDesc(this.plugin.t('enable-highlight-desc')) + .addToggle(toggle => toggle + .setValue(this.plugin.settings.enableHighlight) + .onChange(async (value) => { + this.plugin.settings.enableHighlight = value; + await this.plugin.saveSettings(); + })); + + new Setting(containerEl) + .setName(this.plugin.t('enable-italic')) + .setDesc(this.plugin.t('enable-italic-desc')) + .addToggle(toggle => toggle + .setValue(this.plugin.settings.enableItalic) + .onChange(async (value) => { + this.plugin.settings.enableItalic = value; + await this.plugin.saveSettings(); + })); + + new Setting(containerEl) + .setName(this.plugin.t('enable-strikethrough')) + .setDesc(this.plugin.t('enable-strikethrough-desc')) + .addToggle(toggle => toggle + .setValue(this.plugin.settings.enableStrikethrough) + .onChange(async (value) => { + this.plugin.settings.enableStrikethrough = value; + await this.plugin.saveSettings(); + })); + + new Setting(containerEl) + .setName(this.plugin.t('enable-inline-latex')) + .setDesc(this.plugin.t('enable-inline-latex-desc')) + .addToggle(toggle => toggle + .setValue(this.plugin.settings.enableInlineLatex) + .onChange(async (value) => { + this.plugin.settings.enableInlineLatex = value; + await this.plugin.saveSettings(); + })); + + new Setting(containerEl) + .setName(this.plugin.t('enable-link')) + .setDesc(this.plugin.t('enable-link-desc')) + .addToggle(toggle => toggle + .setValue(this.plugin.settings.enableLink) + .onChange(async (value) => { + this.plugin.settings.enableLink = value; + await this.plugin.saveSettings(); + })); + + } + } +} \ No newline at end of file diff --git a/src/type.ts b/src/type.ts new file mode 100644 index 0000000..1d0804d --- /dev/null +++ b/src/type.ts @@ -0,0 +1,55 @@ +export enum LinkFormat { + MDLINK = 'markdown-link', + WIKILINK = 'wiki-link' +} + +export enum ContextType { + NULL = 'null', + HEADING = 'heading', + INLINECODE = 'inline-code', + BOLD = 'bold', + ITALIC = 'italic', + HIGHLIGHT = 'highlight', + STRIKETHROUGH = 'strikethrough', + BLOCKID = 'block-id', + INLINELATEX = 'inline-latex', + LINKTITLE = 'link-title', + LINEURL = 'line-url', +} + +export interface ContextData { + type: ContextType; + curLine: string; + match: string | null; + range: [number, number] | null; +} + +export interface EasyCopySettings { + addToMenu: boolean; + showNotice: boolean; + useHeadingAsDisplayText: boolean; + linkFormat: LinkFormat; + customizeTargets: boolean; + enableInlineCode: boolean; + enableBold: boolean; + enableHighlight: boolean; + enableItalic: boolean; + enableStrikethrough: boolean; + enableInlineLatex: boolean; + enableLink: boolean; +} + +export const DEFAULT_SETTINGS: EasyCopySettings = { + addToMenu: true, + showNotice: true, + useHeadingAsDisplayText: true, + linkFormat: LinkFormat.WIKILINK, + customizeTargets: false, + enableInlineCode: true, + enableBold: true, + enableHighlight: true, + enableItalic: true, + enableStrikethrough: true, + enableInlineLatex: true, + enableLink: true, +} \ No newline at end of file