diff --git a/src/app.css b/src/app.css
index 91302ca076..e1c6bb592c 100644
--- a/src/app.css
+++ b/src/app.css
@@ -40,6 +40,11 @@ code {
width: auto;
}
+.editor-selection {
+ background: rgba(180, 213, 255, 0.5);
+ border-radius: 2px;
+}
+
.font-secondary {
font-family: 'InstrumentSerif', sans-serif;
}
diff --git a/src/lib/components/common/RichTextInput.svelte b/src/lib/components/common/RichTextInput.svelte
index 2c46a56770..e14b09add4 100644
--- a/src/lib/components/common/RichTextInput.svelte
+++ b/src/lib/components/common/RichTextInput.svelte
@@ -56,6 +56,7 @@
import { Fragment, DOMParser } from 'prosemirror-model';
import { EditorState, Plugin, PluginKey, TextSelection, Selection } from 'prosemirror-state';
+ import { Decoration, DecorationSet } from 'prosemirror-view';
import { Editor, Extension } from '@tiptap/core';
// Yjs imports
@@ -167,6 +168,8 @@
});
};
+ export let onSelectionUpdate = (e) => {};
+
export let id = '';
export let value = '';
export let html = '';
@@ -192,6 +195,8 @@
let jsonValue = '';
let mdValue = '';
+ let lastSelectionBookmark = null;
+
// Yjs setup
let ydoc = null;
let yXmlFragment = null;
@@ -827,6 +832,33 @@
}
};
+ const SelectionDecoration = Extension.create({
+ name: 'selectionDecoration',
+ addProseMirrorPlugins() {
+ return [
+ new Plugin({
+ key: new PluginKey('selection'),
+ props: {
+ decorations: (state) => {
+ const { selection } = state;
+ const { focused } = this.editor;
+
+ if (focused || selection.empty) {
+ return null;
+ }
+
+ return DecorationSet.create(state.doc, [
+ Decoration.inline(selection.from, selection.to, {
+ class: 'editor-selection'
+ })
+ ]);
+ }
+ }
+ })
+ ];
+ }
+ });
+
onMount(async () => {
content = value;
@@ -882,6 +914,7 @@
link: link
}),
Placeholder.configure({ placeholder }),
+ SelectionDecoration,
CodeBlockLowlight.configure({
lowlight
@@ -1168,7 +1201,8 @@
if (files) {
editor.storage.files = files;
}
- }
+ },
+ onSelectionUpdate: onSelectionUpdate
});
if (messageInput) {
diff --git a/src/lib/components/notes/NoteEditor.svelte b/src/lib/components/notes/NoteEditor.svelte
index e7ef01b8d2..3b6d58d7ad 100644
--- a/src/lib/components/notes/NoteEditor.svelte
+++ b/src/lib/components/notes/NoteEditor.svelte
@@ -121,6 +121,8 @@
let showPanel = false;
let selectedPanel = 'chat';
+ let selectedContent = null;
+
let showDeleteConfirm = false;
let showAccessControlModal = false;
@@ -1199,6 +1201,16 @@ Provide the enhanced notes in markdown format. Use markdown syntax for headings,
image={true}
placeholder={$i18n.t('Write something...')}
editable={versionIdx === null && !editing}
+ onSelectionUpdate={({ editor }) => {
+ const { from, to } = editor.state.selection;
+ const selectedText = editor.state.doc.textBetween(from, to, ' ');
+
+ selectedContent = {
+ text: selectedText,
+ from: from,
+ to: to
+ };
+ }}
onChange={(content) => {
note.data.content.html = content.html;
note.data.content.md = content.md;
@@ -1398,6 +1410,9 @@ Provide the enhanced notes in markdown format. Use markdown syntax for headings,
bind:editing
bind:streaming
bind:stopResponseFlag
+ {editor}
+ {inputElement}
+ {selectedContent}
{files}
onInsert={insertHandler}
onStop={stopResponseHandler}
diff --git a/src/lib/components/notes/NoteEditor/Chat.svelte b/src/lib/components/notes/NoteEditor/Chat.svelte
index fa20bdf7a0..d9d86b597d 100644
--- a/src/lib/components/notes/NoteEditor/Chat.svelte
+++ b/src/lib/components/notes/NoteEditor/Chat.svelte
@@ -56,11 +56,14 @@
const i18n = getContext('i18n');
+ export let editor = null;
+
export let editing = false;
export let streaming = false;
export let stopResponseFlag = false;
export let note = null;
+ export let selectedContent = null;
export let files = [];
export let messages = [];
@@ -79,20 +82,23 @@
let messagesContainerElement: HTMLDivElement;
let system = '';
- let editorEnabled = false;
+ let editEnabled = false;
let chatInputElement = null;
const DEFAULT_DOCUMENT_EDITOR_PROMPT = `You are an expert document editor.
## Task
-Based on the user's instruction, update and enhance the existing notes by incorporating relevant and accurate information from the provided context in the content's primary language. Ensure all edits strictly follow the user’s intent.
+Based on the user's instruction, update and enhance the existing notes or selection by incorporating relevant and accurate information from the provided context in the content's primary language. Ensure all edits strictly follow the user’s intent.
## Input Structure
- Existing notes: Enclosed within
+++ {selectedContent?.text} ++