Added command to paste text as copy-link

This commit is contained in:
JL Diaz 2026-05-13 13:54:44 +02:00
parent 95b9bda79b
commit 1492e71e4a
4 changed files with 134 additions and 21 deletions

View file

@ -2,22 +2,63 @@
![Plugin Demo](demo.gif)
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
View file

@ -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"

View file

@ -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);
}
},
});
}
}

View file

@ -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;
}