Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for Linux #2

Merged
merged 9 commits into from
Feb 11, 2024
7 changes: 4 additions & 3 deletions copilot-balancer.el
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,13 @@ Special care has to be taken to ignore pairs in the middle of strings."

(defvar copilot-balancer-top-level-form-start-regexp
(rx line-start (or (literal "(") (literal "[") (literal "{")))
"Regexp for the start of a top level form. Assumes cursor is at the start of a line.")
"Regexp for the start of a top level form. Assumes cursor is at the start
of a line.")

(defvar copilot-balancer-form-end-regexp
(rx (or (literal "}") (literal "]") (literal ")")) line-end)
"Regexp for the end of a form. Assumes cursor is at the last character of the line
(not the actual newline character).")
"Regexp for the end of a form. Assumes cursor is at the last character of
the line (not the actual newline character).")

(defun copilot-balancer-get-top-level-form-beginning-to-point (x)
(save-excursion
Expand Down
77 changes: 55 additions & 22 deletions copilot.el
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ indentation offset."
:type 'directory
:group 'copilot)

(defconst copilot--dist-dir
(defconst copilot--server-executable
(if (eq system-type 'windows-nt)
(f-join copilot-install-dir "node_modules" "copilot-node-server" "copilot" "dist")
(f-join copilot-install-dir "node_modules" "copilot-node-server" "copilot" "dist" "agent.js")
(f-join copilot-install-dir "bin" "copilot-node-server"))
"The dist directory containing agent.js file.")

Expand All @@ -119,6 +119,9 @@ You may adjust this variable at your own risk."
(defvar-local copilot--overlay nil
"Overlay for Copilot completion.")

(defvar-local copilot--keymap-overlay nil
"Overlay used to surround point and make copilot-completion-keymap activate.")

(defvar copilot--connection nil
"Copilot agent jsonrpc connection instance.")

Expand Down Expand Up @@ -205,7 +208,7 @@ Please upgrade the server via `M-x copilot-reinstall-server`"))
:notification-dispatcher #'copilot--handle-notification
:process (make-process :name "copilot agent"
:command (list copilot-node-executable
(concat copilot--dist-dir "/agent.js"))
copilot--server-executable)
:coding 'utf-8-emacs-unix
:connection-type 'pipe
:stderr (get-buffer-create "*copilot stderr*")
Expand Down Expand Up @@ -346,8 +349,9 @@ automatically, browse to %s." user-code verification-uri))
(setq mode (get mode 'derived-mode-parent))))
(when mode
(cl-some (lambda (s)
(when (and (boundp s) (numberp (symbol-value s)))
(symbol-value s)))
;; s can be a symbol or a number.
(cond ((numberp s) s)
((and (boundp s) (numberp (symbol-value s))) (symbol-value s))))
(alist-get mode copilot-indentation-alist))))
(progn
(when (and
Expand Down Expand Up @@ -553,12 +557,20 @@ To work around posn problems with after-string property.")
(defconst copilot-completion-map (make-sparse-keymap)
"Keymap for Copilot completion overlay.")

(defun copilot--get-or-create-keymap-overlay ()
"Make or return the local copilot--keymap-overlay."
(unless (overlayp copilot--keymap-overlay)
(setq copilot--keymap-overlay (make-overlay 1 1 nil nil t))
(overlay-put copilot--keymap-overlay 'keymap copilot-completion-map)
(overlay-put copilot--keymap-overlay 'priority 101))
copilot--keymap-overlay)

(defun copilot--get-overlay ()
"Create or get overlay for Copilot."
(unless (overlayp copilot--overlay)
(setq copilot--overlay (make-overlay 1 1 nil nil t))
(overlay-put copilot--overlay 'keymap copilot-completion-map)
(overlay-put copilot--overlay 'priority 100))
(overlay-put
copilot--overlay 'keymap-overlay (copilot--get-or-create-keymap-overlay)))
copilot--overlay)

(defun copilot--overlay-end (ov)
Expand All @@ -568,6 +580,16 @@ To work around posn problems with after-string property.")
(defun copilot--set-overlay-text (ov completion)
"Set overlay OV with COMPLETION."
(move-overlay ov (point) (line-end-position))

;; set overlay position for the keymap, to activate copilot-completion-map
;;
;; if the point is at the end of the buffer, we will create a
;; 0-length buffer. But this is ok, since the keymap will still
;; activate _so long_ as no other overlay contains the point.
;;
;; see https://github.com/copilot-emacs/copilot.el/issues/251 for details.
(move-overlay (overlay-get ov 'keymap-overlay) (point) (min (point-max) (+ 1 (point))))

(let* ((tail (buffer-substring (copilot--overlay-end ov) (line-end-position)))
(p-completion (concat (propertize completion 'face 'copilot-overlay-face)
tail)))
Expand Down Expand Up @@ -608,6 +630,7 @@ already saving an excursion. This is also a private function."
(copilot--async-request 'notifyRejected
(list :uuids `[,(overlay-get copilot--overlay 'uuid)])))
(delete-overlay copilot--overlay)
(delete-overlay copilot--keymap-overlay)
(setq copilot--real-posn nil)))

(defun copilot-accept-completion (&optional transform-fn)
Expand Down Expand Up @@ -899,35 +922,45 @@ command that triggered `post-command-hook'."
(defun copilot-installed-version ()
"Return the version number of currently installed `copilot-node-server'."
(when-let*
((package-json (f-join copilot-install-dir "node_modules" "copilot-node-server" "package.json"))
((package-json
(if (eq system-type 'windows-nt)
(f-join copilot-install-dir "node_modules" "copilot-node-server" "package.json")
(f-join copilot-install-dir "lib" "node_modules" "copilot-node-server" "package.json")))
((file-exists-p package-json)))
(with-temp-buffer
(insert-file-contents package-json)
(goto-char (point-min))
(when (search-forward "\"version\": \"" nil t)
(buffer-substring-no-properties (point) (- (line-end-position) 2))))))
(save-match-data
(when (re-search-forward "\"version\": \"\\([0-9]+\.[0-9]+\.[0-9]+\\)")
(match-string 1))))))

;; XXX: This function is modified from `lsp-mode'; see `lsp-async-start-process'
;; function for more information.
(defun copilot-async-start-process (callback error-callback &rest command)
"Start async process COMMAND with CALLBACK and ERROR-CALLBACK."
(let ((name (cl-first command)))
(with-current-buffer (compilation-start (mapconcat #'shell-quote-argument (-filter (lambda (cmd)
(not (null cmd)))
command)
" ") t
(lambda (&rest _)
(generate-new-buffer-name "*copilot-install-server*")))
(with-current-buffer
(compilation-start
(mapconcat
#'shell-quote-argument
(-filter
(lambda (cmd)
(not (null cmd)))
command) " ")
t
(lambda (&rest _)
(generate-new-buffer-name "*copilot-install-server*")))
(view-mode +1)
(add-hook
'compilation-finish-functions
(lambda (_buf status)
(if (string= "finished\n" status)
(condition-case err
(funcall callback)
(error
(funcall error-callback (error-message-string err))))
(funcall error-callback (s-trim-right status))))
(when callback
(condition-case err
(funcall callback)
(error
(funcall error-callback (error-message-string err)))))
(when error-callback
(funcall error-callback (s-trim-right status)))))
nil t))))

;;;###autoload
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Retired maintainer: [@zerolfx][].

## Installation

0. Ensure your Emacs version is at least 27, and the dependency package `editorconfig` ([melpa](https://melpa.org/#/editorconfig)) is also installed.
0. Ensure your Emacs version is at least 27, the dependency package `editorconfig` ([melpa](https://melpa.org/#/editorconfig)) and `jsonrpc` ([elpa](https://elpa.gnu.org/packages/jsonrpc.html), >= 1.0.24) are both installed.

1. Install [Node.js][] v18+. (You can specify the path to `node` executable by setting `copilot-node-executable`.)

Expand Down