emacs-lsp / lsp-mode

Emacs client/library for the Language Server Protocol
https://emacs-lsp.github.io/lsp-mode
GNU General Public License v3.0
4.79k stars 888 forks source link

`lsp--all-watchable-directories` unable to handle symlink loops #3011

Open sata opened 3 years ago

sata commented 3 years ago

Thank you for the bug report

Bug description

Given a directory structure of:

── testdata
    ├── symlinks
    │   ├── dir-symlink -> ../../testdata
    │   ├── file-symlink -> ../test.file
    │   ├── invalid-symlink -> /non/existing/file
    │   └── windows-file-symlink -> C:/Users/ibrahim/go/src/github.com/golang/dep/internal/fs/testdata/test.file
    └── test.file

lsp--all-watchable-directories will fail with recursive (error "Lisp nesting exceeds ‘max-lisp-eval-depth’") as the function recursively will chase the dir-symlink without checking depth or if it's a cyclic symlink.

Backtrace:

Debugger entered--Lisp error: (error "Lisp nesting exceeds ‘max-lisp-eval-depth’")
  (prog1 list (setq list (cdr list)))
  (car-safe (prog1 list (setq list (cdr list))))
  (setq elt (car-safe (prog1 list (setq list (cdr list)))) it elt it-index i)
  (and list (setq elt (car-safe (prog1 list (setq list (cdr list)))) it elt it-index i) (or (not (string-match it str)) (ignore (setq needle it))))
  (while (and list (setq elt (car-safe (prog1 list (setq list (cdr list)))) it elt it-index i) (or (not (string-match it str)) (ignore (setq needle it)))) (setq it elt it-index i i (1+ i)))
  (let ((list regex-list) (i 0) elt it it-index) (ignore it it-index) (while (and list (setq elt (car-safe (prog1 list (setq list (cdr list)))) it elt it-index i) (or (not (string-match it str)) (ignore (setq needle it)))) (setq it elt it-index i i (1+ i))))
  (let (needle) (let ((list regex-list) (i 0) elt it it-index) (ignore it it-index) (while (and list (setq elt (car-safe (prog1 list (setq list ...))) it elt it-index i) (or (not (string-match it str)) (ignore (setq needle it)))) (setq it elt it-index i i (1+ i)))) needle)
  lsp--string-match-any(("[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") "/home/s/sources/source-controller/internal/fs/test...")
  (not (lsp--string-match-any ignored-directories full-path))
  (and (f-dir-p full-path) (not (equal path ".")) (not (equal path "..")) (not (lsp--string-match-any ignored-directories full-path)))
  (let ((full-path (f-join dir path))) (and (f-dir-p full-path) (not (equal path ".")) (not (equal path "..")) (not (lsp--string-match-any ignored-directories full-path))))
  lsp--path-is-watchable-directory("symlinks" "/home/s/sources/source-controller/internal/fs/test..." ("[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'"))
  (closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--path-is-watchable-directory path dir ignored-directories))("symlinks")
  funcall((closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--path-is-watchable-directory path dir ignored-directories)) "symlinks")
  (if (funcall pred it) (progn (setq result (cons it result))))
  (while list (setq it (car-safe (prog1 list (setq list (cdr list)))) it-index i i (1+ i)) (if (funcall pred it) (progn (setq result (cons it result)))))
  (let ((list list) (i 0) it it-index) (ignore it it-index) (while list (setq it (car-safe (prog1 list (setq list (cdr list)))) it-index i i (1+ i)) (if (funcall pred it) (progn (setq result (cons it result))))))
  (let (result) (let ((list list) (i 0) it it-index) (ignore it it-index) (while list (setq it (car-safe (prog1 list (setq list (cdr list)))) it-index i i (1+ i)) (if (funcall pred it) (progn (setq result (cons it result)))))) (nreverse result))
  -filter((closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--path-is-watchable-directory path dir ignored-directories)) ("." ".." "symlinks" "test.file"))
  (-map #'(lambda (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) (-filter #'(lambda (path) (lsp--path-is-watchable-directory path dir ignored-directories)) (directory-files dir)))
  (apply #'nconc (list dir) (-map #'(lambda (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) (-filter #'(lambda (path) (lsp--path-is-watchable-directory path dir ignored-directories)) (directory-files dir))))
  (let* ((dir (if (f-symlink\? dir) (file-truename dir) dir))) (apply #'nconc (list dir) (-map #'(lambda (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) (-filter #'(lambda (path) (lsp--path-is-watchable-directory path dir ignored-directories)) (directory-files dir)))))
  lsp--all-watchable-directories("/home/s/sources/source-controller/internal/fs/test..." ("[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'"))
  (closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories))("dir-symlink")
  mapcar((closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) ("dir-symlink"))
  -map((closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) ("dir-symlink"))
  (apply #'nconc (list dir) (-map #'(lambda (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) (-filter #'(lambda (path) (lsp--path-is-watchable-directory path dir ignored-directories)) (directory-files dir))))
  (let* ((dir (if (f-symlink\? dir) (file-truename dir) dir))) (apply #'nconc (list dir) (-map #'(lambda (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) (-filter #'(lambda (path) (lsp--path-is-watchable-directory path dir ignored-directories)) (directory-files dir)))))
  lsp--all-watchable-directories("/home/s/sources/source-controller/internal/fs/test..." ("[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'"))
  (closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories))("symlinks")
  mapcar((closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) ("symlinks"))
  -map((closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) ("symlinks"))
  (apply #'nconc (list dir) (-map #'(lambda (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) (-filter #'(lambda (path) (lsp--path-is-watchable-directory path dir ignored-directories)) (directory-files dir))))
  (let* ((dir (if (f-symlink\? dir) (file-truename dir) dir))) (apply #'nconc (list dir) (-map #'(lambda (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) (-filter #'(lambda (path) (lsp--path-is-watchable-directory path dir ignored-directories)) (directory-files dir)))))
  lsp--all-watchable-directories("/home/s/sources/source-controller/internal/fs/test..." ("[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'"))
  (closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories))("dir-symlink")
  mapcar((closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) ("dir-symlink"))
  -map((closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) ("dir-symlink"))
  (apply #'nconc (list dir) (-map #'(lambda (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) (-filter #'(lambda (path) (lsp--path-is-watchable-directory path dir ignored-directories)) (directory-files dir))))
  (let* ((dir (if (f-symlink\? dir) (file-truename dir) dir))) (apply #'nconc (list dir) (-map #'(lambda (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) (-filter #'(lambda (path) (lsp--path-is-watchable-directory path dir ignored-directories)) (directory-files dir)))))
  lsp--all-watchable-directories("/home/s/sources/source-controller/internal/fs/test..." ("[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'"))
  (closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories))("symlinks")
  mapcar((closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) ("symlinks"))
  -map((closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) ("symlinks"))
  (apply #'nconc (list dir) (-map #'(lambda (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) (-filter #'(lambda (path) (lsp--path-is-watchable-directory path dir ignored-directories)) (directory-files dir))))
  (let* ((dir (if (f-symlink\? dir) (file-truename dir) dir))) (apply #'nconc (list dir) (-map #'(lambda (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) (-filter #'(lambda (path) (lsp--path-is-watchable-directory path dir ignored-directories)) (directory-files dir)))))
  lsp--all-watchable-directories("/home/s/sources/source-controller/internal/fs/test..." ("[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'"))
  (closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories))("dir-symlink")
  mapcar((closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) ("dir-symlink"))
  -map((closure ((dir . "/home/s/sources/source-controller/internal/fs/test...") (ignored-directories "[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'") (dir . "/home/s/sources/source-controller/internal/fs/test...") cl-struct-lsp-watch-tags cl-struct-lsp--client-tags lsp--log-lines company-minimum-prefix-length dap-ui-menu-items dap-auto-configure-mode yas-also-auto-indent-first-line yas-wrap-around-region yas-indent-line yas-inhibit-overlay-modification-protection t) (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) ("dir-symlink"))
  (apply #'nconc (list dir) (-map #'(lambda (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) (-filter #'(lambda (path) (lsp--path-is-watchable-directory path dir ignored-directories)) (directory-files dir))))
  (let* ((dir (if (f-symlink\? dir) (file-truename dir) dir))) (apply #'nconc (list dir) (-map #'(lambda (path) (lsp--all-watchable-directories (f-join dir path) ignored-directories)) (-filter #'(lambda (path) (lsp--path-is-watchable-directory path dir ignored-directories)) (directory-files dir)))))
  lsp--all-watchable-directories("/home/s/sources/source-controller/internal/fs/test..." ("[/\\\\]\\.git\\'" "[/\\\\]\\.github\\'" "[/\\\\]\\.circleci\\'" "[/\\\\]\\.hg\\'" "[/\\\\]\\.bzr\\'" "[/\\\\]_darcs\\'" "[/\\\\]\\.svn\\'" "[/\\\\]_FOSSIL_\\'" "[/\\\\]\\.idea\\'" "[/\\\\]\\.ensime_cache\\'" "[/\\\\]\\.eunit\\'" "[/\\\\]node_modules" "[/\\\\]\\.yarn\\'" "[/\\\\]\\.fslckout\\'" "[/\\\\]\\.tox\\'" "[/\\\\]dist\\'" "[/\\\\]dist-newstyle\\'" "[/\\\\]\\.stack-work\\'" "[/\\\\]\\.bloop\\'" "[/\\\\]\\.metals\\'" "[/\\\\]target\\'" "[/\\\\]\\.ccls-cache\\'" "[/\\\\]\\.vscode\\'" "[/\\\\]\\.deps\\'" "[/\\\\]build-aux\\'" "[/\\\\]autom4te.cache\\'" "[/\\\\]\\.reference\\'" "[/\\\\]\\.lsp\\'" "[/\\\\]\\.clj-kondo\\'" "[/\\\\]\\.shadow-cljs\\'" "[/\\\\]\\.babel_cache\\'" "[/\\\\]\\.cpcache\\'" "[/\\\\]bin/Debug\\'" "[/\\\\]obj\\'" "[/\\\\]_opam\\'" "[/\\\\]_build\\'" "[/\\\\]\\.direnv\\'"))

Steps to reproduce

  1. Clone repository github.com/fluxcd/source-controller
  2. Download lsp-start-plan.el
  3. Add go-mode to the list of modes
  4. Open cloned repository
  5. Open controllers/bucket_controllers.go

Expected behavior

Expect symloops to be detected and ignored and be able to interact with gopls.

Which Language Server did you use?

gopls

OS

Linux

Error callstack

The crash happens before, but post that point, I only receive timed out requests when trying to lookup any method definition.

[Trace - 09:38:26 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 467
}

[Trace - 09:38:26 pm] Sending request 'textDocument/codeAction - (469)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "range": {
    "start": {
      "line": 74,
      "character": 24
    },
    "end": {
      "line": 74,
      "character": 24
    }
  },
  "context": {
    "diagnostics": []
  }
}

[Trace - 09:38:26 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 468
}

[Trace - 09:38:26 pm] Sending request 'textDocument/hover - (470)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "position": {
    "line": 74,
    "character": 24
  }
}

[Trace - 09:38:27 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 460
}

[Trace - 09:38:27 pm] Sending request 'textDocument/hover - (471)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "position": {
    "line": 74,
    "character": 24
  }
}

[Trace - 09:38:27 pm] Sending request 'textDocument/documentSymbol - (472)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  }
}

[Trace - 09:38:27 pm] Sending request 'textDocument/codeAction - (473)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "range": {
    "start": {
      "line": 74,
      "character": 24
    },
    "end": {
      "line": 74,
      "character": 24
    }
  },
  "context": {
    "diagnostics": []
  }
}

[Trace - 09:38:27 pm] Sending request 'textDocument/documentLink - (474)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  }
}

[Trace - 09:38:27 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 466
}

[Trace - 09:38:27 pm] Sending request 'textDocument/documentHighlight - (475)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "position": {
    "line": 74,
    "character": 24
  }
}

[Trace - 09:38:28 pm] Sending request 'textDocument/definition - (476)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "position": {
    "line": 74,
    "character": 24
  }
}

[Trace - 09:38:38 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 476
}

[Trace - 09:38:38 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 469
}

[Trace - 09:38:38 pm] Sending request 'textDocument/codeAction - (477)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "range": {
    "start": {
      "line": 74,
      "character": 24
    },
    "end": {
      "line": 74,
      "character": 24
    }
  },
  "context": {
    "diagnostics": []
  }
}

