Skip to content

Commit 1a8e1e1

Browse files
knilinkbbatsov
authored andcommitted
feat: customizable lsp event handler and lsp server log
1 parent 8f4a04e commit 1a8e1e1

File tree

2 files changed

+96
-25
lines changed

2 files changed

+96
-25
lines changed

README.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,31 @@ For example:
309309
(setq copilot-network-proxy '(:host "127.0.0.1" :port 7890))
310310
```
311311

312+
### copilot-on-request
313+
314+
Register a handler to be called when a request of type method is received. Return JSON serializable as result or calling `jsonrpc-error` for errors. [readmore](https://www.gnu.org/software/emacs/manual/html_node/elisp/JSONRPC-Overview.html)
315+
316+
For example:
317+
318+
```elisp
319+
; Display desktop notification if emacs is built with d-bus
320+
(copilot-on-request
321+
'window/showMessageRequest
322+
(lambda (msg) (notifications-notify :title "Emacs Copilot" :body (plist-get msg :message))))
323+
```
324+
325+
### copilot-on-notification
326+
327+
Register a listener for copilot notifications.
328+
329+
For example:
330+
331+
```elisp
332+
(copilot-on-notification
333+
'window/logMessage
334+
(lambda (msg) (message (plist-get msg :message))
335+
```
336+
312337
## Known Issues
313338

314339
### Wrong Position of Other Completion Popups
@@ -332,7 +357,7 @@ But I decided to allow them to coexist, allowing you to choose a better one at a
332357
## Reporting Bugs
333358

334359
+ Make sure you have restarted your Emacs (and rebuild the plugin if necessary) after updating the plugin.
335-
+ Please enable event logging by customize `copilot-log-max` (to e.g. 1000), then paste related logs in the `*copilot events*` and `*copilot stderr*` buffer.
360+
+ Please enable event logging by customize `copilot-log-max` (to e.g. 1000) and enable debug log `(setq copilot-server-args '("--stdio" "--debug"))`, then paste related logs in the `*copilot events*`, `*copilot stderr*` and `*copilot-language-server-log*` buffer.
336361
+ If an exception is thrown, please also paste the stack trace (use `M-x toggle-debug-on-error` to enable stack trace).
337362

338363
## Thanks

copilot.el

Lines changed: 70 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ SUCCESS-FN is the CALLBACK."
406406
#'make-instance
407407
'jsonrpc-process-connection
408408
:name "copilot"
409+
:request-dispatcher #'copilot--handle-request
409410
:notification-dispatcher #'copilot--handle-notification
410411
:process (make-process :name "copilot server"
411412
:command (copilot--command)
@@ -719,31 +720,76 @@ automatically, browse to %s." user-code verification-uri))
719720
(defvar copilot--panel-lang nil
720721
"Language of current panel solutions.")
721722

723+
(defvar copilot--request-handlers (make-hash-table :test 'equal)
724+
"Hash table storing request handlers.")
725+
726+
(defun copilot-on-request (method handler)
727+
"Register a request HANDLER for the given METHOD.
728+
Each request METHOD can have only one HANDLER."
729+
(puthash method handler copilot--request-handlers))
730+
731+
(defun copilot--handle-request (_ method msg)
732+
"Handle MSG of type METHOD by calling the appropriate registered handler."
733+
(let ((handler (gethash method copilot--request-handlers)))
734+
(when handler
735+
(funcall handler msg))))
736+
737+
(defvar copilot--notification-handlers (make-hash-table :test 'equal)
738+
"Hash table storing lists of notification handlers.")
739+
740+
(defun copilot-on-notification (method handler)
741+
"Register a notification HANDLER for the given METHOD."
742+
(let ((handlers (gethash method copilot--notification-handlers '())))
743+
(puthash method (cons handler handlers) copilot--notification-handlers)))
744+
722745
(defun copilot--handle-notification (_ method msg)
723-
"Handle MSG of type METHOD."
724-
(when (eql method 'PanelSolution)
725-
(copilot--dbind (((:completionText completion-text)) ((:score completion-score))) msg
726-
(with-current-buffer "*copilot-panel*"
727-
(unless (member (secure-hash 'sha256 completion-text)
728-
(org-map-entries (lambda () (org-entry-get nil "SHA"))))
729-
(save-excursion
730-
(goto-char (point-max))
731-
(insert "* Solution\n"
732-
" :PROPERTIES:\n"
733-
" :SCORE: " (number-to-string completion-score) "\n"
734-
" :SHA: " (secure-hash 'sha256 completion-text) "\n"
735-
" :END:\n"
736-
"#+BEGIN_SRC " copilot--panel-lang "\n"
737-
completion-text "\n#+END_SRC\n\n")
738-
(call-interactively #'mark-whole-buffer)
739-
(org-sort-entries nil ?R nil nil "SCORE"))))))
740-
(when (eql method 'PanelSolutionsDone)
741-
(message "Copilot: Finish synthesizing solutions.")
742-
(display-buffer "*copilot-panel*")
743-
(with-current-buffer "*copilot-panel*"
744-
(save-excursion
745-
(goto-char (point-max))
746-
(insert "End of solutions.\n")))))
746+
"Handle MSG of type METHOD by calling all appropriate registered handlers."
747+
(let ((handlers (gethash method copilot--notification-handlers '())))
748+
(dolist (handler handlers)
749+
(funcall handler msg))))
750+
751+
(copilot-on-notification
752+
'window/logMessage
753+
(lambda (msg)
754+
(copilot--dbind (:type log-level :message log-msg) msg
755+
(with-current-buffer (get-buffer-create "*copilot-language-server-log*")
756+
(save-excursion
757+
(goto-char (point-max))
758+
(insert (propertize (concat log-msg "\n")
759+
'face (pcase log-level
760+
(4 'shadow)
761+
(3 'success)
762+
(2 'warning)
763+
(1 'error)))))))))
764+
765+
(copilot-on-notification
766+
'PanelSolution
767+
(lambda (msg)
768+
(copilot--dbind (((:completionText completion-text)) ((:score completion-score))) msg
769+
(with-current-buffer "*copilot-panel*"
770+
(unless (member (secure-hash 'sha256 completion-text)
771+
(org-map-entries (lambda () (org-entry-get nil "SHA"))))
772+
(save-excursion
773+
(goto-char (point-max))
774+
(insert "* Solution\n"
775+
" :PROPERTIES:\n"
776+
" :SCORE: " (number-to-string completion-score) "\n"
777+
" :SHA: " (secure-hash 'sha256 completion-text) "\n"
778+
" :END:\n"
779+
"#+BEGIN_SRC " copilot--panel-lang "\n"
780+
completion-text "\n#+END_SRC\n\n")
781+
(call-interactively #'mark-whole-buffer)
782+
(org-sort-entries nil ?R nil nil "SCORE")))))))
783+
784+
(copilot-on-notification
785+
'PanelSolutionsDone
786+
(lambda (_msg)
787+
(message "Copilot: Finish synthesizing solutions.")
788+
(display-buffer "*copilot-panel*")
789+
(with-current-buffer "*copilot-panel*"
790+
(save-excursion
791+
(goto-char (point-max))
792+
(insert "End of solutions.\n")))))
747793

748794
(defun copilot--get-panel-completions (callback)
749795
"Get panel completions with CALLBACK."

0 commit comments

Comments
 (0)