diff --git a/src/extras/editor/editorStrings.ts b/src/extras/editor/editorStrings.ts index a4e0b46..4967726 100644 --- a/src/extras/editor/editorStrings.ts +++ b/src/extras/editor/editorStrings.ts @@ -28,6 +28,14 @@ const editorStrings = { "en-US": "Insert Citation", "zh-CN": "插入引用", }, + copySectionLink: { + "en-US": "Copy Section Link", + "zh-CN": "复制章节链接", + }, + copyLineLink: { + "en-US": "Copy Line Link", + "zh-CN": "复制行链接", + }, heading1: { "en-US": "Heading 1", "zh-CN": "一级标题", diff --git a/src/extras/editor/magicKey.ts b/src/extras/editor/magicKey.ts index eb32373..91b22e0 100644 --- a/src/extras/editor/magicKey.ts +++ b/src/extras/editor/magicKey.ts @@ -12,6 +12,7 @@ declare const _currentEditorInstance: { interface MagicKeyOptions { insertTemplate?: () => void; insertLink?: (type: "inbound" | "outbound") => void; + copyLink?: (mode: "section" | "line") => void; enable?: boolean; } @@ -52,6 +53,18 @@ class PluginState { getPlugin("citation")?.insertCitation(); }, }, + { + messageId: "copySectionLink", + command: (state) => { + this.options.copyLink?.("section"); + }, + }, + { + messageId: "copyLineLink", + command: (state) => { + this.options.copyLink?.("line"); + }, + }, { messageId: "table", command: (state) => { diff --git a/src/modules/editor/toolbar.ts b/src/modules/editor/toolbar.ts index 2d899a0..722a75a 100644 --- a/src/modules/editor/toolbar.ts +++ b/src/modules/editor/toolbar.ts @@ -1,8 +1,10 @@ import { config } from "../../../package.json"; import { ICONS } from "../../utils/config"; -import { getLineAtCursor, getSectionAtCursor } from "../../utils/editor"; -import { showHint } from "../../utils/hint"; -import { getNoteLink } from "../../utils/link"; +import { + copyNoteLink, + getLineAtCursor, + getSectionAtCursor, +} from "../../utils/editor"; import { getString } from "../../utils/locale"; import { openLinkCreator } from "../../utils/linkCreator"; import { slice } from "../../utils/str"; @@ -144,20 +146,7 @@ async function getMenuData(editor: Zotero.EditorInstance) { }, }), callback: (e) => { - const link = - getNoteLink(e.editor._item, { - lineIndex: currentLine, - }) || ""; - new ztoolkit.Clipboard() - .addText(link, "text/plain") - .addText( - `${ - e.editor._item.getNoteTitle().trim() || link - }`, - "text/html", - ) - .copy(); - showHint(`Link ${link} copied`); + copyNoteLink(e.editor, "line"); }, }, { @@ -168,20 +157,7 @@ async function getMenuData(editor: Zotero.EditorInstance) { }, }), callback: (e) => { - const link = - getNoteLink(e.editor._item, { - sectionName: currentSection, - }) || ""; - new ztoolkit.Clipboard() - .addText(link, "text/plain") - .addText( - `${ - e.editor._item.getNoteTitle().trim() || link - }`, - "text/html", - ) - .copy(); - showHint(`Link ${link} copied`); + copyNoteLink(e.editor, "section"); }, }, { diff --git a/src/utils/editor.ts b/src/utils/editor.ts index 188d8ca..3647198 100644 --- a/src/utils/editor.ts +++ b/src/utils/editor.ts @@ -3,6 +3,8 @@ import { TextSelection } from "prosemirror-state"; import { getNoteTreeFlattened } from "./note"; import { getPref } from "./prefs"; import { openLinkCreator } from "./linkCreator"; +import { getNoteLink } from "./link"; +import { showHint } from "./hint"; export { insert, @@ -12,6 +14,7 @@ export { scroll, scrollToSection, getEditorInstance, + copyNoteLink, moveHeading, updateHeadingTextAtLine, getEditorCore, @@ -447,6 +450,35 @@ function getTextBetweenLines( return core.view.state.doc.textBetween(from, to); } +async function copyNoteLink( + editor: Zotero.EditorInstance, + mode: "section" | "line", +) { + const currentLine = getLineAtCursor(editor); + const currentSection = (await getSectionAtCursor(editor)) || ""; + + let link = + getNoteLink(editor._item, { + sectionName: mode === "section" ? currentSection : undefined, + lineIndex: mode === "line" ? currentLine : undefined, + }) || ""; + if (!link) { + showHint("No note link found"); + return; + } + if (mode === "section") { + link += `#${currentSection}`; + } + new ztoolkit.Clipboard() + .addText(link, "text/plain") + .addText( + `${editor._item.getNoteTitle().trim() || link}`, + "text/html", + ) + .copy(); + showHint(`Link ${link} copied`); +} + function initEditorPlugins(editor: Zotero.EditorInstance) { const previewType = getPref("editor.noteLinkPreviewType") as string; if (!["hover", "ctrl"].includes(previewType)) { @@ -495,6 +527,9 @@ function initEditorPlugins(editor: Zotero.EditorInstance) { mode, }); }, + copyLink: (mode: "section" | "line") => { + copyNoteLink(editor, mode); + }, enable: getPref("editor.useMagicKey") as boolean, }, markdownPaste: {