unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Improving describe-mode and discoverability
@ 2016-06-23 18:29 Clément Pit--Claudel
  2016-06-23 18:46 ` Robert Weiner
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Clément Pit--Claudel @ 2016-06-23 18:29 UTC (permalink / raw)
  To: Emacs developers


[-- Attachment #1.1.1: Type: text/plain, Size: 3607 bytes --]

Hey Emacs,

Among the many ways to get information about a package (READMEs, Commentaries, manuals, menu-bar menus, and describe-mode; are there others?), describe-mode is the only universally available one. It always works, but it's not very nice to use: it just gives you a list of function names and the associated bindings.

Recently I added an extra documentation feature to one of my packages, biblio.el.  It's a single function that walks a keymap, and displays for each binding not only the name of the associated function, but also the first line of the documentation of each function. Here's how it looks in haskell-mode:

    Help with ‘haskell-mode’

    ‘C-M-q’ (prog-indent-sexp)
      Indent the expression after point.

    ‘C-c C-c’ (haskell-compile)
      Compile the Haskell program including the current buffer.

    ‘C-c C-s’ (haskell-mode-toggle-scc-at-point)
      If point is in an SCC annotation, kill the annotation.  Otherwise, try to insert a new annotation.

    ‘C-c TAB’ (haskell-process-do-info)
      Print info on the identifier at point.

    ‘C-c C-t’ (haskell-process-do-type)
      Print the type of the given expression.

    ‘C-c C-v’ (haskell-mode-enable-process-minor-mode)
      Tell the user to choose a minor mode for process interaction.

    ‘C-c C-b’, ‘C-c C-z’ (haskell-interactive-switch)
      Switch to the interactive mode for this session.

    ‘C-c C-l’ (haskell-process-load-file)
      Load the current buffer file.

    ‘C-c C-.’ (haskell-mode-format-imports)
      Format the imports by aligning and sorting them.

    ‘<remap> <delete-indentation>’ (haskell-delete-indentation)
      Like `delete-indentation' but ignoring Bird-style ">".

It's not much, but I think it looks much better. I've attached examples of the output for several other modes to this email, as well as the code used to generate this example. Contrast with the default output of C-h m for haskell-mode:

    key             binding
    ---             -------

    C-c             Prefix Command
    C-x             Prefix Command
    ESC             Prefix Command
    <remap>         Prefix Command

    <remap> <delete-indentation>    haskell-delete-indentation

    C-c C-b         haskell-interactive-switch
    C-c C-c         haskell-compile
    C-c TAB         haskell-process-do-info
    C-c C-l         haskell-process-load-file
    C-c C-s         haskell-mode-toggle-scc-at-point
    C-c C-t         haskell-process-do-type
    C-c C-v         haskell-mode-enable-process-minor-mode
    C-c C-z         haskell-interactive-switch
    C-c ESC         Prefix Command
    C-c C-.         haskell-mode-format-imports

    C-M-q           prog-indent-sexp

