
* lisp/textmodes/enriched.el: Use lexical-binding. (enriched-mode): Use `delete-dups` to avoid `add-to-list` on a local variable. * lisp/textmodes/makeinfo.el: Use lexical-binding. (makeinfo-region): Remove unused var `filename-or-header`. * lisp/textmodes/refbib.el: Use lexical-binding. (r2b-put-field): Remove unused var `multi-line`. (r2b-barf-output): Remove unused var `match`. * lisp/textmodes/refer.el: Use lexical-binding. (refer-find-entry-internal): Remove unused vars `old-buffer` and `found`. * lisp/textmodes/reftex-auc.el: Use lexical-binding. (LaTeX-add-bibitems): Declare function. (reftex-plug-into-AUCTeX): Use `add-function` and `advice-add` so we can properly unplug. * lisp/textmodes/reftex-cite.el: Use lexical-binding. (reftex-create-bibtex-file): Remove unused var `file`. (reftex--found-list): Declare var. (reftex-offer-bib-menu): Rename local var to `reftex--found-list`. * lisp/textmodes/reftex-dcr.el: Use lexical-binding. (reftex-use-itimer-in-xemacs): Delete XEmacs-only var. (reftex-toggle-auto-view-crossref): Delete XEmacs-only code. (reftex-start-itimer-once): Delete XEmacs-only function. * lisp/textmodes/reftex-global.el: Use lexical-binding. (reftex-isearch-push-state-function): Use a closure instead of `(lambda). * lisp/textmodes/reftex-index.el: Use lexical-binding. (mark-active, transient-mark-mode): Delete var declarations. (reftex-index-mode-map): Remove XEmacs-only code. Use `mapc` so we can use closures instead of hand-built lambdas. (reftex-index-next, reftex-index-previous): Tweak interactive spec to remove unused prefix arg and mark it as a motion command. (reftex-index-phrases-font-lock-keywords) (reftex-index-phrases-font-lock-keywords): Move initialization into declaration. (reftex-index-initialize-phrases-buffer, reftex-index-phrases-mode) reftex-index-phrases-apply-to-region: Remove XEmacs-only code. (TeX-master): Remove redundant declaration. (reftex--chars-first): Rename dynvar from `chars-first`. Adjust all uses. * lisp/textmodes/reftex-parse.el: Use lexical-binding. * lisp/textmodes/reftex-ref.el: Use lexical-binding. (reftex-label): Remove always-nil var `text`. (reftex-refstyle): Declare before first use. (<toplevel>): Use closures rather than `eval` when building commands from `reftex-ref-style-alist`. * lisp/textmodes/reftex-sel.el: Use lexical-binding. (reftex-select-label-mode-map, reftex-select-bib-mode-map): Use `mapc` so we can use closures instead of hand-built lambdas. (reftex-select-label-mode, reftex-select-bib-mode): Remove XEmacs-only code. (reftex-select-data, reftex-select-prompt, reftex-refstyle): Move declaration before first use. (reftex--found-list, reftex--cb-flag, reftex--last-data) (reftex--call-back, reftex--help-string): Move declaration before use, and rename by adding `reftext--` prefix. Adjust all uses in this file. For `reftex--found-list` adjust corresponding uses in `reftex-cite.el`. (reftex-select-item): Explicitly let-bind them. Remove XEmacs-only code. * lisp/textmodes/reftex-toc.el: Use lexical-binding. (reftex-toc-mode-map, reftex-toc-mode, reftex-toc-restore-region) (reftex-toc-next, reftex-toc-previous, reftex-toc-next-heading) (reftex-toc-previous-heading, reftex-toggle-auto-toc-recenter (reftex-make-separate-toc-frame): Remove XEmacs-only code. * lisp/textmodes/reftex-vars.el: Use lexical-binding. * lisp/textmodes/reftex.el: Use lexical-binding. (reftex-mode-map, reftex-mode, reftex-fontify-select-label-buffer) (reftex-verified-face): Remove XEmacs-only code. (reftex-region-active-p, reftex-overlay-put, reftex-move-overlay) (reftex-make-overlay, reftex-get-buffer-visiting, reftex-delete-overlay): Redefine as obsolete aliases. Replace all callers. (current-message): Remove XEmacs-only definition. * lisp/textmodes/remember.el: Use lexical-binding. * lisp/textmodes/table.el (<toplevel>): Use closures rather than `(lambda) to build commands. * lisp/textmodes/texinfmt.el: Use lexical-binding. (texinfo-example-start): Declare var. (texinfo-format-region, texinfo-format-buffer-1): Remove unused var `last-input-buffer`. (texinfo-format-scan): Use `dlet` to bind `whitespace-silent`. (texinfo-optional-braces-discard, texinfo-format-parse-line-args) (texinfo-format-parse-args): Remove unused var `start`. (texinfo-multitable-widths): Remove unused var `start-of-templates`. (texinfo-multitable-item): Strength-reduce `eval` to `symbol-value`. (texinfo-alias): Remove unused vars `start` and `args`. (texinfo-defun-type symbol-property): Change the car to help the type symbol rather than an expression returning it. (texinfo-format-deffn): Remove corresponding `eval`. (texinfo-clear): Remove unused var `value`. (texinfo-format-ifeq): Remove unused var `end`. * lisp/textmodes/texinfo.el: Use lexical-binding. (tex-show-print-queue): Declare function. * lisp/textmodes/texnfo-upd.el: Use lexical-binding. (texinfo-start-menu-description): Remove unused var `end`. (texinfo-insert-node-lines): Remove unused var `beginning-marker`. (texinfo-multiple-files-update): Remove unused vars `next-node-name` and `previous-node-name`. * lisp/textmodes/two-column.el: Use lexical-binding.
227 lines
8.6 KiB
EmacsLisp
227 lines
8.6 KiB
EmacsLisp
;;; text-mode.el --- text mode, and its idiosyncratic commands -*- lexical-binding: t -*-
|
||
|
||
;; Copyright (C) 1985, 1992, 1994, 2001-2021 Free Software Foundation,
|
||
;; Inc.
|
||
|
||
;; Maintainer: emacs-devel@gnu.org
|
||
;; Keywords: wp
|
||
;; Package: emacs
|
||
|
||
;; This file is part of GNU Emacs.
|
||
|
||
;; GNU Emacs 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 3 of the License, or
|
||
;; (at your option) any later version.
|
||
|
||
;; GNU Emacs 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. If not, see <https://www.gnu.org/licenses/>.
|
||
|
||
;;; Commentary:
|
||
|
||
;; This package provides the fundamental text mode documented in the
|
||
;; Emacs user's manual.
|
||
|
||
;;; Code:
|
||
|
||
;; Normally non-nil defaults for hooks are bad, but since this file is
|
||
;; preloaded it's ok/better, and avoids this showing up in customize-rogue.
|
||
(defcustom text-mode-hook '(text-mode-hook-identify)
|
||
"Normal hook run when entering Text mode and many related modes."
|
||
:type 'hook
|
||
:options '(turn-on-auto-fill turn-on-flyspell)
|
||
:group 'text)
|
||
|
||
(defvar text-mode-variant nil
|
||
"Non-nil if this buffer's major mode is a variant of Text mode.")
|
||
(make-obsolete-variable 'text-mode-variant 'derived-mode-p "27.1")
|
||
|
||
(defvar text-mode-syntax-table
|
||
(let ((st (make-syntax-table)))
|
||
(modify-syntax-entry ?\" ". " st)
|
||
(modify-syntax-entry ?\\ ". " st)
|
||
;; We add `p' so that M-c on 'hello' leads to 'Hello' rather than 'hello'.
|
||
(modify-syntax-entry ?' "w p" st)
|
||
;; UAX #29 says HEBREW PUNCTUATION GERESH behaves like a letter
|
||
;; for the purposes of finding word boundaries.
|
||
(modify-syntax-entry #x5f3 "w ") ; GERESH
|
||
;; UAX #29 says HEBREW PUNCTUATION GERSHAYIM should not be a word
|
||
;; boundary when surrounded by letters. Our infrastructure for
|
||
;; finding a word boundary doesn't support 3-character
|
||
;; definitions, so for now simply make this a word-constituent
|
||
;; character. This leaves a problem of having GERSHAYIM at the
|
||
;; beginning or end of a word, where it should be a boundary;
|
||
;; FIXME.
|
||
(modify-syntax-entry #x5f4 "w ") ; GERSHAYIM
|
||
;; These all should not be a word boundary when between letters,
|
||
;; according to UAX #29, so they again are prone to the same
|
||
;; problem as GERSHAYIM; FIXME.
|
||
(modify-syntax-entry #xb7 "w ") ; MIDDLE DOT
|
||
(modify-syntax-entry #x2027 "w ") ; HYPHENATION POINT
|
||
(modify-syntax-entry #xff1a "w ") ; FULLWIDTH COLON
|
||
st)
|
||
"Syntax table used while in `text-mode'.")
|
||
|
||
(defvar text-mode-map
|
||
(let ((map (make-sparse-keymap)))
|
||
(define-key map "\e\t" #'ispell-complete-word)
|
||
map)
|
||
"Keymap for `text-mode'.
|
||
Many other modes, such as `mail-mode', `outline-mode' and `indented-text-mode',
|
||
inherit all the commands defined in this map.")
|
||
|
||
(easy-menu-define text-mode-menu text-mode-map
|
||
"Menu for `text-mode'."
|
||
'("Text"
|
||
["Center Line" center-line
|
||
:help "Center the current line"]
|
||
["Center Paragraph" center-paragraph
|
||
:help "Center the current paragraph"]
|
||
["Center Region" center-region
|
||
:help "Center the marked region"
|
||
:enable (region-active-p)]
|
||
"---"
|
||
["Paragraph Indent" paragraph-indent-minor-mode
|
||
:help "Toggle paragraph indent minor mode"
|
||
:style toggle
|
||
:selected (bound-and-true-p paragraph-indent-minor-mode)]
|
||
["Auto Fill" toggle-text-mode-auto-fill
|
||
:help "Automatically fill text while typing in text modes (Auto Fill mode)"
|
||
:style toggle
|
||
:selected (memq 'turn-on-auto-fill text-mode-hook)]))
|
||
|
||
|
||
(define-derived-mode text-mode nil "Text"
|
||
"Major mode for editing text written for humans to read.
|
||
In this mode, paragraphs are delimited only by blank or white lines.
|
||
You can thus get the full benefit of adaptive filling
|
||
(see the variable `adaptive-fill-mode').
|
||
\\{text-mode-map}
|
||
Turning on Text mode runs the normal hook `text-mode-hook'."
|
||
(setq-local text-mode-variant t)
|
||
(setq-local require-final-newline mode-require-final-newline))
|
||
|
||
(define-derived-mode paragraph-indent-text-mode text-mode "Parindent"
|
||
"Major mode for editing text, with leading spaces starting a paragraph.
|
||
In this mode, you do not need blank lines between paragraphs
|
||
when the first line of the following paragraph starts with whitespace.
|
||
`paragraph-indent-minor-mode' provides a similar facility as a minor mode.
|
||
Special commands:
|
||
\\{text-mode-map}
|
||
Turning on Paragraph-Indent Text mode runs the normal hooks
|
||
`text-mode-hook' and `paragraph-indent-text-mode-hook'."
|
||
:abbrev-table nil :syntax-table nil
|
||
(paragraph-indent-minor-mode))
|
||
|
||
(define-minor-mode paragraph-indent-minor-mode
|
||
"Minor mode for editing text, with leading spaces starting a paragraph.
|
||
In this mode, you do not need blank lines between paragraphs when the
|
||
first line of the following paragraph starts with whitespace, as with
|
||
`paragraph-indent-text-mode'.
|
||
Turning on Paragraph-Indent minor mode runs the normal hook
|
||
`paragraph-indent-text-mode-hook'."
|
||
:initial-value nil
|
||
;; Change the definition of a paragraph start.
|
||
(let ((ps-re "[ \t\n\f]\\|"))
|
||
(if (string-prefix-p ps-re paragraph-start)
|
||
(if (not paragraph-indent-minor-mode)
|
||
(setq-local paragraph-start
|
||
(substring paragraph-start (length ps-re))))
|
||
(if paragraph-indent-minor-mode
|
||
(setq-local paragraph-start (concat ps-re paragraph-start)))))
|
||
;; Change the indentation function.
|
||
(if paragraph-indent-minor-mode
|
||
(add-function :override (local 'indent-line-function)
|
||
#'indent-to-left-margin)
|
||
(remove-function (local 'indent-line-function)
|
||
#'indent-to-left-margin)))
|
||
|
||
(defalias 'indented-text-mode #'text-mode)
|
||
|
||
;; This can be made a no-op once all modes that use text-mode-hook
|
||
;; are "derived" from text-mode. (As of 2015/04, and probably well before,
|
||
;; the only one I can find that doesn't so derive is rmail-edit-mode.)
|
||
(defun text-mode-hook-identify ()
|
||
"Mark that this mode has run `text-mode-hook'.
|
||
This is how `toggle-text-mode-auto-fill' knows which buffers to operate on."
|
||
(setq-local text-mode-variant t))
|
||
|
||
(defun toggle-text-mode-auto-fill ()
|
||
"Toggle whether to use Auto Fill in Text mode and related modes.
|
||
This command affects all buffers that use modes related to Text mode,
|
||
both existing buffers and buffers that you subsequently create."
|
||
(interactive)
|
||
(let ((enable-mode (not (memq 'turn-on-auto-fill text-mode-hook))))
|
||
(if enable-mode
|
||
(add-hook 'text-mode-hook #'turn-on-auto-fill)
|
||
(remove-hook 'text-mode-hook #'turn-on-auto-fill))
|
||
(dolist (buffer (buffer-list))
|
||
(with-current-buffer buffer
|
||
(if (or (derived-mode-p 'text-mode) text-mode-variant)
|
||
(auto-fill-mode (if enable-mode 1 0)))))
|
||
(message "Auto Fill %s in Text modes"
|
||
(if enable-mode "enabled" "disabled"))))
|
||
|
||
|
||
(defun center-paragraph ()
|
||
"Center each nonblank line in the paragraph at or after point.
|
||
See `center-line' for more info."
|
||
(interactive)
|
||
(save-excursion
|
||
(forward-paragraph)
|
||
(or (bolp) (newline 1))
|
||
(let ((end (point)))
|
||
(backward-paragraph)
|
||
(center-region (point) end))))
|
||
|
||
(defun center-region (from to)
|
||
"Center each nonblank line starting in the region.
|
||
See `center-line' for more info."
|
||
(interactive "r")
|
||
(if (> from to)
|
||
(let ((tem to))
|
||
(setq to from from tem)))
|
||
(save-excursion
|
||
(save-restriction
|
||
(narrow-to-region from to)
|
||
(goto-char from)
|
||
(while (not (eobp))
|
||
(or (save-excursion (skip-chars-forward " \t") (eolp))
|
||
(center-line))
|
||
(forward-line 1)))))
|
||
|
||
(defun center-line (&optional nlines)
|
||
"Center the line point is on, within the width specified by `fill-column'.
|
||
This means adjusting the indentation so that it equals
|
||
the distance between the end of the text and `fill-column'.
|
||
The argument NLINES says how many lines to center."
|
||
(interactive "P")
|
||
(if nlines (setq nlines (prefix-numeric-value nlines)))
|
||
(while (not (eq nlines 0))
|
||
(save-excursion
|
||
(let ((lm (current-left-margin))
|
||
space)
|
||
(beginning-of-line)
|
||
(delete-horizontal-space)
|
||
(end-of-line)
|
||
(delete-horizontal-space)
|
||
(setq space (- fill-column lm (current-column)))
|
||
(if (> space 0)
|
||
(indent-line-to (+ lm (/ space 2))))))
|
||
(cond ((null nlines)
|
||
(setq nlines 0))
|
||
((> nlines 0)
|
||
(setq nlines (1- nlines))
|
||
(forward-line 1))
|
||
((< nlines 0)
|
||
(setq nlines (1+ nlines))
|
||
(forward-line -1)))))
|
||
|
||
(provide 'text-mode)
|
||
|
||
;;; text-mode.el ends here
|