[Trace - 09:38:38 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 470
}

[Trace - 09:38:38 pm] Sending request 'textDocument/hover - (478)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "position": {
    "line": 74,
    "character": 24
  }
}

[Trace - 09:38:38 pm] Sending request 'textDocument/documentSymbol - (479)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  }
}

[Trace - 09:38:38 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 473
}

[Trace - 09:38:38 pm] Sending request 'textDocument/codeAction - (480)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "range": {
    "start": {
      "line": 74,
      "character": 24
    },
    "end": {
      "line": 74,
      "character": 24
    }
  },
  "context": {
    "diagnostics": []
  }
}

[Trace - 09:38:38 pm] Sending request 'textDocument/documentLink - (481)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  }
}

[Trace - 09:38:38 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 475
}

[Trace - 09:38:38 pm] Sending request 'textDocument/documentHighlight - (482)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "position": {
    "line": 74,
    "character": 24
  }
}

[Trace - 09:38:40 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 477
}

[Trace - 09:38:40 pm] Sending request 'textDocument/codeAction - (483)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "range": {
    "start": {
      "line": 74,
      "character": 24
    },
    "end": {
      "line": 74,
      "character": 24
    }
  },
  "context": {
    "diagnostics": []
  }
}

[Trace - 09:38:41 pm] Sending request 'textDocument/documentSymbol - (484)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  }
}

