File size: 2,833 Bytes
6b7fbaf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import React, { useRef } from 'react';
import Editor, { OnMount } from '@monaco-editor/react';
import * as monaco from 'monaco-editor';

const CodeEditor: React.FC<{ filePath: string | null; projectPath: string }> = ({ filePath, projectPath }) => {
  const editorRef = useRef<monaco.editor.IStandaloneCodeEditor | null>(null);

  const handleEditorDidMount: OnMount = (editor, monaco) => {
    editorRef.current = editor;

    monaco.languages.registerInlineCompletionsProvider('*', {
      provideInlineCompletions: async (model, position, context, token) => {
        const prefix = model.getValueInRange({
          startLineNumber: 1,
          startColumn: 1,
          endLineNumber: position.lineNumber,
          endColumn: position.column,
        });
        const suffix = model.getValueInRange({
          startLineNumber: position.lineNumber,
          startColumn: position.column,
          endLineNumber: model.getLineCount(),
          endColumn: model.getLineMaxColumn(model.getLineCount()),
        });

        try {
          const resp = await fetch('/api/autocomplete', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
              prefix,
              suffix,
              filepath: filePath || '',
              language: model.getLanguageId(),
              max_tokens: 64,
              model: 'groq-llama-3.1-8b-instant',
            }),
          });
          if (!resp.ok) return { items: [] };
          const data = await resp.json();
          const completions = data.completions || [];
          return {
            items: completions.map((c: any) => ({
              insertText: c.text,
              range: {
                startLineNumber: position.lineNumber,
                startColumn: position.column,
                endLineNumber: position.lineNumber,
                endColumn: position.column,
              },
            })),
          };
        } catch (e) {
          return { items: [] };
        }
      },
      freeInlineCompletions: () => {},
    });
  };

  if (!filePath) return (
    <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--text-secondary)', fontSize: 14 }}>
      ← Select a file from the explorer to start editing
    </div>
  );

  return (
    <Editor
      height="100%"
      defaultLanguage="typescript"
      theme="vs-dark"
      path={filePath}
      onMount={handleEditorDidMount}
      loading={<div style={{ color: 'var(--text-secondary)', padding: 20 }}>Loading editor...</div>}
      options={{
        fontSize: 13,
        minimap: { enabled: true },
        smoothScrolling: true,
        cursorBlinking: 'smooth',
        inlineSuggest: { enabled: true },
      }}
    />
  );
};

export default CodeEditor;