diff --git a/web/core/lib/editor/editor.css b/web/core/lib/editor/editor.css index 0e2de11..595c436 100644 --- a/web/core/lib/editor/editor.css +++ b/web/core/lib/editor/editor.css @@ -186,7 +186,7 @@ } pre { - background: #0d0d0d; + background: #011c32; color: #fff; font-family: 'JetBrainsMono', monospace; padding: 0.75rem 1rem; @@ -221,6 +221,17 @@ } } +.node-inline-completion { + display: inline-block; + background: var(--violet-3); + padding: 0 8px; + border-radius: 4px; +} + +.node-inline-completion svg { + display: inline-block; +} + .toolbar-menu { box-shadow: 0 2px 2px var(--black-a7); } diff --git a/web/core/lib/editor/extensions/inline-completion/inline-completion.tsx b/web/core/lib/editor/extensions/inline-completion/inline-completion.tsx index 3989ea1..6d95a7a 100644 --- a/web/core/lib/editor/extensions/inline-completion/inline-completion.tsx +++ b/web/core/lib/editor/extensions/inline-completion/inline-completion.tsx @@ -1,4 +1,4 @@ -import { Node, NodeViewWrapper, ReactNodeViewRenderer } from "@tiptap/react"; +import { findChildren, Node, NodeViewWrapper, ReactNodeViewRenderer } from '@tiptap/react'; import { Editor } from "@tiptap/core"; import React, { useEffect, useRef } from "react"; import { KeyboardIcon } from "@radix-ui/react-icons"; @@ -13,35 +13,52 @@ declare module '@tiptap/core' { } } -const extensionName = "inline-completion-completion"; +const extensionName = "inline-completion"; export const InlineCompletion = Node.create({ name: extensionName, group: "block", defining: true, isolating: true, + hasTrigger: false, content: "text*", addOptions() { return { HTMLAttributes: { - class: "inline-completion-completion", + class: "inline-completion", }, } }, addKeyboardShortcuts() { return { "Mod-\\": (): boolean => { + // @ts-ignore + this.hasTrigger = true this.editor.commands.triggerInlineCompletion() return true }, "Tab": (): boolean => { + // @ts-ignore + this.hasTrigger = false this.editor.commands.completeInlineCompletion() return true }, "`": (): boolean => { + // @ts-ignore + if (!this.hasTrigger) { + return false + } + // @ts-ignore + this.hasTrigger = false this.editor.commands.completeInlineCompletion() return true }, Escape: (): boolean => { + // @ts-ignore + if (!this.hasTrigger) { + return false + } + // @ts-ignore + this.hasTrigger = false this.editor.commands.cancelInlineCompletion(); return true }, @@ -56,10 +73,21 @@ export const InlineCompletion = Node.create({ attrs: options, }) }, - completeInlineCompletion: (options: any) => ({ commands }: { commands: any }) => { + completeInlineCompletion: (options: any) => ({ commands, tr }: { commands: any, tr: any }) => { const pos = this.editor.view.state.selection.$anchor.pos; - commands.deleteNode(this.name) + // commands.deleteNode(this.name) commands.insertContentAt(pos, "done completion") + + try { + tr.doc.descendants((node, pos) => { + if (node.type.name == this.name) { + commands.deleteRange({ from: pos, to: pos + node.nodeSize }) + return false; + } + }) + } catch (e) { + console.log(e) + } }, cancelInlineCompletion: (options: any) => ({ commands }: { commands: any }) => { commands.deleteNode(this.name) @@ -91,7 +119,7 @@ const InlineCompletionView = (props?: { editor: Editor }) => { return ( - show inline completion ` + type ` to completion ); }; diff --git a/web/studio/styles/global.css b/web/studio/styles/global.css index e1e7d26..41390a9 100644 --- a/web/studio/styles/global.css +++ b/web/studio/styles/global.css @@ -611,7 +611,7 @@ input { } .inline-completion-tip { - margin-left: 1em; + margin-left: 0.2em; background: #fff; font-weight: 500; border-radius: 0.2em;