all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: jpkotta <jpkotta@gmail.com>
To: help-gnu-emacs@gnu.org
Subject: Re: Getting a menu in the minibuffer
Date: Fri, 25 Dec 2009 00:00:32 -0800 (PST)	[thread overview]
Message-ID: <40d89bee-5e79-4da3-9af8-04bfba7ba8e3@n38g2000yqf.googlegroups.com> (raw)
In-Reply-To: 87oclo7us9.fsf@Traian.DecebalComp

On Dec 24, 12:25 am, Cecil Westerhof <Ce...@decebal.nl> wrote:
> jpkotta <jpko...@gmail.com> writes:
> >> There are several commands that give a little menu in the menu buffer.
> >> For example tmm-menubar. I would like something like that also. I am
> >> busy with extending GNUS. I think the best way to use those extra
> >> functions -and maybe some standard ones- would be by using a menu. Is
> >> there a place where building something like that is explained, or do I
> >> need to consult the sources?
>
> > A very simple echo area menu is
> >http://www.emacswiki.org/emacs/OneTwoThreeMenu.
>
> Thanks.
>
> > I have some modifications to it that: automatically format the items
> > into columns; allow for continually re-displaying the menu until C-g
> > is pressed; and allow for any keystroke to select an item.  I use my
> > modified version but I wanted to work on it a bit more before
> > submitting a patch.  If you're interested I can send it.
>
> I sure am.
>
> --
> Cecil Westerhof
> Senior Software Engineer
> LinkedIn:http://www.linkedin.com/in/cecilwesterhof

I figured I might as well post it here, sorry if it's too big.

Example:

(123-menu-defmenu-repeated
 nav-menu
 ("i" "[i] up line" 'previous-line)
 ("j" "[j] left char" 'backward-char)
 ("k" "[k] down line" 'next-line)
 ("l" "[l] right char" 'forward-char)
 ("C-i" "[C-i] up para" 'backward-paragraph)
 ("C-j" "[C-j] left word" 'c-backward-subword)
 ("C-k" "[C-k] down para" 'forward-paragraph)
 ("C-l" "[C-l] right word" 'c-forward-subword)
 ("u" "[u] scroll left" (lambda () (interactive)
                            (force-scroll-left -8)))
 ("o" "[o] scroll right" (lambda () (interactive)
                           (force-scroll-left 8)))
 ("C-u" "[C-u] scroll up"  'cua-scroll-up)
 ("C-o" "[C-o] scroll down" 'cua-scroll-down)
 )

Modified 123-menu.el file:

;;; 123-menu.el --- Simple menuing system, reminiscent of Lotus 123 in
DOS

;; Copyright (C) 2006  Free Software Foundation, Inc.

;; Author: Marc Abramowitz <http://marc-abramowitz.com>
;; Modified by Jonathan Kotta <jpkotta@gmail.com>
;; Keywords: convenience

;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published
by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;;; Commentary:

;; Even though I've been using Emacs for years, I still have trouble
;; remembering a lot of the key combinations for commands that I don't
;; use all the time (e.g.: killing and yanking rectangles, bookmarks,
;; etc.). I think Lotus 123 for DOS had a remarkably cool user
;; interface in that the menus let you explore around and find things
;; if you were a newbie, but once you knew the key sequences, you
;; could become very fast with it. This is my attempt at doing
;; something like the Lotus 123 menu system for Emacs.

;;; Code:

;; Common Lisp functions
(eval-when-compile (require 'cl))

(defmacro ilam (&rest body)
  `(lambda () (interactive) ,@body))

(defmacro ilamq (&rest body)
  `'(lambda () (interactive) ,@body))

(defvar 123-menu-stack '())

(defmacro 123-menu-make-menu-item (menu key caption &rest rest)
  `(setf ,menu
         (append ,menu
                 (list (list
                        :key       ,key
                        :caption   ,caption
                        :func      ,@rest)))))

(defmacro 123-menu-defmenu (name &rest rest)
  `(progn
     (defconst ,name
       (let ((menu))
         ;; (message (format "%s has %d entries" ',name (length
',rest)))
         (dolist (item ',rest)
           (123-menu-make-menu-item menu (first item) (second item)
(eval (third item))))
         ;; (message (format "menu = %s" menu))
         menu))
     (fset (intern (concat "123-menu-display-menu-" (symbol-name
',name)))
           (ilamq (123-menu-display-menu ,name)))
     )
  )

(defmacro 123-menu-defmenu-repeated (name &rest rest)
  `(progn
     (defconst ,name
       (let ((menu))
         ;; (message (format "%s has %d entries" ',name (length
',rest)))
         (dolist (item ',rest)
           (123-menu-make-menu-item menu (first item) (second item)
(eval (third item))))
         ;; (message (format "menu = %s" menu))
         menu))
     (fset (intern (concat "123-menu-display-menu-" (symbol-name
',name)))
           (ilamq (123-menu-display-menu ,name t)))
     )
  )

(defun format-width (str width)
  (format (concat "%-" (format "%d" width) "s") str))

(defun 123-menu-print-menu (menu)
  (let ((col-width 0)
        (num-cols  0)
        (captions  ())
        (msg       ""))
    (setq captions (mapcar
                    (lambda (x) (getf x :caption))
                    menu))
    (setq col-width (1+ (reduce 'max (mapcar 'length captions))))
    (setq num-cols (/ (frame-width) col-width))
    (setq captions (mapcar
                    (lambda (x) (format-width x col-width))
                    captions))
    (dotimes (i (length captions))
      (if (and (not (eq i 0))
               (eq 0 (mod i num-cols)))
          (setq msg (concat msg "\n")))
      (setq msg (concat msg (elt captions i))))
    (message msg)
    ))

(defun 123-menu-display-menu (menu &optional repeated)
  (interactive)
  (let ((map      (make-sparse-keymap))
        (continue t)
        (c        ""))
    (dolist (item menu)
      (define-key map (eval `(kbd ,(getf item :key))) (getf
item :func)))
    ;; (message (format "caption = %s ; func = %s" (getf
item :caption) (getf item :func))))
    (define-key map "~" (ilamq (123-menu-display-menu (elt 123-menu-
stack 1))))
    (setf 123-menu-stack (push menu 123-menu-stack))
    (while continue
      (123-menu-print-menu menu)
      (setq c (read-key-sequence nil))
      (setq c (lookup-key map c))
      (cond
       ((eq c 'Helper-help-options)
        (Helper-help-options))
       ((commandp c)
        (condition-case nil
            (call-interactively c)
          (error nil))
        (unless repeated
          (setq continue nil)))
       (t
        (ding)
        (setq continue nil)))))
  (pop 123-menu-stack))

(provide '123-menu)
;;; 123-menu.el ends here


  reply	other threads:[~2009-12-25  8:00 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-22 14:18 Getting a menu in the minibuffer Cecil Westerhof
2009-12-23 23:34 ` jpkotta
2009-12-24  6:25   ` Cecil Westerhof
2009-12-25  8:00     ` jpkotta [this message]
2009-12-28  9:45       ` Xavier Maillard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=40d89bee-5e79-4da3-9af8-04bfba7ba8e3@n38g2000yqf.googlegroups.com \
    --to=jpkotta@gmail.com \
    --cc=help-gnu-emacs@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.