UNPKG

shahnevis-core

Version:

**Shahnevis Core** is a lightweight and flexible library for building custom code editors. It provides essential features like syntax highlighting, a minimap, multi-cursor support, line numbering, and plugin management. This library is framework-agnostic,

125 lines (111 loc) 4.7 kB
/* This file is part of Shahnevis Core. Copyright (C) 2024 shahrooz saneidarani (github.com/shahroozD) Shahnevis Core is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Shahnevis Core is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. */ var editor = document.getElementById('editor'); var cursors = [{ start: editor.selectionStart, end: editor.selectionEnd }]; // Store positions of all cursors // Utility function to render multiple cursors in the editor function renderCursors() { var text = editor.value; var highlightedText = ''; var lastIndex = 0; // Render each cursor cursors.forEach(function (cursor) { highlightedText += text.substring(lastIndex, cursor.start) + "<span class=\"multi-cursor\">|</span>" + text.substring(cursor.start, cursor.end); lastIndex = cursor.end; }); // Add remaining text after the last cursor highlightedText += text.substring(lastIndex); editor.innerHTML = highlightedText; // Replace with innerHTML to show cursors } function getCursorPositionAbove(cursor) { var lines = editor.value.split('\n'); var currentLineIndex = editor.value.substring(0, cursor.start).split('\n').length - 1; // Prevent cursor movement beyond the top of the document if (currentLineIndex === 0) { return null; } var newLineIndex = currentLineIndex - 1; var newLineLength = lines[newLineIndex].length; var newCursorPosition = Math.min(newLineLength, cursor.start - lines.slice(0, currentLineIndex).join('\n').length - 1); return { start: newCursorPosition + lines.slice(0, newLineIndex).join('\n').length + (newLineIndex > 0 ? 1 : 0), end: newCursorPosition + lines.slice(0, newLineIndex).join('\n').length + (newLineIndex > 0 ? 1 : 0) }; } function getCursorPositionBelow(cursor) { var lines = editor.value.split('\n'); var currentLineIndex = editor.value.substring(0, cursor.start).split('\n').length - 1; // Prevent cursor movement beyond the bottom of the document if (currentLineIndex === lines.length - 1) { return null; } var newLineIndex = currentLineIndex + 1; var newLineLength = lines[newLineIndex].length; var newCursorPosition = Math.min(newLineLength, cursor.start - lines.slice(0, currentLineIndex).join('\n').length - 1); return { start: newCursorPosition + lines.slice(0, newLineIndex).join('\n').length + (newLineIndex > 0 ? 1 : 0), end: newCursorPosition + lines.slice(0, newLineIndex).join('\n').length + (newLineIndex > 0 ? 1 : 0) }; } function applyInputToAllCursors(input) { var text = editor.value; var newText = []; var offset = 0; cursors.forEach(function (cursor) { var beforeCursor = text.substring(0, cursor.start + offset); var afterCursor = text.substring(cursor.end + offset); newText.push(beforeCursor + input + afterCursor); offset += input.length; // Adjust the offset based on input length }); editor.value = newText.join(''); // Update the editor with new text renderCursors(); // Rerender cursors after update } function clearAllCursorsExceptPrimary() { cursors = [cursors[0]]; // Retain only the first cursor (primary one) renderCursors(); } // Add multi-cursor with Ctrl + Alt + Arrow keys export function handleMultiCursor(event) { var cursor = { start: editor.selectionStart, end: editor.selectionEnd }; // Ctrl + Alt + Down Arrow - Add a new cursor on the line below if (event.ctrlKey && event.key === 'ArrowDown') { event.preventDefault(); var newCursorPosition = getCursorPositionBelow(cursor); if (newCursorPosition) { cursors.push(newCursorPosition); // Add new cursor renderCursors(); } } // Ctrl + Alt + Up Arrow - Add a new cursor on the line above if (event.ctrlKey && event.key === 'ArrowUp') { event.preventDefault(); var _newCursorPosition = getCursorPositionAbove(cursor); if (_newCursorPosition) { cursors.push(_newCursorPosition); // Add new cursor renderCursors(); } } // Any other key event - apply the input to all cursors if (!event.ctrlKey) { applyInputToAllCursors(event.key); } } // Clear all cursors when clicking elsewhere in the editor // editor.addEventListener('click', clearAllCursorsExceptPrimary);