@@ -553,9 +553,9 @@ If set to `:none' neither of two will be enabled."
553553The actual trace output at each level depends on the language server in use.
554554Changes take effect only when a new session is started."
555555 :type '(choice (const :tag " Disabled" " off" )
556- (const :tag " Messages only" " messages" )
557- (const :tag " Verbose" " verbose" )
558- (const :tag " Default (disabled)" nil ))
556+ (const :tag " Messages only" " messages" )
557+ (const :tag " Verbose" " verbose" )
558+ (const :tag " Default (disabled)" nil ))
559559 :group 'lsp-mode
560560 :package-version '(lsp-mode . " 6.1" ))
561561
@@ -684,6 +684,12 @@ must be used for handling a particular message.")
684684 :type 'number
685685 :group 'lsp-mode )
686686
687+ (defcustom lsp-file-watch-threshold 300
688+ " Show warning if the files to watch are more than.
689+ Set to nil to disable the warning."
690+ :type 'number
691+ :group 'lsp-mode )
692+
687693(defvar lsp-custom-markup-modes
688694 '((rust-mode " no_run" " rust,no_run" " rust,ignore" " rust,should_panic" ))
689695 " Mode to uses with markdown code blocks.
@@ -1203,7 +1209,7 @@ DELETE when `lsp-mode.el' is deleted.")
12031209 (equal 'created event-type)
12041210 (not (lsp--string-match-any lsp-file-watch-ignored file-name)))
12051211
1206- (lsp-watch-root-folder file-name callback watch)
1212+ (lsp-watch-root-folder ( file-truename file- name) callback watch)
12071213
12081214 ; ; process the files that are already present in
12091215 ; ; the directory.
@@ -1215,33 +1221,82 @@ DELETE when `lsp-mode.el' is deleted.")
12151221 (memq event-type '(created deleted changed)))
12161222 (funcall callback event)))))
12171223
1218- (defun lsp-watch-root-folder (dir callback &optional watch )
1224+ (defun lsp--directory-files-recursively (dir regexp &optional include-directories )
1225+ " Copy of `directory-files-recursively' but it skips `lsp-file-watch-ignored' ."
1226+ (let* ((result nil )
1227+ (files nil )
1228+ (dir (directory-file-name dir))
1229+ ; ; When DIR is "/", remote file names like "/method:" could
1230+ ; ; also be offered. We shall suppress them.
1231+ (tramp-mode (and tramp-mode (file-remote-p (expand-file-name dir)))))
1232+ (dolist (file (sort (file-name-all-completions " " dir)
1233+ 'string< ))
1234+ (unless (member file '(" ./" " ../" ))
1235+ (if (and (directory-name-p file)
1236+ (not (lsp--string-match-any lsp-file-watch-ignored (f-join dir (f-filename file)))))
1237+ (let* ((leaf (substring file 0 (1- (length file))))
1238+ (full-file (concat dir " /" leaf)))
1239+ ; ; Don't follow symlinks to other directories.
1240+ (unless (file-symlink-p full-file)
1241+ (setq result
1242+ (nconc result (lsp--directory-files-recursively
1243+ full-file regexp include-directories))))
1244+ (when (and include-directories
1245+ (string-match regexp leaf))
1246+ (setq result (nconc result (list full-file)))))
1247+ (when (string-match regexp file)
1248+ (push (concat dir " /" file) files )))))
1249+ (nconc result (nreverse files ))))
1250+
1251+ (defun lsp-watch-root-folder (dir callback &optional watch warn-big-repo? )
12191252 " Create recursive file notificaton watch in DIR.
12201253CALLBACK will be called when there are changes in any of
12211254the monitored files. WATCHES is a hash table directory->file
12221255notification handle which contains all of the watch that
12231256already have been created."
1224- (lsp-log " Creating watch for %s" dir)
1225- (let ((watch (or watch (make-lsp-watch :root-directory dir))))
1226- (condition-case err
1227- (progn
1228- (puthash
1229- (file-truename dir)
1230- (file-notify-add-watch
1231- dir
1232- '(change)
1233- (lambda (event ) (lsp--folder-watch-callback event callback watch)))
1234- (lsp-watch-descriptors watch))
1235- (seq-do
1236- (-rpartial #'lsp-watch-root-folder callback watch)
1237- (seq-filter (lambda (f )
1238- (and (file-directory-p f)
1239- (not (gethash (file-truename f) (lsp-watch-descriptors watch)))
1240- (not (lsp--string-match-any lsp-file-watch-ignored f))
1241- (not (-contains? '(" ." " .." ) (f-filename f)))))
1242- (directory-files dir t ))))
1243- (error (lsp-log " Failed to create a watch for %s: message" (error-message-string err)))
1244- (file-missing (lsp-log " Failed to create a watch for %s: message" (error-message-string err))))
1257+ (let* ((dir (if (f-symlink? dir)
1258+ (file-truename dir)
1259+ dir))
1260+ (watch (or watch (make-lsp-watch :root-directory dir))))
1261+ (lsp-log " Creating watch for %s" dir)
1262+ (when (or
1263+ (not warn-big-repo?)
1264+ (not lsp-file-watch-threshold)
1265+ (let ((number-of-files (length (lsp--directory-files-recursively dir " .*" t ))))
1266+ (or
1267+ (< number-of-files lsp-file-watch-threshold)
1268+ (condition-case _err
1269+ (yes-or-no-p
1270+ (format
1271+ " There are %s files in folder %s and watching the repo which may slow Emacs down. To configure:
1272+ 1. Use `lsp-enable-file-watchers' to disable file watchers globally or for the project(via .dir-local).
1273+ 2. Increase/set to nil `lsp-file-watch-threshold' to remove the warning.
1274+ Do you want to continue?"
1275+ number-of-files
1276+ dir))
1277+ ('quit )))))
1278+ (condition-case err
1279+ (progn
1280+ (puthash
1281+ dir
1282+ (file-notify-add-watch dir
1283+ '(change)
1284+ (lambda (event )
1285+ (lsp--folder-watch-callback event callback watch)))
1286+ (lsp-watch-descriptors watch))
1287+ (seq-do
1288+ (-rpartial #'lsp-watch-root-folder callback watch)
1289+ (seq-filter (lambda (f )
1290+ (and (file-directory-p f)
1291+ (not (gethash (if (f-symlink? f)
1292+ (file-truename f)
1293+ f)
1294+ (lsp-watch-descriptors watch)))
1295+ (not (lsp--string-match-any lsp-file-watch-ignored f))
1296+ (not (-contains? '(" ." " .." ) (f-filename f)))))
1297+ (directory-files dir t ))))
1298+ (error (lsp-log " Failed to create a watch for %s: message" (error-message-string err)))
1299+ (file-missing (lsp-log " Failed to create a watch for %s: message" (error-message-string err)))))
12451300 watch))
12461301
12471302(defun lsp-kill-watch (watch )
@@ -2447,27 +2502,33 @@ disappearing, unset all the variables related to it."
24472502(defun lsp--file-process-event (session root-folder event )
24482503 " Process file event."
24492504 (let ((changed-file (cl-caddr event)))
2450- (->> session
2451- lsp-session-folder->servers
2452- (gethash root-folder)
2453- (seq-do (lambda (workspace )
2454- (when (->> workspace
2455- lsp--workspace-registered-server-capabilities
2456- (-any? (lambda (capability )
2457- (and (string= (lsp--registered-capability-method capability)
2458- " workspace/didChangeWatchedFiles" )
2459- (->> capability
2460- lsp--registered-capability-options
2461- (gethash " watchers" )
2462- (seq-find (-lambda ((&hash " globPattern" glob-pattern))
2463- (-let [glob-regex (eshell-glob-regexp glob-pattern)]
2464- (or (string-match glob-regex changed-file)
2465- (string-match glob-regex (f-relative changed-file root-folder)))))))))))
2466- (with-lsp-workspace workspace
2467- (lsp-notify
2468- " workspace/didChangeWatchedFiles"
2469- `((changes . [((type . ,(alist-get (cadr event) lsp--file-change-type))
2470- (uri . ,(lsp--path-to-uri changed-file)))]))))))))))
2505+ (->>
2506+ session
2507+ lsp-session-folder->servers
2508+ (gethash root-folder)
2509+ (seq-do (lambda (workspace )
2510+ (when (->>
2511+ workspace
2512+ lsp--workspace-registered-server-capabilities
2513+ (-any?
2514+ (lambda (capability )
2515+ (and
2516+ (string= (lsp--registered-capability-method capability)
2517+ " workspace/didChangeWatchedFiles" )
2518+ (->>
2519+ capability
2520+ lsp--registered-capability-options
2521+ (gethash " watchers" )
2522+ (seq-find
2523+ (-lambda ((&hash " globPattern" glob-pattern))
2524+ (-let [glob-regex (eshell-glob-regexp glob-pattern)]
2525+ (or (string-match glob-regex changed-file)
2526+ (string-match glob-regex (f-relative changed-file root-folder)))))))))))
2527+ (with-lsp-workspace workspace
2528+ (lsp-notify
2529+ " workspace/didChangeWatchedFiles"
2530+ `((changes . [((type . ,(alist-get (cadr event) lsp--file-change-type))
2531+ (uri . ,(lsp--path-to-uri changed-file)))]))))))))))
24712532
24722533(defun lsp--server-register-capability (reg )
24732534 " Register capability REG."
@@ -2476,14 +2537,17 @@ disappearing, unset all the variables related to it."
24762537 (when (and lsp-enable-file-watchers
24772538 (string= method " workspace/didChangeWatchedFiles" ))
24782539 (-let* ((created-watches (lsp-session-watches session))
2479- (root-folders (cl-set-difference (lsp-find-roots-for-workspace lsp--cur-workspace session)
2480- (ht-keys created-watches))))
2540+ (root-folders (cl-set-difference
2541+ (lsp-find-roots-for-workspace lsp--cur-workspace session)
2542+ (ht-keys created-watches))))
24812543 ; ; create watch for each root folder withtout such
24822544 (dolist (folder root-folders)
2483- (puthash folder (lsp-watch-root-folder
2484- folder
2485- (-partial #'lsp--file-process-event session folder))
2486- created-watches))))
2545+ (let ((watch (make-lsp-watch :root-directory folder)))
2546+ (puthash folder watch created-watches)
2547+ (lsp-watch-root-folder (file-truename folder)
2548+ (-partial #'lsp--file-process-event session folder)
2549+ watch
2550+ t )))))
24872551
24882552 (push
24892553 (make-lsp--registered-capability :id id :method method :options registerOptions)
@@ -4036,7 +4100,7 @@ unless overriden by a more specific face association."
40364100 :group 'lsp-faces )
40374101
40384102(defvar lsp-semantic-highlighting-faces
4039- '((" ^variable\\ .parameter\\ (\\ ..*\\ )?$" . lsp-face-semhl-variable-parameter)
4103+ '((" ^variable\\ .parameter\\ (\\ ..*\\ )?$" . lsp-face-semhl-variable-parameter)
40404104 (" ^variable\\ .other\\ .local\\ (\\ ..*\\ )?$" . lsp-face-semhl-variable-local)
40414105 (" ^variable\\ .other\\ .field\\ .static\\ (\\ ..*\\ )?$" . lsp-face-semhl-field-static)
40424106 (" ^variable\\ .other\\ .field\\ (\\ ..*\\ )?$" . lsp-face-semhl-field)
@@ -4070,10 +4134,10 @@ unless overriden by a more specific face association."
40704134 (when (s-matches-p (car regexp-and-face) scope-name)
40714135 (cdr regexp-and-face)))
40724136 lsp-semantic-highlighting-faces))
4073- scope-names)))
4137+ scope-names)))
40744138 (unless maybe-face
40754139 (lsp--warn " Unknown scopes [%s], please amend lsp-semantic-highlighting-faces"
4076- (s-join " , " scope-names)))
4140+ (s-join " , " scope-names)))
40774141 maybe-face))
40784142
40794143(defvar-local lsp--facemap nil )
@@ -5188,8 +5252,8 @@ SESSION is the active session."
51885252 :rootUri (lsp--path-to-uri root)
51895253 :capabilities (lsp--client-capabilities)
51905254 :initializationOptions initialization-options)
5191- (when lsp-server-trace
5192- (list :trace lsp-server-trace))
5255+ (when lsp-server-trace
5256+ (list :trace lsp-server-trace))
51935257 (when (lsp--client-multi-root client)
51945258 (->> workspace-folders
51955259 (-map (lambda (folder )
0 commit comments