File size: 3,185 Bytes
5d0136a
 
9f3e6d3
 
 
 
 
 
5d0136a
9f3e6d3
 
5d0136a
d78ffd0
5d0136a
 
 
 
 
 
 
9f3e6d3
5d0136a
d78ffd0
5d0136a
9f3e6d3
5d0136a
 
 
 
 
 
 
 
 
 
 
 
 
0282567
 
 
 
 
 
 
 
 
5d0136a
0282567
5d0136a
 
 
9f3e6d3
 
 
 
c86c048
 
 
 
 
 
 
 
 
 
 
 
 
 
0282567
 
 
 
 
 
c86c048
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5d0136a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// @ts-check

import {
  commandsCtx,
  editorViewCtx,
  parserCtx,
  serializerCtx
} from '@milkdown/core';
import { $command, $useKeymap } from '@milkdown/utils';

import { handlePrompt } from './handle-prompt';

export function makeEnterPlugins({ workerConnection }) {
  // Create a command that sends the current input content to the chat log
  const myEnterCommand = $command('MyEnterCommand', (ctx) => {
    return () => (state, dispatch) => {
      const view = ctx.get(editorViewCtx);
      const toMarkdown = ctx.get(serializerCtx);
      const fromMarkdown = ctx.get(parserCtx);
      const markdown = (toMarkdown(view.state.doc) || '').trim();

      if (markdown) {
        handlePrompt({ promptMarkdown: markdown, workerConnection });
      }

      // Clear input
      const emptyDoc = fromMarkdown('');
      const tr = view.state.tr.replaceWith(0, view.state.doc.content.size, emptyDoc.content);
      view.dispatch(tr);
      return true;
    };
  });

  const myEnterKeymap = $useKeymap('MyEnterKeymap', {
    MyEnter: {
      shortcuts: 'Enter',
      command: (ctx) => {
        const commands = ctx.get(commandsCtx);
        return () => {
          // Check if slash menu is open first
          const slashMenu = document.querySelector('.milkdown-slash-menu[data-show="true"]');
          if (slashMenu) {
            // Let the slash menu handle Enter
            return false;
          }
          return commands.call(myEnterCommand.key);
        };
      },
      priority: 50, // Lower priority so slash menu can intercept first
    },
  });

  return [
    myEnterCommand,
    myEnterKeymap
  ];
}

/**
 * Setup Enter key handling for Crepe editor
 * @param {import('@milkdown/crepe').Crepe} crepeInput 
 * @param {ReturnType<import('./worker-connection').workerConnection>} workerConnection 
 */
export function setupCrepeEnterKey(crepeInput, workerConnection) {
  // Add Enter key handling through Crepe's underlying editor
  crepeInput.editor.action((ctx) => {
    const view = ctx.get(editorViewCtx);
    if (view.dom) {
      view.dom.addEventListener('keydown', (e) => {
        if (e.key === 'Enter' && !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) {
          // Check if slash menu is open - if so, let it handle Enter
          const slashMenu = document.querySelector('.milkdown-slash-menu[data-show="true"]');
          if (slashMenu) {
            return false; // Don't prevent default, let slash menu handle it
          }
          
          e.preventDefault();
          
          // Get markdown using the underlying editor's serializer
          const toMarkdown = ctx.get(serializerCtx);
          const markdown = toMarkdown(view.state.doc).trim();
          
          if (markdown) {
            handlePrompt({ promptMarkdown: markdown, workerConnection });
            // Clear the input
            const fromMarkdown = ctx.get(parserCtx);
            const emptyDoc = fromMarkdown('');
            const tr = view.state.tr.replaceWith(0, view.state.doc.content.size, emptyDoc.content);
            view.dispatch(tr);
          }
          
          return true;
        }
        return false;
      });
    }
  });
}