emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/embark b80d96ce0a 2/2: Improve handling of relative pat


From: ELPA Syncer
Subject: [elpa] externals/embark b80d96ce0a 2/2: Improve handling of relative paths in export, collect and act-all
Date: Fri, 25 Mar 2022 21:57:28 -0400 (EDT)

branch: externals/embark
commit b80d96ce0ab79e73829322e46c6d7493eb2b8c34
Author: Omar Antolín <omar.antolin@gmail.com>
Commit: Omar Antolín <omar.antolin@gmail.com>

    Improve handling of relative paths in export, collect and act-all
    
    Before this change I had some ad hoc handling of converting from
    relative to absolute paths (see the two removed TODOs) that failed to
    cover some cases where it was needed. For example, I trie attaching
    multiple files to an email message by using embark-act-all from
    mml-attach-file, and this failed to find the files if they weren't in
    the default-directory of the email composition buffer!
    
    The basic source of the problem is that typically file completion
    candidates are just the last portion of a file path, and should be
    taken relative to the directory specified in the minibuffer input, but
    that directory is *not* necessarily the default-directory of the
    minibuffer or the buffer current before the minibuffer. Embark has
    long had embark--default-directory which has some reasonable
    heuristics to figure out the correct directory candidates which are
    relative paths can be found in.
    
    With this change all use of candidate collectors (those are used for
    all the commands for sets of candidates: export, collect and act-all)
    will now add the correct path to file candidates, so that future
    actions can safely find them.
    
    Previously dired export would make candidates relative to an
    appropriately chosen directory to achieve a less cluttered look, but
    collect buffers did not do this. Now collect buffers do so as well.
---
 embark.el | 129 +++++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 69 insertions(+), 60 deletions(-)

diff --git a/embark.el b/embark.el
index 2f67d572b8..9e96162c90 100644
--- a/embark.el
+++ b/embark.el
@@ -943,10 +943,8 @@ their own target finder.  See for example
            candidate)
         ,start . ,end))))
 
