Skip to content

Commit

Permalink
refactor: improve gnuls checking / preview on remote hosts
Browse files Browse the repository at this point in the history
  • Loading branch information
alexluigit committed Oct 1, 2022
1 parent 77e738b commit a877ba8
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 60 deletions.
42 changes: 19 additions & 23 deletions dirvish-extras.el
Original file line number Diff line number Diff line change
Expand Up @@ -169,39 +169,35 @@ keyword in that prefix or infix."
:type ,(cons (if f-dirp 'dir 'file) f-truename))
dirvish--attrs-hash)))))

(defun dirvish-gnuls-available-p (dir)
"Check if GNU ls is available or not over DIR."
(with-temp-buffer
(cl-letf (((symbol-function 'display-message-or-buffer) #'ignore))
(let ((default-directory dir))
(= (tramp-handle-shell-command "ls --version") 0)))))

(defun dirvish-noselect-tramp (fn dir flags remote)
"Return the Dired buffer at DIR with listing FLAGS.
Save the REMOTE host to `dirvish-tramp-hosts'.
FN is the original `dired-noselect' closure."
(let* ((r-flags (cdr (assoc remote dirvish-tramp-hosts #'equal)))
(ftp (tramp-ftp-file-name-p dir))
(let* ((saved-flags (cdr (assoc remote dirvish-tramp-hosts #'equal)))
(ftp? (tramp-ftp-file-name-p dir))
(short-flags "-Alh")
(gnu? t)
(dired-buffers nil) ; disable reuse from dired
(buffer (apply fn (list dir (if ftp short-flags (or r-flags flags))))))
(unless (or r-flags ftp)
(setq gnu? (dirvish-gnuls-available-p dir))
(push (cons remote (if gnu? flags short-flags)) dirvish-tramp-hosts))
(unless gnu?
(kill-buffer buffer)
(setq buffer (apply fn (list dir short-flags))))
(default-directory dir)
(dired-buffers nil)
(buffer (cond (ftp? (funcall fn dir short-flags))
(saved-flags (funcall fn dir saved-flags))
((= (process-file "ls" nil nil nil "--version") 0)
(push (cons remote flags) dirvish-tramp-hosts)
(funcall fn dir flags))
(t (push (cons remote short-flags) dirvish-tramp-hosts)
(funcall fn dir short-flags)))))
(with-current-buffer buffer
(dirvish-prop :tramp (tramp-dissect-file-name dir))
buffer)))

(defun dirvish-tramp--async-p (&optional vec)
(defun dirvish-tramp--async-p (vec)
"Return t if tramp connection VEC support async commands."
(when-let ((vec (or vec (dirvish-prop :tramp))))
(or (tramp-local-host-p vec)
(and (tramp-get-method-parameter vec 'tramp-direct-async)
(tramp-get-connection-property vec "direct-async-process" nil)))))
;; no password needed
(and (stringp (tramp-get-connection-property vec "first-password-request"))
;; the connection is localhost or support `direct-async-process'
(or (tramp-local-host-p vec)
(and (tramp-get-method-parameter vec 'tramp-direct-async)
(tramp-get-connection-property
vec "direct-async-process" nil)))))

(defun dirvish-tramp-dir-data-proc-s (proc _exit)
"Sentinel for `dirvish-data-for-dir''s process PROC."
Expand Down
4 changes: 2 additions & 2 deletions dirvish.el
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ buffer, it defaults to filename under the cursor when it is nil."
(push (cons key buffer) (dv-roots dv))
(push (cons key buffer) dired-buffers))
(with-current-buffer buffer
(cond (new-buffer-p)
(cond (new-buffer-p nil)
((and (not remote) (not (equal flags dired-actual-switches)))
(dired-sort-other flags))
((eq dired-auto-revert-buffer t) (revert-buffer))
Expand Down Expand Up @@ -1174,7 +1174,7 @@ Run `dirvish-setup-hook' afterwards when SETUP is non-nil."
(setq dirvish--this dv)))

(defun dirvish--reuse-or-create (path layout)
"Find PATH in a dirvish session with LAYOUT."
"Find PATH in a dirvish session and set its layout with LAYOUT."
(let ((dir (or path default-directory))
(dv (or dirvish--this (car (dirvish--find-reusable)))))
(cond (dv (with-selected-window (dirvish--create-root-window dv)
Expand Down
60 changes: 26 additions & 34 deletions extensions/dirvish-fd.el
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@
"The default fd program."
:type 'string :group 'dirvish)

(defun dirvish-fd--find-ls-program (&optional remote)
"Find ls programm on a local or `REMOTE' host ."
(defun dirvish-fd--find-gnu-ls (&optional remote)
"Find ls from gnu coreutils on a local or REMOTE host ."
(let* ((ls (executable-find "ls" remote))
(gls (executable-find "gls" remote))
(idp (executable-find insert-directory-program remote))
(ls-is-gnu? (and ls (= 0 (process-file ls nil nil nil "--version"))))
(idp-is-gnu-ls? (and idp (= 0 (process-file idp nil nil nil "--version")))))
(idp-is-gnu-ls?
(and idp (= 0 (process-file idp nil nil nil "--version")))))
(cond
;; just use GNU ls if found
(ls-is-gnu? ls)
Expand All @@ -51,7 +52,7 @@
insert-directory-program))))

(defcustom dirvish-fd-ls-program
(dirvish-fd--find-ls-program)
(dirvish-fd--find-gnu-ls)
"Listing program for `fd'."
:type '(string :tag "Listing program, such as `ls'") :group 'dirvish)

Expand Down Expand Up @@ -80,6 +81,12 @@ should return a list of regular expressions."
(defvar-local dirvish-fd--output "")
(defvar-local dirvish-fd--input "" "Last used fd user input.")

(defun dirvish-fd--ensure-fd (remote)
"Return fd executable on REMOTE or localhost.
Raise an error if fd executable is not available."
(or (and remote (dirvish-fd--find-fd-program remote)) dirvish-fd-program
(user-error "`dirvish-fd' requires `fd', please install it")))

(defsubst dirvish-fd--header-offset ()
"Return # of header lines in a fd buffer."
(if (or (not (boundp 'dired-free-space))
Expand Down Expand Up @@ -270,17 +277,16 @@ value 16, let the user choose the root directory of their search."
(let* ((base-dir (cond
((eq current-dir-p 4) default-directory)
((eq current-dir-p 16)
(let ((dir (car (find-file-read-args "Select root directory: " nil))))
(let ((dir (car (find-file-read-args
"Select root directory: " nil))))
(if (file-directory-p dir)
(file-name-as-directory dir)
(dirvish--get-parent-path dir))))
(t dirvish-fd-default-dir)))
(remote (file-remote-p base-dir))
(fd-program (dirvish-fd--get-fd-program remote)))
(unless fd-program
(user-error "`dirvish-fd' requires `fd', please install it"))

(let* ((command (concat fd-program " -H -td --color=never -0 . " (file-local-name base-dir)))
(fd-program (dirvish-fd--ensure-fd remote)))
(let* ((command (concat fd-program " -H -td --color=never -0 . "
(file-local-name base-dir)))
(default-directory base-dir)
(output (shell-command-to-string command))
(files-raw (split-string output "\0" t))
Expand All @@ -289,7 +295,7 @@ value 16, let the user choose the root directory of their search."
(full-file (concat remote file)))
(dired-jump nil full-file))))

(defun dirvish-fd-filter (proc string)
(defun dirvish-fd-proc-filter (proc string)
"Filter for `dirvish-fd' processes PROC and output STRING."
(let ((buf (process-buffer proc)))
(if (buffer-name buf)
Expand Down Expand Up @@ -329,13 +335,14 @@ value 16, let the user choose the root directory of their search."
"Revert buffer function for fd buffer."
(dirvish-fd default-directory (or dirvish-fd--input "")))

(cl-defun dirvish-fd-proc-s (proc _)
(cl-defun dirvish-fd-proc-sentinel (proc _)
"Sentinel for `dirvish-fd' process PROC."
(pcase-let* ((buf (process-buffer proc))
(success (eq (process-exit-status proc) 0))
(`(,input ,dir ,dv) (process-get proc 'info)))
(unless (buffer-live-p buf)
(cl-return-from dirvish-fd-proc-s (message "`fd' process terminated")))
(cl-return-from dirvish-fd-proc-sentinel
(message "`fd' process terminated")))
(with-selected-window (dv-root-window dv)
(unless (eq (current-buffer) buf)
(dirvish-fd-switch-to-buffer buf)))
Expand All @@ -352,7 +359,7 @@ value 16, let the user choose the root directory of their search."
((equal input "") (dirvish-update-body-h))
(t (dirvish-fd--narrow input (car (dirvish-prop :fd-arglist)))))
(when (eq input 'cancelled)
(cl-return-from dirvish-fd-proc-s (kill-buffer buf)))
(cl-return-from dirvish-fd-proc-sentinel (kill-buffer buf)))
(let ((bufname (dirvish-fd--bufname input dir dv)))
(dirvish-prop :root bufname)
(setf (dv-index dv) (cons bufname buf))
Expand Down Expand Up @@ -399,20 +406,6 @@ When GLOB, convert the regexs using `dired-glob-regexp'."
(interactive)
(dirvish--kill-buffer (current-buffer)))

(defun dirvish-fd--get-fd-program (remote)
"Return executable of fd.
If `REMOTE' is non-nil, search on remote host."
(if remote
(dirvish-fd--find-fd-program remote)
dirvish-fd-program))

(defun dirvish-fd--get-ls-program (remote)
"Return executable of ls.
If `REMOTE' is non-nil, search on remote host."
(if remote
(dirvish-fd--find-ls-program remote)
dirvish-fd-ls-program))

;;;###autoload
(defun dirvish-fd (dir pattern)
"Run `fd' on DIR and go into Dired mode on a buffer of the output.
Expand All @@ -428,14 +421,13 @@ The command run is essentially:
(or (file-directory-p dir)
(user-error "'fd' command requires a directory: %s" dir))
(let* ((remote (file-remote-p dir))
(fd-program (dirvish-fd--get-fd-program remote))
(ls-program (dirvish-fd--get-ls-program remote))
(fd-program (dirvish-fd--ensure-fd remote))
(ls-program (or (and remote (dirvish-fd--find-gnu-ls remote))
dirvish-fd-ls-program))
(dv (or (dirvish-curr) (progn (dirvish dir) dirvish--this)))
(fd-switches (or (dirvish-prop :fd-switches) dirvish-fd-switches ""))
(ls-switches (or dired-actual-switches (dv-ls-switches dv)))
(buffer (dirvish--util-buffer 'fd dv nil t)))
(unless fd-program
(user-error "`dirvish-fd' requires `fd', please install it"))
(dirvish--kill-buffer (get-buffer (dirvish-fd--bufname pattern dir dv)))
(with-current-buffer buffer
(erase-buffer)
Expand All @@ -461,8 +453,8 @@ The command run is essentially:
"--exec-batch" ,ls-program
,@(or (split-string ls-switches) "")
"--quoting-style=literal" "--directory"))))
(set-process-filter proc #'dirvish-fd-filter)
(set-process-sentinel proc #'dirvish-fd-proc-s)
(set-process-filter proc #'dirvish-fd-proc-filter)
(set-process-sentinel proc #'dirvish-fd-proc-sentinel)
(dirvish-fd--argparser (split-string (or fd-switches "")))
(process-put proc 'info (list pattern dir dv))))
(dirvish-fd-switch-to-buffer buffer)))
Expand Down
3 changes: 2 additions & 1 deletion extensions/dirvish-peek.el
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ one of categories in `dirvish-peek-categories'."
('library
(setq cand (file-truename
(or (ignore-errors (find-library-name cand)) "")))))
(dirvish-debounce nil (dirvish-preview-update dirvish--this cand))))
(unless (file-remote-p cand)
(dirvish-debounce nil (dirvish-preview-update dirvish--this cand)))))

(defun dirvish-peek-exit-h ()
"Hook for `minibuffer-exit-hook' to destroy peek session."
Expand Down

0 comments on commit a877ba8

Please sign in to comment.