[Trace - 09:38:41 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 480
}

[Trace - 09:38:41 pm] Sending request 'textDocument/codeAction - (485)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "range": {
    "start": {
      "line": 74,
      "character": 24
    },
    "end": {
      "line": 74,
      "character": 24
    }
  },
  "context": {
    "diagnostics": []
  }
}

[Trace - 09:38:41 pm] Sending request 'textDocument/documentLink - (486)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  }
}

[Trace - 09:38:41 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 482
}

[Trace - 09:38:41 pm] Sending request 'textDocument/documentHighlight - (487)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "position": {
    "line": 74,
    "character": 24
  }
}

[Trace - 09:39:36 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 483
}

[Trace - 09:39:36 pm] Sending request 'textDocument/codeAction - (488)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "range": {
    "start": {
      "line": 74,
      "character": 24
    },
    "end": {
      "line": 74,
      "character": 24
    }
  },
  "context": {
    "diagnostics": []
  }
}

[Trace - 09:39:37 pm] Sending request 'textDocument/documentSymbol - (489)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  }
}

[Trace - 09:39:37 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 485
}

[Trace - 09:39:37 pm] Sending request 'textDocument/codeAction - (490)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "range": {
    "start": {
      "line": 74,
      "character": 24
    },
    "end": {
      "line": 74,
      "character": 24
    }
  },
  "context": {
    "diagnostics": []
  }
}

