mirror of
https://github.com/jldiaz/copy-protocol-plugin.git
synced 2026-07-22 06:56:55 +00:00
Added command to paste text as copy-link
This commit is contained in:
parent
95b9bda79b
commit
1492e71e4a
4 changed files with 134 additions and 21 deletions
59
README.md
59
README.md
|
|
@ -2,22 +2,63 @@
|
|||
|
||||

|
||||
|
||||
This is a simple plugin for Obsidian that registers a custom `obsidian://copy` protocol.
|
||||
It allows you to create internal links that, when clicked, will silently copy a specific text to your clipboard without opening any external applications or showing popups.
|
||||
## What is this for?
|
||||
|
||||
## Usage
|
||||
Have you ever wanted to create a note that, when you click a link, **automatically copies a snippet of text to your clipboard**? This plugin makes that possible.
|
||||
|
||||
Create a link using the following format:
|
||||
`[Link text](obsidian://copy?text=Your%20text%20here)`
|
||||
Some use cases:
|
||||
|
||||
When you click the link, "Your text here" will be copied to your clipboard, and a small notice will appear to confirm the action.
|
||||
- A "cheat sheet" note with commands, passwords, or templates — click the link, paste anywhere.
|
||||
- A collection of code snippets ready to paste into a terminal.
|
||||
- Frequently used texts (email signatures, boilerplate, addresses) accessible from any note.
|
||||
- Query strings to paste into other apps (e.g. to search specific emails in Outlook, my primary use case)
|
||||
|
||||
Note: Remember to URL-encode your text (e.g., use `%20` instead of spaces).
|
||||
## How it works
|
||||
|
||||
The plugin registers a custom `obsidian://copy` protocol. When you click a link using this protocol, the text embedded in the URL is silently copied to your clipboard and a small confirmation notice appears — no popups, no external apps.
|
||||
|
||||
## Creating links manually
|
||||
|
||||
```markdown
|
||||
[Click to copy](obsidian://copy?text=Your-text-here)
|
||||
```
|
||||
|
||||
When clicked, **"Your-text-here"** is copied to your clipboard.
|
||||
|
||||
For text containing spaces, wrap the URL in angle brackets:
|
||||
|
||||
```markdown
|
||||
[Click to copy](<obsidian://copy?text=Hello world>)
|
||||
```
|
||||
|
||||
Other special characters need to be encoded, and as you can see it can be tedious to do manually, so a command for that is included.
|
||||
|
||||
## Creating links with a keyboard shortcut
|
||||
|
||||
The plugin includes a command called **Copy Protocol: Paste clipboard as copy-protocol link** that automates the process. It reads your current clipboard content and inserts a ready-to-use markdown link at the cursor. If you have text selected in the editor, that selection becomes the link label; otherwise, the clipboard text itself is used as a label.
|
||||
|
||||
### To assign a keyboard shortcut
|
||||
|
||||
1. Open **Settings → Hotkeys**.
|
||||
2. Search for "Paste clipboard as copy-protocol link".
|
||||
3. Click the `+` button and press your preferred key combination.
|
||||
|
||||
### Example workflow
|
||||
|
||||
1. Copy a command or text you want to reuse (e.g. `git log --oneline`).
|
||||
2. In your note, type a label like `Show git log` and select it.
|
||||
3. Press your hotkey.
|
||||
4. The selection is replaced with:
|
||||
```
|
||||
[Show git log](<obsidian://copy?text=git%20log%20--oneline>)
|
||||
```
|
||||
5. Clicking that link copies `git log --oneline` to your clipboard instantly.
|
||||
|
||||
## Installation
|
||||
|
||||
You can install this plugin via [BRAT](https://github.com/TfTHacker/obsidian42-brat):
|
||||
You can install this plugin from the Community Plugins settings of Obsidian, or via [BRAT](https://github.com/TfTHacker/obsidian42-brat):
|
||||
|
||||
1. Open the BRAT settings in Obsidian.
|
||||
2. Click "Add Beta plugin".
|
||||
2. Click **Add Beta plugin**.
|
||||
3. Paste the repository URL: `jldiaz/copy-protocol-plugin`.
|
||||
4. Enable the plugin in your Community Plugins list.
|
||||
|
|
|
|||
8
package-lock.json
generated
8
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "obsidian-sample-plugin",
|
||||
"version": "1.0.0",
|
||||
"name": "copy-text-protocol",
|
||||
"version": "1.0.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "obsidian-sample-plugin",
|
||||
"version": "1.0.0",
|
||||
"name": "copy-text-protocol",
|
||||
"version": "1.0.1",
|
||||
"license": "0-BSD",
|
||||
"dependencies": {
|
||||
"obsidian": "latest"
|
||||
|
|
|
|||
56
src/main.ts
56
src/main.ts
|
|
@ -1,13 +1,63 @@
|
|||
import { Plugin, Notice } from 'obsidian';
|
||||
import { Editor, MarkdownView, Plugin, Notice } from 'obsidian';
|
||||
|
||||
export default class CopyProtocolPlugin extends Plugin {
|
||||
async onload() {
|
||||
// Register the obsidian://copy protocol handler
|
||||
this.registerObsidianProtocolHandler('copy', async (params) => {
|
||||
if (params.text) {
|
||||
const query = decodeURIComponent(params.text);
|
||||
await navigator.clipboard.writeText(query);
|
||||
// Obsidian already decodes URL params before calling the handler,
|
||||
// so no need for an extra decodeURIComponent here.
|
||||
await navigator.clipboard.writeText(params.text);
|
||||
new Notice(`Copied to clipboard!`);
|
||||
}
|
||||
});
|
||||
|
||||
// Register the "paste as link" command
|
||||
this.addCommand({
|
||||
id: 'paste-as-copy-link',
|
||||
name: 'Paste clipboard as copy-protocol link',
|
||||
editorCallback: async (editor: Editor, _view: MarkdownView) => {
|
||||
// Read clipboard content
|
||||
let clipboardText: string;
|
||||
try {
|
||||
clipboardText = await navigator.clipboard.readText();
|
||||
} catch {
|
||||
new Notice('Could not read clipboard.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!clipboardText) {
|
||||
new Notice('Clipboard is empty.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Get current selection (used as the link label)
|
||||
const selection = editor.getSelection();
|
||||
|
||||
// Build the obsidian://copy URL, URL-encoding the clipboard text
|
||||
const encodedText = encodeURIComponent(clipboardText);
|
||||
const url = `obsidian://copy?text=${encodedText}`;
|
||||
|
||||
// Build the markdown link:
|
||||
// [<label>](<url>) — angle-bracket form avoids issues with spaces
|
||||
// The label is either the selected text or the raw clipboard text
|
||||
// (truncated to 50 chars for readability if no selection).
|
||||
const label = selection.length > 0
|
||||
? selection
|
||||
: clipboardText.length > 50
|
||||
? clipboardText.slice(0, 50) + '…'
|
||||
: clipboardText;
|
||||
|
||||
const markdownLink = `[${label}](<${url}>)`;
|
||||
|
||||
if (selection.length > 0) {
|
||||
// Replace the selection with the link
|
||||
editor.replaceSelection(markdownLink);
|
||||
} else {
|
||||
// Insert at cursor position
|
||||
editor.replaceSelection(markdownLink);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
32
styles.css
32
styles.css
|
|
@ -1,8 +1,30 @@
|
|||
/*
|
||||
* Visual indicator for obsidian://copy protocol links.
|
||||
*
|
||||
* Prepends a clipboard icon (lucide:copy) before the link text using a CSS
|
||||
* mask so it inherits the current link color from the active theme.
|
||||
* Works in both Reading View and Live Preview.
|
||||
*/
|
||||
|
||||
This CSS file will be included with your plugin, and
|
||||
available in the app when your plugin is enabled.
|
||||
a[href^="obsidian://copy"]::before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 0.75em;
|
||||
height: 0.75em;
|
||||
margin-right: 0.25em;
|
||||
vertical-align: middle;
|
||||
/* Fills with the link color of the active theme */
|
||||
background-color: currentColor;
|
||||
/* Lucide "copy" icon as a mask — shape only, color comes from above */
|
||||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='14' height='14' x='8' y='8' rx='2' ry='2'/%3E%3Cpath d='M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2'/%3E%3C/svg%3E");
|
||||
-webkit-mask-size: contain;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='14' height='14' x='8' y='8' rx='2' ry='2'/%3E%3Cpath d='M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2'/%3E%3C/svg%3E");
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
If your plugin does not need CSS, delete this file.
|
||||
|
||||
*/
|
||||
/* Show a "copy" cursor on hover to reinforce the action */
|
||||
a[href^="obsidian://copy"]:hover {
|
||||
cursor: copy;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue