X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/ca3fa30248b923c17c021c0fcdb945271d14e8c2..0877d0dc24ee792b9b14592869ea1aa0934aee58:/lisp/textmodes/texinfo.el diff --git a/lisp/textmodes/texinfo.el b/lisp/textmodes/texinfo.el index be23a439bf..44e839d247 100644 --- a/lisp/textmodes/texinfo.el +++ b/lisp/textmodes/texinfo.el @@ -1,8 +1,7 @@ ;;; texinfo.el --- major mode for editing Texinfo files -*- coding: utf-8 -*- -;; Copyright (C) 1985, 1988, 1989, 1990, 1991, 1992, 1993, 1996, 1997, -;; 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 -;; Free Software Foundation, Inc. +;; Copyright (C) 1985, 1988-1993, 1996-1997, 2000-2013 Free Software +;; Foundation, Inc. ;; Author: Robert J. Chassell ;; Date: [See date below for texinfo-version] @@ -33,7 +32,16 @@ ;;; Code: -(eval-when-compile (require 'tex-mode) (require 'cl)) +(eval-when-compile (require 'tex-mode)) +(declare-function tex-buffer "tex-mode" ()) +(declare-function tex-region "tex-mode" (beg end)) +(declare-function tex-send-command "tex-mode") +(declare-function tex-recenter-output-buffer "tex-mode" (linenum)) +(declare-function tex-print "tex-mode" (&optional alt)) +(declare-function tex-view "tex-mode" ()) +(declare-function tex-shell-running "tex-mode" ()) +(declare-function tex-kill-job "tex-mode" ()) + (defvar outline-heading-alist) (defgroup texinfo nil @@ -319,11 +327,12 @@ chapter." (defconst texinfo-environments '("cartouche" "copying" "defcv" "deffn" "defivar" "defmac" - "defmethod" "defop" "defopt" "defspec" "deftp" "deftypefn" - "deftypefun" "deftypevar" "deftypevr" "defun" "defvar" + "defmethod" "defop" "defopt" "defspec" "deftp" "deftypecv" + "deftypefn" "deftypefun" "deftypeivar" "deftypemethod" + "deftypeop" "deftypevar" "deftypevr" "defun" "defvar" "defvr" "description" "detailmenu" "direntry" "display" "documentdescription" "enumerate" "example" "flushleft" - "flushright" "format" "ftable" "group" "ifclear" "ifset" + "flushright" "format" "ftable" "group" "html" "ifclear" "ifset" "ifhtml" "ifinfo" "ifnothtml" "ifnotinfo" "ifnotplaintext" "ifnottex" "ifplaintext" "iftex" "ignore" "itemize" "lisp" "macro" "menu" "multitable" "quotation" "smalldisplay" @@ -443,7 +452,9 @@ Subexpression 1 is what goes into the corresponding `@end' statement.") (define-key map "\C-c\C-s" 'texinfo-show-structure) (define-key map "\C-c}" 'up-list) + ;; FIXME: This is often used for "close block" aka texinfo-insert-@end. (define-key map "\C-c]" 'up-list) + (define-key map "\C-c/" 'texinfo-insert-@end) (define-key map "\C-c{" 'texinfo-insert-braces) ;; bindings for inserting strings @@ -500,6 +511,12 @@ Subexpression 1 is what goes into the corresponding `@end' statement.") (regexp-opt (texinfo-filter 2 texinfo-section-list)) "Regular expression matching just the Texinfo chapter level headings.") +(defun texinfo-current-defun-name () + "Return the name of the Texinfo node at point, or nil." + (save-excursion + (if (re-search-backward "^@node[ \t]+\\([^,\n]+\\)" nil t) + (match-string-no-properties 1)))) + ;;; Texinfo mode ;;;###autoload @@ -569,69 +586,53 @@ be the first node in the file. Entering Texinfo mode calls the value of `text-mode-hook', and then the value of `texinfo-mode-hook'." - (set (make-local-variable 'page-delimiter) - (concat - "^@node [ \t]*[Tt]op\\|^@\\(" - texinfo-chapter-level-regexp - "\\)\\>")) - (make-local-variable 'require-final-newline) - (setq require-final-newline mode-require-final-newline) - (make-local-variable 'indent-tabs-mode) - (setq indent-tabs-mode nil) - (make-local-variable 'paragraph-separate) - (setq paragraph-separate - (concat "\b\\|@[a-zA-Z]*[ \n]\\|" paragraph-separate)) - (make-local-variable 'paragraph-start) - (setq paragraph-start (concat "\b\\|@[a-zA-Z]*[ \n]\\|" paragraph-start)) - (make-local-variable 'sentence-end-base) - (setq sentence-end-base - "\\(@\\(end\\)?dots{}\\|[.?!]\\)[]\"'”)}]*") - (make-local-variable 'adaptive-fill-mode) - (setq adaptive-fill-mode nil) - (make-local-variable 'fill-column) - (setq fill-column 70) - (make-local-variable 'comment-start) - (setq comment-start "@c ") - (make-local-variable 'comment-start-skip) - (setq comment-start-skip "@c +\\|@comment +") - (make-local-variable 'words-include-escapes) - (setq words-include-escapes t) - (make-local-variable 'imenu-generic-expression) - (setq imenu-generic-expression texinfo-imenu-generic-expression) + (setq-local page-delimiter + (concat "^@node [ \t]*[Tt]op\\|^@\\(" + texinfo-chapter-level-regexp + "\\)\\>")) + (setq-local require-final-newline mode-require-final-newline) + (setq-local indent-tabs-mode nil) + (setq-local paragraph-separate + (concat "\b\\|@[a-zA-Z]*[ \n]\\|" + paragraph-separate)) + (setq-local paragraph-start (concat "\b\\|@[a-zA-Z]*[ \n]\\|" + paragraph-start)) + (setq-local sentence-end-base "\\(@\\(end\\)?dots{}\\|[.?!]\\)[]\"'”)}]*") + (setq-local fill-column 70) + (setq-local comment-start "@c ") + (setq-local comment-start-skip "@c +\\|@comment +") + (setq-local words-include-escapes t) + (setq-local imenu-generic-expression texinfo-imenu-generic-expression) (setq imenu-case-fold-search nil) - (make-local-variable 'font-lock-defaults) (setq font-lock-defaults '(texinfo-font-lock-keywords nil nil nil backward-paragraph)) - (set (make-local-variable 'syntax-propertize-function) - texinfo-syntax-propertize-function) - (set (make-local-variable 'parse-sexp-lookup-properties) t) + (setq-local syntax-propertize-function texinfo-syntax-propertize-function) + (setq-local parse-sexp-lookup-properties t) + (setq-local add-log-current-defun-function #'texinfo-current-defun-name) ;; Outline settings. - (set (make-local-variable 'outline-heading-alist) - ;; We should merge outline-heading-alist and texinfo-section-list - ;; but in the mean time, let's just generate one from the other. - (mapcar (lambda (x) (cons (concat "@" (car x)) (cadr x))) - texinfo-section-list)) - (set (make-local-variable 'outline-regexp) - (concat (regexp-opt (mapcar 'car outline-heading-alist) t) - "\\>")) - - (make-local-variable 'tex-start-of-header) - (setq tex-start-of-header "%\\*\\*start") - (make-local-variable 'tex-end-of-header) - (setq tex-end-of-header "%\\*\\*end") - (make-local-variable 'tex-first-line-header-regexp) - (setq tex-first-line-header-regexp "^\\\\input") - (make-local-variable 'tex-trailer) - (setq tex-trailer "@bye\n") - - ;; Prevent filling certain lines, in addition to ones specified - ;; by the user. - (let ((prevent-filling "^@\\(def\\|multitable\\)")) - (set (make-local-variable 'auto-fill-inhibit-regexp) - (if (null auto-fill-inhibit-regexp) - prevent-filling - (concat auto-fill-inhibit-regexp "\\|" prevent-filling))))) + (setq-local outline-heading-alist + ;; We should merge `outline-heading-alist' and + ;; `texinfo-section-list'. But in the mean time, let's + ;; just generate one from the other. + (mapcar (lambda (x) (cons (concat "@" (car x)) (cadr x))) + texinfo-section-list)) + (setq-local outline-regexp + (concat (regexp-opt (mapcar 'car outline-heading-alist) t) + "\\>")) + + (setq-local tex-start-of-header "%\\*\\*start") + (setq-local tex-end-of-header "%\\*\\*end") + (setq-local tex-first-line-header-regexp "^\\\\input") + (setq-local tex-trailer "@bye\n") + + ;; Prevent filling certain lines, in addition to ones specified by + ;; the user. + (setq-local auto-fill-inhibit-regexp + (let ((prevent-filling "^@\\(def\\|multitable\\)")) + (if (null auto-fill-inhibit-regexp) + prevent-filling + (concat auto-fill-inhibit-regexp "\\|" prevent-filling))))) @@ -646,7 +647,13 @@ Puts point on a blank line between them." (completing-read (format "Block name [%s]: " texinfo-block-default) texinfo-environments nil nil nil nil texinfo-block-default)) - \n "@" str \n _ \n "@end " str \n) + \n "@" str + ;; Blocks that take parameters: all the def* blocks take parameters, + ;; plus a few others. + (if (or (string-match "\\`def" str) + (member str '("table" "ftable" "vtable"))) + '(nil " " -)) + \n _ \n "@end " str \n) (defun texinfo-inside-macro-p (macro &optional bound) "Non-nil if inside a macro matching the regexp MACRO." @@ -671,7 +678,8 @@ Puts point on a blank line between them." (not (match-end 1))))) (defvar texinfo-enable-quote-macros "@\\(code\\|samp\\|kbd\\)\\>") -(defvar texinfo-enable-quote-envs '("example\\>" "lisp\\>")) +(defvar texinfo-enable-quote-envs + '("example\\>" "smallexample\\>" "lisp\\>")) (defun texinfo-insert-quote (&optional arg) "Insert the appropriate quote mark for Texinfo. Usually inserts the value of `texinfo-open-quote' (normally ``) or @@ -717,163 +725,131 @@ With prefix argument or inside @code or @example, inserts a plain \"." (not (looking-at "@end")))) (texinfo-next-unmatched-end))) -(defun texinfo-insert-@end () +(define-skeleton texinfo-insert-@end "Insert the matching `@end' for the last Texinfo command that needs one." - (interactive) - (let ((string (ignore-errors (save-excursion + (backward-word 1) (texinfo-last-unended-begin) - (match-string 1))))) - (insert "@end ") - (if string (insert string "\n")))) - -;; The following insert commands accept a prefix arg N, which is the -;; number of words (actually s-exprs) that should be surrounded by -;; braces. Thus you can first paste a variable name into a .texinfo -;; buffer, then say C-u 1 C-c C-c v at the beginning of the just -;; pasted variable name to put @var{...} *around* the variable name. -;; Operate on previous word or words with negative arg. - -;; These commands use texinfo-insert-@-with-arg -(defun texinfo-insert-@-with-arg (string &optional arg) - (if arg - (progn - (setq arg (prefix-numeric-value arg)) - (if (< arg 0) - (progn - (skip-chars-backward " \t\n\r\f") - (save-excursion - (forward-sexp arg) - (insert "@" string "{")) - (insert "}")) - (skip-chars-forward " \t\n\r\f") - (insert "@" string "{") - (forward-sexp arg) - (insert "}"))) - (insert "@" string "{}") - (backward-char))) - -(defun texinfo-insert-braces () + (or (match-string 1) '-))) + \n "@end " str \n) + +(define-skeleton texinfo-insert-braces "Make a pair of braces and be poised to type inside of them. Use \\[up-list] to move forward out of the braces." - (interactive) - (insert "{}") - (backward-char)) + nil + "{" _ "}") -(defun texinfo-insert-@code (&optional arg) +(define-skeleton texinfo-insert-@code "Insert a `@code{...}' command in a Texinfo buffer. A numeric argument says how many words the braces should surround. The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "code" arg)) + nil + "@code{" _ "}") -(defun texinfo-insert-@dfn (&optional arg) +(define-skeleton texinfo-insert-@dfn "Insert a `@dfn{...}' command in a Texinfo buffer. A numeric argument says how many words the braces should surround. The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "dfn" arg)) + nil + "@dfn{" _ "}") -(defun texinfo-insert-@email (&optional arg) +(define-skeleton texinfo-insert-@email "Insert a `@email{...}' command in a Texinfo buffer. A numeric argument says how many words the braces should surround. The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "email" arg)) + nil + "@email{" _ "}") -(defun texinfo-insert-@emph (&optional arg) +(define-skeleton texinfo-insert-@emph "Insert a `@emph{...}' command in a Texinfo buffer. A numeric argument says how many words the braces should surround. The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "emph" arg)) + nil + "@emph{" _ "}") -(defun texinfo-insert-@example () +(define-skeleton texinfo-insert-@example "Insert the string `@example' in a Texinfo buffer." - (interactive) - (insert "@example\n")) + nil + \n "@example" \n) -(defun texinfo-insert-@file (&optional arg) +(define-skeleton texinfo-insert-@file "Insert a `@file{...}' command in a Texinfo buffer. A numeric argument says how many words the braces should surround. The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "file" arg)) + nil + "@file{" _ "}") -(defun texinfo-insert-@item () +(define-skeleton texinfo-insert-@item "Insert the string `@item' in a Texinfo buffer. If in a table defined by @table, follow said string with a space. Otherwise, follow with a newline." - (interactive) - (insert "@item" + nil + \n "@item" (if (equal (ignore-errors (save-excursion (texinfo-last-unended-begin) (match-string 1))) "table") - ?\s - ?\n))) + " " '\n) + _ \n) -(defun texinfo-insert-@kbd (&optional arg) +(define-skeleton texinfo-insert-@kbd "Insert a `@kbd{...}' command in a Texinfo buffer. A numeric argument says how many words the braces should surround. The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "kbd" arg)) + nil + "@kbd{" _ "}") -(defun texinfo-insert-@node () +(define-skeleton texinfo-insert-@node "Insert the string `@node' in a Texinfo buffer. Insert a comment on the following line indicating the order of arguments to @node. Insert a carriage return after the comment line. Leave point after `@node'." - (interactive) - (insert "@node \n@comment node-name, next, previous, up\n") - (forward-line -2) - (forward-char 6)) + nil + \n "@node " _ \n) -(defun texinfo-insert-@noindent () +(define-skeleton texinfo-insert-@noindent "Insert the string `@noindent' in a Texinfo buffer." - (interactive) - (insert "@noindent\n")) + nil + \n "@noindent" \n) -(defun texinfo-insert-@quotation () +(define-skeleton texinfo-insert-@quotation "Insert the string `@quotation' in a Texinfo buffer." - (interactive) - (insert "@quotation\n")) + \n "@quotation" \n) -(defun texinfo-insert-@samp (&optional arg) +(define-skeleton texinfo-insert-@samp "Insert a `@samp{...}' command in a Texinfo buffer. A numeric argument says how many words the braces should surround. The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "samp" arg)) + nil + "@samp{" _ "}") -(defun texinfo-insert-@strong (&optional arg) +(define-skeleton texinfo-insert-@strong "Insert a `@strong{...}' command in a Texinfo buffer. A numeric argument says how many words the braces should surround. The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "strong" arg)) + nil + "@strong{" _ "}") -(defun texinfo-insert-@table () +(define-skeleton texinfo-insert-@table "Insert the string `@table' in a Texinfo buffer." - (interactive) - (insert "@table ")) + nil + \n "@table " _ \n) -(defun texinfo-insert-@var (&optional arg) +(define-skeleton texinfo-insert-@var "Insert a `@var{}' command in a Texinfo buffer. A numeric argument says how many words the braces should surround. The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "var" arg)) + nil + "@var{" _ "}") -(defun texinfo-insert-@uref (&optional arg) +(define-skeleton texinfo-insert-@uref "Insert a `@uref{}' command in a Texinfo buffer. A numeric argument says how many words the braces should surround. The default is not to surround any existing words with the braces." - (interactive "P") - (texinfo-insert-@-with-arg "uref" arg)) + nil + "@uref{" _ "}") (defalias 'texinfo-insert-@url 'texinfo-insert-@uref) ;;; Texinfo file structure @@ -1051,5 +1027,4 @@ You are prompted for the job number (use a number shown by a previous (provide 'texinfo) -;; arch-tag: 005d7c38-43b9-4b7d-aa1d-aea69bae73e1 ;;; texinfo.el ends here