[RFC PATCH 1/3] emacs: selection-menu.el

Tomi Ollila tomi.ollila at iki.fi
Thu Feb 23 07:10:15 PST 2012


RFC/Idea for "improving" some selections made (in notmuch or elsewhere)
In the hope that this will be useful, and to get some improvement advice.

I've found it somewhat difficult to use completing-read (i also tried ido-)
to complete email addresses for mail recipients (not only due to the
large selection of choises provided by nottoomuch-addresses.sh ;)
and have tried to find alternatives.

The buffer selection systems (electric-buffer-list, bs-show, etc) have been
pretty useful but I haven't found anything general.

After some 3 iterations I've come up with something like those but for
arbitraty strings and so-far named that tool 'selection-menu'

This works by popping up buffer with all the choices shown in separate
lines. arrow keys (and c-p/c-n) can be used to choose string and
RET/SPC to select that. Any other key will abort the selection (ESC
mentioned spesifically as it never "unreads" any events).

If requested user not choosing anything but pressing some key that
key is "unread" so that the parent buffer will get it. I did that
as in first tests I wanted to continue writing If I did not choose
anything... More tests will show If really didn't want to loose that
event).
---
 emacs/selection-menu.el |   68 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 68 insertions(+), 0 deletions(-)
 create mode 100644 emacs/selection-menu.el

diff --git a/emacs/selection-menu.el b/emacs/selection-menu.el
new file mode 100644
index 0000000..b65cef3
--- /dev/null
+++ b/emacs/selection-menu.el
@@ -0,0 +1,68 @@
+;;; selection-menu.el --- "generic" menu to choose one string.
+;;;
+;;; Author: Tomi Ollila -- too ät iki piste fi
+
+;;; License: GPLv2+
+
+(defun selection-menu (ident items &optional unread)
+  "Pops up a buffer listing lines given ITEMS one per line.
+Use arrow keys (and C-p/C-n) to select and SPC/RET to select.
+Return to parent buffer when any other key is pressed.
+In this case if optional UNREAD is non-nil return the
+read key back to input queue for parent to consume."
+  (if (eq (length items) 0) nil
+    (let ((helpmsg "Type ESC to abort, Space or Enter to select.")
+	  (saved-point (point))
+	  select buffer first last overlay pevent)
+      (save-window-excursion
+	(setq buffer (get-buffer-create " *Selection Menu*"))
+	(set-buffer buffer)
+	(setq buffer-read-only nil)
+	(kill-all-local-variables)
+	(erase-buffer)
+	(dolist (item items) (insert " " item "\n"))
+	(forward-line -1)
+	(setq last (point))
+	(goto-char (point-min))
+	(setq first (1+ (point)))
+	(pop-to-buffer buffer)
+	(setq mode-name "Selection Menu"
+	      mode-line-buffer-identification (concat "*" ident "*")
+	      buffer-read-only t
+	      overlay (make-overlay (point) (line-end-position)))
+	(overlay-put overlay 'face 'highlight)
+	(while
+	    (let ((event (read-key helpmsg)))
+	      (cond ((or (eq event 'up) (eq event 16))
+		     (when (> (point) first)
+		       (forward-line -1)
+		       (move-overlay overlay (point) (line-end-position)))
+		     t)
+		    ((or (eq event 'down) (eq event 14))
+		     (when (< (point) last)
+		       (forward-line)
+		       (move-overlay overlay (point) (line-end-position)))
+		     t)
+		    ((or (eq event 32) (eq event 13) (eq event 'return))
+		     (setq select
+			   (buffer-substring (1+ (point))
+					     (line-end-position)))
+		     nil)
+		    ((eq event 'escape)
+		     nil)
+		    (t (setq pevent event)
+		       nil)
+		    ))))
+      (goto-char saved-point)
+      (kill-buffer buffer)
+      (if (and unread pevent)
+	  (push pevent unread-command-events))
+      (message "")
+      select)))
+
+;;(selection-menu "foo" (list))
+;;(selection-menu "foo" (list "a"))
+;;(selection-menu "Send mail to:" (list "a" "b" "c" "d" "faaarao") t)
+;; test by entering c-x c-e at the end of previous lines
+
+(provide 'selection-menu)
-- 
1.7.8.2



More information about the notmuch mailing list