update packages
This commit is contained in:
@@ -16,7 +16,8 @@
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;; Code for dealing with asynchronous processes.
|
||||
|
||||
;; Code for dealing with treemacs' asynchronous features.
|
||||
|
||||
;;; Code:
|
||||
|
||||
@@ -30,25 +31,34 @@
|
||||
(require 'treemacs-workspaces)
|
||||
(require 'treemacs-dom)
|
||||
(require 'treemacs-logging)
|
||||
(require 'treemacs-visuals)
|
||||
|
||||
(eval-when-compile
|
||||
(require 'inline)
|
||||
(require 'treemacs-macros))
|
||||
|
||||
(treemacs-import-functions-from treemacs-rendering
|
||||
treemacs-do-delete-single-node)
|
||||
|
||||
(defconst treemacs--dirs-to-collapse.py
|
||||
(if (member "treemacs-dirs-to-collapse.py" (directory-files treemacs-dir))
|
||||
(f-join treemacs-dir "treemacs-dirs-to-collapse.py")
|
||||
(f-join treemacs-dir "src/scripts/treemacs-dirs-to-collapse.py")))
|
||||
(treemacs-join-path treemacs-dir "treemacs-dirs-to-collapse.py")
|
||||
(treemacs-join-path treemacs-dir "src/scripts/treemacs-dirs-to-collapse.py")))
|
||||
|
||||
(defconst treemacs--git-status.py
|
||||
(if (member "treemacs-git-status.py" (directory-files treemacs-dir))
|
||||
(f-join treemacs-dir "treemacs-git-status.py")
|
||||
(f-join treemacs-dir "src/scripts/treemacs-git-status.py")))
|
||||
(treemacs-join-path treemacs-dir "treemacs-git-status.py")
|
||||
(treemacs-join-path treemacs-dir "src/scripts/treemacs-git-status.py")))
|
||||
|
||||
(defconst treemacs--single-file-git-status.py
|
||||
(if (member "treemacs-single-file-git-status.py" (directory-files treemacs-dir))
|
||||
(f-join treemacs-dir "treemacs-single-file-git-status.py")
|
||||
(f-join treemacs-dir "src/scripts/treemacs-single-file-git-status.py")))
|
||||
(treemacs-join-path treemacs-dir "treemacs-single-file-git-status.py")
|
||||
(treemacs-join-path treemacs-dir "src/scripts/treemacs-single-file-git-status.py")))
|
||||
|
||||
(defconst treemacs--find-ignored-files.py
|
||||
(if (member "treemacs-find-ignored-files.py" (directory-files treemacs-dir))
|
||||
(treemacs-join-path treemacs-dir "treemacs-find-ignored-files.py")
|
||||
(treemacs-join-path treemacs-dir "src/scripts/treemacs-find-ignored-files.py")))
|
||||
|
||||
(defvar treemacs--git-cache-max-size 60
|
||||
"Maximum size for `treemacs--git-cache'.
|
||||
@@ -83,12 +93,16 @@ DEFAULT: Face"
|
||||
("R" 'treemacs-git-renamed-face)
|
||||
(_ ,default)))))
|
||||
|
||||
(defvar treemacs--git-mode nil
|
||||
"Saves the specific version of git-mode that is active.
|
||||
Values are either `simple', `extended', `deferred' or nil.")
|
||||
|
||||
(define-inline treemacs--get-node-face (path git-info default)
|
||||
"Return the appropriate face for PATH based on GIT-INFO.
|
||||
If there is no git entry for PATH return DEFAULT.
|
||||
|
||||
PATH: Filepath
|
||||
GIT-INFO: Hashtable
|
||||
GIT-INFO: Hash-Table
|
||||
DEFAULT: Face"
|
||||
(declare (pure t) (side-effect-free t))
|
||||
(inline-letevals (path git-info default)
|
||||
@@ -180,7 +194,7 @@ GIT-FUTURE: Pfuture"
|
||||
|
||||
(defun treemacs--git-status-process-simple (path)
|
||||
"Start a simple git status process for files under PATH."
|
||||
(let* ((default-directory (f-canonical path))
|
||||
(let* ((default-directory (file-truename path))
|
||||
(process-environment (cons "GIT_OPTIONAL_LOCKS=0" process-environment))
|
||||
(future (pfuture-new "git" "status" "--porcelain" "--ignored" "-z" ".")))
|
||||
(process-put future 'default-directory default-directory)
|
||||
@@ -215,7 +229,7 @@ GIT-FUTURE: Pfuture"
|
||||
(if (eq ?R (aref status 0))
|
||||
(setq i (1+ i))
|
||||
(ht-set! git-info-hash
|
||||
(f-join git-root (s-trim-left path))
|
||||
(treemacs-join-path git-root (s-trim-left path))
|
||||
(substring (s-trim-left status) 0 1)))))
|
||||
(setq i (1+ i)))))))))
|
||||
git-info-hash))
|
||||
@@ -370,36 +384,77 @@ newline."
|
||||
(when (= 0 (process-exit-status future))
|
||||
(read output)))))
|
||||
|
||||
(defun treemacs--prefetch-gitignore-cache (path)
|
||||
"Pre-load all the git-ignored files in the given PATH.
|
||||
|
||||
PATH is either the symbol `all', in which case the state of all projects in the
|
||||
current workspace is gathered instead, or a single project's path, when that
|
||||
project has just been added to the workspace.
|
||||
|
||||
Required for `treemacs-hide-gitignored-files-mode' to properly work with
|
||||
deferred git-mode, as otherwise ignored files will not be hidden on the first
|
||||
run because the git cache has yet to be filled."
|
||||
(if (eq path 'all)
|
||||
(setf path (-map #'treemacs-project->path
|
||||
(treemacs-workspace->projects (treemacs-current-workspace))))
|
||||
(setf path (list path)))
|
||||
(pfuture-callback `(,treemacs-python-executable
|
||||
"-O"
|
||||
,treemacs--find-ignored-files.py
|
||||
,@path)
|
||||
:on-error (ignore)
|
||||
:on-success
|
||||
(let ((ignore-pairs (read (pfuture-callback-output)))
|
||||
(ignored-files nil))
|
||||
(while ignore-pairs
|
||||
(let* ((root (pop ignore-pairs))
|
||||
(file (pop ignore-pairs))
|
||||
(cache (ht-get treemacs--git-cache root)))
|
||||
(unless cache
|
||||
(setf cache (make-hash-table :size 20 :test 'equal))
|
||||
(ht-set! treemacs--git-cache root cache))
|
||||
(ht-set! cache file "!")
|
||||
(push file ignored-files)))
|
||||
(treemacs-run-in-every-buffer
|
||||
(treemacs-save-position
|
||||
(dolist (file ignored-files)
|
||||
(when-let (treemacs-is-path-visible? file)
|
||||
(treemacs-do-delete-single-node file))))))))
|
||||
|
||||
(define-minor-mode treemacs-git-mode
|
||||
"Toggle `treemacs-git-mode'.
|
||||
|
||||
When enabled treemacs will check files' git status and highlight them
|
||||
accordingly. This git integration is available in 3 variants: simple, extended
|
||||
accordingly. This git integration is available in 3 variants: simple, extended
|
||||
and deferred.
|
||||
|
||||
The simple variant will start a git status process whose output is parsed in
|
||||
elisp. This version is simpler and slightly faster, but incomplete - it will
|
||||
elisp. This version is simpler and slightly faster, but incomplete - it will
|
||||
highlight only files, not directories.
|
||||
|
||||
The extended variant requires a non-trivial amount of parsing to be done, which
|
||||
is achieved with python (specifically python3). It is slightly slower, but
|
||||
complete - both files and directories will be highlighted according to their
|
||||
git status.
|
||||
is achieved with python (specifically python3). It is slightly slower, but
|
||||
complete - both files and directories will be highlighted according to their git
|
||||
status.
|
||||
|
||||
The deferred variant is the same is extended, except the tasks of rendering
|
||||
nodes and highlighting them are separated. The former happens immediately, the
|
||||
latter after `treemacs-deferred-git-apply-delay' seconds of idle time. This may
|
||||
be faster (if not in truth then at least in appereance) as the git process is
|
||||
given a much greater amount of time to finish. The downside is that the effect
|
||||
of nodes changing their colors may be somewhat jarring, though this effect is
|
||||
nodes and highlighting them are separated. The former happens immediately, the
|
||||
latter after `treemacs-deferred-git-apply-delay' seconds of idle time. This may
|
||||
be faster (if not in truth then at least in appearance) as the git process is
|
||||
given a much greater amount of time to finish. The downside is that the effect
|
||||
of nodes changing their colours may be somewhat jarring, though this issue is
|
||||
largely mitigated due to the use of a caching layer.
|
||||
|
||||
All versions run asynchronously and are optimized for not doing more work than
|
||||
All versions run asynchronously and are optimised for not doing more work than
|
||||
is necessary, so their performance cost should, for the most part, be the
|
||||
constant time needed to fork a subprocess."
|
||||
:init-value nil
|
||||
:global t
|
||||
:lighter nil
|
||||
:group 'treemacs
|
||||
:group 'treemacs-git
|
||||
;; case when the mode is re-activated by `custom-set-minor-mode'
|
||||
(when (and (equal arg 1) treemacs--git-mode)
|
||||
(setf arg treemacs--git-mode))
|
||||
(if treemacs-git-mode
|
||||
(if (memq arg '(simple extended deferred))
|
||||
(treemacs--setup-git-mode arg)
|
||||
@@ -412,8 +467,8 @@ Use either ARG as git integration value of read it interactively."
|
||||
(interactive (list (-> (completing-read "Git Integration: " '("Simple" "Extended" "Deferred"))
|
||||
(downcase)
|
||||
(intern))))
|
||||
(setq treemacs-git-mode arg)
|
||||
(pcase treemacs-git-mode
|
||||
(setf treemacs--git-mode arg)
|
||||
(pcase treemacs--git-mode
|
||||
((or 'extended 'deferred)
|
||||
(fset 'treemacs--git-status-process-function #'treemacs--git-status-process-extended)
|
||||
(fset 'treemacs--git-status-parse-function #'treemacs--parse-git-status-extended))
|
||||
@@ -426,12 +481,13 @@ Use either ARG as git integration value of read it interactively."
|
||||
|
||||
(defun treemacs--tear-down-git-mode ()
|
||||
"Tear down `treemacs-git-mode'."
|
||||
(setf treemacs--git-mode nil)
|
||||
(fset 'treemacs--git-status-process-function #'ignore)
|
||||
(fset 'treemacs--git-status-parse-function (lambda (_) (ht))))
|
||||
|
||||
(define-inline treemacs--get-or-parse-git-result (future)
|
||||
"Get the parsed git result of FUTURE.
|
||||
Parse and set it if it hasn't been done yet. If FUTURE is nil an empty hash
|
||||
Parse and set it if it hasn't been done yet. If FUTURE is nil an empty hash
|
||||
table is returned.
|
||||
|
||||
FUTURE: Pfuture process"
|
||||
@@ -445,6 +501,43 @@ FUTURE: Pfuture process"
|
||||
result))
|
||||
(ht)))))
|
||||
|
||||
(define-minor-mode treemacs-hide-gitignored-files-mode
|
||||
"Toggle `treemacs-hide-gitignored-files-mode'.
|
||||
|
||||
When enabled treemacs will hide files that are ignored by git.
|
||||
|
||||
Some form of `treemacs-git-mode' *must* be enabled, otherwise this feature will
|
||||
have no effect.
|
||||
|
||||
Both `extended' and `deferred' git-mode settings will work in full (in case of
|
||||
`deferred' git-mode treemacs will pre-load the list of ignored files so they
|
||||
will be hidden even on the first run). The limitations of `simple' git-mode
|
||||
apply here as well: since it only knows about files and not directories only
|
||||
files will be hidden."
|
||||
:init-value nil
|
||||
:global t
|
||||
:lighter nil
|
||||
:group 'treemacs-git
|
||||
(if treemacs-hide-gitignored-files-mode
|
||||
(progn
|
||||
(add-to-list 'treemacs-pre-file-insert-predicates
|
||||
#'treemacs-is-file-git-ignored?)
|
||||
(when (and (eq 'deferred treemacs--git-mode)
|
||||
(not (get 'treemacs-hide-gitignored-files-mode
|
||||
:prefetch-done)))
|
||||
(treemacs--prefetch-gitignore-cache 'all)
|
||||
(put 'treemacs-hide-gitignored-files-mode :prefetch-done t)))
|
||||
(setf treemacs-pre-file-insert-predicates
|
||||
(delete #'treemacs-is-file-git-ignored?
|
||||
treemacs-pre-file-insert-predicates)))
|
||||
(treemacs-run-in-every-buffer
|
||||
(treemacs--do-refresh (current-buffer) 'all))
|
||||
(when (called-interactively-p 'interactive)
|
||||
(treemacs-pulse-on-success "Git-ignored files will now be %s"
|
||||
(propertize
|
||||
(if treemacs-hide-gitignored-files-mode "hidden." "displayed.")
|
||||
'face 'font-lock-constant-face))) )
|
||||
|
||||
(treemacs-only-during-init
|
||||
(let ((has-git (not (null (executable-find "git"))))
|
||||
(has-python (not (null treemacs-python-executable))))
|
||||
|
||||
Reference in New Issue
Block a user