From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Philip Kaludercic Newsgroups: gmane.emacs.devel Subject: Re: Adding a "quick-help" menu Date: Sun, 18 Sep 2022 10:53:58 +0000 Message-ID: <878rmhdkc9.fsf@posteo.net> References: <87v8pn4968.fsf@posteo.net> <87h7156lg5.fsf@gnus.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="7328"; mail-complaints-to="usenet@ciao.gmane.io" Cc: emacs-devel@gnu.org To: Lars Ingebrigtsen Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sun Sep 18 12:55:19 2022 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oZrxH-0001lO-Ey for ged-emacs-devel@m.gmane-mx.org; Sun, 18 Sep 2022 12:55:19 +0200 Original-Received: from localhost ([::1]:55406 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oZrxG-0006E8-J7 for ged-emacs-devel@m.gmane-mx.org; Sun, 18 Sep 2022 06:55:18 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:38740) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oZrw4-0004rx-HW for emacs-devel@gnu.org; Sun, 18 Sep 2022 06:54:04 -0400 Original-Received: from mout02.posteo.de ([185.67.36.66]:41117) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oZrw2-0007ZP-9G for emacs-devel@gnu.org; Sun, 18 Sep 2022 06:54:04 -0400 Original-Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id 08A72240104 for ; Sun, 18 Sep 2022 12:53:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1663498440; bh=Nl93tbdomF2TbdFCrL/8dr0CuQOv5U5YG9pGnrNn76o=; h=From:To:Cc:Subject:Autocrypt:Date:From; b=Tdi0XfqEzVw7XmdUHhovF/STqZQ4UHJ0XTpsPCptbgzx4kQbLqzNMiAXgrjIBptri evU5iRZPmizC/7ibb2HfNyYx/4pyhlt0E0Za9AFXi/ibqzO4mc+vYWfmah0qtx9HC0 O9XGDKDAi/ZZbuTdfpuDz3cpoHl+AMn1rdlkUISUPyiHyaXMfm4uljqn+nBVyWDQqL uCEoPGWPzGB4cGIi8pkAyqKQPe95mBy/D+K2GIATvkQvU25RJ42HFR2z/Th1/3OhZx 2VWWM1dcN0ihfC/wd4cl+Rv6MBDPrln1tQJ1ViraJP299VLJFS28q8MYPuKdpUM/xG /OJQcMbojCozQ== Original-Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4MVl6b25rxz6tpc; Sun, 18 Sep 2022 12:53:59 +0200 (CEST) In-Reply-To: <87h7156lg5.fsf@gnus.org> (Lars Ingebrigtsen's message of "Sun, 18 Sep 2022 12:11:54 +0200") Autocrypt: addr=philipk@posteo.net; prefer-encrypt=nopreference; keydata= mDMEYHHqUhYJKwYBBAHaRw8BAQdAp3GdmYJ6tm5McweY6dEvIYIiry+Oz9rU4MH6NHWK0Ee0QlBo aWxpcCBLYWx1ZGVyY2ljIChnZW5lcmF0ZWQgYnkgYXV0b2NyeXB0LmVsKSA8cGhpbGlwa0Bwb3N0 ZW8ubmV0PoiQBBMWCAA4FiEEDM2H44ZoPt9Ms0eHtVrAHPRh1FwFAmBx6lICGwMFCwkIBwIGFQoJ CAsCBBYCAwECHgECF4AACgkQtVrAHPRh1FyTkgEAjlbGPxFchvMbxzAES3r8QLuZgCxeAXunM9gh io0ePtUBALVhh9G6wIoZhl0gUCbQpoN/UJHI08Gm1qDob5zDxnIHuDgEYHHqUhIKKwYBBAGXVQEF AQEHQNcRB+MUimTMqoxxMMUERpOR+Q4b1KgncDZkhrO2ql1tAwEIB4h4BBgWCAAgFiEEDM2H44Zo Pt9Ms0eHtVrAHPRh1FwFAmBx6lICGwwACgkQtVrAHPRh1Fw1JwD/Qo7kvtib8jy7puyWrSv0MeTS g8qIxgoRWJE/KKdkCLEA/jb9b9/g8nnX+UcwHf/4VfKsjExlnND3FrBviXUW6NcB Received-SPF: pass client-ip=185.67.36.66; envelope-from=philipk@posteo.net; helo=mout02.posteo.de X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:295572 Archived-At: --=-=-= Content-Type: text/plain Lars Ingebrigtsen writes: > Philip Kaludercic writes: > >> There is a fork of mg (MicroEmacs)[0] that binds C-h q to a command that >> pops up a buffer with these contents: > > I think having a "cheat sheet" like this would be useful. Calling it a "cheat sheet" sounds like a good idea. I've added `cheat-sheet' as an alias: --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-Add-a-quick-help-menu.patch >From ddd1a02d3bc23c448b8d5869c8b9fe38a2b322ef Mon Sep 17 00:00:00 2001 From: Philip Kaludercic Date: Sat, 17 Sep 2022 16:52:01 +0200 Subject: [PATCH] Add a quick-help menu * lisp/help.el (help-map): Bind 'help-quit-or-quick' instead of 'help-quit'. (help-quick-sections): Add variable. (help-quick): Add main command. (cheat-sheet): Add alias for 'help-quick'. (help-quit-or-quick): Add auxiliary command. --- lisp/help.el | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) diff --git a/lisp/help.el b/lisp/help.el index 92b87cf799..126eddef30 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -112,7 +112,7 @@ help-map (define-key map "v" 'describe-variable) (define-key map "w" 'where-is) (define-key map "x" 'describe-command) - (define-key map "q" 'help-quit) + (define-key map "q" 'help-quit-or-quick) map) "Keymap for characters following the Help key.") @@ -125,11 +125,122 @@ global-map (defvar help-button-cache nil) + +(defvar help-quick-sections + '(("FILE" + (save-buffers-kill-terminal . "exit") + (find-file . "find") + (write-file . "write") + (save-buffer . "save") + (save-some-buffers . "all")) + ("BUFFER" + (kill-buffer . "kill") + (list-buffers . "list") + (switch-to-buffer . "switch") + (goto-line . "goto line") + (read-only-mode . "read only")) + ("WINDOW" + (delete-window . "only other") + (delete-other-windows . "only this") + (split-window-below . "split vert.") + (split-window-right . "split horiz.") + (other-window . "other")) + ("MARK/KILL" + (set-mark-command . "mark") + (kill-region . "wipe") + (kill-line . "kill") + (yank . "yank") + (exchange-point-and-mark . "swap")) + ("PROJECT" + (project-switch-project . "switch") + (project-find-file . "find file") + (project-find-regexp . "search") + (project-query-replace-regexp . "replace") + (project-compile . "compile")) + ("MISC" + (undo . "undo") + (isearch-forward . "search") + (isearch-backward . "rev-search") + (query-replace . "replace") + (fill-paragraph . "reformat")))) + +;; Inspired by a mg fork (https://github.com/troglobit/mg) +(defun help-quick () + "Display a quick-help buffer." + (interactive) + (with-current-buffer (get-buffer-create "*Quick Help*") + (let ((inhibit-read-only t) (padding 2) blocks) + + ;; Go through every section and prepare a text-rectangle to be + ;; inserted later. + (dolist (section help-quick-sections) + (let ((max-key-len 0) (max-cmd-len 0) keys) + (dolist (ent (reverse (cdr section))) + (catch 'skip + (let* ((bind (where-is-internal (car ent) nil t)) + (key (if bind + (propertize + (key-description bind) + 'face 'help-key-binding) + (throw 'skip nil)))) + (setq max-cmd-len (max (length (cdr ent)) max-cmd-len) + max-key-len (max (length key) max-key-len)) + (push (cons key (cdr ent)) keys)))) + (when keys + (let ((fmt (format "%%-%ds %%-%ds%s" max-key-len max-cmd-len + (make-string padding ?\s))) + (width (+ max-key-len 1 max-cmd-len padding))) + (push `(,width + ,(propertize + (concat + (car section) + (make-string (- width (length (car section))) ?\s)) + 'face 'bold) + ,@(mapcar (lambda (ent) + (format fmt (car ent) (cdr ent))) + keys)) + blocks))))) + + ;; Insert each rectangle in order until they don't fit into the + ;; frame any more, in which case the next sections are inserted + ;; in a new "line". + (erase-buffer) + (dolist (block (nreverse blocks)) + (when (> (+ (car block) (current-column)) (frame-width)) + (goto-char (point-max)) + (newline 2)) + (save-excursion + (insert-rectangle (cdr block))) + (end-of-line)) + (delete-trailing-whitespace)) + + ;; Display the buffer at the bottom of the page and shrink it + ;; immediately. + (help-mode) + (with-selected-window (display-buffer-at-bottom (current-buffer) '()) + (fit-window-to-buffer)) + (message + (substitute-command-keys "Toggle the quick help buffer using \\[help-quit-or-quick].")))) + +(defalias 'cheat-sheet #'help-quick) + (defun help-quit () "Just exit from the Help command's command loop." (interactive) nil) +(defun help-quit-or-quick () + "Call `help-quit' or `help-quick' depending on the context." + (interactive) + (cond + (help-buffer-under-preparation + ;; FIXME: There should be a better way to detect if we are in the + ;; help command loop. + (help-quit)) + ((and-let* ((window (get-buffer-window "*Quick Help*"))) + (quit-window t window))) + ((help-quick)))) + (defvar help-return-method nil "What to do to \"exit\" the help buffer. This is a list -- 2.37.3 --=-=-=--