hacky vim copy mode

Signed-off-by: Ronni Skansing <rskansing@gmail.com>
This commit is contained in:
Ronni Skansing
2025-10-05 21:48:27 +02:00
parent 027ea3158d
commit 1dd66074fc
3 changed files with 92 additions and 0 deletions
@@ -6,6 +6,10 @@
import { BiMap } from '$lib/utils/maps';
import { previewQR as generateQR } from '$lib/utils/qrPreview';
import { vimModeEnabled } from '$lib/store/vimMode.js';
import {
setupVimClipboardIntegration,
destroyVimClipboardIntegration
} from '$lib/utils/vimClipboard.js';
/** @type {'domain'|'page'|'email'} */
export let contentType;
@@ -160,6 +164,9 @@
.then((vimModule) => {
const statusNode = vimStatusBar;
vimModeInstance = vimModule.initVimMode(editor, statusNode);
// integrate system clipboard with vim registers
setupVimClipboardIntegration(editor, vimModeInstance, localVimMode, monaco);
})
.catch((e) => {
console.error('vim mode not available', e);
@@ -170,6 +177,9 @@
const destroyVimMode = () => {
if (vimModeInstance) {
try {
// cleanup clipboard integration first
destroyVimClipboardIntegration(vimModeInstance);
// use official monaco-vim dispose method
vimModeInstance.dispose();
} catch (e) {
@@ -4,6 +4,10 @@
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
import { vimModeEnabled } from '$lib/store/vimMode.js';
import {
setupVimClipboardIntegration,
destroyVimClipboardIntegration
} from '$lib/utils/vimClipboard.js';
export let value = '';
export let height = 'medium';
@@ -119,6 +123,9 @@
.then((vimModule) => {
const statusNode = vimStatusBar;
vimModeInstance = vimModule.initVimMode(editor, statusNode);
// integrate system clipboard with vim registers
setupVimClipboardIntegration(editor, vimModeInstance, localVimMode, monaco);
})
.catch(() => {
console.warn('vim mode not available - monaco-vim package not installed');
@@ -129,6 +136,9 @@
const destroyVimMode = () => {
if (vimModeInstance) {
try {
// cleanup clipboard integration first
destroyVimClipboardIntegration(vimModeInstance);
// use official monaco-vim dispose method
vimModeInstance.dispose();
} catch (e) {
+72
View File
@@ -0,0 +1,72 @@
/**
* hacky vim copy to clipboard on visual mode d or y key down
*/
/**
* sets up clipboard integration for vim mode in monaco editor
* @param {Object} editor - monaco editor instance
* @param {Object} vimModeInstance - vim mode instance from monaco-vim
* @param {boolean} localVimMode - current vim mode state
* @param {Object} monaco - monaco editor module
* @returns {Function} cleanup function to remove event listeners
*/
export function setupVimClipboardIntegration(editor, vimModeInstance, localVimMode, monaco) {
if (!editor || !vimModeInstance || !localVimMode) {
return () => {};
}
// check if clipboard api is available
if (typeof navigator === 'undefined' || !navigator.clipboard) {
console.warn('clipboard api not available');
return () => {}; // noop cleanup
}
// listen for y and d key presses to copy to system clipboard
const keyDownDisposable = editor.onKeyDown(async (e) => {
if (!localVimMode) return;
// detect y or d key presses
if (e.keyCode === monaco.KeyCode.KeyY || e.keyCode === monaco.KeyCode.KeyD) {
// get current selection immediately
const selection = editor.getSelection();
// only copy to clipboard if we have selected text (visual mode)
if (selection && !selection.isEmpty()) {
// copy selected text to clipboard
try {
const selectedText = editor.getModel().getValueInRange(selection);
if (selectedText && selectedText.trim()) {
await navigator.clipboard.writeText(selectedText);
}
} catch (e) {
console.error(e);
}
}
}
});
// cleanup function to remove event listener
const cleanup = () => {
if (keyDownDisposable) {
keyDownDisposable.dispose();
}
};
// store cleanup function on vim instance for later use
if (vimModeInstance) {
vimModeInstance._clipboardCleanup = cleanup;
}
return cleanup;
}
/**
* destroys vim clipboard integration
* @param {Object} vimModeInstance - vim mode instance from monaco-vim
*/
export function destroyVimClipboardIntegration(vimModeInstance) {
if (vimModeInstance && vimModeInstance._clipboardCleanup) {
vimModeInstance._clipboardCleanup();
delete vimModeInstance._clipboardCleanup;
}
}