diff --git a/README.md b/README.md index da68af0..031771d 100644 --- a/README.md +++ b/README.md @@ -30,3 +30,21 @@ import { copilotPlugin } from "@val-town/codemirror-codeium"; // This is a CodeMirror extension copilotPlugin(); ``` + +### CSS + +This adds a `.ghostText` class to CodeMirror decorations for the AI-written +text. You can add your own style for this class. The demo uses this style: + +```css +.cm-ghostText, +.cm-ghostText * { + opacity: 0.6; + filter: grayscale(20%); + cursor: pointer; +} + +.cm-ghostText:hover { + background: #eee; +} +``` diff --git a/demo/demo.css b/demo/demo.css index 6fba8d9..7e35478 100644 --- a/demo/demo.css +++ b/demo/demo.css @@ -46,7 +46,11 @@ main { .cm-ghostText, .cm-ghostText * { - /* color: rgb(120, 120, 120, 0.8) !important; */ opacity: 0.6; filter: grayscale(20%); + cursor: pointer; +} + +.cm-ghostText:hover { + background: #eee; } diff --git a/src/completionDecoration.ts b/src/completionDecoration.ts index c5ec18d..cfcb0f0 100644 --- a/src/completionDecoration.ts +++ b/src/completionDecoration.ts @@ -16,8 +16,6 @@ export const completionDecoration = StateField.define({ update(state: CompletionState, transaction: Transaction) { for (const effect of transaction.effects) { if (effect.is(addSuggestions)) { - // When adding a suggestion, we set th ghostText - // NOTE: here we're adjusting the decoration range // to refer to locations in the document _after_ we've // inserted the text. diff --git a/src/plugin.ts b/src/plugin.ts index 7c91304..9b6e7d8 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -2,10 +2,28 @@ import { EditorView } from "@codemirror/view"; import { Extension, Prec } from "@codemirror/state"; import { completionDecoration } from "./completionDecoration.js"; import { completionRequester } from "./completionRequester.js"; -import { sameKeyCommand, rejectSuggestionCommand } from "./commands.js"; +import { + sameKeyCommand, + rejectSuggestionCommand, + acceptSuggestionCommand, +} from "./commands.js"; import { CodeiumConfig, codeiumConfig } from "./config.js"; import { Language } from "./api/proto/exa/codeium_common_pb/codeium_common_pb.js"; +function isDecorationClicked(view: EditorView) { + let inRange = false; + const head = view.state.selection.asSingle().ranges.at(0)?.head; + if (head !== undefined) { + view.state + .field(completionDecoration) + .decorations?.between(head, head, () => { + inRange = true; + }); + return inRange; + } + return false; +} + function completionPlugin() { return EditorView.domEventHandlers({ keydown(event, view) { @@ -20,8 +38,12 @@ function completionPlugin() { return false; } }, - mousedown(_event, view) { - return rejectSuggestionCommand(view); + mouseup(_event, view) { + if (isDecorationClicked(view)) { + return acceptSuggestionCommand(view); + } else { + return rejectSuggestionCommand(view); + } }, }); }