[Trace - 09:39:37 pm] Sending request 'textDocument/documentLink - (491)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  }
}

[Trace - 09:39:37 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 487
}

[Trace - 09:39:37 pm] Sending request 'textDocument/documentHighlight - (492)'.
Params: {
  "textDocument": {
    "uri": "file:///home/s/sources/source-controller/controllers/bucket_controller.go"
  },
  "position": {
    "line": 74,
    "character": 24
  }
}

[Trace - 09:39:40 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 491
}

[Trace - 09:39:40 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 490
}

[Trace - 09:39:40 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 486
}

[Trace - 09:39:40 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 481
}

[Trace - 09:39:40 pm] Sending notification '$/cancelRequest'.
Params: {
  "id": 474
}


### Anything else?

My `elisp` skills are crap, trying to figure out how `directory-files-recursively` is able to detect symloops, but it seems it simply stops after certain depth. Same approach could work here? 
sata commented 3 years ago

(defun lsp--all-watchable-directories (dir ignored-directories visited)
  "Traverse DIR recursively and return a list of paths that should have watchers set on them.
IGNORED-DIRECTORIES will be used for exclusions. Visited keeps
track of visited paths to avoid infinite recursion when encountering symlink loops"
  (let* ((dir (if (f-symlink? dir)
                  (file-truename dir)
                dir)))
    (puthash dir t visited)
    (apply #'nconc
           ;; the directory itself is assumed to be part of the set
           (list dir)
           ;; collect all subdirectories that are watchable
           (-map
            (lambda (path)
              (let ((subpath (f-join dir path)))
                (if (not (gethash subpath visited nil))
                    (lsp--all-watchable-directories subpath ignored-directories visited))))
            ;; but only look at subdirectories that are watchable
            (-filter (lambda (path) (lsp--path-is-watchable-directory path dir ignored-directories))
                     (directory-files dir))))))

This patch seems to make it work. Basically tracking if one has visited the path or not when recursing down into sub directories.

I can make a PR if it makes sense to you as well?

Also have to update the invocation in lsp-watch-root-folder with additional argument (make-hash-table)

quolpr commented 2 years ago

Hmm, having same issue. Hope this PR will be merged soon

mangas commented 2 months ago

I think I have the same issue as well. Any chance we could get this into a release version?

I pushed a minimal reproducible setup here