emacs: gptel enhancements including gptel-ask and keybindings
This commit is contained in:
parent
ec98d3bfab
commit
40be300bf4
@ -2320,71 +2320,90 @@ These help speed eglot up apparently [[https://www.reddit.com/r/emacs/comments/1
|
||||
#+begin_src emacs-lisp
|
||||
(setq gptel-default-mode #'org-mode)
|
||||
(setq
|
||||
gptel-model 'claude-3-sonnet-20240229
|
||||
gptel-model 'claude-sonnet-4-20250514
|
||||
gptel-backend (gptel-make-anthropic "Claude"
|
||||
:stream t :key (with-temp-buffer
|
||||
(insert-file-contents (expand-file-name "gptel-key" user-emacs-directory))
|
||||
(buffer-string))))
|
||||
(add-hook 'gptel-post-response-functions #'font-lock-ensure)
|
||||
(insert-file-contents (expand-file-name "gptel-key" user-emacs-directory))
|
||||
(buffer-string))))
|
||||
;; (add-hook 'gptel-post-response-functions #'font-lock-ensure)
|
||||
|
||||
(setq gptel-prompt-prefix-alist '((markdown-mode . "### ")
|
||||
(org-mode . "* ")
|
||||
(text-mode . "### ")))
|
||||
|
||||
(evil-define-key 'normal joe/evil-space-mode-map (kbd "SPC a a") #'gptel)
|
||||
(evil-define-key 'normal joe/evil-space-mode-map (kbd "SPC a RET") #'gptel-ask)
|
||||
(evil-define-key 'normal joe/evil-space-mode-map (kbd "SPC a M") #'gptel-mode)
|
||||
(evil-define-key 'visual joe/evil-space-mode-map (kbd "SPC a c") #'gptel-add) ;; Will delete context at point
|
||||
(evil-define-key 'normal joe/evil-space-mode-map (kbd "SPC a <backspace>") #'joe/gptel-context-remove-all)
|
||||
|
||||
(evil-define-key 'visual joe/evil-space-mode-map (kbd "SPC a r") #'gptel-rewrite)
|
||||
(evil-define-key 'visual joe/evil-space-mode-map (kbd "SPC a RET") #'gptel-ask)
|
||||
(evil-define-key 'visual joe/evil-space-mode-map (kbd "SPC a c") #'gptel-add)
|
||||
#+end_src
|
||||
|
||||
This function was suggested by Karthink in order to fix an issue where gptel
|
||||
org-mode was jumping back up to the top anytime the buffer was saved. Keeping it
|
||||
around just in case.
|
||||
gptel-context-remove-all without confirmation
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun joe/gptel-context-remove-all (&optional verbose)
|
||||
"Remove all gptel context. No confirmation."
|
||||
(interactive (list t))
|
||||
(if (null gptel-context--alist)
|
||||
(message "No gptel context sources to remove.")
|
||||
(cl-loop
|
||||
for (source . ovs) in gptel-context--alist
|
||||
if (bufferp source) do ;Buffers and buffer regions
|
||||
(mapc #'gptel-context-remove ovs)
|
||||
else do (gptel-context-remove source) ;files or other types
|
||||
finally do (setq gptel-context--alist nil))))
|
||||
#+end_src
|
||||
|
||||
gptel-ask command so I can ask LLMs about whatever I have in my region. Might be
|
||||
nice to add some more functionality similar to gptel-quick, like dwim behavior
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defvar gptel-ask--history nil)
|
||||
|
||||
(defun gptel-ask (prompt)
|
||||
(interactive
|
||||
(list (read-string (format "Ask %s: " (gptel-backend-name gptel-backend)) nil 'gptel-ask--history)))
|
||||
(when (string= prompt "") (user-error "A prompt is required."))
|
||||
(let ((region-text (buffer-substring-no-properties (region-beginning) (region-end)))
|
||||
(buffer-existed (get-buffer "*gptel-ask*"))
|
||||
(buffer (get-buffer-create "*gptel-ask*")))
|
||||
|
||||
(with-current-buffer buffer
|
||||
(unless buffer-existed
|
||||
(org-mode)
|
||||
(let ((map (copy-keymap (current-local-map))))
|
||||
(evil-define-key 'nomal map "q" 'quit-window)
|
||||
(use-local-map map)))
|
||||
(erase-buffer)
|
||||
(insert (format "* %s\n\n" prompt)))
|
||||
|
||||
(pop-to-buffer buffer)
|
||||
(gptel-request
|
||||
(concat prompt "\n\nRegion text:\n" region-text)
|
||||
:system "You are an LLM living inside of Emacs. Answer questions concisely, no flattery"
|
||||
:stream t
|
||||
:callback
|
||||
(lambda (response info)
|
||||
(cond
|
||||
((not response)
|
||||
(message "gptel-ask failed with message: %s" (plist-get info :status)))
|
||||
((stringp response)
|
||||
(with-current-buffer (get-buffer "*gptel-ask*")
|
||||
(let ((inhibit-read-only t))
|
||||
(goto-char (point-max))
|
||||
(insert response)))))))))
|
||||
#+end_src
|
||||
|
||||
https://github.com/karthink/gptel/issues/199
|
||||
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defun gptel--save-state ()
|
||||
"Write the gptel state to the buffer.
|
||||
|
||||
This saves chat metadata when writing the buffer to disk. To
|
||||
restore a chat session, turn on `gptel-mode' after opening the
|
||||
file."
|
||||
(pcase major-mode
|
||||
('org-mode
|
||||
(org-with-wide-buffer
|
||||
(goto-char (point-min))
|
||||
(when (org-at-heading-p)
|
||||
(org-open-line 1))
|
||||
(org-entry-put (point-min) "GPTEL_MODEL" gptel-model)
|
||||
(org-entry-put (point-min) "GPTEL_BACKEND" (gptel-backend-name gptel-backend))
|
||||
(unless (equal (default-value 'gptel-temperature) gptel-temperature)
|
||||
(org-entry-put (point-min) "GPTEL_TEMPERATURE"
|
||||
(number-to-string gptel-temperature)))
|
||||
(unless (string= (default-value 'gptel--system-message)
|
||||
gptel--system-message)
|
||||
(org-entry-put (point-min) "GPTEL_SYSTEM"
|
||||
gptel--system-message))
|
||||
(when gptel-max-tokens
|
||||
(org-entry-put
|
||||
(point-min) "GPTEL_MAX_TOKENS" gptel-max-tokens))
|
||||
;; Save response boundaries
|
||||
(letrec ((write-bounds
|
||||
(lambda (attempts)
|
||||
(let* ((bounds (gptel--get-bounds))
|
||||
(offset (caar bounds))
|
||||
(offset-marker (set-marker (make-marker) offset)))
|
||||
(org-entry-put (point-min) "GPTEL_BOUNDS"
|
||||
(prin1-to-string (gptel--get-bounds)))
|
||||
(when (and (not (= (marker-position offset-marker) offset))
|
||||
(> attempts 0))
|
||||
(funcall write-bounds (1- attempts)))))))
|
||||
(funcall write-bounds 6))))
|
||||
(_ (save-excursion
|
||||
(save-restriction
|
||||
(add-file-local-variable 'gptel-model gptel-model)
|
||||
(add-file-local-variable 'gptel--backend-name
|
||||
(gptel-backend-name gptel-backend))
|
||||
(unless (equal (default-value 'gptel-temperature) gptel-temperature)
|
||||
(add-file-local-variable 'gptel-temperature gptel-temperature))
|
||||
(unless (string= (default-value 'gptel--system-message)
|
||||
gptel--system-message)
|
||||
(add-file-local-variable 'gptel--system-message gptel--system-message))
|
||||
(when gptel-max-tokens
|
||||
(add-file-local-variable 'gptel-max-tokens gptel-max-tokens))
|
||||
(add-file-local-variable 'gptel--bounds (gptel--get-bounds)))))))
|
||||
|
||||
;; Quick helper to cat the key
|
||||
(with-temp-buffer
|
||||
(insert-file-contents (expand-file-name "gptel-key" user-emacs-directory))
|
||||
(clipboard-kill-region (point-min) (point-max)))
|
||||
#+end_src
|
||||
** Programming Languages
|
||||
*** COMMENT treesitter
|
||||
|
Loading…
x
Reference in New Issue
Block a user