My implementation is rather brittle (I don't have sufficient knowledge of keymaps), but I think a documentation facility in the line of the one demoed above would be very useful.  Most interactive functions are already documented, so we'd be tapping into a large body of existing docs, making them more accessible.

What do you think? I would be happy to get help in refining this code (and this proposal). For example, we could consider hyperlinking the function names to their sources, or letting users expand the first line of the documentation to show the full docstring. We could also think about ways to cover functions that are not bound to a key by default, but which users may want to bind (e.g. by looking for interactive functions starting with the mode's name).

Cheers,
Clément.

[-- Attachment #1.1.2: shell-script-mode-help --]
[-- Type: text/plain, Size: 2517 bytes --]

Help with ‘sh-mode’

‘C-M-q’ (prog-indent-sexp)
  Indent the expression after point.

‘C-c :’ (sh-set-shell)
  Set this buffer's shell to SHELL (a string).

‘C-c C-z’ (sh-show-shell)
  Pop the shell interaction buffer.

‘C-c C-d’ (sh-cd-here)
  Change directory in the current interaction shell to the current one.

‘C-c C-n’ (sh-send-line-or-region-and-step)
  Send the current line to the inferior shell and step to the next line.

‘C-c C-x’ (executable-interpret)
  Run script with user-specified args, and collect output in a buffer.

‘C-c +’ (sh-add)
  Insert an addition of VAR and prefix DELTA for Bourne (type) shell.

‘C-c C-\’ (sh-backslash-region)
  Insert, align, or delete end-of-line backslashes on the lines in the region.

‘C-c >’ (sh-learn-buffer-indent)
  Learn how to indent the buffer the way it currently is.

‘C-c <’ (sh-learn-line-indent)
  Learn how to indent a line as it currently is indented.

‘C-c =’ (sh-set-indent)
  Set the indentation for the current line.

‘C-c ?’ (sh-show-indent)
  Show the how the current line would be indented.

‘C-c C-c’ (sh-case)
  Insert a case/switch statement.  See `sh-feature'.

‘C-c C-f’ (sh-for)
  Insert a for loop.  See `sh-feature'.

‘C-c TAB’ (sh-if)
  Insert an if statement.  See `sh-feature'.

‘C-c C-l’ (sh-indexed-loop)
  Insert an indexed loop from 1 to n.  See `sh-feature'.

‘C-c C-o’ (sh-while-getopts)
  Insert a while getopts loop.  See `sh-feature'.

‘C-c C-r’ (sh-repeat)
  Insert a repeat loop definition.  See `sh-feature'.

‘C-c C-s’ (sh-select)
  Insert a select statement.  See `sh-feature'.

‘C-c C-t’ (sh-tmp-file)
  Insert code to setup temporary file handling.  See `sh-feature'.

‘C-c C-u’ (sh-until)
  Insert an until loop.  See `sh-feature'.

‘C-c C-w’ (sh-while)
  Insert a while loop.  See `sh-feature'.

‘C-c (’ (sh-function)
  Insert a function definition.  See `sh-feature'.

‘=’ (sh-assignment)
  Remember preceding identifier for future completion and do self-insert.

‘C-M-x’ (sh-execute-region)
  Pass optional header and region to a subshell for noninteractive execution.

‘<remap> <forward-sentence>’ (sh-end-of-command)
  Move point to successive ends of commands.

‘<remap> <backward-sentence>’ (sh-beginning-of-command)
  Move point to successive beginnings of commands.

‘<remap> <delete-backward-char>’ (backward-delete-char-untabify)
  Delete characters backward, changing tabs into spaces.

[-- Attachment #1.1.3: elisp-mode-help --]
[-- Type: text/plain, Size: 411 bytes --]

Help with ‘emacs-lisp-mode’

‘DEL’ (backward-delete-char-untabify)
  Delete characters backward, changing tabs into spaces.

‘C-M-q’ (indent-pp-sexp)
  Indent each line of the list starting just after point, or prettyprint it.

‘C-M-x’ (eval-defun)
  Evaluate the top-level form containing point, or after point.

‘C-M-i’ (completion-at-point)
  Perform completion on the text around point.

[-- Attachment #1.1.4: python-mode-help --]
[-- Type: text/plain, Size: 2363 bytes --]

Help with ‘python-mode’

‘C-M-q’ (prog-indent-sexp)
  Indent the expression after point.

‘<remap> <mark-defun>’ (python-mark-defun)
  Put mark at end of this defun, point at beginning.

‘<remap> <backward-up-list>’ (python-nav-backward-up-list)
  Move backward out of one level of parentheses (or blocks).

‘<remap> <forward-sentence>’ (python-nav-forward-block)
  Move forward to next block of code.

‘<remap> <backward-sentence>’ (python-nav-backward-block)
  Move backward to previous block of code.

‘C-c C-d’ (python-describe-at-point)
  

‘C-c C-f’ (python-eldoc-at-point)
  Get help on SYMBOL using `help'.

‘C-c C-v’ (python-check)
  Check a Python file (default current buffer's file).

‘C-c C-z’ (python-shell-switch-to-shell)
  Switch to inferior Python process buffer.

‘C-c C-l’ (python-shell-send-file)
  Send FILE-NAME to inferior Python PROCESS.

‘C-c C-c’ (python-shell-send-buffer)
  Send the entire buffer to inferior Python process.

‘C-c C-r’ (python-shell-send-region)
  Send the region delimited by START and END to inferior Python process.

‘C-c C-s’ (python-shell-send-string)
  Send STRING to inferior Python PROCESS.

‘C-c C-p’ (run-python)
  Run an inferior Python process.

‘C-c C-t c’ (python-skeleton-class)
  Insert class statement.

‘C-c C-t d’ (python-skeleton-def)
  Insert def statement.

‘C-c C-t f’ (python-skeleton-for)
  Insert for statement.

‘C-c C-t i’ (python-skeleton-if)
  Insert if statement.

‘C-c C-t m’ (python-skeleton-import)
  Insert import statement.

‘C-c C-t t’ (python-skeleton-try)
  Insert try statement.

‘C-c C-t w’ (python-skeleton-while)
  Insert while statement.

‘C-c >’ (python-indent-shift-right)
  Shift lines contained in region START END by COUNT columns to the right.

‘C-c <’ (python-indent-shift-left)
  Shift lines contained in region START END by COUNT columns to the left.

‘C-c C-j’ (imenu)
  Jump to a place in the buffer chosen using a buffer menu or mouse menu.

‘DEL’ (python-indent-dedent-line-backspace)
  De-indent current line.

‘<backtab>’ (python-indent-dedent-line)
  De-indent current line.

‘C-M-i’ (completion-at-point)
  Perform completion on the text around point.

‘C-M-x’ (python-shell-send-defun)
  Send the current defun to inferior Python process.

[-- Attachment #1.1.5: rst-mode-help --]
[-- Type: text/plain, Size: 5004 bytes --]

Help with ‘rst-mode’

‘C-M-i’ (ispell-complete-word)
  Try to complete the word before or at point.

‘C-c 5’ (rst-deprecated-compile-slides-preview)
  Deprecated binding for rst-compile-slides-preview, use \[rst-compile-slides-preview] instead.

‘C-c 4’ (rst-deprecated-compile-pdf-preview)
  Deprecated binding for rst-compile-pdf-preview, use \[rst-compile-pdf-preview] instead.

‘C-c 3’ (rst-deprecated-compile-pseudo-region)
  Deprecated binding for rst-compile-pseudo-region, use \[rst-compile-pseudo-region] instead.

‘C-c 2’ (rst-deprecated-compile-alt-toolset)
  Deprecated binding for rst-compile-alt-toolset, use \[rst-compile-alt-toolset] instead.

‘C-c 1’ (rst-deprecated-compile)
  Deprecated binding for rst-compile, use \[rst-compile] instead.

‘C-c C-c C-c’ (rst-compile)
  Compile command to convert reST document into some output file.

‘C-c C-c C-a’ (rst-compile-alt-toolset)
  Compile command with the alternative tool-set.

‘C-c C-c C-x’ (rst-compile-pseudo-region)
  Show pseudo-XML rendering.

‘C-c C-c C-p’ (rst-compile-pdf-preview)
  Convert the document to a PDF file and launch a preview program.

‘C-c C-c C-s’ (rst-compile-slides-preview)
  Convert the document to an S5 slide presentation and launch a preview program.

‘C-c C-f’ (rst-deprecated-goto-section)
  Deprecated binding for rst-goto-section, use \[rst-goto-section] instead.

‘C-c C-u’ (rst-deprecated-toc-update)
  Deprecated binding for rst-toc-update, use \[rst-toc-update] instead.

‘C-c TAB’ (rst-deprecated-toc-insert)
  Deprecated binding for rst-toc-insert, use \[rst-toc-insert] instead.

‘C-c C-t C-t’ (rst-toc)
  Display a table-of-contents.

‘C-c C-t TAB’ (rst-toc-insert)
  Insert a simple text rendering of the table of contents.

‘C-c C-t C-u’ (rst-toc-update)
  Automatically find the contents section of a document and update.

‘C-c C-t C-j’ (rst-goto-section)
  Go to the section the current line describes.

‘C-c C-w’ (rst-deprecated-straighten-bullets-region)
  Deprecated binding for rst-straighten-bullets-region, use \[rst-straighten-bullets-region] instead.

‘C-c C-v’ (rst-deprecated-convert-bullets-to-enumeration)
  Deprecated binding for rst-convert-bullets-to-enumeration, use \[rst-convert-bullets-to-enumeration] instead.

‘C-c C-e’ (rst-deprecated-enumerate-region)
  Deprecated binding for rst-enumerate-region, use \[rst-enumerate-region] instead.

‘C-c C-b’ (rst-deprecated-bullet-list-region)
  Deprecated binding for rst-bullet-list-region, use \[rst-bullet-list-region] instead.

‘C-c C-l C-b’ (rst-bullet-list-region)
  Add bullets to all the leftmost paragraphs in the given region.

‘C-c C-l C-e’ (rst-enumerate-region)
  Add enumeration to all the leftmost paragraphs in the given region.

‘C-c C-l C-c’ (rst-convert-bullets-to-enumeration)
  Convert the bulleted and enumerated items in the region to enumerated lists.

‘C-c C-l C-s’ (rst-straighten-bullets-region)
  Make all the bulleted list items in the region consistent.

‘C-c C-l TAB’ (rst-insert-list)
  Insert a list item at the current point.

‘C-c C-d’ (rst-deprecated-line-block-region)
  Deprecated binding for rst-line-block-region, use \[rst-line-block-region] instead.

‘C-c C-r C-l’ (rst-line-block-region)
  Toggle line block prefixes for a region.

‘C-c C-r <tab>’ (rst-shift-region)
  Shift region BEG to END by CNT tabs.

‘C-c C-r <t>’, ‘C-c C-l <t>’ (rst-deprecated-shift-region)
  Deprecated binding for rst-shift-region, use \[rst-shift-region] instead.

‘C-c C-p’ (rst-deprecated-forward-section)
  Deprecated binding for rst-forward-section, use \[rst-forward-section] instead.

‘C-c C-n’ (rst-deprecated-backward-section)
  Deprecated binding for rst-backward-section, use \[rst-backward-section] instead.

‘C-c RET’ (rst-deprecated-mark-section)
  Deprecated binding for rst-mark-section, use \[rst-mark-section] instead.

‘C-c C-s’ (rst-deprecated-straighten-adornments)
  Deprecated binding for rst-straighten-adornments, use \[rst-straighten-adornments] instead.

‘C-c C-a <t>’ (rst-deprecated-adjust)
  Deprecated binding for rst-adjust, use \[rst-adjust] instead.

‘C-c C-a C-d’ (rst-display-adornments-hierarchy)
  Display the current file's section title adornments hierarchy.

‘C-c C-a C-s’ (rst-straighten-adornments)
  Redo all the adornments in the current buffer.

‘C-c C-h’, ‘C-c C-a C-h’, ‘C-c C-r C-h’, ‘C-c C-l C-h’, ‘C-c C-t C-h’, ‘C-c C-c C-h’ (describe-prefix-bindings)
  Describe the bindings of the prefix used to reach this command.

‘C-=’, ‘C-c C-=’, ‘C-c C-a C-a’ (rst-adjust)
  Auto-adjust the adornment around point.

‘C-M-e’ (rst-forward-section)
  Skip to the next reStructuredText section title.

‘C-M-a’ (rst-backward-section)
  Like `rst-forward-section', except move back one title.

‘C-M-h’ (rst-mark-section)
  Select COUNT sections around point.
  

[-- Attachment #1.1.6: c-mode-help --]
[-- Type: text/plain, Size: 3092 bytes --]

Help with ‘c-mode’

‘M-q’ (c-fill-paragraph)
  Like \[fill-paragraph] but handles C and C++ style comments.

‘C-M-e’ (c-end-of-defun)
  Move forward to the end of a top level declaration.

‘C-M-a’ (c-beginning-of-defun)
  Move backward to the beginning of a defun.

‘C-M-j’, ‘M-j’ (c-indent-new-comment-line)
  Break line at point and indent, continuing comment or macro if within one.

‘M-e’ (c-end-of-statement)
  Go to the end of the innermost C statement.

‘M-a’ (c-beginning-of-statement)
  Go to the beginning of the innermost C statement.

‘C-M-q’ (c-indent-exp)
  Indent each line in the balanced expression following point syntactically.

‘C-M-h’ (c-mark-function)
  Put mark at end of the current top-level declaration or macro, point at beginning.

‘TAB’ (c-indent-line-or-region)
  Indent active region, current line, or block starting on this line.

‘C-c C-w’ (c-subword-mode)
  Toggle subword movement and editing (Subword mode).

‘C-c .’ (c-set-style)
  Set the current buffer to use the style STYLENAME.

‘C-c C-s’ (c-show-syntactic-information)
  Show syntactic information for current line.

‘C-c C-q’ (c-indent-defun)
  Indent the current top-level declaration or macro syntactically.

‘C-c C-o’ (c-set-offset)
  Change the value of a syntactic element symbol in `c-offsets-alist'.

‘C-c C-l’ (c-toggle-electric-state)
  Toggle the electric indentation feature.

‘C-c C-c’ (comment-region)
  Comment or uncomment each line in the region.

‘C-c C-b’ (c-submit-bug-report)
  Submit via mail a bug report on CC Mode.

‘C-c C-a’ (c-toggle-auto-newline)
  Toggle auto-newline feature.

‘C-c C-\’ (c-backslash-region)
  Insert, align, or delete end-of-line backslashes on the lines in the region.

‘C-c DEL’, ‘C-c C-DEL’, ‘C-c <C-backspace>’ (c-hungry-delete-backwards)
  Delete the preceding character or all preceding whitespace

‘C-c C-d’, ‘C-c <deletechar>’, ‘C-c <C-deletechar>’, ‘C-c <C-delete>’ (c-hungry-delete-forward)
  Delete the following character or all following whitespace

‘C-c C-u’ (c-up-conditional)
  Move back to the containing preprocessor conditional, leaving mark behind.

‘C-c C-p’ (c-backward-conditional)
  Move back across a preprocessor conditional, leaving mark behind.

‘C-c C-n’ (c-forward-conditional)
  Move forward across a preprocessor conditional, leaving mark behind.

‘C-d’ (c-electric-delete-forward)
  Delete the following character or whitespace.

‘DEL’ (c-electric-backspace)
  Delete the preceding character or whitespace.

‘#’ (c-electric-pound)
  Insert a "#".

‘}’, ‘{’ (c-electric-brace)
  Insert a brace.

‘/’ (c-electric-slash)
  Insert a slash character.

‘*’ (c-electric-star)
  Insert a star character.

‘,’, ‘;’ (c-electric-semi&comma)
  Insert a comma or semicolon.

‘:’ (c-electric-colon)
  Insert a colon.

‘)’, ‘(’ (c-electric-paren)
  Insert a parenthesis.

‘C-c C-e’ (c-macro-expand)
  Expand C macros in the region, using the C preprocessor.

[-- Attachment #1.1.7: shell-mode-help --]
[-- Type: text/plain, Size: 3336 bytes --]

Help with ‘shell-mode’

‘M-r’ (comint-history-isearch-backward-regexp)
  Search for a regular expression backward in input history using Isearch.

‘<C-up>’, ‘M-p’ (comint-previous-input)
  Cycle backwards through input history, saving input.

‘<C-down>’, ‘M-n’ (comint-next-input)
  Cycle forwards through input history.

‘C-c .’ (comint-insert-previous-argument)
  Insert the INDEXth argument from the previous Comint command-line at point.

‘C-c C-s’ (comint-write-output)
  Write output from interpreter since last input to FILENAME.

‘C-c C-d’ (comint-send-eof)
  Send an EOF to the current buffer's process.

‘C-c C-p’ (comint-previous-prompt)
  Move to end of Nth previous prompt in the buffer.

‘C-c C-n’ (comint-next-prompt)
  Move to end of Nth next prompt in the buffer.

‘C-c C-l’ (comint-dynamic-list-input-ring)
  Display a list of recent inputs entered into the current buffer.

‘C-c C-e’ (comint-show-maximum-output)
  Put the end of the buffer at the bottom of the window.

‘C-c C-r’, ‘C-M-l’ (comint-show-output)
  Display start of this batch of interpreter output at top of window.

‘C-c C-o’ (comint-delete-output)
  Delete all output from interpreter since last input.

‘C-c RET’ (comint-copy-old-input)
  Insert after prompt old input at point as new input to be edited.

‘C-c C-\’ (comint-quit-subjob)
  Send quit signal to the current subjob.

‘C-c C-z’ (comint-stop-subjob)
  Stop the current subjob.

‘C-c C-c’ (comint-interrupt-subjob)
  Interrupt the current subjob.

‘C-c C-w’ (backward-kill-word)
  Kill characters backward until encountering the beginning of a word.

‘C-c C-u’ (comint-kill-input)
  Kill all text from last stuff output by interpreter to point.

‘C-c C-a’ (comint-bol-or-process-mark)
  Move point to beginning of line (after prompt) or to the process mark.

‘C-c C-x’ (comint-get-next-from-history)
  After fetching a line from input history, this fetches the following line.

‘C-c SPC’ (comint-accumulate)
  Accumulate a line to send as input along with more lines.

‘C-c M-r’ (comint-previous-matching-input-from-input)
  Search backwards through input history for match for current input.

‘C-c M-s’ (comint-next-matching-input-from-input)
  Search forwards through input history for match for current input.

‘C-c M-o’ (comint-clear-buffer)
  Clear the comint buffer.

‘RET’ (comint-send-input)
  Send input to process.

‘C-d’ (comint-delchar-or-maybe-eof)
  Delete ARG characters forward or send an EOF to subprocess.

‘<kp-delete>’, ‘<delete>’ (delete-forward-char)
  Delete the following N characters (previous if N is negative).

‘<mouse-2>’ (comint-insert-input)
  In a Comint buffer, set the current input to the previous input at point.

‘C-c C-b’ (shell-backward-command)
  Move backward across ARG shell command(s).  Does not cross lines.

‘C-c C-f’ (shell-forward-command)
  Move forward across ARG shell command(s).  Does not cross lines.

‘TAB’ (completion-at-point)
  Perform completion on the text around point.

‘M-?’ (comint-dynamic-list-filename-completions)
  Display a list of possible completions for the filename at point.

‘M-RET’ (shell-resync-dirs)
  Resync the buffer's idea of the current directory stack.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.1.8: help-with-major-mode.el --]
[-- Type: text/x-emacs-lisp; name="help-with-major-mode.el", Size: 3510 bytes --]

;;; Help with major mode
;; Extracted from https://github.com/cpitclaudel/biblio.el/blob/master/biblio-core.el#L265
;; Requires: seq, dash

(defsubst hwmm--as-list (x)
  "Make X a list, if it isn't."
  (if (consp x) x (list x)))

(defun hwmm--map-keymap (func map)
  "Call `map-keymap' on FUNC and MAP, and collect the results."
  (let ((out))
    (map-keymap (lambda (&rest args) (push (apply func args) out)) map)
    out))

(defun hwmm--flatten-map (keymap &optional prefix)
  "Flatten KEYMAP, prefixing its keys with PREFIX.
This should really be in Emacs core (in Elisp), instead of being
implemented in C (at least for sparse keymaps).  Don't run this on
non-sparse keymaps."
  (nreverse
   (cond
    ((keymapp keymap)
     (seq-map (lambda (key-value)
                "Add PREFIX to key in KEY-VALUE."
                (cons (append prefix (hwmm--as-list (car key-value)))
                      (cdr key-value)))
              (delq nil
                    (apply
                     #'seq-concatenate
                     'list (hwmm--map-keymap
                            (lambda (k v)
                              "Return a list of bindings in V, prefixed by K."
                              (hwmm--flatten-map v (hwmm--as-list k)))
                            keymap)))))
    ;; This breaks if keymap is a symbol whose function cell is a keymap
    ((symbolp keymap)
     (list (cons prefix keymap))))))

(defun hwmm--group-alist (alist)
  "Return a copy of ALIST whose keys are lists of keys, grouped by value.
That is, if two key map to `eq' values, they are grouped."
  (let ((map (make-hash-table :test 'eq))
        (new-alist nil))
    (pcase-dolist (`(,key . ,value) alist)
      (puthash value (cons key (gethash value map)) map))
    (pcase-dolist (`(,_ . ,value) alist)
      (-when-let* ((keys (gethash value map)))
        (push (cons (nreverse keys) value) new-alist)
        (puthash value nil map)))
    (nreverse new-alist)))

(defun hwmm--quote (str)
  "Quote STR and call `substitute-command-keys' on it."
  (if str (substitute-command-keys (concat "`" str "'")) ""))

(defun hwmm--quote-keys (keys)
  "Quote and concatenate keybindings in KEYS."
  (mapconcat (lambda (keyseq)
               (hwmm--quote (ignore-errors (help-key-description keyseq nil))))
             keys ", "))

(defun hwmm--brief-docs (command)
  "Return first line of documentation of COMMAND."
  (let ((docs (or (ignore-errors (documentation command t)) "")))
    (string-match "\\(.*\\)$" docs)
    (match-string-no-properties 1 docs)))

(defun hwmm--help-with-major-mode-1 (keyseqs-command)
  "Print help on KEYSEQS-COMMAND to standard output."
  ;; (hwmm-with-fontification 'font-lock-function-name-face
  (insert (format "%s (%S)\n"
                  (hwmm--quote-keys (car keyseqs-command))
                  (cdr keyseqs-command)))
  (insert (format "  %s\n\n" (hwmm--brief-docs (cdr keyseqs-command)))))

(defun hwmm--help-with-major-mode ()
  "Display help with current major mode."
  (let ((buf (format "*%S help*" major-mode)))
    (with-help-window buf
      (princ (format "Help with %s\n\n" (hwmm--quote (symbol-name major-mode))))
      (let ((bindings (nreverse
                       (hwmm--group-alist
                        (hwmm--flatten-map
                         (current-local-map))))))
        (with-current-buffer buf
          (seq-do #'hwmm--help-with-major-mode-1 bindings))))
    buf))

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2016-07-06 17:47 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-23 18:29 Improving describe-mode and discoverability Clément Pit--Claudel
2016-06-23 18:46 ` Robert Weiner
2016-06-23 18:52   ` Clément Pit--Claudel
2016-06-23 19:11     ` Robert Weiner
2016-06-23 19:36       ` Clément Pit--Claudel
2016-06-23 20:26 ` Drew Adams
2016-06-23 21:50   ` Clément Pit--Claudel
2016-06-23 22:07     ` Drew Adams
2016-06-23 22:10       ` Dmitry Gutov
2016-06-23 22:27         ` Clément Pit--Claudel
2016-06-23 23:15           ` Drew Adams
2016-06-23 23:39             ` Clément Pit--Claudel
2016-06-24  0:05               ` Drew Adams
2016-06-24  2:59                 ` Clément Pit--Claudel
2016-07-06 17:47 ` John Wiegley

Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).