77; ; Description: Preview the current ivy file selection.
88; ; Keyword: file ivy swiper preview select selection
99; ; Version: 0.1.5
10- ; ; Package-Requires: ((emacs "25.1") (ivy "0.8.0") (f "0.20.0"))
10+ ; ; Package-Requires: ((emacs "25.1") (ivy "0.8.0") (s "1.12.0") ( f "0.20.0"))
1111; ; URL: https://github.com/jcs-elpa/ivy-file-preview
1212
1313; ; This file is NOT part of GNU Emacs.
3434
3535(require 'cl-lib )
3636(require 'f )
37+ (require 's )
3738(require 'ivy )
3839
3940(defgroup ivy-file-preview nil
5253 :type 'boolean
5354 :group 'ivy-file-preview )
5455
56+ (defcustom ivy-file-preview-overlay-p t
57+ " Show overlays while previewing."
58+ :type 'boolean
59+ :group 'ivy-file-preview )
60+
5561(defvar ivy-file-preview--preview-files '()
5662 " Files that are previewing, and will be closed after action is done." )
5763
6167(defvar ivy-file-preview--window-status '()
6268 " Record windows status for when canceling command." )
6369
70+ (defvar ivy-file-preview--overlays '()
71+ " List of overlays." )
72+
6473; ;; Util
6574
6675(defun ivy-file-preview--project-path ()
7281 (goto-char (point-min ))
7382 (forward-line (1- ln)))
7483
84+ (defun ivy-file-preview--convert-pos (ln col )
85+ " Convert LN and COL to position point."
86+ (save-excursion
87+ (ivy-file-preview--goto-line ln)
88+ (move-to-column col)
89+ (point )))
90+
91+ (defun ivy-file-preview--make-overlay (beg end )
92+ " Make a new overlay with BEG and END."
93+ (let ((ol (make-overlay beg end)))
94+ (overlay-put ol 'face (if (= beg (point )) 'ivy-current-match 'ivy-minibuffer-match-highlight ))
95+ (overlay-put ol 'priority 0 )
96+ (push ol ivy-file-preview--overlays)))
97+
98+ (defun ivy-file-preview--delete-overlays ()
99+ " Delete all overlays in list."
100+ (dolist (ov ivy-file-preview--overlays) (delete-overlay ov)))
101+
75102; ;; Core
76103
104+ (defun ivy-file-preview--extract-candidates-overlay-data ()
105+ " Extract the overlay data from current ivy candidates."
106+ (let* ((project-dir (ivy-file-preview--project-path))
107+ (fn (if project-dir
108+ (s-replace project-dir " " ivy-file-preview--selected-file)
109+ ivy-file-preview--selected-file))
110+ (cands (or ivy--old-cands ivy--all-candidates '()))
111+ (cands-len (length cands)) current-cand entered ln-data
112+ ln col
113+ cand-fn (results '()) break (index 0 ))
114+ (while (and (not break) (< index cands-len))
115+ (setq current-cand (nth index cands))
116+ (setq ln-data (split-string current-cand " :" ))
117+ (setq cand-fn (nth 0 ln-data))
118+ (if (string= cand-fn fn)
119+ (progn
120+ (setq ln (nth 1 ln-data) col (nth 2 ln-data))
121+ (push (list :line-number ln :column col) results)
122+ (setq entered t ))
123+ (when entered (setq break t )))
124+ (setq index (1+ index)))
125+ results))
126+
127+ (defun ivy-file-preview--make-overlays ()
128+ " Make overlays through out the whole buffer."
129+ (let ((ov-data (ivy-file-preview--extract-candidates-overlay-data))
130+ pos ln col
131+ (len (length ivy-text)))
132+ (dolist (data ov-data)
133+ (setq ln (plist-get data :line-number )
134+ col (plist-get data :column ))
135+ (if (not col)
136+ (setq pos ln)
137+ (setq ln (string-to-number ln)
138+ col (string-to-number col))
139+ (setq pos (ivy-file-preview--convert-pos ln col)))
140+ (ivy-file-preview--make-overlay pos (+ pos len)))))
141+
77142(defun ivy-file-preview--open-file (fn pos )
78143 " Open the file path (FN).
79144POS can either be an integer or cons cell represent line number and columns."
145+ (setq ivy-file-preview--selected-file fn)
80146 (if (file-exists-p fn) (find-file fn) (switch-to-buffer fn))
81147 (cond ((consp pos)
82148 (ivy-file-preview--goto-line (car pos))
@@ -93,7 +159,12 @@ POS can either be an integer or cons cell represent line number and columns."
93159 (when project-dir (setq fn (f-join project-dir fn)))
94160 (when (and ivy-file-preview-preview-only (not (find-buffer-visiting fn)))
95161 (push fn ivy-file-preview--preview-files))
96- (ivy-file-preview--open-file fn pos))))
162+ (unless (string= ivy-file-preview--selected-file fn)
163+ (ivy-file-preview--delete-overlays))
164+ (ivy-file-preview--open-file fn pos)
165+ (when ivy-file-preview-overlay-p
166+ (ivy-file-preview--delete-overlays)
167+ (ivy-file-preview--make-overlays)))))
97168
98169(defun ivy-file-preview--after-select (&rest _ )
99170 " Execution after selection."
@@ -111,8 +182,9 @@ POS can either be an integer or cons cell represent line number and columns."
111182
112183(defun ivy-file-preview--cancel-revert ()
113184 " Revert frame status if user cancel the commands."
114- (if ivy-exit
115- (setq ivy-file-preview--selected-file " " )
185+ (ivy-file-preview--delete-overlays)
186+ (unless ivy-exit
187+ (setq ivy-file-preview--selected-file " " )
116188 (switch-to-buffer (nth 0 ivy-file-preview--window-status))
117189 (set-window-point minibuffer-scroll-window (nth 1 ivy-file-preview--window-status))))
118190
@@ -129,7 +201,7 @@ POS can either be an integer or cons cell represent line number and columns."
129201 (delete-dups ivy-file-preview--preview-files)
130202 (dolist (fn ivy-file-preview--preview-files)
131203 (unless (string= ivy-file-preview--selected-file fn)
132- (kill-buffer (f-filename fn))))
204+ (ignore-errors ( kill-buffer (f-filename fn) ))))
133205 (setq ivy-file-preview--selected-file " " )
134206 (setq ivy-file-preview--preview-files '()))
135207
0 commit comments