branch: elpa/helm commit ddf8eb3450a413a04be55f4b0389da53e6ea7a08 Author: Thierry Volpiatto <thie...@posteo.net> Commit: Thierry Volpiatto <thie...@posteo.net>
Make helm-async process-filter much faster Store incomplete-line directly in process instead of storing it in the source. --- helm-core.el | 62 ++++++++++++++++++++---------------------------------------- 1 file changed, 20 insertions(+), 42 deletions(-) diff --git a/helm-core.el b/helm-core.el index fc248343d2..fa1871f5c4 100644 --- a/helm-core.el +++ b/helm-core.el @@ -1300,8 +1300,7 @@ Allow specifying the height of this line." (defvar helm-async-processes nil "List of informations about asynchronous processes managed by Helm. Each element of the list is of form: -(<process> . (append source ((incomplete-line . \"\") (item-count . 0)))). -Where incomplete-line and item-count are elements used by the process filter.") +(<process> . (append source ((item-count . 0)))).") (defvar helm-before-initialize-hook nil "Runs before Helm initialization. @@ -4397,8 +4396,7 @@ Cache the candidates if there is no cached value yet." (cond ((processp candidates) (push (cons candidates (append source - (list (cons 'item-count 0) - (cons 'incomplete-line "")))) + (list (cons 'item-count 0)))) helm-async-processes) (set-process-filter candidates 'helm-output-filter) (setq candidates nil)) @@ -5535,10 +5533,11 @@ This will work only in Emacs-26+, i.e. Emacs versions that have (with-local-quit (helm-output-filter-1 (assoc process helm-async-processes) output-string))) -(defun helm-output-filter-1 (process-assoc output-string) - (helm-log "helm-output-filter-1" "output-string = %S" output-string) +(defun helm-output-filter-1 (process-assoc output) + (helm-log "helm-output-filter-1" "output-string = %S" output) (with-current-buffer helm-buffer - (let ((source (cdr process-assoc))) + (let ((source (cdr process-assoc)) + (proc (car process-assoc))) (save-excursion (helm-aif (assoc-default 'insertion-marker source) (goto-char it) @@ -5546,17 +5545,23 @@ This will work only in Emacs-26+, i.e. Emacs versions that have (helm-insert-header-from-source source) (setcdr process-assoc (append source `((insertion-marker . ,(point-marker)))))) - (helm-output-filter--process-source - (car process-assoc) output-string source - (helm-candidate-number-limit source)))) + ;; This method for handling incomplete lines should fix as well Bug#1187. + (setq output (concat (process-get proc 'incomplete-line) output)) + (let ((end (string-match ".*\\'" output))) + (process-put proc 'incomplete-line (substring output end)) + ;; output should now have only wholelines. + (setq output (substring output 0 end)) + ;; Now run the transformers (if some) on candidates and insert them in + ;; helm-buffer. + (helm-output-filter--process-source + (car process-assoc) output source + (helm-candidate-number-limit source))))) (helm-output-filter--post-process))) -(defun helm-output-filter--process-source (process output-string source limit) +(defun helm-output-filter--process-source (process output source limit) (cl-dolist (candidate (helm-transform-candidates - (helm-output-filter--collect-candidates - (split-string output-string - helm-process-output-split-string-separator) - (assq 'incomplete-line source)) + (split-string output + helm-process-output-split-string-separator t) source t)) (setq candidate (helm--maybe-process-filter-one-by-one-candidate candidate source)) @@ -5577,33 +5582,6 @@ This will work only in Emacs-26+, i.e. Emacs versions that have 'helm-async-outer-limit-hook) (cl-return)))) -(defun helm-output-filter--collect-candidates (lines incomplete-line-info) - "Collect LINES maybe completing the truncated first and last lines." - ;; The output of process may come in chunks of any size, so the last - ;; line of LINES could be truncated, this truncated line is stored - ;; in INCOMPLETE-LINE-INFO to be concatenated with the first - ;; incomplete line of the next arriving chunk. INCOMPLETE-LINE-INFO - ;; is an attribute of source; it is created with an empty string - ;; when the source is computed => (incomplete-line . "") - (helm-log "helm-output-filter--collect-candidates" - "incomplete-line-info = %S" (cdr incomplete-line-info)) - (butlast - (cl-loop for line in lines - ;; On start `incomplete-line-info' value is empty string. - for newline = (helm-aif (cdr incomplete-line-info) - (prog1 - (concat it line) - (setcdr incomplete-line-info nil)) - line) - collect newline - ;; Store last incomplete line (last chunk truncated) until - ;; new output arrives. Previously storing 'line' in - ;; incomplete-line-info assumed output was truncated in - ;; only two chunks. But output could be large and - ;; truncated in more than two chunks. Therefore store - ;; 'newline' to contain the previous chunks (Bug#1187). - finally do (setcdr incomplete-line-info newline)))) - (defun helm-output-filter--post-process () (helm-aif (get-buffer-window helm-buffer 'visible) (with-selected-window it