X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/8f1204db34c0e8380f1eb81c9202520511744be3..a6d583c00a8079c98000fdc80c870f7cdcc9f291:/lisp/textmodes/text-mode.el diff --git a/lisp/textmodes/text-mode.el b/lisp/textmodes/text-mode.el index 0a72141961..9263c48f18 100644 --- a/lisp/textmodes/text-mode.el +++ b/lisp/textmodes/text-mode.el @@ -1,8 +1,10 @@ -;;; text-mode.el --- text mode, and its idiosyncratic commands. +;;; text-mode.el --- text mode, and its idiosyncratic commands -;; Copyright (C) 1985, 1992, 1994 Free Software Foundation, Inc. +;; Copyright (C) 1985, 1992, 1994, 2002, 2003, 2004, +;; 2005, 2006 Free Software Foundation, Inc. ;; Maintainer: FSF +;; Keywords: wp ;; This file is part of GNU Emacs. @@ -17,9 +19,9 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. ;;; Commentary: @@ -28,92 +30,101 @@ ;;; Code: -(defvar text-mode-syntax-table nil - "Syntax table used while in text mode.") - -(defvar text-mode-abbrev-table nil - "Abbrev table used while in text mode.") -(define-abbrev-table 'text-mode-abbrev-table ()) - -(if text-mode-syntax-table - () - (setq text-mode-syntax-table (make-syntax-table)) - (modify-syntax-entry ?\" ". " text-mode-syntax-table) - (modify-syntax-entry ?\\ ". " text-mode-syntax-table) - (modify-syntax-entry ?' "w " text-mode-syntax-table)) - -(defvar text-mode-map nil - "Keymap for Text mode. -Many other modes, such as Mail mode, Outline mode and Indented Text mode, +(defcustom text-mode-hook nil + "Normal hook run when entering Text mode and many related modes." + :type 'hook + :options '(turn-on-auto-fill turn-on-flyspell) + :group 'data) + +(defvar text-mode-variant nil + "Non-nil if this buffer's major mode is a variant of Text mode. +Use (derived-mode-p 'text-mode) instead.") + +(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) + 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) + (define-key map "\es" 'center-line) + (define-key map "\eS" 'center-paragraph) + 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.") -(if text-mode-map - () - (setq text-mode-map (make-sparse-keymap)) - (define-key text-mode-map "\e\t" 'ispell-complete-word) - (define-key text-mode-map "\t" 'tab-to-tab-stop) - (define-key text-mode-map "\es" 'center-line) - (define-key text-mode-map "\eS" 'center-paragraph)) - -;(defun non-saved-text-mode () -; "Like text-mode, but delete auto save file when file is saved for real." -; (text-mode) -; (make-local-variable 'delete-auto-save-files) -; (setq delete-auto-save-files t)) - -(defun text-mode () - "Major mode for editing text intended for humans to read. +(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'." + (make-local-variable 'text-mode-variant) + (setq text-mode-variant t) + (set (make-local-variable 'require-final-newline) + mode-require-final-newline) + (set (make-local-variable 'indent-line-function) 'indent-relative)) + +(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 Text mode calls the value of the variable `text-mode-hook', -if that value is non-nil." +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)) + +(defun 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'." (interactive) - (kill-all-local-variables) - (use-local-map text-mode-map) - (setq mode-name "Text") - (setq major-mode 'text-mode) - (setq local-abbrev-table text-mode-abbrev-table) - (set-syntax-table text-mode-syntax-table) - (run-hooks 'text-mode-hook)) - -(defvar indented-text-mode-map () - "Keymap for Indented Text mode. -All the commands defined in Text mode are inherited unless overridden.") - -(if indented-text-mode-map - () - ;; Make different definition for TAB before the one in text-mode-map, but - ;; share the rest. - (let ((newmap (make-sparse-keymap))) - (define-key newmap "\t" 'indent-relative) - (setq indented-text-mode-map (nconc newmap text-mode-map)))) - -(defun indented-text-mode () - "Major mode for editing text with indented paragraphs. -In this mode, paragraphs are delimited only by blank lines. -You can thus get the benefit of adaptive filling - (see the variable `adaptive-fill-mode'). -\\{indented-text-mode-map} -Turning on `indented-text-mode' calls the value of the variable -`text-mode-hook', if that value is non-nil." + (set (make-local-variable 'paragraph-start) + (concat "[ \t\n\f]\\|" paragraph-start)) + (set (make-local-variable 'indent-line-function) 'indent-to-left-margin) + (run-hooks 'paragraph-indent-text-mode-hook)) + +(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. +(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." + (set (make-local-variable 'text-mode-variant) t)) + +(add-hook 'text-mode-hook 'text-mode-hook-identify) + +(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) - (kill-all-local-variables) - (use-local-map text-mode-map) - (define-abbrev-table 'text-mode-abbrev-table ()) - (setq local-abbrev-table text-mode-abbrev-table) - (set-syntax-table text-mode-syntax-table) - (make-local-variable 'indent-line-function) - (setq indent-line-function 'indent-relative-maybe) - (make-local-variable 'paragraph-start) - (setq paragraph-start (concat "^$\\|" page-delimiter)) - (make-local-variable 'paragraph-separate) - (setq paragraph-separate paragraph-start) - (use-local-map indented-text-mode-map) - (setq mode-name "Indented Text") - (setq major-mode 'indented-text-mode) - (run-hooks 'text-mode-hook 'indented-text-mode-hook)) - + (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." @@ -141,21 +152,33 @@ See `center-line' for more info." (center-line)) (forward-line 1))))) -(defun center-line () +(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'." - (interactive) - (save-excursion - (let (line-length) - (beginning-of-line) - (delete-horizontal-space) - (end-of-line) - (delete-horizontal-space) - (setq line-length (current-column)) - (beginning-of-line) - (indent-to - (+ left-margin - (/ (- fill-column left-margin line-length) 2)))))) - +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)) + line-length) + (beginning-of-line) + (delete-horizontal-space) + (end-of-line) + (delete-horizontal-space) + (setq line-length (current-column)) + (if (> (- fill-column lm line-length) 0) + (indent-line-to + (+ lm (/ (- fill-column lm line-length) 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))))) + +;;; arch-tag: a07ccaad-da13-4d7b-9c61-cd04f5926aab ;;; text-mode.el ends here