mirror of
https://github.com/moyf/easy-copy.git
synced 2026-07-22 05:43:47 +00:00
feat: 🎸 support more commands and options
- 3 new commands to copy current file/block links - option to add display text for block link ✅ Closes: #7 #8
This commit is contained in:
parent
1f44a9545b
commit
40f9e40b4b
4 changed files with 165 additions and 59 deletions
21
src/i18n.ts
21
src/i18n.ts
|
|
@ -11,6 +11,7 @@ export type TranslationKey =
|
|||
| 'inline-code-copied' | 'block-id-copied' | 'note-link-copied' | 'heading-copied' | 'strikethrough-copied'
|
||||
| 'inline-latex-copied' | 'bold-copied' | 'highlight-copied' | 'italic-copied' | 'link-text-copied' | 'link-url-copied'
|
||||
| 'format' | 'add-to-menu' | 'add-to-menu-desc' | 'show-notice' | 'show-notice-desc'
|
||||
| 'add-extra-commands' | 'add-extra-commands-desc'
|
||||
| 'use-heading-as-display' | 'use-heading-as-display-desc' | 'block-id'
|
||||
| 'use-frontmatter-as-display' | 'use-frontmatter-as-display-desc' | 'frontmatter-key' | 'frontmatter-key-desc'
|
||||
| 'link-format'| 'link-format-desc' | 'markdown-link' | 'wiki-link' | 'contextual-copy'
|
||||
|
|
@ -26,6 +27,8 @@ export type TranslationKey =
|
|||
| 'auto-add-block-id' | 'auto-add-block-id-desc'
|
||||
| 'manual-block-id' | 'manual-block-id-desc'
|
||||
| 'modal-block-id' | 'modal-block-id-desc'
|
||||
| 'auto-block-display-text' | 'auto-block-display-text-desc'
|
||||
| 'generate-current-block-link-auto' | 'generate-current-block-link-manual'
|
||||
| 'error-block-id-empty' | 'error-block-id-invalid';
|
||||
|
||||
// 本地化翻译字典
|
||||
|
|
@ -66,6 +69,8 @@ export const translations: Record<Language, Record<TranslationKey, string>> = {
|
|||
'target': 'Target',
|
||||
'add-to-menu': 'Add to menu',
|
||||
'add-to-menu-desc': 'Add the command to the context menu',
|
||||
'add-extra-commands': 'Add extra commands',
|
||||
'add-extra-commands-desc': 'Enable to add "Copy current note link" and "Generate & copy current block link" commands to the command palette',
|
||||
'show-notice': 'Show notice',
|
||||
'show-notice-desc': 'Show notification when content is copied',
|
||||
'use-heading-as-display': 'Use heading as display text',
|
||||
|
|
@ -90,10 +95,14 @@ export const translations: Record<Language, Record<TranslationKey, string>> = {
|
|||
'enable-inline-latex-desc': 'Enable copying inline LaTeX like $latex example$',
|
||||
'enable-link': 'Enable link title/url',
|
||||
'enable-link-desc': 'Enable copying link like [linktitle](linkurl) - the plugin will copy the title or the URL of the link based on the current cursor position.',
|
||||
'auto-block-display-text': 'Auto display text for block links',
|
||||
'auto-block-display-text-desc': 'Automatically generate display text for block ID links (if disabled, block links will not show display text)',
|
||||
|
||||
// 命令名称
|
||||
'contextual-copy': 'Contextual copy',
|
||||
'copy-current-file-link': 'Copy current file link',
|
||||
'generate-current-block-link-auto': 'Generate & copy current block link (auto)',
|
||||
'generate-current-block-link-manual': 'Generate & copy current block link (manual)',
|
||||
'file-link-copied': 'File link copied!',
|
||||
},
|
||||
[Language.ZH]: {
|
||||
|
|
@ -127,6 +136,8 @@ export const translations: Record<Language, Record<TranslationKey, string>> = {
|
|||
'target': '复制对象',
|
||||
'add-to-menu': '添加到菜单',
|
||||
'add-to-menu-desc': '将命令添加到右键菜单',
|
||||
'add-extra-commands': '添加拓展命令',
|
||||
'add-extra-commands-desc': '启用后,将在命令面板中添加“复制当前笔记的链接”和“生成并复制当前块的链接”命令',
|
||||
'show-notice': '显示通知',
|
||||
'show-notice-desc': '复制内容时显示通知提示',
|
||||
'use-heading-as-display': '使用标题作为显示文本',
|
||||
|
|
@ -155,16 +166,24 @@ export const translations: Record<Language, Record<TranslationKey, string>> = {
|
|||
// 命令名称
|
||||
'contextual-copy': '智能复制',
|
||||
'copy-current-file-link': '复制当前文件链接',
|
||||
'generate-current-block-link-auto': '生成并复制当前块链接(自动)',
|
||||
'generate-current-block-link-manual': '生成并复制当前块链接(手动)',
|
||||
'file-link-copied': '当前文件链接已复制!',
|
||||
'use-frontmatter-as-display': '使用 Frontmatter 属性作为显示文本',
|
||||
'use-frontmatter-as-display-desc': '启用后,使用指定 Frontmatter 属性的值作为链接显示文本',
|
||||
'frontmatter-key': 'Frontmatter 属性名',
|
||||
'frontmatter-key-desc': '用于显示文本的 Frontmatter 属性名(默认:title)',
|
||||
'auto-block-display-text': '块链接自动显示文本',
|
||||
'auto-block-display-text-desc': '自动为块ID链接生成显示文本(关闭后,块链接不显示文本)',
|
||||
},
|
||||
[Language.ZH_TW]: {
|
||||
// 复制 Block ID
|
||||
'auto-add-block-id': '自動新增塊ID',
|
||||
'auto-add-block-id-desc': '啟用後,若沒有可複製內容時,會自動在當前文本末尾新增一個隨機的塊ID(^xxxx)',
|
||||
'add-extra-commands': '添加擴展命令',
|
||||
'add-extra-commands-desc': '啟用後,會在命令面板中新增「複製當前筆記鏈接」和「生成並複製當前塊鏈接」命令',
|
||||
'auto-block-display-text': '塊連結自動顯示文本',
|
||||
'auto-block-display-text-desc': '自動為塊ID連結生成顯示文本(關閉後,塊連結不顯示文本)',
|
||||
'manual-block-id': '手動輸入塊ID',
|
||||
'manual-block-id-desc': '啟用後,可以在彈窗中手動輸入塊ID',
|
||||
'modal-block-id': '輸入塊ID',
|
||||
|
|
@ -221,6 +240,8 @@ export const translations: Record<Language, Record<TranslationKey, string>> = {
|
|||
// 命令名称
|
||||
'contextual-copy': '智能複製',
|
||||
'copy-current-file-link': '複製當前文件連結',
|
||||
'generate-current-block-link-auto': '生成並複製當前塊連結(自動)',
|
||||
'generate-current-block-link-manual': '生成並複製當前塊連結(手動)',
|
||||
'file-link-copied': '當前文件連結已複製!',
|
||||
'use-frontmatter-as-display': '使用屬性作為顯示文本',
|
||||
'use-frontmatter-as-display-desc': '啟用後,使用指定屬性的值作為連結顯示文本',
|
||||
|
|
|
|||
175
src/main.ts
175
src/main.ts
|
|
@ -1,4 +1,4 @@
|
|||
import { Editor, MarkdownView, Notice, Plugin, Menu, Platform } from 'obsidian';
|
||||
import { Editor, MarkdownView, Notice, Plugin, Menu, Platform, MarkdownFileInfo } from 'obsidian';
|
||||
import { Language, TranslationKey, I18n } from './i18n';
|
||||
import { ContextData, ContextType, DEFAULT_SETTINGS, EasyCopySettings, LinkFormat } from './type';
|
||||
import { EasyCopySettingTab } from './settingTab';
|
||||
|
|
@ -34,14 +34,50 @@ export default class EasyCopy extends Plugin {
|
|||
}
|
||||
});
|
||||
|
||||
// 新增:复制当前文件链接命令
|
||||
this.addCommand({
|
||||
id: 'copy-current-file-link',
|
||||
name: this.t('copy-current-file-link'),
|
||||
callback: () => {
|
||||
this.copyCurrentFileLink();
|
||||
}
|
||||
});
|
||||
if (this.settings.addExtraCommands){
|
||||
// 新增:复制当前文件链接命令
|
||||
this.addCommand({
|
||||
id: 'copy-current-file-link',
|
||||
name: this.t('copy-current-file-link'),
|
||||
callback: () => {
|
||||
this.copyCurrentFileLink();
|
||||
}
|
||||
});
|
||||
|
||||
// 新增:复制当前文件链接命令
|
||||
this.addCommand({
|
||||
id: 'generate-current-block-link-auto',
|
||||
name: this.t('generate-current-block-link-auto'),
|
||||
editorCallback: (editor: Editor, fileInfo: MarkdownFileInfo) => {
|
||||
const file = fileInfo.file;
|
||||
if (!file){
|
||||
new Notice(this.t('no-file'));
|
||||
return;
|
||||
}
|
||||
const filename = file.basename;
|
||||
// 自动生成名称
|
||||
this.insertBlockIdAndCopyLink(editor, filename, false);
|
||||
}
|
||||
});
|
||||
|
||||
// 新增:复制当前文件链接命令
|
||||
this.addCommand({
|
||||
id: 'generate-current-block-link-manual',
|
||||
name: this.t('generate-current-block-link-manual'),
|
||||
editorCallback: (editor: Editor, fileInfo: MarkdownFileInfo) => {
|
||||
const file = fileInfo.file;
|
||||
if (!file){
|
||||
new Notice(this.t('no-file'));
|
||||
return;
|
||||
}
|
||||
const filename = file.basename;
|
||||
// 手动输入名称
|
||||
this.insertBlockIdAndCopyLink(editor, filename, true);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
// This adds a settings tab so the user can configure various aspects of the plugin
|
||||
this.addSettingTab(new EasyCopySettingTab(this.app, this));
|
||||
|
|
@ -304,54 +340,11 @@ export default class EasyCopy extends Plugin {
|
|||
if (contextType.type == ContextType.NULL) {
|
||||
// 如果启用自动添加 Block ID
|
||||
if (this.settings.autoAddBlockId) {
|
||||
let blockId = '';
|
||||
const isManual = this.settings.allowManualBlockId;
|
||||
|
||||
await this.insertBlockIdAndCopyLink(editor, filename, isManual);
|
||||
|
||||
|
||||
if (isManual) {
|
||||
// 用 Modal 弹窗获取 Block ID
|
||||
const modalBlockId = await new Promise<string | null>((resolve) => {
|
||||
new BlockIdInputModal(this.app,
|
||||
this.t('modal-block-id'), this.t('modal-block-id-desc'),
|
||||
this.t.bind(this),
|
||||
(result: any) => {
|
||||
resolve(result ?? null);
|
||||
}
|
||||
).open();
|
||||
});
|
||||
if (!modalBlockId) return;
|
||||
blockId = modalBlockId;
|
||||
} else {
|
||||
// 随机生成
|
||||
const randomId = Math.random().toString(36).substr(2, 6);
|
||||
blockId = `${randomId}`;
|
||||
}
|
||||
|
||||
// —— 新逻辑:定位 block(段落)末尾 ——
|
||||
const cursor = editor.getCursor();
|
||||
const { start, end } = this.detectBlockRange(editor, cursor.line);
|
||||
const firstLine = editor.getLine(start);
|
||||
const lastLine = editor.getLine(end);
|
||||
|
||||
// 检查 block 最后一行末是否已有块ID
|
||||
if (!/\^[a-zA-Z0-9_-]+$/.test(lastLine.trim())) {
|
||||
// 在 block 最后一行末尾插入块ID
|
||||
let insertText = '^'+blockId;
|
||||
|
||||
if (lastLine.startsWith('> ') || lastLine.startsWith('``')) {
|
||||
insertText = '\n' + insertText;
|
||||
} else if (!lastLine.endsWith(' ')) {
|
||||
insertText = ' ' + insertText;
|
||||
}
|
||||
|
||||
editor.replaceRange(insertText, { line: end, ch: lastLine.length });
|
||||
|
||||
// 如果不是手动输入的,使用简短的显示文本
|
||||
const useBrief = !isManual;
|
||||
|
||||
// 复制块ID链接
|
||||
this.copyBlockLink(blockId, filename, useBrief, firstLine);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
new Notice(this.t('no-content'));
|
||||
|
|
@ -425,9 +418,12 @@ export default class EasyCopy extends Plugin {
|
|||
/*
|
||||
* 复制块链接
|
||||
*/
|
||||
private copyBlockLink(content: string, filename: string, useBrief: boolean, firstLine: string=''): void {
|
||||
private copyBlockLink(content: string, filename: string, useBrief: boolean, firstLine=''): void {
|
||||
const blockId = content;
|
||||
|
||||
let text = firstLine;
|
||||
|
||||
const autoDisplayText = this.settings.autoBlockDisplayText;
|
||||
|
||||
// 先去掉结尾的 ^ 及其后面的内容(如果有的话)
|
||||
text = text.replace(/\^.*\s*$/, '');
|
||||
|
|
@ -465,15 +461,22 @@ export default class EasyCopy extends Plugin {
|
|||
} else {
|
||||
displayText = tempText;
|
||||
}
|
||||
} else {
|
||||
displayText = briefText;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// displayText = "^"+displayText;
|
||||
let blockIdLink = this.settings.linkFormat === LinkFormat.WIKILINK
|
||||
? `[[${filename}#^${blockId}|${displayText}]]`
|
||||
: `[^${displayText}](${filename}#^${blockId})`;
|
||||
|
||||
const blockIdLink = this.settings.linkFormat === LinkFormat.WIKILINK
|
||||
? `[[${filename}#^${blockId}|${displayText}]]`
|
||||
: `[^${displayText}](${filename}#^${blockId})`;
|
||||
if (!autoDisplayText) {
|
||||
blockIdLink = this.settings.linkFormat === LinkFormat.WIKILINK
|
||||
? `[[${filename}#^${blockId}]]`
|
||||
: `[](${filename}#^${blockId})`;
|
||||
}
|
||||
|
||||
navigator.clipboard.writeText(blockIdLink);
|
||||
if (this.settings.showNotice) {
|
||||
|
|
@ -564,6 +567,60 @@ export default class EasyCopy extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入 Block ID 并复制块链接
|
||||
* @param editor 编辑器实例
|
||||
* @param filename 当前文件名
|
||||
*/
|
||||
private async insertBlockIdAndCopyLink(editor: Editor, filename: string, isManual=false): Promise<void> {
|
||||
let blockId = '';
|
||||
|
||||
if (isManual) {
|
||||
// 用 Modal 弹窗获取 Block ID
|
||||
const modalBlockId = await new Promise<string | null>((resolve) => {
|
||||
new BlockIdInputModal(this.app,
|
||||
this.t('modal-block-id'), this.t('modal-block-id-desc'),
|
||||
this.t.bind(this),
|
||||
(result: any) => {
|
||||
resolve(result ?? null);
|
||||
}
|
||||
).open();
|
||||
});
|
||||
if (!modalBlockId) return;
|
||||
blockId = modalBlockId;
|
||||
} else {
|
||||
// 随机生成
|
||||
const randomId = Math.random().toString(36).substr(2, 6);
|
||||
blockId = `${randomId}`;
|
||||
}
|
||||
|
||||
// —— 新逻辑:定位 block(段落)末尾 ——
|
||||
const cursor = editor.getCursor();
|
||||
const { start, end } = this.detectBlockRange(editor, cursor.line);
|
||||
const firstLine = editor.getLine(start);
|
||||
const lastLine = editor.getLine(end);
|
||||
|
||||
// 检查 block 最后一行末是否已有块ID
|
||||
if (!/\^[a-zA-Z0-9_-]+$/.test(lastLine.trim())) {
|
||||
// 在 block 最后一行末尾插入块ID
|
||||
let insertText = '^' + blockId;
|
||||
|
||||
if (lastLine.startsWith('> ') || lastLine.startsWith('``')) {
|
||||
insertText = '\n' + insertText;
|
||||
} else if (!lastLine.endsWith(' ')) {
|
||||
insertText = ' ' + insertText;
|
||||
}
|
||||
|
||||
editor.replaceRange(insertText, { line: end, ch: lastLine.length });
|
||||
|
||||
// 如果不是手动输入的,使用简短的显示文本
|
||||
const useBrief = !isManual;
|
||||
|
||||
// (生成之后)复制块ID链接
|
||||
this.copyBlockLink(blockId, filename, useBrief, firstLine);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化国际化设置,使用Obsidian的语言设置
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -26,6 +26,16 @@ export class EasyCopySettingTab extends PluginSettingTab {
|
|||
await this.plugin.saveSettings();
|
||||
}));
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(this.plugin.t('add-extra-commands'))
|
||||
.setDesc(this.plugin.t('add-extra-commands-desc'))
|
||||
.addToggle(toggle => toggle
|
||||
.setValue(this.plugin.settings.addExtraCommands)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.addExtraCommands = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(this.plugin.t('show-notice'))
|
||||
.setDesc(this.plugin.t('show-notice-desc'))
|
||||
|
|
@ -68,6 +78,20 @@ export class EasyCopySettingTab extends PluginSettingTab {
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
// 新增:自动为 Block 链接添加显示文本
|
||||
new Setting(containerEl)
|
||||
.setName(this.plugin.t('auto-block-display-text'))
|
||||
.setDesc(this.plugin.t('auto-block-display-text-desc'))
|
||||
.addToggle(toggle => toggle
|
||||
.setValue(this.plugin.settings.autoBlockDisplayText)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.autoBlockDisplayText = value;
|
||||
await this.plugin.saveSettings();
|
||||
this.display();
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(this.plugin.t('use-heading-as-display'))
|
||||
.setDesc(this.plugin.t('use-heading-as-display-desc'))
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ export interface EasyCopySettings {
|
|||
useFrontmatterAsDisplay: boolean; // 是否使用 frontmatter 属性作为显示文本
|
||||
frontmatterKey: string; // frontmatter 属性名
|
||||
addToMenu: boolean;
|
||||
addExtraCommands: boolean;
|
||||
showNotice: boolean;
|
||||
useHeadingAsDisplayText: boolean;
|
||||
linkFormat: LinkFormat;
|
||||
|
|
@ -41,12 +42,14 @@ export interface EasyCopySettings {
|
|||
enableLink: boolean;
|
||||
autoAddBlockId: boolean; // 是否自动添加 Block ID
|
||||
allowManualBlockId: boolean; // 是否允许手动输入 Block ID
|
||||
autoBlockDisplayText: boolean; // 自动为 Block 添加显示文本
|
||||
}
|
||||
|
||||
export const DEFAULT_SETTINGS: EasyCopySettings = {
|
||||
useFrontmatterAsDisplay: false,
|
||||
frontmatterKey: 'title',
|
||||
addToMenu: true,
|
||||
addExtraCommands: true,
|
||||
showNotice: true,
|
||||
useHeadingAsDisplayText: true,
|
||||
linkFormat: LinkFormat.WIKILINK,
|
||||
|
|
@ -60,4 +63,5 @@ export const DEFAULT_SETTINGS: EasyCopySettings = {
|
|||
enableLink: true,
|
||||
autoAddBlockId: false, // 默认关闭
|
||||
allowManualBlockId: false, // 默认关闭
|
||||
autoBlockDisplayText: true,
|
||||
}
|
||||
Loading…
Reference in a new issue