emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/eglot 6531c8b 58/69: Merge branch 'master' into jsonrpc


From: João Távora
Subject: [elpa] externals/eglot 6531c8b 58/69: Merge branch 'master' into jsonrpc-refactor
Date: Fri, 22 Jun 2018 11:55:04 -0400 (EDT)

branch: externals/eglot
commit 6531c8b208736c9f30f829608791deaa44a9160f
Merge: 7371f68 1506172
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>

    Merge branch 'master' into jsonrpc-refactor
---
 eglot-tests.el | 19 +++++++-----
 eglot.el       | 94 +++++++++++++++++++++++++++++++++++++---------------------
 2 files changed, 72 insertions(+), 41 deletions(-)

diff --git a/eglot-tests.el b/eglot-tests.el
index 56ec980..b57b949 100644
--- a/eglot-tests.el
+++ b/eglot-tests.el
@@ -181,6 +181,9 @@ Pass TIMEOUT to `eglot--with-timeout'."
   (define-derived-mode rust-mode prog-mode "Rust"))
 (add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-mode))
 
+(defun eglot--tests-connect ()
+  (apply #'eglot--connect (eglot--guess-contact)))
+
 (ert-deftest auto-detect-running-server ()
   "Visit a file and M-x eglot, then visit a neighbour. "
   (skip-unless (executable-find "rls"))
@@ -192,7 +195,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
       (eglot--with-timeout 2
         (with-current-buffer
             (eglot--find-file-noselect "project/coiso.rs")
-          (should (setq server (apply #'eglot (eglot--interactive))))
+          (should (setq server (eglot--tests-connect)))
           (should (eglot--current-server)))
         (with-current-buffer
             (eglot--find-file-noselect "project/merdix.rs")
@@ -212,7 +215,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
       (eglot--with-timeout 3
         (with-current-buffer
             (eglot--find-file-noselect "project/coiso.rs")
-          (should (setq server (apply #'eglot (eglot--interactive))))
+          (should (setq server (eglot--tests-connect)))
           ;; In 1.2 seconds > `eglot-autoreconnect' kill servers. We
           ;; should have a automatic reconnection.
           (run-with-timer 1.2 nil (lambda () (delete-process
@@ -244,7 +247,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
                             :client-notifications c-notifs
                             :client-replies c-replies
                             )
-            (should (apply #'eglot (eglot--interactive)))
+            (should (eglot--tests-connect))
             (let (register-id)
               (eglot--wait-for (s-requests 1)
                   (&key id method &allow-other-keys)
@@ -274,7 +277,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
           (eglot--find-file-noselect "diag-project/main.rs")
         (should (zerop (shell-command "cargo init")))
         (eglot--sniffing (:server-notifications s-notifs)
-          (apply #'eglot (eglot--interactive))
+          (eglot--tests-connect)
           (eglot--wait-for (s-notifs 1)
               (&key _id method &allow-other-keys)
             (string= method 'textDocument/publishDiagnostics))
@@ -304,7 +307,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
                           :client-replies c-replies
                           :client-requests c-reqs
                           )
-          (apply #'eglot (eglot--interactive))
+          (eglot--tests-connect)
           (goto-char (point-min))
           (search-forward "return te")
           (insert "st")
@@ -342,7 +345,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
                           :client-replies c-replies
                           :client-requests c-reqs
                           )
-          (apply #'eglot (eglot--interactive))
+          (eglot--tests-connect)
           (goto-char (point-min)) (search-forward "return te")
           (eglot-rename "bla")
           (should (equal (buffer-string) "fn test() -> i32 { let bla=3; return 
bla; }")))))))
@@ -355,7 +358,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
     (eglot--with-timeout 4
       (with-current-buffer
           (eglot--find-file-noselect "project/something.py")
-        (should (apply #'eglot (eglot--interactive)))
+        (should (eglot--tests-connect))
         (goto-char (point-max))
         (completion-at-point)
         (should (looking-back "sys.exit"))))))
@@ -368,7 +371,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
     (eglot--with-timeout 4
       (with-current-buffer
           (eglot--find-file-noselect "project/something.py")
-        (should (apply #'eglot (eglot--interactive)))
+        (should (eglot--tests-connect))
         (goto-char (point-max))
         (setq eldoc-last-message nil)
         (completion-at-point)
diff --git a/eglot.el b/eglot.el
index 32879ec..0a060a5 100644
--- a/eglot.el
+++ b/eglot.el
@@ -46,6 +46,13 @@
 ;; To "unmanage" these buffers, shutdown the server with M-x
 ;; eglot-shutdown.
 ;;
+;; You can also do:
+;;
+;;   (add-hook 'foo-mode-hook 'eglot-ensure)
+;;
+;; To attempt to start an eglot session automatically everytime a
+;; foo-mode buffer is visited.
+;;
 ;;; Code:
 
 (require 'json)
@@ -255,8 +262,10 @@ function with the server still running."
 (defvar eglot--command-history nil
   "History of CONTACT arguments to `eglot'.")
 
-(defun eglot--interactive ()
-  "Helper for `eglot'."
+(defun eglot--guess-contact (&optional interactive)
+  "Helper for `eglot'.
+Return (MANAGED-MODE PROJECT CONTACT CLASS).
+If INTERACTIVE, maybe prompt user."
   (let* ((guessed-mode (if buffer-file-name major-mode))
          (managed-mode
           (cond
@@ -274,17 +283,20 @@ function with the server still running."
                     (prog1 (car guess) (setq guess (cdr guess)))
                   'eglot-lsp-server))
          (program (and (listp guess) (stringp (car guess)) (car guess)))
-         (base-prompt "[eglot] Enter program to execute (or <host>:<port>): ")
+         (base-prompt
+          (and interactive
+               "[eglot] Enter program to execute (or <host>:<port>): "))
          (prompt
-          (cond (current-prefix-arg base-prompt)
-                ((null guess)
-                 (format "[eglot] Sorry, couldn't guess for `%s'\n%s!"
-                         managed-mode base-prompt))
-                ((and program (not (executable-find program)))
-                 (concat (format "[eglot] I guess you want to run `%s'"
-                                 (combine-and-quote-strings guess))
-                         (format ", but I can't find `%s' in PATH!" program)
-                         "\n" base-prompt))))
+          (and base-prompt
+               (cond (current-prefix-arg base-prompt)
+                     ((null guess)
+                      (format "[eglot] Sorry, couldn't guess for `%s'!\n%s"
+                              managed-mode base-prompt))
+                     ((and program (not (executable-find program)))
+                      (concat (format "[eglot] I guess you want to run `%s'"
+                                      (combine-and-quote-strings guess))
+                              (format ", but I can't find `%s' in PATH!" 
program)
+                              "\n" base-prompt)))))
          (contact
           (if prompt
               (let ((s (read-shell-command
@@ -296,7 +308,7 @@ function with the server still running."
                     (list (match-string 1 s) (string-to-number (match-string 2 
s)))
                   (split-string-and-unquote s)))
             guess)))
-    (list managed-mode project class contact t)))
+    (list managed-mode project class contact)))
 
 ;;;###autoload
 (defun eglot (managed-major-mode project class contact &optional interactive)
@@ -327,26 +339,22 @@ keyword-value plist used to initialize CLASS or a plain 
list as
 described in `eglot-server-programs', which see.
 
 INTERACTIVE is t if called interactively."
-  (interactive (eglot--interactive))
-  (let* ((nickname (file-name-base (directory-file-name
-                                    (car (project-roots project)))))
-         (current-server (eglot--current-server))
+  (interactive (append (eglot--guess-contact t) '(t)))
+  (let* ((current-server (eglot--current-server))
          (live-p (and current-server (jsonrpc-running-p current-server))))
     (if (and live-p
              interactive
              (y-or-n-p "[eglot] Live process found, reconnect instead? "))
         (eglot-reconnect current-server interactive)
       (when live-p (ignore-errors (eglot-shutdown current-server)))
-      (let ((server (eglot--connect project
-                                    managed-major-mode
-                                    (format "%s/%s" nickname 
managed-major-mode)
-                                    nickname
+      (let ((server (eglot--connect managed-major-mode
+                                    project
                                     class
                                     contact)))
         (eglot--message "Connected! Process `%s' now \
 managing `%s' buffers in project `%s'."
                         (jsonrpc-name server) managed-major-mode
-                        nickname)
+                        (eglot--project-nickname server))
         server))))
 
 (defun eglot-reconnect (server &optional interactive)
@@ -355,14 +363,34 @@ INTERACTIVE is t if called interactively."
   (interactive (list (eglot--current-server-or-lose) t))
   (when (jsonrpc-running-p server)
     (ignore-errors (eglot-shutdown server interactive)))
-  (eglot--connect (eglot--project server)
-                  (eglot--major-mode server)
-                  (jsonrpc-name server)
-                  (eglot--project-nickname server)
+  (eglot--connect (eglot--major-mode server)
+                  (eglot--project server)
                   (eieio-object-class-name server)
                   (eglot--saved-initargs server))
   (eglot--message "Reconnected!"))
 
+(defvar eglot--managed-mode) ; forward decl
+
+(defun eglot-ensure ()
+  "Start Eglot session for current buffer if there isn't one."
+  (let ((buffer (current-buffer)))
+    (cl-labels
+        ((maybe-connect
+          ()
+          (remove-hook 'post-command-hook #'maybe-connect nil)
+          (eglot--with-live-buffer buffer
+            (if eglot--managed-mode
+                (eglot--message "%s is already managed by existing `%s'"
+                                buffer
+                                (eglot--project-nickname 
(eglot--current-server)))
+              (let ((server (apply #'eglot--connect (eglot--guess-contact))))
+                (eglot--message
+                 "Automatically started `%s' to manage `%s' buffers in project 
`%s'"
+                 (eglot--project-nickname server)
+                 major-mode
+                 (eglot--project-nickname server)))))))
+      (add-hook 'post-command-hook #'maybe-connect 'append nil))))
+
 (defun eglot-events-buffer (server)
   "Display events buffer for SERVER."
   (interactive (eglot--current-server-or-lose))
@@ -380,12 +408,12 @@ INTERACTIVE is t if called interactively."
 
 (defvar eglot-connect-hook nil "Hook run after connecting in 
`eglot--connect'.")
 
-(defun eglot--connect (project managed-major-mode name nickname
-                               class contact)
-  "Connect to PROJECT, MANAGED-MAJOR-MODE, NAME.
-And don't forget NICKNAME and CLASS, CONTACT.  This docstring
-appeases checkdoc, that's all."
-  (let* ((readable-name (format "EGLOT (%s/%s)" nickname managed-major-mode))
+(defun eglot--connect (managed-major-mode project class contact)
+  "Connect to MANAGED-MAJOR-MODE, PROJECT, CLASS and CONTACT.
+This docstring appeases checkdoc, that's all."
+  (let* ((nickname (file-name-base (directory-file-name
+                                    (car (project-roots project)))))
+         (readable-name (format "EGLOT (%s/%s)" nickname managed-major-mode))
          (initargs
           (cond ((keywordp (car contact)) contact)
                 ((integerp (cadr contact))
@@ -410,7 +438,7 @@ appeases checkdoc, that's all."
          (server
           (apply
            #'make-instance class
-           :name name
+           :name readable-name
            :notification-dispatcher (funcall spread 
#'eglot-handle-notification)
            :request-dispatcher (funcall spread #'eglot-handle-request)
            :on-shutdown #'eglot--on-shutdown



reply via email to

[Prev in Thread] Current Thread [Next in Thread]