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

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

[elpa] master 469a4ab 081/348: Add ivy-push-view and ivy-pop-view


From: Oleh Krehel
Subject: [elpa] master 469a4ab 081/348: Add ivy-push-view and ivy-pop-view
Date: Sat, 8 Apr 2017 11:03:32 -0400 (EDT)

branch: master
commit 469a4ab686e01636fa541259f3e0ce42b715a312
Author: Oleh Krehel <address@hidden>
Commit: Oleh Krehel <address@hidden>

    Add ivy-push-view and ivy-pop-view
    
    * ivy.el (ivy-default-view-name): New defun.
    (ivy-push-view): New command.
    (ivy-pop-view-action): New defun.
    (ivy-pop-view): New command.
    (ivy-set-view-recur): Extend views, they can now specify the point
    position.
    
    Quick explanation:
    
    1. Use `ivy-push-view' to store a view - your current window tree.
    This contains: all windows on the current frame, and their configuration
    w.r.t. horizontal or vertical splits. The point positions in each window
    are stored as well.
    
    2. Use `ivy-switch-buffer' to select stored views.
    
    3. Use `ivy-pop-view' to delete a stored view that you don't want any
    more.
---
 ivy.el | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 82 insertions(+), 4 deletions(-)

diff --git a/ivy.el b/ivy.el
index 550a97b..9530cb5 100644
--- a/ivy.el
+++ b/ivy.el
@@ -2759,6 +2759,78 @@ TREE is a nested list with the following valid cars:
 
 TREE can be nested multiple times to have mulitple window splits.")
 
+(defun ivy-default-view-name ()
+  (let* ((default-view-name
+          (concat "{} "
+                  (mapconcat #'identity
+                             (cl-sort
+                              (mapcar (lambda (w)
+                                        (with-current-buffer (window-buffer w)
+                                          (if (buffer-file-name)
+                                              (file-name-nondirectory
+                                               (buffer-file-name))
+                                            (buffer-name))))
+                                      (window-list))
+                              #'string<)
+                             " ")))
+         (view-name-re (concat "\\`"
+                               (regexp-quote default-view-name)
+                               " \\([0-9]+\\)"))
+         old-view)
+    (cond ((setq old-view
+                 (cl-find-if
+                  (lambda (x)
+                    (string-match view-name-re (car x)))
+                  ivy-views))
+           (format "%s %d"
+                   default-view-name
+                   (1+ (string-to-number
+                        (match-string 1 (car old-view))))))
+          ((assoc default-view-name ivy-views)
+           (concat default-view-name " 1"))
+          (t
+           default-view-name))))
+
+(defun ivy-push-view ()
+  "Push the current window tree on `ivy-views'.
+Currently, the split configuration (i.e. horizonal or vertical)
+and point positions are saved, but the split positions aren't.
+Use `ivy-pop-view' to delete any item from `ivy-views'."
+  (interactive)
+  (let* ((view (cl-labels ((ft (tr)
+                             (if (consp tr)
+                                 (if (eq (car tr) t)
+                                     (list 'vert
+                                           (ft (nth 2 tr))
+                                           (ft (nth 3 tr)))
+                                   (list 'horz
+                                         (ft (nth 2 tr))
+                                         (ft (nth 3 tr))))
+                               (with-current-buffer (window-buffer tr)
+                                 (if (buffer-file-name)
+                                     (list 'file (buffer-file-name) (point))
+                                   (list 'buffer (buffer-name) (point)))))))
+                 (ft (car (window-tree)))))
+         (view-name (ivy-read "Name view: " nil
+                              :initial-input (ivy-default-view-name))))
+    (when view-name
+      (push (list view-name view) ivy-views))))
+
+(defun ivy-pop-view-action (view)
+  "Delete VIEW from `ivy-views'."
+  (setq ivy-views (delete view ivy-views))
+  (setq ivy--all-candidates
+        (delete (car view) ivy--all-candidates))
+  (setq ivy--old-cands nil))
+
+(defun ivy-pop-view ()
+  "Delete a view to delete from `ivy-views'."
+  (interactive)
+  (ivy-read "Pop view: " ivy-views
+            :preselect (caar ivy-views)
+            :action #'ivy-pop-view-action
+            :caller 'ivy-pop-view))
+
 (defun ivy-source-views ()
   (mapcar #'car ivy-views))
 
@@ -2783,7 +2855,7 @@ TREE can be nested multiple times to have mulitple window 
splits.")
            (with-selected-window wnd2
              (ivy-set-view-recur (nth 2 view)))))
         ((eq (car view) 'file)
-         (let* ((name (cadr view))
+         (let* ((name (nth 1 view))
                 (virtual (assoc name ivy--virtual-buffers))
                 buffer)
            (cond ((setq buffer (get-buffer name))
@@ -2791,11 +2863,17 @@ TREE can be nested multiple times to have mulitple 
window splits.")
                  (virtual
                   (find-file (cdr virtual)))
                  ((file-exists-p name)
-                  (find-file name)))))
+                  (find-file name))))
+         (when (and (> (length view) 2)
+                    (numberp (nth 2 view)))
+           (goto-char (nth 2 view))))
         ((eq (car view) 'buffer)
-         (switch-to-buffer (cadr view)))
+         (switch-to-buffer (nth 1 view))
+         (when (and (> (length view) 2)
+                    (numberp (nth 2 view)))
+           (goto-char (nth 2 view))))
         ((eq (car view) 'sexp)
-         (eval (cadr view)))))
+         (eval (nth 1 view)))))
 
 (defun ivy--switch-buffer-action (buffer)
   "Switch to BUFFER.



reply via email to

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