]> git.eshelyaron.com Git - emacs.git/commitdiff
Simplify dir-watching strategy of w/didchangewatchedfiles
authorJoão Távora <joaotavora@gmail.com>
Wed, 3 Feb 2021 10:41:40 +0000 (10:41 +0000)
committerJoão Távora <joaotavora@gmail.com>
Wed, 3 Feb 2021 10:41:40 +0000 (10:41 +0000)
Instead of massaging the globPattern to match directories instead of
files, which is fragile, gather the list of directoris to watch by
matching the globPattern against every file recursively (except hidden
files and dirs).

This is still not 100% correct, but should do the right thing is most
cases.  Notably, if the correct dirs are being watched, the glob
pattern is matched against all existing and new files in those
directories, which does include hidden files.

* eglot.el (eglot-register-capability): match file globs against
files only.
(eglot--files-recursively): Rename from eglot--directories-recursively.

GitHub-reference: per https://github.com/joaotavora/eglot/issues/602

lisp/progmodes/eglot.el

index 90d973c6b63be0901723d56461a07d80ab6235b9..80780f57f9aceb116bded5b4442eab83e1ff8136 100644 (file)
@@ -2612,25 +2612,20 @@ at point.  With prefix argument, prompt for ACTION-KIND."
   (let* (success
          (globs (mapcar
                  (eglot--lambda ((FileSystemWatcher) globPattern)
-                   (cons
-                    (eglot--glob-compile globPattern t t)
-                    (eglot--glob-compile
-                     (replace-regexp-in-string "/[^/]*$" "/" globPattern) t t)))
+                   (eglot--glob-compile globPattern t t))
                  watchers))
          (dirs-to-watch
-          (cl-loop for dir in (eglot--directories-recursively)
-                   when (cl-loop for g in globs
-                                 thereis (ignore-errors (funcall (cdr g) dir)))
-                   collect dir)))
+          (cl-loop for f in (eglot--files-recursively)
+                   when (cl-loop for g in globs thereis (funcall g f))
+                   collect (file-name-directory f) into dirs
+                   finally (cl-return (delete-dups dirs)))))
     (cl-labels
         ((handle-event
           (event)
           (pcase-let ((`(,desc ,action ,file ,file1) event))
             (cond
              ((and (memq action '(created changed deleted))
-                   (cl-find file (mapcar #'car globs)
-                            :test (lambda (f glob)
-                                    (funcall glob f))))
+                   (cl-find file globs :test (lambda (f g) (funcall g f))))
               (jsonrpc-notify
                server :workspace/didChangeWatchedFiles
                `(:changes ,(vector `(:uri ,(eglot--path-to-uri file)
@@ -2724,14 +2719,14 @@ If NOERROR, return predicate, else erroring function."
   (when (eq ?! (aref arg 1)) (aset arg 1 ?^))
   `(,self () (re-search-forward ,(concat "\\=" arg)) (,next)))
 
-(defun eglot--directories-recursively (&optional dir)
+(defun eglot--files-recursively (&optional dir)
   "Because `directory-files-recursively' isn't complete in 26.3."
   (cons (setq dir (expand-file-name (or dir default-directory)))
-        (cl-loop
-         with default-directory = dir
-         with completion-regexp-list = '("^[^.]")
-         for f in (file-name-all-completions "" dir)
-         when (file-directory-p f) append (eglot--directories-recursively f))))
+        (cl-loop with default-directory = dir
+                 with completion-regexp-list = '("^[^.]")
+                 for f in (file-name-all-completions "" dir)
+                 if (file-name-directory f) append (eglot--files-recursively f)
+                 else collect (expand-file-name f))))
 
 \f
 ;;; Rust-specific