;;; 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]
;;; 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
(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"
(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
(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
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)))))
\f
(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."
(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
(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)
\f
;;; Texinfo file structure
(provide 'texinfo)
-;; arch-tag: 005d7c38-43b9-4b7d-aa1d-aea69bae73e1
;;; texinfo.el ends here