[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/blist fa54e09b57 03/31: More features
From: |
ELPA Syncer |
Subject: |
[elpa] externals/blist fa54e09b57 03/31: More features |
Date: |
Tue, 28 Dec 2021 16:57:25 -0500 (EST) |
branch: externals/blist
commit fa54e09b5736b331e4aa0583729694abed44fcb5
Author: JSDurand <mmemmew@gmail.com>
Commit: JSDurand <mmemmew@gmail.com>
More features
* blist.el (blist-annotation-column-name, blist-annotation-column):
Add a column to show if the bookmark has annotations.
(blist-set-annotation-column): This command updates the annotation
column if the name of the column changes.
(blist-select-manner): How to select multiple bookmarks. The user can
choose to open horizontally, vertically, or even in a spiral manner,
with detailed controls.
(blist-rename-history, blist-rename): Rename a bookmark.
(blist-get-annotation): Return if BOOKMARK has annotation. If
BOOKMARK has no annotation, return a space string.
(blist-mode-map): Bind more key-bindings.
(blist-list-bookmarks): Delete trailing whitespaces after the list is
displayed, so as to avoid surprises.
(blist-operate-range): Skip groups now.
(blist-prepare-select-windows): Prepare the windows for selection.
(blist-select): Select multiple windows.
(blist-all-bookmarks, blist-jump-to-line): Changed syntax.
---
blist.el | 302 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 279 insertions(+), 23 deletions(-)
diff --git a/blist.el b/blist.el
index e3a74527e4..fd07087847 100644
--- a/blist.el
+++ b/blist.el
@@ -122,6 +122,46 @@ See `blist-sorter'."
(const nil :tag "No sorting")
(function :tag "Sorting function")))
+;;;; Annotation Column Name
+
+(defcustom blist-annotation-column-name "A"
+ "The name of the column showing whether a bookmark has \
+annotations.
+
+Only the first letter will be shown.
+
+If one changes this, run `blist-set-annotation-column' to set the
+annotation column again."
+ :group 'blist
+ :type 'string
+ :set #'blist-set-annotation-column)
+
+;;;; How to open multiple bookmarks?
+
+(defcustom blist-select-manner (list 'vertical)
+ "How to select multiple bookmarks.
+The value should be a list of symbols. Allowed symbols are as
+follows.
+
+- vertical: open bookmarks vertically.
+- horizontal: open bookmarks horizontally. Vertical takes
+ precedence.
+- spiral: open bookmark in a spiral manner. If vertical
+ is also present, spiral vertically; otherwise
+ spiral horizontally. By default toward right
+ / down, unless left / up is present.
+- left: the direction to open. The bookmarks that are
+ higher on the list are opened on the right.
+- right, up, down: similar to left. Left takes precedence over
+ right, and up takes precedence over down.
+- tab: open the bookmarks in a new tab. Requires
+ 'tab-bar if used.
+
+There will be no errors if there are unrecognized symbols in the
+list; they are simply ignored."
+ :group 'blist
+ :type '(list symbol))
+
;;; Variables
;;;; Sorter
@@ -130,6 +170,12 @@ See `blist-sorter'."
"The function used to sort the bookmark list.
See `ilist-string' for how the sorter should behave.")
+;;;; Rename history
+
+(defvar blist-rename-history nil
+ "The variable that stores the strings that the user has inputted \
+to rename bookmarks.")
+
;;; Display
;;;; Columns
@@ -153,6 +199,30 @@ an integer or a float between 0 and 1")))
:left
"..."))
+;;;;; Annotation column
+
+(defun blist-get-annotation (bookmark)
+ "Return if BOOKMARK has annotation.
+If BOOKMARK has no annotation, return a space string."
+ (cond
+ ((let ((annotation (bookmark-get-annotation bookmark)))
+ (and (stringp annotation)
+ (not (string= annotation ""))))
+ "*")
+ (" ")))
+
+(defvar blist-annotation-column
+ (list blist-annotation-column-name #'blist-get-annotation
+ 1 1 :left nil)
+ "The specification of the ANNOTATION column.")
+
+(defun blist-set-annotation-column (&rest _args)
+ "Set the annotation column.
+ARGS are there to conform to the customization interface."
+ (setq blist-annotation-column
+ (list blist-annotation-column-name #'blist-get-annotation
+ 1 1 :left nil)))
+
;;;;; Location column
(defun blist-get-location (bookmark)
@@ -207,6 +277,9 @@ of the required type."
;;;; List function
+;; REVIEW: Maybe I shall call `delete-trailing-whitespace' at the end
+;; of the function to avoid surprises of the trailing whitespaces?
+
;;;###autoload
(defun blist-list-bookmarks (&rest _args)
"List bookmarks in an ibuffer fashion.
@@ -218,7 +291,9 @@ used as a `revert-buffer-function'."
(bookmark-maybe-load-default-file)
(let ((buffer (get-buffer-create bookmark-bmenu-buffer)))
(with-current-buffer buffer
- (let ((inhibit-read-only t))
+ (let ((inhibit-read-only t)
+ ;; a final newline is important
+ (delete-trailing-lines nil))
(widen)
(delete-region (point-min) (point-max))
(insert
@@ -226,13 +301,15 @@ used as a `revert-buffer-function'."
bookmark-alist
(append
(list ilist-mark-column
+ blist-annotation-column
(blist-name-column))
(cond
(blist-display-location-p (list blist-location-column))))
blist-filter-groups
blist-discard-empty-p
blist-sorter))
- (insert (string #xa)))
+ (insert (string #xa))
+ (delete-trailing-whitespace))
(goto-char (point-min))
(blist-mode))
(display-buffer buffer)
@@ -253,7 +330,7 @@ used as a `revert-buffer-function'."
(let ((map blist-mode-map))
(define-key map (vector ?n) #'blist-next-line)
- (define-key map (vector #x20) #'forward-line)
+ (define-key map (vector #x20) #'next-line)
(define-key map (vector ?p) #'blist-prev-line)
(define-key map (vector ?N) #'blist-next-item)
(define-key map (vector ?P) #'blist-prev-item)
@@ -263,8 +340,19 @@ used as a `revert-buffer-function'."
(define-key map (vector 'backtab) #'blist-prev-group)
(define-key map (vector 'return) #'blist-return)
(define-key map (vector ?o) #'blist-open-other-window)
+ (define-key map (vector ?v) #'blist-select)
+ (define-key map (vector ?r) #'blist-rename)
+ (define-key map (vector ?w) #'blist-locate)
+ (define-key map (vector ?R) #'blist-relocate)
+ (define-key map (vector ?a) #'blist-show-annotation)
+ (define-key map (vector ?A) #'blist-show-all-annotations)
+ (define-key map (vector ?e) #'blist-edit-annotation)
+ (define-key map (vector ?/) #'blist-search)
+ (define-key map (vector ?s) #'blist-save)
(define-key map (vector #x29) #'blist-next-marked)
(define-key map (vector #x28) #'blist-prev-marked)
+ (define-key map (vector ?\M-}) #'blist-next-marked)
+ (define-key map (vector ?\M-{) #'blist-prev-marked)
(define-key map (vector ?m) #'blist-mark)
(define-key map (vector ?d) #'blist-mark-for-deletion)
(define-key map (vector ?\C-d) #'blist-mark-for-deletion-backward)
@@ -283,6 +371,7 @@ used as a `revert-buffer-function'."
(define-key map (vector ?% ?l) #'blist-mark-by-location)
(define-key map (vector ?j) #'blist-jump-to-line)
(define-key map (vector ?J) #'blist-jump-to-group)
+ (define-key map (vector ?\M-j) #'blist-jump-to-group)
(define-key map (vector ?\M-g) #'blist-jump-to-line)
(define-key map (vector ?\M-G) #'blist-jump-to-group))
@@ -329,7 +418,7 @@ range, unless region is active."
(setq end default-end))
((setq start (point))
(setq end (progn
- (ilist-forward-line arg)
+ (ilist-forward-line arg nil t)
(point)))))
(cond
(no-sort-p (cons start end))
@@ -347,7 +436,8 @@ range, unless region is active."
(cond
((ilist-get-index)
(bookmark-jump
- (nth (ilist-get-index) bookmark-alist)))))
+ (nth (ilist-get-index) bookmark-alist)))
+ ((user-error "No bookmark to open on this line"))))
;;;; Open in another window
@@ -359,7 +449,175 @@ range, unless region is active."
(cond ((ilist-get-index)
(bookmark--jump-via
(nth (ilist-get-index) bookmark-alist)
- #'switch-to-buffer-other-window))))
+ #'switch-to-buffer-other-window))
+ ((user-error "No bookmark to open on this line"))))
+
+;;;; blist-select
+
+;;;;; Prepare windows
+
+(defun blist-prepare-select-windows (num)
+ "Create and return NUM windows according to \
+`blist-select-manner'.
+
+NUM should be a positive integer."
+ (cond
+ ((or (not (integerp num))
+ (<= num 0))
+ (error "NUM should be a positive integer, but got %S" num)))
+ (let* ((tabp (memq 'tab blist-select-manner))
+ (verticalp (memq 'vertical blist-select-manner))
+ (leftp (memq 'left blist-select-manner))
+ (upp (memq 'up blist-select-manner))
+ (spiralp (memq 'spiral blist-select-manner))
+ (size (cond
+ ;; spirals split in half
+ (spiralp nil)
+ (verticalp (floor (frame-height) num))
+ ((floor (frame-width) num))))
+ (current-direction verticalp)
+ (orig-window (selected-window))
+ temp-window windows)
+ (cond (tabp (require 'tab-bar) (tab-bar-new-tab)))
+ ;; create a new window so that we are definitely in a normal window
+ (select-window (split-window (frame-root-window) nil 'below))
+ (delete-other-windows)
+ (setq orig-window (selected-window))
+ (setq windows (cons orig-window windows))
+ (setq temp-window orig-window)
+ (setq num (1- num))
+ (while (> num 0)
+ (setq
+ temp-window
+ (split-window temp-window size
+ (cond
+ (current-direction
+ ;; vertical
+ (cond (upp 'above) ('below)))
+ ;; horizontal
+ (leftp 'left)
+ ('right))))
+ (setq windows (cons temp-window windows))
+ ;; change direction for spirals
+ (cond (spiralp
+ (setq current-direction (not current-direction))))
+ (setq num (1- num)))
+ (reverse windows)))
+
+;;;;; select function
+
+;;;###autoload
+(defun blist-select ()
+ "Open all marked bookmarks.
+If there are no marked bookmarks, and if the point is on a group
+header, open all bookmarks of the group.
+
+If there are no marked bookmarks, and if the point is on a
+bookmark line, then open the bookmark on that line.
+
+Otherwise signal an error.
+
+How the bookmarks are opened are controlled by the variable
+`blist-select-manner'."
+ (interactive)
+ (blist-assert-mode)
+ (let* ((marked-items (ilist-map-lines #'ilist-get-index
+ #'ilist-is-marked))
+ (marked-items
+ (cond
+ (marked-items)
+ ((ilist-get-group)
+ (let ((start (point))
+ (end (save-excursion
+ (ilist-forward-group-header 1)
+ (point))))
+ (ilist-map-lines
+ #'ilist-get-index #'ilist-get-index start end)))
+ ;; HACK: if not on a normal line, it will return nil, so
+ ;; that cond will skip this clause
+ ((delq nil (list (ilist-get-index))))
+ ((user-error "No bookmarks to open"))))
+ (marked-items (mapcar
+ (lambda (index) (nth index bookmark-alist))
+ marked-items))
+ (windows (blist-prepare-select-windows
+ (length marked-items)))
+ (orig-window (car windows)))
+ (while (consp windows)
+ (select-window (car windows))
+ (bookmark-jump (car marked-items))
+ (setq marked-items (cdr marked-items))
+ (setq windows (cdr windows)))
+ (select-window orig-window)))
+
+;;;; rename
+
+;;;###autoload
+(defun blist-rename (old new)
+ "Rename the bookmark at point by NEW.
+If the current buffer is in `blist-mode', this also runs
+`revert-buffer' afterwards.
+
+If called with \\[universal-argument], or if there is no bookmark
+at point, prompt for the OLD bookmark to rename."
+ (interactive
+ (list
+ (cond
+ ((or current-prefix-arg
+ (null (ilist-get-index)))
+ (let* ((names (mapcar
+ #'bookmark-name-from-full-record
+ bookmark-alist))
+ (default (cond
+ ((ilist-get-index)
+ (bookmark-name-from-full-record
+ (nth (ilist-get-index)
+ bookmark-alist)))))
+ (prompt (cond
+ (default (format "Rename bookmark (%s): "
+ default))
+ ("Rename bookmark: "))))
+ (completing-read prompt names nil t nil
+ 'blist-rename-history default)))
+ ((bookmark-name-from-full-record
+ (nth (ilist-get-index) bookmark-alist))))
+ (read-string "Rename bookmark to: " nil 'blist-rename-history
+ (cond
+ ((ilist-get-index)
+ (bookmark-name-from-full-record
+ (nth (ilist-get-index) bookmark-alist)))))))
+ ;; error out for invalid input
+ (cond
+ ((or (not (and
+ (stringp old)
+ (not (string= old ""))))
+ (not (and
+ (stringp new)
+ (not (string= new "")))))
+ (error "OLD and NEW should be non-empty strings, \
+but got %S and %S"
+ old new)))
+ (bookmark-set-name old new)
+ (cond ((derived-mode-p 'blist-mode) (revert-buffer)))
+ ;; increase modification count
+ (setq bookmark-alist-modification-count
+ (1+ bookmark-alist-modification-count))
+ ;; save if the user wants to
+ (cond ((bookmark-time-to-save-p) (bookmark-save))))
+
+;;;; relocate
+
+;;;; show annotations
+
+;;;; show all annotations
+
+;;;; edit annotations
+
+;;;; search (limit)
+
+;;;; save
+
+;;;; load
;;;; blist-toggle-group
@@ -400,8 +658,7 @@ range, unless region is active."
"Either open the bookmark or toggle the group."
(interactive)
(cond
- ((ilist-get-group)
- (blist-toggle-group))
+ ((ilist-get-group) (blist-toggle-group))
((ilist-get-index) (blist-open))
((user-error "Nothing to do here"))))
@@ -412,9 +669,11 @@ range, unless region is active."
"Toggle the display of locations of bookmarks."
(interactive)
(let (temp)
- (setq-local blist-display-location-p
- (not blist-display-location-p))
- (setq temp blist-display-location-p)
+ ;; a little C-like hacky style
+ (setq
+ temp
+ (setq-local blist-display-location-p
+ (not blist-display-location-p)))
(blist-list-bookmarks)
;; restore the value of the variable
(setq-local blist-display-location-p temp)))
@@ -425,11 +684,7 @@ range, unless region is active."
"Return the list of all bookmark indices, even the hidden ones."
(append
;; normal lines
- (ilist-map-lines
- (lambda ()
- (bookmark-name-from-full-record
- (nth (ilist-get-index) bookmark-alist)))
- #'ilist-get-index)
+ (ilist-map-lines #'ilist-get-index #'ilist-get-index)
;; hidden lines
(apply
#'append
@@ -443,12 +698,8 @@ range, unless region is active."
temp)
(setq
temp
- (ilist-map-lines
- (lambda ()
- (bookmark-name-from-full-record
- (nth (ilist-get-index) bookmark-alist)))
- #'ilist-get-index
- start end))
+ (ilist-map-lines #'ilist-get-index #'ilist-get-index
+ start end))
(blist-toggle-group)
temp))
(lambda ()
@@ -463,7 +714,12 @@ range, unless region is active."
(list
(completing-read
"Jump to bookmark: "
- (blist-all-bookmarks) nil t)))
+ (mapcar
+ (lambda (index)
+ (bookmark-name-from-full-record
+ (nth index bookmark-alist)))
+ (blist-all-bookmarks))
+ nil t)))
(blist-assert-mode)
(let (res pos)
(save-excursion
- [elpa] branch externals/blist created (now e7d56657eb), ELPA Syncer, 2021/12/28
- [elpa] externals/blist 97a8b93b12 01/31: initial working version, ELPA Syncer, 2021/12/28
- [elpa] externals/blist 896e5568f8 04/31: More features, ELPA Syncer, 2021/12/28
- [elpa] externals/blist a4c0a7626f 07/31: fix defcustom problem, ELPA Syncer, 2021/12/28
- [elpa] externals/blist fa54e09b57 03/31: More features,
ELPA Syncer <=
- [elpa] externals/blist a24f9d6d35 06/31: fix `blist-select', ELPA Syncer, 2021/12/28
- [elpa] externals/blist a0b9bc4eb5 18/31: * blist.el (blist-relocate): Fix a bug caused by a typo., ELPA Syncer, 2021/12/28
- [elpa] externals/blist 950a214456 28/31: New option: blist-use-header-p, ELPA Syncer, 2021/12/28
- [elpa] externals/blist 4a5eb414f7 27/31: Fix errors and byte-compile, ELPA Syncer, 2021/12/28
- [elpa] externals/blist db67745821 13/31: Fix some README issues, ELPA Syncer, 2021/12/28
- [elpa] externals/blist c868a2d8b3 24/31: * blist.el (blist-all-bookmarks): refactor, ELPA Syncer, 2021/12/28
- [elpa] externals/blist eddd17ce4d 14/31: try to fix image, ELPA Syncer, 2021/12/28
- [elpa] externals/blist 4a4d94c09d 20/31: blist.el: QoL refinements, ELPA Syncer, 2021/12/28
- [elpa] externals/blist c2f4bc47d4 25/31: fix previous bugs caused by invisibility, ELPA Syncer, 2021/12/28
- [elpa] externals/blist f1b556af33 12/31: Add README, ELPA Syncer, 2021/12/28