-(defun embark-target-completion-at-point (&optional relative)
-  "Return the completion candidate at point in a completions buffer.
-If the completions are file names and RELATIVE is non-nil, return
-relative path."
+(defun embark-target-completion-at-point ()
+  "Return the completion candidate at point in a completions buffer."
   (when (derived-mode-p 'completion-list-mode)
     (if (not (get-text-property (point) 'mouse-face))
         (user-error "No completion here")
@@ -964,7 +962,7 @@ relative path."
                       (point-max)))
         (let ((raw (buffer-substring beg end)))
           `(,embark--type
-            ,(if (and (eq embark--type 'file) (not relative))
+            ,(if (eq embark--type 'file)
                  (abbreviate-file-name (expand-file-name raw))
                raw)
             ,beg . ,end))))))
@@ -2079,26 +2077,32 @@ target."
   "Collect candidates and see if they all transform to the same type.
 Return a plist with keys `:type', `:orig-type', `:candidates', and
 `:orig-candidates'."
- (pcase-let ((`(,type . ,candidates)
-              (run-hook-with-args-until-success 'embark-candidate-collectors)))
-   (append
-    (list :orig-type type :orig-candidates candidates)
-    (or (unless (null candidates)
-          (when-let ((transformer (alist-get type embark-transformer-alist)))
-            (pcase-let* ((`(,new-type . ,first-cand)
-                          (funcall transformer type (car candidates))))
-              (let ((new-candidates (list first-cand)))
-                (when (cl-every
-                       (lambda (cand)
-                         (pcase-let ((`(,t-type . ,t-cand)
-                                      (funcall transformer type cand)))
-                           (when (eq t-type new-type)
-                             (push t-cand new-candidates)
-                             t)))
-                       (cdr candidates))
-                  (list :type new-type
-                        :candidates (nreverse new-candidates)))))))
-        (list :type type :candidates candidates)))))
+  (pcase-let ((`(,type . ,candidates)
+               (run-hook-with-args-until-success 
'embark-candidate-collectors)))
+    (when (eq type 'file)
+      (let ((dir (embark--default-directory)))
+        (setq candidates
+              (mapcar (lambda (cand)
+                        (abbreviate-file-name (expand-file-name cand dir)))
+                      candidates))))
+    (append
+     (list :orig-type type :orig-candidates candidates)
+     (or (unless (null candidates)
+           (when-let ((transformer (alist-get type embark-transformer-alist)))
+             (pcase-let* ((`(,new-type . ,first-cand)
+                           (funcall transformer type (car candidates))))
+               (let ((new-candidates (list first-cand)))
+                 (when (cl-every
+                        (lambda (cand)
+                          (pcase-let ((`(,t-type . ,t-cand)
+                                       (funcall transformer type cand)))
+                            (when (eq t-type new-type)
+                              (push t-cand new-candidates)
+                              t)))
+                        (cdr candidates))
+                   (list :type new-type
+                         :candidates (nreverse new-candidates)))))))
+         (list :type type :candidates candidates)))))
 
 ;;;###autoload
 (defun embark-act-all (&optional arg)
@@ -2120,15 +2124,11 @@ ARG is the prefix argument."
   (let* ((transformed (embark--maybe-transform-candidates))
          (type (plist-get transformed :type))
          (orig-type (plist-get transformed :orig-type))
-         (dir (embark--default-directory))
          (candidates
           (or (cl-mapcar
                (lambda (cand orig-cand)
-                 (list :type type :orig-type orig-type
-                       ;; TODO The file special casing here seems odd.
-                       ;; Why do we need this?
-                       :target (if (eq type 'file) (expand-file-name cand dir) 
cand)
-                       :orig-target orig-cand))
+                 (list :type type :target cand
+                       :orig-type orig-type :orig-target orig-cand))
                (plist-get transformed :candidates)
                (plist-get transformed :orig-candidates))
               (user-error "No candidates to act on")))
@@ -2543,8 +2543,7 @@ This makes `embark-export' work in Embark Collect 
buffers."
        (next-completion 1)
        (let (all)
          (while (not (eobp))
-           ;; TODO next line looks a little funny now
-           (push (cdr (embark-target-completion-at-point 'relative-path)) all)
+           (push (cadr (embark-target-completion-at-point)) all)
            (next-completion 1))
          (nreverse all))))))
 
@@ -2674,25 +2673,6 @@ embark collect direct action minor mode by adding the 
function
 `embark-collect-direct-action-minor-mode' to
 `embark-collect-mode-hook'.")
 
-(defun embark--for-display (string)
-  "Return visibly equivalent STRING without display and invisible properties."
-  (let ((len (length string)) (pos 0) chunks)
-    (while (/= pos len)
-      (let ((dis (next-single-property-change pos 'display string len))
-            (display (get-text-property pos 'display string)))
-        (if (stringp display)
-            (progn (push display chunks) (setq pos dis))
-          (while (/= pos dis)
-            (let ((inv (next-single-property-change pos 'invisible string 
dis)))
-              (unless (get-text-property pos 'invisible string)
-                (unless (and (= pos 0) (= inv len))
-                  ;; avoid allocation for full string
-                  (push (substring string pos inv) chunks)))
-              (setq pos inv))))))
-    (propertize
-     (if chunks (apply #'concat (nreverse chunks)) string)
-     'embark--candidate string)))
-
 (defun embark-collect--list-view ()
   "List view of candidates and annotations for Embark Collect buffer."
   (let ((max-width 0)
@@ -2881,11 +2861,38 @@ candidate."
     (goto-char (point-min))
     (while (embark-collect-mark (embark-collect--marked-p)))))
 
+(defun embark--for-display (string)
+  "Return visibly equivalent STRING without display and invisible properties."
+  (let ((len (length string)) (pos 0) chunks)
+    (while (/= pos len)
+      (let ((dis (next-single-property-change pos 'display string len))
+            (display (get-text-property pos 'display string)))
+        (if (stringp display)
+            (progn (push display chunks) (setq pos dis))
+          (while (/= pos dis)
+            (let ((inv (next-single-property-change pos 'invisible string 
dis)))
+              (unless (get-text-property pos 'invisible string)
+                (unless (and (= pos 0) (= inv len))
+                  ;; avoid allocation for full string
+                  (push (substring string pos inv) chunks)))
+              (setq pos inv))))))
+    (propertize
+     (if chunks (apply #'concat (nreverse chunks)) string)
+     'embark--candidate string)))
+
 (defun embark-collect--update-candidates (buffer)
   "Update candidates for Embark Collect BUFFER."
-  (pcase-let* ((`(,type . ,candidates)
-                (run-hook-with-args-until-success 
'embark-candidate-collectors))
-               (affixator (embark-collect--affixator type)))
+  (let* ((transformed (embark--maybe-transform-candidates))
+         (type (plist-get transformed :orig-type)) ; we need the originals for
+         (candidates (plist-get transformed :orig-candidates)) ; default action
+         (affixator (embark-collect--affixator type)))
+    (when (eq type 'file)
+      (let ((dir (buffer-local-value 'default-directory buffer)))
+        (setq candidates
+              (mapcar (lambda (cand)
+                        (let ((rel (file-relative-name cand dir)))
+                          (if (string-prefix-p "../" rel) cand rel)))
+                      candidates))))
     (when affixator (setq candidates (funcall affixator candidates)))
     (setq candidates
           (if (stringp (car candidates))
@@ -2906,7 +2913,13 @@ buffer has a unique name."
     (with-current-buffer buffer
       ;; we'll run the mode hooks once the buffer is displayed, so
       ;; the hooks can make use of the window
-      (delay-mode-hooks (embark-collect-mode))
+      (delay-mode-hooks (embark-collect-mode)))
+
+    (embark--cache-info buffer)
+    (unless (embark-collect--update-candidates buffer)
+      (user-error "No candidates to collect"))
+
+    (with-current-buffer buffer
       (setq tabulated-list-use-header-line nil) ; default to no header
       (add-hook 'tabulated-list-revert-hook #'embark-collect--revert nil t)
       (setq embark-collect--view
@@ -2917,10 +2930,6 @@ buffer has a unique name."
         (setq embark-collect--view 'list)
         (embark-collect-zebra-minor-mode)))
 
-    (unless (embark-collect--update-candidates buffer)
-      (user-error "No candidates to collect"))
-
-    (embark--cache-info buffer)
     (let ((window (display-buffer buffer)))
       (with-selected-window window
         (run-mode-hooks)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]