-;;; texinfo.el --- major mode for editing Texinfo files -*- coding: utf-8 -*-
+;;; texinfo.el --- major mode for editing Texinfo files
-;; Copyright (C) 1985, 1988-1993, 1996-1997, 2000-2012
-;; Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1988-1993, 1996-1997, 2000-2016 Free Software
+;; Foundation, Inc.
;; Author: Robert J. Chassell
;; Date: [See date below for texinfo-version]
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
;; Keywords: maint, tex, docs
;; This file is part of GNU Emacs.
;;; Code:
(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)
+(defvar skeleton-end-newline)
+
(defgroup texinfo nil
"Texinfo Mode."
:link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
"Make Info file from current buffer.
Use the \\[next-error] command to move to the next error
-\(if there are errors\)."
+\(if there are errors)."
t nil)
(autoload 'kill-compilation
(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))
- (set (make-local-variable 'sentence-end-base)
- "\\(@\\(end\\)?dots{}\\|[.?!]\\)[]\"'”)}]*")
- (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 skeleton.el from adding a newline to each inserted
+ ;; skeleton. Those which do want a newline do that explicitly in
+ ;; their define-skeleton form.
+ (setq-local skeleton-end-newline nil)
+
+ ;; 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
(if (or (string-match "\\`def" str)
(member str '("table" "ftable" "vtable")))
'(nil " " -))
- \n _ \n "@end " str \n)
+ \n _ \n "@end " str \n \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
-`texinfo-close-quote' (normally ''), depending on the context.
+Usually inserts the value of `texinfo-open-quote' (normally \\=`\\=`) or
+`texinfo-close-quote' (normally \\='\\='), depending on the context.
With prefix argument or inside @code or @example, inserts a plain \"."
(interactive "*P")
(let ((top (or (save-excursion (re-search-backward "@node\\>" nil t))
(backward-word 1)
(texinfo-last-unended-begin)
(or (match-string 1) '-)))
- \n "@end " str \n)
+ \n "@end " str \n \n)
(define-skeleton texinfo-insert-braces
"Make a pair of braces and be poised to type inside of them.
(define-skeleton texinfo-insert-@example
"Insert the string `@example' in a Texinfo buffer."
nil
- \n "@example" \n)
+ \n "@example" \n \n)
(define-skeleton texinfo-insert-@file
"Insert a `@file{...}' command in a Texinfo buffer.
(define-skeleton texinfo-insert-@quotation
"Insert the string `@quotation' in a Texinfo buffer."
- \n "@quotation" \n)
+ \n "@quotation" \n _ \n)
(define-skeleton texinfo-insert-@samp
"Insert a `@samp{...}' command in a Texinfo buffer.