Created
December 26, 2024 19:49
-
-
Save merisbahti/436e63bab36731c021724c1d681a680f to your computer and use it in GitHub Desktop.
ai hints plugin for steel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(require (prefix-in helix. "helix/commands.scm")) | |
(require (prefix-in helix.static. "helix/static.scm")) | |
(require "helix/misc.scm") | |
(require "component.scm") | |
(require "helix/editor.scm") | |
(require-builtin helix/components) | |
(require-builtin helix/core/text as text.) | |
(require "cogs/helix-ext.scm") | |
(define (run-cmd cmd . args) | |
(let | |
([builder (command cmd args)]) | |
(set-piped-stdout! builder) | |
(~> builder spawn-process Ok->value wait->stdout Ok->value))) | |
(define api-key (trim (run-cmd "printenv" "OPENAI_API_KEY"))) | |
(define (get-document-as-slice) | |
(let* ([focus (editor-focus)] | |
[focus-doc-id (editor->doc-id focus)]) | |
(text.rope->string (editor->text focus-doc-id)))) | |
(define openapi-server "https://api.openai.com/v1/chat/completions") | |
(define (make-request code-with-cursor callback) | |
(spawn-native-thread | |
(fn () | |
(define output | |
(run-cmd | |
"curl" | |
openapi-server | |
"-d" | |
(value->jsexpr-string | |
(hash | |
'model | |
"gpt-4o-mini" | |
'messages | |
(list | |
(hash | |
'role | |
"user" | |
'content | |
(string-join | |
(list "Only answer in code without wrapping into markdown, what would you put at the position of <CURSOR>, don't include text before or after <CURSOR>: | |
" | |
code-with-cursor)))) | |
'prediction | |
(hash 'type "content" 'content code-with-cursor) | |
'temperature | |
0.1)) | |
"-H" | |
"Content-Type: application/json" | |
"-H" | |
(string-join (list "Authorization: Bearer " api-key)))) | |
(define parsed-output | |
(~> | |
(string->jsexpr output) | |
(hash-ref 'choices) | |
(list-ref 0) | |
(hash-ref 'message) | |
(hash-ref 'content))) | |
(hx.with-context | |
(fn () | |
(callback parsed-output)))))) | |
(define *latest-inlay-hint* (None)) | |
(provide ask-prompt) | |
(provide accept-current-hint) | |
;; accepts the current ai generated hint | |
(define (accept-current-hint) | |
(when (not (None? *latest-inlay-hint*)) | |
(helix.static.insert_string (cadr *latest-inlay-hint*)) | |
(clear-inlay-hint))) | |
(define (clear-inlay-hint) | |
(when (not (None? *latest-inlay-hint*)) | |
(apply remove-inlay-hint (cons *helix.cx* *latest-inlay-hint*)) | |
(set! *latest-inlay-hint* (None)))) | |
;; each character should'nt send a request | |
(define *latest-debounce-id* 0) | |
(define (ask-prompt) | |
(define current-debounce-id (+ 1 *latest-debounce-id*)) | |
(set! *latest-debounce-id* current-debounce-id) | |
(define doc (get-document-as-slice)) | |
(define cursor-pos (hx.cx->pos)) | |
(define code-with-cursor | |
(string-join | |
(list | |
(substring doc 0 cursor-pos) | |
"<CURSOR>" | |
(substring doc cursor-pos)))) | |
(enqueue-thread-local-callback-with-delay 300 | |
(fn () | |
(when | |
(not (equal? current-debounce-id *latest-debounce-id*)) | |
(return! void)) | |
(make-request code-with-cursor | |
(fn (x) | |
(when (not (equal? current-debounce-id *latest-debounce-id*)) (return! void)) | |
(hx.with-context | |
(fn () | |
(clear-inlay-hint) | |
(set! *latest-inlay-hint* (list cursor-pos x)) | |
(add-inlay-hint *helix.cx* cursor-pos x)))))))) | |
(register-hook! "post-command" | |
(fn (_) | |
(clear-inlay-hint))) | |
(register-hook! "post-insert-char" | |
(fn (_) | |
(clear-inlay-hint) | |
(ask-prompt))) | |
(register-hook! "on-mode-switch" | |
(fn (_) | |
(set! *latest-debounce-id* (+ 1 *latest-debounce-id*)) | |
(clear-inlay-hint))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment