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: Sat, 17 Sep 2022 14:53:56 +0000 Message-ID: <87y1ui2gsb.fsf@posteo.net> References: <87v8pn4968.fsf@posteo.net> <8735cr3ubp.fsf@posteo.net> 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="33329"; mail-complaints-to="usenet@ciao.gmane.io" To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sat Sep 17 16:56:03 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 1oZZEg-0008Qb-I0 for ged-emacs-devel@m.gmane-mx.org; Sat, 17 Sep 2022 16:56:02 +0200 Original-Received: from localhost ([::1]:56240 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oZZEf-00045z-GD for ged-emacs-devel@m.gmane-mx.org; Sat, 17 Sep 2022 10:56:01 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:48370) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oZZCm-0002j6-Sz for emacs-devel@gnu.org; Sat, 17 Sep 2022 10:54:08 -0400 Original-Received: from mout01.posteo.de ([185.67.36.65]:33067) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oZZCk-0005fu-CT for emacs-devel@gnu.org; Sat, 17 Sep 2022 10:54:04 -0400 Original-Received: from submission (posteo.de [185.67.36.169]) by mout01.posteo.de (Postfix) with ESMTPS id 64913240027 for ; Sat, 17 Sep 2022 16:54:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1663426440; bh=K2VDnHd70vGa4bS/18P+gJW+9kxXxWDvcI8BNKiX/mE=; h=From:To:Subject:Autocrypt:Date:From; b=FFWsUKNb48DguENHVxkUtF89qA+vKLQbpfK+5pLudf0o5Zt+xkKaQZ5sWXT1BtTfl Qoov+lZZ+QlFaxk4m2aAnqCirKaccf1dUGKyqadAip+wiB/BTLCd+4+o8AkWLlMXs9 H0SMwU+tCBYXh1YPr15DKli9XSSWJbkDRmE6YdvRh2mXfmwasTVimYHO0P4RQFvKXt 5DyKg25lcfvP5LEnPKHRCJxEWORIWkg7MfBK7x9SDY+tFTV0tnxmayn3ghAe1wKnaQ /BM3oDxqkIkAghcsnSAVNjngUXohpFC+zRrot4GSALZPjAwdElcpiyU9nHS8H2z0qV rXCJAUipOICcQ== Original-Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4MVDTz5XCjz9rxG for ; Sat, 17 Sep 2022 16:53:57 +0200 (CEST) In-Reply-To: <8735cr3ubp.fsf@posteo.net> (Philip Kaludercic's message of "Fri, 16 Sep 2022 21:03:54 +0000") 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.65; envelope-from=philipk@posteo.net; helo=mout01.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, 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:295529 Archived-At: --=-=-= Content-Type: text/plain Philip Kaludercic 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: >> >> FILE BUFFER WINDOW MARK/KILL MISC >> C-x C-c exit C-x C-k close C-0 only other C-space mark C-_ undo >> C-x C-f find C-x k other C-1 only this C-w wipe C-s search >> C-x C-s save C-x C-b list C-2 split two C-k close C-r r-search >> C-x s all C-x b switch C-x ^ enlarge C-y yank M-% replace >> C-x i insert C-x g goto ln C-x o other win C-x C-x swap M-q reformat >> ______________________________________________________________________________ >> C-h q toggle quick help | C-h t show tutorial | C-h b show key bindings >> >> I notice that in GNU Emacs C-h q is bound to `help-quit', which does >> nothing if you are not in the help command loop. Would having a >> "quick-help" menu along these lines for common operations make sense for >> GNU Emacs as well? >> >> [0] https://github.com/troglobit/mg > > Here is a quick sketch of how this could look like: I've further refined the sketch and how have a patch: --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-Add-a-quick-help-menu.patch >From d0899b748b0047e1d1c773b06076faeba2535fee 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. (help-quit-or-quick): Add auxiliary command. --- lisp/help.el | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) diff --git a/lisp/help.el b/lisp/help.el index 92b87cf799..089db8c2dd 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,118 @@ 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))) + (let* ((bind (where-is-internal (car ent) nil t)) + (key (if bind + (propertize + (key-description bind) + 'face 'help-key-binding) + (propertize "N.B." 'face 'error)))) + (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))) + (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].")))) + (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 --=-=-= Content-Type: text/plain Next to the above sections this patch also includes a few commands for project management. Perhaps there are a few more ideas on what could be added? --=-=-=--