Skip to content

Commit 66f7551

Browse files
committed
feat: customizable lsp event handler and lsp server log
1 parent 5fa27b5 commit 66f7551

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
@@ -311,6 +311,31 @@ For example:
311311
(setq copilot-network-proxy '(:host "127.0.0.1" :port 7890))
312312
```
313313

314+
### copilot-on-request
315+
316+
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)
317+
318+
For example:
319+
320+
```elisp
321+
; Display desktop notification if emacs is built with d-bus
322+
(copilot-on-request
323+
'window/showMessageRequest
324+
(lambda (msg) (notifications-notify :title "Emacs Copilot" :body (plist-get msg :message))))
325+
```
326+
327+
### copilot-on-notification
328+
329+
Register a listener for copilot notifications.
330+
331+
For example:
332+
333+
```elisp
334+
(copilot-on-notification
335+
'window/logMessage
336+
(lambda (msg) (message (plist-get msg :message))
337+
```
338+
314339
## Known Issues
315340

316341
### Wrong Position of Other Completion Popups
@@ -334,7 +359,7 @@ But I decided to allow them to coexist, allowing you to choose a better one at a
334359
## Reporting Bugs
335360

336361
+ Make sure you have restarted your Emacs (and rebuild the plugin if necessary) after updating the plugin.
337-
+ 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.
362+
+ 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.
338363
+ If an exception is thrown, please also paste the stack trace (use `M-x toggle-debug-on-error` to enable stack trace).
339364

340365
## Roadmap

copilot.el

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

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

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

0 commit comments

Comments
 (0)