mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-06-14 12:31:25 +00:00
Split up shortdoc functions and groups, fix their format
Move shortdoc group definitions from shortdoc.el to a separate file shortdoc-doc.el. Document shortdoc group format in a future-proof way and guide package authors on how to use shortdoc groups across past Emacs versions. * lisp/emacs-lisp/shortdoc-doc.el: New file. * lisp/emacs-lisp/shortdoc.el: Document shortdoc group format in a future-proof way. Require 'shortdoc-doc'. (shortdoc--keyword-plist-p): New function. (shortdoc--check): Update to check the documented shortdoc group format. (shortdoc--groups, define-short-documentation-group): Pull out of autoloaded 'progn'. (define-short-documentation-group): Report errors in terms of byte compiler warnings. (alist, map, string, file-name, file, hash-table, list, symbol) (comparison, vector, regexp, sequence, buffer, overlay, process, number) (text-properties, keymaps): Move group to shortdoc-doc.el. (shortdoc): Move alias to after function. (shortdoc-add-function): Add argument checks. * doc/lispref/tips.texi (Documentation Group Tips): New section. * doc/lispref/elisp.texi (Top): * doc/lispref/tips.texi (Tips): Add references to it. * doc/lispref/help.texi (Documentation Groups): Ditto, and add some concept index entries. (bug#80297)
This commit is contained in:
parent
c29971b6fa
commit
82882db8ed
5 changed files with 229 additions and 1959 deletions
|
|
@ -1661,6 +1661,7 @@ Tips and Conventions
|
|||
* Compilation Tips:: Making compiled code run fast.
|
||||
* Warning Tips:: Turning off compiler warnings.
|
||||
* Documentation Tips:: Writing readable documentation strings.
|
||||
* Documentation Group Tips:: Writing useful documentation groups.
|
||||
* Comment Tips:: Conventions for writing comments.
|
||||
* Library Headers:: Standard headers for library packages.
|
||||
|
||||
|
|
|
|||
|
|
@ -828,14 +828,16 @@ if the user types the help character again.
|
|||
@cindex documentation groups
|
||||
@cindex groups of functions
|
||||
@cindex function groups
|
||||
@cindex shortdoc groups
|
||||
|
||||
Emacs can list functions based on various groupings. For instance,
|
||||
@code{string-trim} and @code{mapconcat} are ``string'' functions, so
|
||||
@kbd{M-x shortdoc RET string RET} will give an overview
|
||||
of functions that operate on strings.
|
||||
@kbd{M-x shortdoc RET string RET} will give an overview of these and
|
||||
other functions that operate on strings.
|
||||
|
||||
The documentation groups are created with the
|
||||
@code{define-short-documentation-group} macro.
|
||||
@code{define-short-documentation-group} macro. @xref{Documentation
|
||||
Group Tips}, for how to write good documentation groups.
|
||||
|
||||
@defmac define-short-documentation-group group &rest functions
|
||||
Define @var{group} as a group of functions, and provide short
|
||||
|
|
@ -846,6 +848,7 @@ summaries of using those functions. The optional argument
|
|||
(@var{func} [@var{keyword} @var{val}]@dots{})
|
||||
@end lisp
|
||||
|
||||
@cindex documentation group keywords
|
||||
The following keywords are recognized:
|
||||
|
||||
@table @code
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ in batch mode, e.g., with a command run by @kbd{@w{M-x compile
|
|||
* Compilation Tips:: Making compiled code run fast.
|
||||
* Warning Tips:: Turning off compiler warnings.
|
||||
* Documentation Tips:: Writing readable documentation strings.
|
||||
* Documentation Group Tips:: Writing useful documentation groups.
|
||||
* Comment Tips:: Conventions for writing comments.
|
||||
* Library Headers:: Standard headers for library packages.
|
||||
@end menu
|
||||
|
|
@ -934,6 +935,89 @@ If you do not anticipate anyone editing your code with older Emacs
|
|||
versions, there is no need for this work-around.
|
||||
@end itemize
|
||||
|
||||
@node Documentation Group Tips
|
||||
@section Tips for Documentation Groups
|
||||
@cindex documentation groups, tips
|
||||
@cindex tips for documentation groups
|
||||
|
||||
@cindex documentation groups, compatibility
|
||||
Documentation groups, available since Emacs 28, are useful to document
|
||||
functions of Lisp packages based on various groupings
|
||||
(@pxref{Documentation Groups}). This section gives some tips on how you
|
||||
can define documentation groups in your Lisp package in a way such that
|
||||
users of different Emacs versions can equally well use these groups.
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
To define documentation groups for your own Lisp package across
|
||||
different Emacs versions, you can use a boilerplate template along the
|
||||
lines of the following to make your package compile and load without
|
||||
errors:
|
||||
|
||||
@smallexample
|
||||
@group
|
||||
;;; well-doc.el --- a well-documented package -*- lexical-binding: t; -*-
|
||||
|
||||
@dots{} package header and contents @dots{}
|
||||
@end group
|
||||
|
||||
@group
|
||||
;; Explicitly require shortdoc for Emacs 28, which does not have an
|
||||
;; autoload for macro `define-short-documentation-group'. And for
|
||||
;; Emacs 30, so that we can redefine `shortdoc--check' later.
|
||||
(require 'shortdoc nil t)
|
||||
|
||||
(eval-when-compile
|
||||
|
||||
;; Default macro `define-short-documentation-group' for Emacs 27
|
||||
;; and older, which do not have the shortdoc feature at all.
|
||||
(unless (fboundp 'define-short-documentation-group)
|
||||
(defmacro define-short-documentation-group (&rest _)))
|
||||
|
||||
;; Disable too rigid shortdoc checks for Emacs 30, which let it
|
||||
;; error out on newer shortdoc keywords.
|
||||
(when (eq emacs-major-version 30)
|
||||
(fset 'shortdoc--check #'ignore)))
|
||||
@end group
|
||||
|
||||
@group
|
||||
(define-short-documentation-group well-doc
|
||||
@dots{})
|
||||
|
||||
;;; well-doc.el ends here
|
||||
@end group
|
||||
@end smallexample
|
||||
|
||||
@findex define-short-documentation-group
|
||||
If you do not intend to support some of the Emacs versions mentioned
|
||||
above, you can safely omit the corresponding forms from the template.
|
||||
If you intend to support only Emacs 31 and newer, you do not need any
|
||||
of the above and can just use @code{define-short-documentation-group}.
|
||||
|
||||
@item
|
||||
@cindex documentation group keywords, compatibility
|
||||
Newer Emacs versions might introduce newer documentation group features
|
||||
and keywords. However, these features or keywords will never break the
|
||||
display of a documentation group in older Emacs versions. Suppose you
|
||||
use a hypothetical group keyword @code{:super-pretty-print}, available
|
||||
in some future Emacs version, like this in your Lisp package
|
||||
@file{well-doc.el}:
|
||||
|
||||
@smallexample
|
||||
@group
|
||||
(define-short-documentation-group well-doc
|
||||
(well-doc-foo
|
||||
:eval (well-doc-foo)
|
||||
:super-pretty-print t))
|
||||
@end group
|
||||
@end smallexample
|
||||
|
||||
That future Emacs version will then supposedly super-pretty-print the
|
||||
example for function @code{well-doc-foo}. Older Emacs versions will
|
||||
silently ignore keyword @code{:super-pretty-print} and show the example
|
||||
according to their regular display rules.
|
||||
@end itemize
|
||||
|
||||
@node Comment Tips
|
||||
@section Tips on Writing Comments
|
||||
@cindex comments, Lisp convention for
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;;; shortdoc.el --- Short function summaries -*- lexical-binding: t -*-
|
||||
;;; shortdoc-doc.el --- Builtin shortdoc groups -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2020-2026 Free Software Foundation, Inc.
|
||||
|
||||
|
|
@ -22,119 +22,16 @@
|
|||
|
||||
;;; Commentary:
|
||||
|
||||
;; This package lists functions based on various groupings.
|
||||
;; This file defines builtin Emacs shortdoc groups.
|
||||
;;
|
||||
;; For instance, `string-trim' and `mapconcat' are `string' functions,
|
||||
;; so `M-x shortdoc RET string RET' will give an overview of functions
|
||||
;; that operate on strings.
|
||||
;;
|
||||
;; The documentation groups are created with the
|
||||
;; `define-short-documentation-group' macro.
|
||||
;; If a shortdoc group describes builtin functions, functions from
|
||||
;; subr.el or simple.el or otherwise preloaded files, or functions from
|
||||
;; different files, then you should probably define it in this file.
|
||||
;; Otherwise, you might as well define the shortdoc group in the file
|
||||
;; where the documented functions live, like treesit.el does it.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'seq)
|
||||
(require 'text-property-search)
|
||||
(eval-when-compile (require 'cl-lib))
|
||||
|
||||
(defgroup shortdoc nil
|
||||
"Short documentation."
|
||||
:group 'lisp)
|
||||
|
||||
(defface shortdoc-heading
|
||||
'((t :inherit variable-pitch :height 1.3 :weight bold))
|
||||
"Face used for a heading."
|
||||
:version "28.1")
|
||||
|
||||
(defface shortdoc-section
|
||||
'((t :inherit variable-pitch))
|
||||
"Face used for a section.")
|
||||
|
||||
;;;###autoload
|
||||
(defun shortdoc--check (group functions)
|
||||
(let ((keywords '( :no-manual :args :eval :no-eval :no-value :no-eval*
|
||||
:result :result-string :eg-result :eg-result-string :doc)))
|
||||
(dolist (f functions)
|
||||
(when (consp f)
|
||||
(dolist (x f)
|
||||
(when (and (keywordp x) (not (memq x keywords)))
|
||||
(error "Shortdoc %s function `%s': bad keyword `%s'"
|
||||
group (car f) x)))))))
|
||||
|
||||
;;;###autoload
|
||||
(progn
|
||||
(defvar shortdoc--groups nil)
|
||||
|
||||
(defmacro define-short-documentation-group (group &rest functions)
|
||||
"Add GROUP to the list of defined documentation groups.
|
||||
FUNCTIONS is a list of elements on the form:
|
||||
|
||||
(FUNC
|
||||
:no-manual BOOL
|
||||
:args ARGS
|
||||
:eval EVAL
|
||||
:no-eval EXAMPLE-FORM
|
||||
:no-value EXAMPLE-FORM
|
||||
:no-eval* EXAMPLE-FORM
|
||||
:result RESULT-FORM
|
||||
:result-string RESULT-STRING
|
||||
:eg-result RESULT-FORM
|
||||
:eg-result-string RESULT-STRING)
|
||||
|
||||
FUNC is the function being documented.
|
||||
|
||||
NO-MANUAL should be non-nil if FUNC isn't documented in the
|
||||
manual.
|
||||
|
||||
ARGS is optional list of function FUNC's arguments. FUNC's
|
||||
signature is displayed automatically if ARGS is not present.
|
||||
Specifying ARGS might be useful where you don't want to document
|
||||
some of the uncommon arguments a function might have.
|
||||
|
||||
While the `:no-manual' and `:args' property can be used for
|
||||
any (FUNC ..) form, all of the other properties shown above
|
||||
cannot be used simultaneously in such a form.
|
||||
|
||||
Here are some common forms with examples of properties that go
|
||||
together:
|
||||
|
||||
1. Document a form or string, and its evaluated return value.
|
||||
(FUNC
|
||||
:eval EVAL)
|
||||
|
||||
If EVAL is a string, it will be inserted as is, and then that
|
||||
string will be `read' and evaluated.
|
||||
|
||||
2. Document a form or string, but manually document its evaluation
|
||||
result. The provided form will not be evaluated.
|
||||
|
||||
(FUNC
|
||||
:no-eval EXAMPLE-FORM
|
||||
:result RESULT-FORM) ;Use `:result-string' if value is in string form
|
||||
|
||||
Using `:no-value' is the same as using `:no-eval'.
|
||||
|
||||
Use `:no-eval*' instead of `:no-eval' where the successful
|
||||
execution of the documented form depends on some conditions.
|
||||
|
||||
3. Document a form or string EXAMPLE-FORM. Also manually
|
||||
document an example result. This result could be unrelated to
|
||||
the documented form.
|
||||
|
||||
(FUNC
|
||||
:no-eval EXAMPLE-FORM
|
||||
:eg-result RESULT-FORM) ;Use `:eg-result-string' if value is in string form
|
||||
|
||||
A FUNC form can have any number of `:no-eval' (or `:no-value'),
|
||||
`:no-eval*', `:result', `:result-string', `:eg-result' and
|
||||
`:eg-result-string' properties."
|
||||
(declare (indent defun))
|
||||
(shortdoc--check group functions)
|
||||
`(progn
|
||||
(setq shortdoc--groups (delq (assq ',group shortdoc--groups)
|
||||
shortdoc--groups))
|
||||
(push (cons ',group ',functions) shortdoc--groups))))
|
||||
|
||||
(define-short-documentation-group alist
|
||||
"Alist Basics"
|
||||
(assoc
|
||||
|
|
@ -1626,335 +1523,6 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'),
|
|||
(keymap-lookup
|
||||
:eval (keymap-lookup (current-global-map) "C-x x g")))
|
||||
|
||||
;;;###autoload
|
||||
(defun shortdoc-display-group (group &optional function same-window)
|
||||
"Pop to a buffer with short documentation summary for functions in GROUP.
|
||||
Interactively, prompt for GROUP.
|
||||
If FUNCTION is non-nil, place point on the entry for FUNCTION (if any).
|
||||
If SAME-WINDOW, don't pop to a new window."
|
||||
(interactive (list (completing-read
|
||||
"Group of functions for which to show summary: "
|
||||
(mapcar #'car shortdoc--groups))))
|
||||
(when (stringp group)
|
||||
(setq group (intern group)))
|
||||
(unless (assq group shortdoc--groups)
|
||||
(error "No such documentation group %s" group))
|
||||
(let ((buf (get-buffer-create (format "*Shortdoc %s*" group))))
|
||||
(shortdoc--insert-group-in-buffer group buf)
|
||||
(funcall (if same-window
|
||||
#'pop-to-buffer-same-window
|
||||
#'pop-to-buffer)
|
||||
buf))
|
||||
(goto-char (point-min))
|
||||
(when function
|
||||
(text-property-search-forward 'shortdoc-function function t)
|
||||
(beginning-of-line)))
|
||||
(provide 'shortdoc-doc)
|
||||
|
||||
(defun shortdoc--insert-group-in-buffer (group &optional buf)
|
||||
"Insert a short documentation summary for functions in GROUP in buffer BUF.
|
||||
BUF defaults to the current buffer if nil or omitted."
|
||||
(with-current-buffer (or buf (current-buffer))
|
||||
(let ((inhibit-read-only t)
|
||||
(prev nil))
|
||||
(erase-buffer)
|
||||
(shortdoc-mode)
|
||||
(button-mode)
|
||||
(mapc
|
||||
(lambda (data)
|
||||
(cond
|
||||
((stringp data)
|
||||
(setq prev nil)
|
||||
(unless (bobp)
|
||||
(insert "\n"))
|
||||
(insert (propertize
|
||||
(substitute-command-keys data)
|
||||
'face 'shortdoc-heading
|
||||
'shortdoc-section t
|
||||
'outline-level 1))
|
||||
(insert (propertize
|
||||
"\n\n"
|
||||
'face 'shortdoc-heading
|
||||
'shortdoc-section t)))
|
||||
;; There may be functions not yet defined in the data.
|
||||
((fboundp (car data))
|
||||
(when prev
|
||||
(insert (make-separator-line)
|
||||
;; This helps with hidden outlines (bug#53981)
|
||||
(propertize "\n" 'face '(:height 0))))
|
||||
(setq prev t)
|
||||
(shortdoc--display-function data))))
|
||||
(cdr (assq group shortdoc--groups))))))
|
||||
|
||||
;;;###autoload
|
||||
(defalias 'shortdoc #'shortdoc-display-group)
|
||||
|
||||
(defun shortdoc--display-function (data)
|
||||
(let ((function (pop data))
|
||||
(start-section (point))
|
||||
arglist-start)
|
||||
;; Function calling convention.
|
||||
(insert (propertize "(" 'shortdoc-function function 'outline-level 2))
|
||||
(if (plist-get data :no-manual)
|
||||
(insert-text-button
|
||||
(symbol-name function)
|
||||
'face 'button
|
||||
'action (lambda (_)
|
||||
(describe-function function))
|
||||
'follow-link t
|
||||
'help-echo "mouse-1, RET: describe function")
|
||||
(insert-text-button
|
||||
(symbol-name function)
|
||||
'face 'button
|
||||
'action (lambda (_)
|
||||
(info-lookup-symbol function 'emacs-lisp-mode))
|
||||
'follow-link t
|
||||
'help-echo "mouse-1, RET: show \
|
||||
function's documentation in the Info manual"))
|
||||
(setq arglist-start (point))
|
||||
(insert ")\n")
|
||||
;; Doc string.
|
||||
(insert " "
|
||||
(or (plist-get data :doc)
|
||||
(car (split-string (or (documentation function)
|
||||
"Error: missing docstring.")
|
||||
"\n"))))
|
||||
(insert "\n")
|
||||
(add-face-text-property start-section (point) 'shortdoc-section t)
|
||||
(let ((print-escape-newlines t)
|
||||
(double-arrow (if (char-displayable-p ?⇒)
|
||||
"⇒"
|
||||
"=>"))
|
||||
(single-arrow (if (char-displayable-p ?→)
|
||||
"→"
|
||||
"->"))
|
||||
(start-example (point)))
|
||||
(cl-loop for (type value) on data by #'cddr
|
||||
do
|
||||
(cl-case type
|
||||
(:eval
|
||||
(insert " ")
|
||||
(if (stringp value)
|
||||
(insert value)
|
||||
(prin1 value (current-buffer)))
|
||||
(insert "\n " double-arrow " ")
|
||||
(let ((expr (if (stringp value)
|
||||
(car (read-from-string value))
|
||||
value)))
|
||||
(prin1 (eval expr) (current-buffer)))
|
||||
(insert "\n"))
|
||||
(:no-eval*
|
||||
(if (stringp value)
|
||||
(insert " " value "\n")
|
||||
(insert " ")
|
||||
(prin1 value (current-buffer)))
|
||||
(insert "\n " single-arrow " "
|
||||
(propertize "[it depends]"
|
||||
'face 'shortdoc-section)
|
||||
"\n"))
|
||||
(:no-value
|
||||
(if (stringp value)
|
||||
(insert " " value)
|
||||
(insert " ")
|
||||
(prin1 value (current-buffer)))
|
||||
(insert "\n"))
|
||||
(:no-eval
|
||||
(if (stringp value)
|
||||
(insert " " value)
|
||||
(insert " ")
|
||||
(prin1 value (current-buffer)))
|
||||
(insert "\n"))
|
||||
(:result
|
||||
(insert " " double-arrow " ")
|
||||
(prin1 value (current-buffer))
|
||||
(insert "\n"))
|
||||
(:result-string
|
||||
(insert " " double-arrow " ")
|
||||
(princ value (current-buffer))
|
||||
(insert "\n"))
|
||||
(:eg-result
|
||||
(insert " e.g. " double-arrow " ")
|
||||
(prin1 value (current-buffer))
|
||||
(insert "\n"))
|
||||
(:eg-result-string
|
||||
(insert " e.g. " double-arrow " ")
|
||||
(princ value (current-buffer))
|
||||
(insert "\n"))))
|
||||
(add-text-properties start-example (point) `(shortdoc-example ,function)))
|
||||
;; Insert the arglist after doing the evals, in case that's pulled
|
||||
;; in the function definition.
|
||||
(save-excursion
|
||||
(goto-char arglist-start)
|
||||
(dolist (param (or (plist-get data :args)
|
||||
(help-function-arglist function t)))
|
||||
(insert " " (symbol-name param)))
|
||||
(add-face-text-property arglist-start (point) 'shortdoc-section t))))
|
||||
|
||||
(defun shortdoc-function-examples (function)
|
||||
"Return all shortdoc examples for FUNCTION.
|
||||
The result is an alist with items of the form (GROUP . EXAMPLES),
|
||||
where GROUP is a shortdoc group where FUNCTION appears, and
|
||||
EXAMPLES is a string with the usage examples of FUNCTION defined
|
||||
in GROUP. Return nil if FUNCTION is not a function or if it
|
||||
doesn't has any shortdoc information."
|
||||
(let ((groups (and (symbolp function)
|
||||
(shortdoc-function-groups function)))
|
||||
(examples nil))
|
||||
(mapc
|
||||
(lambda (group)
|
||||
(with-temp-buffer
|
||||
(shortdoc--insert-group-in-buffer group)
|
||||
(goto-char (point-min))
|
||||
(let ((match (text-property-search-forward
|
||||
'shortdoc-example function t)))
|
||||
(push `(,group . ,(string-trim
|
||||
(buffer-substring-no-properties
|
||||
(prop-match-beginning match)
|
||||
(prop-match-end match))))
|
||||
examples))))
|
||||
groups)
|
||||
examples))
|
||||
|
||||
(defun shortdoc-help-fns-examples-function (function)
|
||||
"Insert Emacs Lisp examples for FUNCTION into the current buffer.
|
||||
You can add this function to the `help-fns-describe-function-functions'
|
||||
hook to show examples of using FUNCTION in *Help* buffers produced
|
||||
by \\[describe-function]."
|
||||
(let* ((examples (shortdoc-function-examples function))
|
||||
(num-examples (length examples))
|
||||
(times 0))
|
||||
(dolist (example examples)
|
||||
(when (zerop times)
|
||||
(if (> num-examples 1)
|
||||
(insert "\n Examples:\n\n")
|
||||
;; Some functions have more than one example per group.
|
||||
;; Count the number of arrows to know if we need to
|
||||
;; pluralize "Example".
|
||||
(let* ((text (cdr example))
|
||||
(count 0)
|
||||
(pos 0)
|
||||
(end (length text))
|
||||
(double-arrow (if (char-displayable-p ?⇒)
|
||||
" ⇒"
|
||||
" =>"))
|
||||
(double-arrow-example (if (char-displayable-p ?⇒)
|
||||
" e.g. ⇒"
|
||||
" e.g. =>"))
|
||||
(single-arrow (if (char-displayable-p ?→)
|
||||
" →"
|
||||
" ->")))
|
||||
(while (and (< pos end)
|
||||
(or (string-match double-arrow text pos)
|
||||
(string-match double-arrow-example text pos)
|
||||
(string-match single-arrow text pos)))
|
||||
(setq count (1+ count)
|
||||
pos (match-end 0)))
|
||||
(if (> count 1)
|
||||
(insert "\n Examples:\n\n")
|
||||
(insert "\n Example:\n\n")))))
|
||||
(setq times (1+ times))
|
||||
(insert " ")
|
||||
(insert (cdr example))
|
||||
(insert "\n\n"))))
|
||||
|
||||
(defun shortdoc-function-groups (function)
|
||||
"Return all shortdoc groups FUNCTION appears in."
|
||||
(cl-loop for group in shortdoc--groups
|
||||
when (assq function (cdr group))
|
||||
collect (car group)))
|
||||
|
||||
(defun shortdoc-add-function (group section elem)
|
||||
"Add ELEM to shortdoc GROUP in SECTION.
|
||||
If GROUP doesn't exist, it will be created.
|
||||
If SECTION doesn't exist, it will be added.
|
||||
|
||||
ELEM is a Lisp form. See `define-short-documentation-group' for
|
||||
details.
|
||||
|
||||
Example:
|
||||
|
||||
(shortdoc-add-function
|
||||
\\='file \"Predicates\"
|
||||
\\='(file-locked-p :no-eval (file-locked-p \"/tmp\")))"
|
||||
(let ((glist (assq group shortdoc--groups)))
|
||||
(unless glist
|
||||
(setq glist (list group))
|
||||
(push glist shortdoc--groups))
|
||||
(let ((slist (member section glist)))
|
||||
(unless slist
|
||||
(setq slist (list section))
|
||||
(nconc glist slist))
|
||||
(while (and (cdr slist)
|
||||
(not (stringp (cadr slist))))
|
||||
(setq slist (cdr slist)))
|
||||
(setcdr slist (cons elem (cdr slist))))))
|
||||
|
||||
(defvar-keymap shortdoc-mode-map
|
||||
:doc "Keymap for `shortdoc-mode'."
|
||||
"n" #'shortdoc-next
|
||||
"p" #'shortdoc-previous
|
||||
"N" #'shortdoc-next-section
|
||||
"P" #'shortdoc-previous-section
|
||||
"C-c C-n" #'shortdoc-next-section
|
||||
"C-c C-p" #'shortdoc-previous-section
|
||||
"w" #'shortdoc-copy-function-as-kill)
|
||||
|
||||
(define-derived-mode shortdoc-mode special-mode "shortdoc"
|
||||
"Mode for shortdoc."
|
||||
:interactive nil
|
||||
(setq-local outline-search-function #'outline-search-level
|
||||
outline-level (lambda ()
|
||||
(get-text-property (point) 'outline-level))))
|
||||
|
||||
(defun shortdoc--goto-section (arg sym &optional reverse)
|
||||
(unless (natnump arg)
|
||||
(setq arg 1))
|
||||
(while (> arg 0)
|
||||
(funcall
|
||||
(if reverse 'text-property-search-backward
|
||||
'text-property-search-forward)
|
||||
sym nil t)
|
||||
(setq arg (1- arg))))
|
||||
|
||||
(defun shortdoc-next (&optional arg)
|
||||
"Move point to the next function.
|
||||
With prefix numeric argument ARG, do it that many times."
|
||||
(interactive "p" shortdoc-mode)
|
||||
(shortdoc--goto-section arg 'shortdoc-function))
|
||||
|
||||
(defun shortdoc-previous (&optional arg)
|
||||
"Move point to the previous function.
|
||||
With prefix numeric argument ARG, do it that many times."
|
||||
(interactive "p" shortdoc-mode)
|
||||
(shortdoc--goto-section arg 'shortdoc-function t)
|
||||
(backward-char 1))
|
||||
|
||||
(defun shortdoc-next-section (&optional arg)
|
||||
"Move point to the next section.
|
||||
With prefix numeric argument ARG, do it that many times."
|
||||
(interactive "p" shortdoc-mode)
|
||||
(shortdoc--goto-section arg 'shortdoc-section))
|
||||
|
||||
(defun shortdoc-previous-section (&optional arg)
|
||||
"Move point to the previous section.
|
||||
With prefix numeric argument ARG, do it that many times."
|
||||
(interactive "p" shortdoc-mode)
|
||||
(shortdoc--goto-section arg 'shortdoc-section t)
|
||||
(forward-line -2))
|
||||
|
||||
(defun shortdoc-copy-function-as-kill ()
|
||||
"Copy name of the function near point into the kill ring."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(goto-char (pos-bol))
|
||||
(when-let* ((re (rx bol "(" (group (+ (not (in " )"))))))
|
||||
(string
|
||||
(and (or (looking-at re)
|
||||
(re-search-backward re nil t))
|
||||
(match-string 1))))
|
||||
(set-text-properties 0 (length string) nil string)
|
||||
(kill-new string)
|
||||
(message string))))
|
||||
|
||||
(provide 'shortdoc)
|
||||
|
||||
;;; shortdoc.el ends here
|
||||
;;; shortdoc-doc.el ends here
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue