diff options
Diffstat (limited to 'lisp/textmodes')
-rw-r--r-- | lisp/textmodes/artist.el | 2 | ||||
-rw-r--r-- | lisp/textmodes/bibtex.el | 51 | ||||
-rw-r--r-- | lisp/textmodes/conf-mode.el | 4 | ||||
-rw-r--r-- | lisp/textmodes/css-mode.el | 32 | ||||
-rw-r--r-- | lisp/textmodes/fill.el | 6 | ||||
-rw-r--r-- | lisp/textmodes/flyspell.el | 46 | ||||
-rw-r--r-- | lisp/textmodes/ispell.el | 848 | ||||
-rw-r--r-- | lisp/textmodes/po.el | 4 | ||||
-rw-r--r-- | lisp/textmodes/reftex-cite.el | 8 | ||||
-rw-r--r-- | lisp/textmodes/reftex-parse.el | 16 | ||||
-rw-r--r-- | lisp/textmodes/reftex-toc.el | 2 | ||||
-rw-r--r-- | lisp/textmodes/reftex-vars.el | 54 | ||||
-rw-r--r-- | lisp/textmodes/reftex.el | 34 | ||||
-rw-r--r-- | lisp/textmodes/remember.el | 28 | ||||
-rw-r--r-- | lisp/textmodes/sgml-mode.el | 173 | ||||
-rw-r--r-- | lisp/textmodes/table.el | 2 | ||||
-rw-r--r-- | lisp/textmodes/tex-mode.el | 117 | ||||
-rw-r--r-- | lisp/textmodes/texinfo.el | 112 | ||||
-rw-r--r-- | lisp/textmodes/tildify.el | 4 |
19 files changed, 1002 insertions, 541 deletions
diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el index c2978b0ea40..2bd7283676e 100644 --- a/lisp/textmodes/artist.el +++ b/lisp/textmodes/artist.el @@ -198,7 +198,7 @@ ;; Variables (defconst artist-version "1.2.6") -(defconst artist-maintainer-address "tab@lysator.liu.se") +(defconst artist-maintainer-address "tab@lysator.liu.se, bug-gnu-emacs@gnu.org") (defvar x-pointer-crosshair) diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el index aa20b739946..01a126eb381 100644 --- a/lisp/textmodes/bibtex.el +++ b/lisp/textmodes/bibtex.el @@ -3020,11 +3020,14 @@ Parsing initializes `bibtex-reference-keys' and `bibtex-strings'." Visit the BibTeX files defined by `bibtex-files' and return a list of corresponding buffers. Initialize in these buffers `bibtex-reference-keys' if not yet set. -List of BibTeX buffers includes current buffer if CURRENT is non-nil. +List of BibTeX buffers includes current buffer if CURRENT is non-nil +and the current buffer visits a file using `bibtex-mode'. If FORCE is non-nil, (re)initialize `bibtex-reference-keys' even if already set. If SELECT is non-nil interactively select a BibTeX buffer. -When called interactively, FORCE is t, CURRENT is t if current buffer uses -`bibtex-mode', and SELECT is t if current buffer does not use `bibtex-mode'," + +When called interactively, FORCE is t, CURRENT is t if current buffer +visits a file using `bibtex-mode', and SELECT is t if current buffer +does not use `bibtex-mode'," (interactive (list (eq major-mode 'bibtex-mode) t (not (eq major-mode 'bibtex-mode)))) (let ((file-path (split-string (or bibtex-file-path default-directory) ":+")) @@ -3062,10 +3065,12 @@ When called interactively, FORCE is t, CURRENT is t if current buffer uses (if (file-readable-p file) (push (find-file-noselect file) buffer-list))) ;; Include current buffer iff we want it. - ;; Exclude current buffer if it doesn't use `bibtex-mode'. - ;; Thus calling `bibtex-initialize' gives meaningful results for - ;; any current buffer. - (unless (and current (eq major-mode 'bibtex-mode)) (setq current nil)) + ;; Exclude current buffer if it does not visit a file using `bibtex-mode'. + ;; This way we exclude BibTeX buffers such as `bibtex-search-buffer' + ;; that are not visiting a BibTeX file. Also, calling `bibtex-initialize' + ;; gives meaningful results for any current buffer. + (unless (and current (eq major-mode 'bibtex-mode) buffer-file-name) + (setq current nil)) (cond ((and current (not (memq (current-buffer) buffer-list))) (push (current-buffer) buffer-list)) ((and (not current) (memq (current-buffer) buffer-list)) @@ -5163,6 +5168,9 @@ Return the URL or nil if none can be generated." (if (stringp (car scheme)) (setq fmt (pop scheme))) (dolist (step scheme) + ;; In the first STEP, if the field contains multiple + ;; matches, we want the match the closest to point. + ;; (if (eq step (car scheme)) (setq text (cdr (assoc-string (car step) fields-alist t))) (if (string-match (nth 1 step) text) (push (cond ((functionp (nth 2 step)) @@ -5233,19 +5241,22 @@ where FILE is the BibTeX file of ENTRY." (if (string= "" field) ;; Unrestricted search. (while (re-search-forward regexp nil t) - (let ((beg (bibtex-beginning-of-entry)) - (end (bibtex-end-of-entry)) - key) - (if (and (<= beg (match-beginning 0)) - (<= (match-end 0) end) - (save-excursion - (goto-char beg) - (and (looking-at bibtex-entry-head) - (setq key (bibtex-key-in-head)))) - (not (assoc key entries))) - (push (list key file - (buffer-substring-no-properties beg end)) - entries)))) + (save-excursion + (let ((mbeg (match-beginning 0)) + (mend (match-end 0)) + (beg (bibtex-beginning-of-entry)) + (end (bibtex-end-of-entry)) + key) + (if (and (<= beg mbeg) + (<= mend end) + (progn + (goto-char beg) + (looking-at bibtex-entry-head)) + (setq key (bibtex-key-in-head)) + (not (assoc key entries))) + (push (list key file + (buffer-substring-no-properties beg end)) + entries))))) ;; The following is slow. But it works reliably even in more ;; complicated cases with BibTeX string constants and crossrefed ;; entries. If you prefer speed over reliability, perform an diff --git a/lisp/textmodes/conf-mode.el b/lisp/textmodes/conf-mode.el index 93ff179229b..67f2d96d003 100644 --- a/lisp/textmodes/conf-mode.el +++ b/lisp/textmodes/conf-mode.el @@ -1,4 +1,4 @@ -;;; conf-mode.el --- Simple major mode for editing conf/ini/properties files +;;; conf-mode.el --- Simple major mode for editing conf/ini/properties files -*- coding: utf-8 -*- ;; Copyright (C) 2004-2013 Free Software Foundation, Inc. @@ -23,7 +23,7 @@ ;;; Commentary: ;; ;; This mode is designed to edit many similar varieties of Conf/Ini files and -;; Java properties. It started out from Aurélien Tisné's ini-mode. +;; Java properties. It started out from Aurélien Tisné's ini-mode. ;; `conf-space-keywords' were inspired by Robert Fitzgerald's any-ini-mode. diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index 97b1dcfb238..cb19c018839 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -266,22 +266,22 @@ ;;;###autoload (define-derived-mode css-mode fundamental-mode "CSS" "Major mode to edit Cascading Style Sheets." - (set (make-local-variable 'font-lock-defaults) css-font-lock-defaults) - (set (make-local-variable 'comment-start) "/*") - (set (make-local-variable 'comment-start-skip) "/\\*+[ \t]*") - (set (make-local-variable 'comment-end) "*/") - (set (make-local-variable 'comment-end-skip) "[ \t]*\\*+/") - (set (make-local-variable 'forward-sexp-function) 'css-forward-sexp) - (set (make-local-variable 'parse-sexp-ignore-comments) t) - (set (make-local-variable 'indent-line-function) 'css-indent-line) - (set (make-local-variable 'fill-paragraph-function) - 'css-fill-paragraph) + (setq-local font-lock-defaults css-font-lock-defaults) + (setq-local comment-start "/*") + (setq-local comment-start-skip "/\\*+[ \t]*") + (setq-local comment-end "*/") + (setq-local comment-end-skip "[ \t]*\\*+/") + (setq-local forward-sexp-function 'css-forward-sexp) + (setq-local parse-sexp-ignore-comments t) + (setq-local indent-line-function 'css-indent-line) + (setq-local fill-paragraph-function 'css-fill-paragraph) + (setq-local add-log-current-defun-function #'css-current-defun-name) (when css-electric-keys (let ((fc (make-char-table 'auto-fill-chars))) (set-char-table-parent fc auto-fill-chars) (dolist (c css-electric-keys) (aset fc c 'indent-according-to-mode)) - (set (make-local-variable 'auto-fill-chars) fc)))) + (setq-local auto-fill-chars fc)))) (defvar comment-continue) @@ -481,5 +481,15 @@ (save-excursion (indent-line-to indent)) (indent-line-to indent))))) +(defun css-current-defun-name () + "Return the name of the CSS section at point, or nil." + (save-excursion + (let ((max (max (point-min) (- (point) 1600)))) ; approx 20 lines back + (when (search-backward "{" max t) + (skip-chars-backward " \t\r\n") + (beginning-of-line) + (if (looking-at "^[ \t]*\\([^{\r\n]*[^ {\t\r\n]\\)") + (match-string-no-properties 1)))))) + (provide 'css-mode) ;;; css-mode.el ends here diff --git a/lisp/textmodes/fill.el b/lisp/textmodes/fill.el index feb2fa6cc73..5b6d5f359e6 100644 --- a/lisp/textmodes/fill.el +++ b/lisp/textmodes/fill.el @@ -721,7 +721,11 @@ space does not end a sentence, so don't break a line there." (move-to-column (current-fill-column)) (if (when (< (point) to) ;; Find the position where we'll break the line. - (forward-char 1) ;Use an immediately following space, if any. + ;; Use an immediately following space, if any. + ;; However, note that `move-to-column' may overshoot + ;; if there are wide characters (Bug#3234). + (unless (> (current-column) (current-fill-column)) + (forward-char 1)) (fill-move-to-break-point linebeg) ;; Check again to see if we got to the end of ;; the paragraph. diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el index 7e692960dbc..81f17c897eb 100644 --- a/lisp/textmodes/flyspell.el +++ b/lisp/textmodes/flyspell.el @@ -63,7 +63,7 @@ Non-nil means use highlight, nil means use minibuffer messages." "Non-nil means Flyspell reports a repeated word as an error. See `flyspell-mark-duplications-exceptions' to add exceptions to this rule. Detection of repeated words is not implemented in -\"large\" regions; see `flyspell-large-region'." +\"large\" regions; see variable `flyspell-large-region'." :group 'flyspell :type 'boolean) @@ -145,9 +145,10 @@ whose length is specified by `flyspell-delay'." (defcustom flyspell-default-deplacement-commands '(next-line previous-line handle-switch-frame handle-select-window - scroll-up scroll-down) + scroll-up + scroll-down) "The standard list of deplacement commands for Flyspell. -See `flyspell-deplacement-commands'." +See variable `flyspell-deplacement-commands'." :group 'flyspell :version "21.1" :type '(repeat (symbol))) @@ -445,13 +446,23 @@ like <img alt=\"Some thing.\">." ;;*---------------------------------------------------------------------*/ ;;* Highlighting */ ;;*---------------------------------------------------------------------*/ -(defface flyspell-incorrect '((t :underline t :inherit error)) +(defface flyspell-incorrect + '((((supports :underline (:style wave))) + :underline (:style wave :color "Red1")) + (t + :underline t :inherit error)) "Flyspell face for misspelled words." + :version "24.4" :group 'flyspell) -(defface flyspell-duplicate '((t :underline t :inherit warning)) +(defface flyspell-duplicate + '((((supports :underline (:style wave))) + :underline (:style wave :color "DarkOrange")) + (t + :underline t :inherit warning)) "Flyspell face for words that appear twice in a row. See also `flyspell-duplicate-distance'." + :version "24.4" :group 'flyspell) (defvar flyspell-overlay nil) @@ -727,7 +738,7 @@ before the current command." (let ((ispell-otherchars (ispell-get-otherchars))) (cond ((not (and (numberp flyspell-pre-point) - (buffer-live-p flyspell-pre-buffer))) + (eq flyspell-pre-buffer (current-buffer)))) nil) ((and (eq flyspell-pre-pre-point flyspell-pre-point) (eq flyspell-pre-pre-buffer flyspell-pre-buffer)) @@ -945,11 +956,10 @@ Mostly we check word delimiters." ;; Prevent anything we do from affecting the mark. deactivate-mark) (if (flyspell-check-pre-word-p) - (with-current-buffer flyspell-pre-buffer + (save-excursion '(flyspell-debug-signal-pre-word-checked) - (save-excursion - (goto-char flyspell-pre-point) - (flyspell-word)))) + (goto-char flyspell-pre-point) + (flyspell-word))) (if (flyspell-check-word-p) (progn '(flyspell-debug-signal-word-checked) @@ -963,16 +973,14 @@ Mostly we check word delimiters." ;; FLYSPELL-CHECK-PRE-WORD-P (setq flyspell-pre-pre-buffer (current-buffer)) (setq flyspell-pre-pre-point (point))) - (progn - (setq flyspell-pre-pre-buffer nil) - (setq flyspell-pre-pre-point nil) - ;; when a word is not checked because of a delayed command - ;; we do not disable the ispell cache. - (if (and (symbolp this-command) + (setq flyspell-pre-pre-buffer nil) + (setq flyspell-pre-pre-point nil) + ;; when a word is not checked because of a delayed command + ;; we do not disable the ispell cache. + (when (and (symbolp this-command) (get this-command 'flyspell-delayed)) - (progn - (setq flyspell-word-cache-end -1) - (setq flyspell-word-cache-result '_))))) + (setq flyspell-word-cache-end -1) + (setq flyspell-word-cache-result '_))) (while (and (not (input-pending-p)) (consp flyspell-changes)) (let ((start (car (car flyspell-changes))) (stop (cdr (car flyspell-changes)))) diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index 1d28de72996..94b184d09a1 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -357,6 +357,10 @@ Must be greater than 1." "ispell") "Program invoked by \\[ispell-word] and \\[ispell-region] commands." :type 'string + :set (lambda (symbol value) + (set-default symbol value) + (if (featurep 'ispell) + (ispell-set-spellchecker-params))) :group 'ispell) (defcustom ispell-alternate-dictionary @@ -745,8 +749,10 @@ OTHERCHARS slots of the alist should contain the same character set as casechars and otherchars in the LANGUAGE.aff file \(e.g., english.aff\). aspell and hunspell don't have this limitation.") -(defvar ispell-really-aspell nil) ; Non-nil if we can use aspell extensions. -(defvar ispell-really-hunspell nil) ; Non-nil if we can use hunspell extensions. +(defvar ispell-really-aspell nil + "Non-nil if we can use aspell extensions.") +(defvar ispell-really-hunspell nil + "Non-nil if we can use hunspell extensions.") (defvar ispell-encoding8-command nil "Command line option prefix to select encoding if supported, nil otherwise. If setting the encoding is supported by spellchecker and is selectable from @@ -769,6 +775,41 @@ here just for backwards compatibility.") (make-obsolete-variable 'ispell-aspell-supports-utf8 'ispell-encoding8-command "23.1") +(defvar ispell-hunspell-dictionary-equivs-alist + '(("american" "en_US") + ("brasileiro" "pt_BR") + ("british" "en_GB") + ("castellano" "es_ES") + ("castellano8" "es_ES") + ("czech" "cs_CZ") + ("dansk" "da_DK") + ("deutsch" "de_DE") + ("deutsch8" "de_DE") + ("english" "en_US") + ("esperanto" "eo") + ("esperanto-tex" "eo") + ("finnish" "fi_FI") + ("francais7" "fr_FR") + ("francais" "fr_FR") + ("francais-tex" "fr_FR") + ("german" "de_DE") + ("german8" "de_DE") + ("italiano" "it_IT") + ("nederlands" "nl_NL") + ("nederlands8" "nl_NL") + ("norsk" "nn_NO") + ("norsk7-tex" "nn_NO") + ("polish" "pl_PL") + ("portugues" "pt_PT") + ("russian" "ru_RU") + ("russianw" "ru_RU") + ("slovak" "sk_SK") + ("slovenian" "sl_SI") + ("svenska" "sv_SE") + ("hebrew" "he_IL")) + "Alist with matching hunspell dict names for standard dict names in + `ispell-dictionary-base-alist'.") + (defvar ispell-emacs-alpha-regexp (if (string-match "^[[:alpha:]]+$" "abcde") "[[:alpha:]]" @@ -821,7 +862,7 @@ Otherwise returns the library directory name, if that is defined." (if (string-match "\\`aspell" speller) "-v" "-vv")))) (goto-char (point-min)) (if interactivep - ;; report version information of ispell and ispell.el + ;; Report version information of ispell and ispell.el (progn (end-of-line) (setq result (concat (buffer-substring-no-properties (point-min) @@ -903,6 +944,25 @@ Otherwise returns the library directory name, if that is defined." (setq default-directory (expand-file-name "~/"))) (apply 'call-process-region args))) +(defun ispell-create-debug-buffer (&optional append) + "Create an ispell debug buffer for debugging output. +Use APPEND to append the info to previous buffer if exists, +otherwise is reset. Returns name of ispell debug buffer. +See `ispell-buffer-with-debug' for an example of use." + (let ((ispell-debug-buffer (get-buffer-create "*ispell-debug*"))) + (with-current-buffer ispell-debug-buffer + (if append + (insert + (format "-----------------------------------------------\n")) + (erase-buffer))) + ispell-debug-buffer)) + +(defsubst ispell-print-if-debug (format &rest args) + "Print message to `ispell-debug-buffer' buffer if enabled." + (if (boundp 'ispell-debug-buffer) + (with-current-buffer ispell-debug-buffer + (goto-char (point-max)) + (insert (apply #'format format args))))) ;; The preparation of the menu bar menu must be autoloaded @@ -1072,6 +1132,176 @@ Return the new dictionary alist." (push (cons aliasname (cdr realdict)) alist)))))) alist)) +;; Make ispell.el work better with hunspell. + +(defvar ispell-hunspell-dict-paths-alist nil + "Alist of parsed hunspell dicts and associated affix files. +Will be used to parse corresponding .aff file and create associated +parameters to be inserted into `ispell-hunspell-dictionary-alist'. +Internal use.") + +(defvar ispell-hunspell-dictionary-alist nil + "Alist of parsed hunspell dicts and associated parameters. +This alist will initially contain names of found dicts. Associated +parameters will be added when dict is used for the first time. +Internal use.") + +(defun ispell-hunspell-fill-dictionary-entry (dict) + "Fill `ispell-dictionary-alist' uninitialized entries for `DICT' and aliases. +Value will be extracted from hunspell affix file and used for +all uninitialized dicts using that affix file." + (if (cadr (assoc dict ispell-dictionary-alist)) + (message "ispell-hfde: Non void entry for %s. Skipping.\n" dict) + (let ((dict-alias + (cadr (assoc dict ispell-hunspell-dictionary-equivs-alist))) + (use-for-dicts (list dict)) + (dict-args-cdr (cdr (ispell-parse-hunspell-affix-file dict))) + newlist) + ;; Get a list of uninitialized dicts using the same affix file. + (dolist (dict-equiv-alist-entry ispell-hunspell-dictionary-equivs-alist) + (let ((dict-equiv-key (car dict-equiv-alist-entry)) + (dict-equiv-value (cadr dict-equiv-alist-entry))) + (if (or (member dict dict-equiv-alist-entry) + (member dict-alias dict-equiv-alist-entry)) + (dolist ( tmp-dict (list dict-equiv-key dict-equiv-value)) + (if (cadr (assoc tmp-dict ispell-dictionary-alist)) + (ispell-print-if-debug + "ispell-hfde: %s already expanded. Skipping.\n" tmp-dict) + (add-to-list 'use-for-dicts tmp-dict)))))) + (ispell-print-if-debug + "ispell-hfde: Filling %s entry. Use for %s.\n" dict use-for-dicts) + ;; The final loop. + (dolist (entry ispell-dictionary-alist) + (if (member (car entry) use-for-dicts) + (add-to-list 'newlist + (append (list (car entry)) dict-args-cdr)) + (add-to-list 'newlist entry))) + (setq ispell-dictionary-alist newlist)))) + +(defun ispell-parse-hunspell-affix-file (dict-key) + "Parse hunspell affix file to extract parameters for `DICT-KEY'. +Return a list in `ispell-dictionary-alist' format." + (let ((affix-file (cadr (assoc dict-key ispell-hunspell-dict-paths-alist)))) + (unless affix-file + (error "ispell-phaf: No matching entry for %s.\n" dict-key)) + (if (not (file-exists-p affix-file)) + (error "ispell-phaf: File \"%s\" not found.\n" affix-file)) + (let ((dict-name (file-name-sans-extension + (file-name-nondirectory affix-file))) + otherchars-string otherchars-list) + (with-temp-buffer + (insert-file-contents affix-file) + (setq otherchars-string + (save-excursion + (goto-char (point-min)) + (if (search-forward-regexp "^WORDCHARS +" nil t ) + (buffer-substring (point) + (progn (end-of-line) (point)))))) + ;; Remove trailing whitespace and extra stuff. Make list if + ;; non-nil. + (setq otherchars-list + (if otherchars-string + (split-string + (if (string-match " +.*$" otherchars-string) + (replace-match "" nil nil otherchars-string) + otherchars-string) + "" t))) + + ;; Fill dict entry + (list dict-key + "[[:alpha:]]" + "[^[:alpha:]]" + (if otherchars-list + (regexp-opt otherchars-list) + "") + t ; many-otherchars-p: We can't tell, set to t. + (list "-d" dict-name) + nil ; extended-char-mode: not supported by hunspell! + 'utf-8))))) + +(defun ispell-find-hunspell-dictionaries () + "Look for installed hunspell dictionaries. +Will initialize `ispell-hunspell-dictionary-alist' and +`ispell-hunspell-dictionary-alist' after values found +and remove `ispell-hunspell-dictionary-equivs-alist' +entries if a specific dict was found." + (let ((hunspell-found-dicts + (split-string + (with-temp-buffer + (ispell-call-process ispell-program-name + null-device + t + nil + "-D") + (buffer-string)) + "[\n\r]+" + t)) + hunspell-default-dict + hunspell-default-dict-entry) + (dolist (dict hunspell-found-dicts) + (let* ((full-name (file-name-nondirectory dict)) + (basename (file-name-sans-extension full-name)) + (affix-file (concat dict ".aff"))) + (if (string-match "\\.aff$" dict) + ;; Found default dictionary + (if hunspell-default-dict + (error "ispell-fhd: Default dict already defined as %s. Not using %s.\n" + hunspell-default-dict dict) + (setq affix-file dict) + (setq hunspell-default-dict (list basename affix-file))) + (if (and (not (assoc basename ispell-hunspell-dict-paths-alist)) + (file-exists-p affix-file)) + ;; Entry has an associated .aff file and no previous value. + (let ((affix-file (expand-file-name affix-file))) + (ispell-print-if-debug + "++ ispell-fhd: dict-entry:%s name:%s basename:%s affix-file:%s\n" + dict full-name basename affix-file) + (add-to-list 'ispell-hunspell-dict-paths-alist + (list basename affix-file))) + (ispell-print-if-debug + "-- ispell-fhd: Skipping entry: %s\n" dict))))) + ;; Remove entry from aliases alist if explicit dict was found. + (let (newlist) + (dolist (dict ispell-hunspell-dictionary-equivs-alist) + (if (assoc (car dict) ispell-hunspell-dict-paths-alist) + (ispell-print-if-debug + "-- ispell-fhd: Excluding %s alias. Standalone dict found.\n" + (car dict)) + (add-to-list 'newlist dict))) + (setq ispell-hunspell-dictionary-equivs-alist newlist)) + ;; Add known hunspell aliases + (dolist (dict-equiv ispell-hunspell-dictionary-equivs-alist) + (let ((dict-equiv-key (car dict-equiv)) + (dict-equiv-value (cadr dict-equiv)) + (exclude-aliases (list ;; Exclude TeX aliases + "esperanto-tex" + "francais7" + "francais-tex" + "norsk7-tex"))) + (if (and (assoc dict-equiv-value ispell-hunspell-dict-paths-alist) + (not (assoc dict-equiv-key ispell-hunspell-dict-paths-alist)) + (not (member dict-equiv-key exclude-aliases))) + (let ((affix-file (cadr (assoc dict-equiv-value + ispell-hunspell-dict-paths-alist)))) + (ispell-print-if-debug "++ ispell-fhd: Adding alias %s -> %s.\n" + dict-equiv-key affix-file) + (add-to-list + 'ispell-hunspell-dict-paths-alist + (list dict-equiv-key affix-file)))))) + ;; Parse and set values for default dictionary. + (setq hunspell-default-dict (car hunspell-default-dict)) + (setq hunspell-default-dict-entry + (ispell-parse-hunspell-affix-file hunspell-default-dict)) + ;; Create an alist of found dicts with only names, except for default dict. + (setq ispell-hunspell-dictionary-alist + (list (append (list nil) (cdr hunspell-default-dict-entry)))) + (dolist (dict (mapcar 'car ispell-hunspell-dict-paths-alist)) + (if (string= dict hunspell-default-dict) + (add-to-list 'ispell-hunspell-dictionary-alist + hunspell-default-dict-entry) + (add-to-list 'ispell-hunspell-dictionary-alist + (list dict)))))) + ;; Set params according to the selected spellchecker (defvar ispell-last-program-name nil @@ -1097,24 +1327,83 @@ aspell is used along with Emacs).") (setq ispell-library-directory (ispell-check-version)) t) (error nil)) - ispell-really-aspell ispell-encoding8-command ispell-emacs-alpha-regexp) - (unless ispell-aspell-dictionary-alist - (ispell-find-aspell-dictionaries))) - - ;; Substitute ispell-dictionary-alist with the list of dictionaries - ;; corresponding to the given spellchecker. If a recent aspell, use - ;; the list of really installed dictionaries and add to it elements - ;; of the original list that are not present there. Allow distro info. + ;; auto-detection will only be used if spellchecker is not + ;; ispell, supports a way to set communication to UTF-8 and + ;; Emacs flavor supports [:alpha:] + (if ispell-really-aspell + (or ispell-aspell-dictionary-alist + (ispell-find-aspell-dictionaries)) + (if ispell-really-hunspell + (or ispell-hunspell-dictionary-alist + (ispell-find-hunspell-dictionaries))))) + + ;; Substitute ispell-dictionary-alist with the list of + ;; dictionaries corresponding to the given spellchecker. + ;; If a recent aspell or hunspell, use the list of really + ;; installed dictionaries and add to it elements of the original + ;; list that are not present there. Allow distro info. (let ((found-dicts-alist - (if (and ispell-really-aspell - ispell-encoding8-command) - ispell-aspell-dictionary-alist + (if (and ispell-encoding8-command + ispell-emacs-alpha-regexp) + (if ispell-really-aspell + ispell-aspell-dictionary-alist + (if ispell-really-hunspell + ispell-hunspell-dictionary-alist)) nil)) + (ispell-dictionary-base-alist ispell-dictionary-base-alist) ispell-base-dicts-override-alist ; Override only base-dicts-alist all-dicts-alist) + ;; While ispell and aspell (through aliases) use the traditional + ;; dict naming originally expected by ispell.el, hunspell + ;; uses locale based names with no alias. We need to map + ;; standard names to locale based names to make default dict + ;; definitions available for hunspell. + (if ispell-really-hunspell + (let (tmp-dicts-alist) + (dolist (adict ispell-dictionary-base-alist) + (let* ((dict-name (nth 0 adict)) + (dict-equiv + (cadr (assoc dict-name + ispell-hunspell-dictionary-equivs-alist))) + (ispell-args (nth 5 adict)) + (ispell-args-has-d (member "-d" ispell-args)) + skip-dict) + ;; Remove "-d" option from `ispell-args' if present + (if ispell-args-has-d + (let ((ispell-args-after-d + (cdr (cdr ispell-args-has-d))) + (ispell-args-before-d + (butlast ispell-args (length ispell-args-has-d)))) + (setq ispell-args + (nconc ispell-args-before-d + ispell-args-after-d)))) + ;; Unless default dict, re-add "-d" option with the mapped value + (if dict-name + (if dict-equiv + (setq ispell-args + (nconc ispell-args (list "-d" dict-equiv))) + (message + "ispell-set-spellchecker-params: Missing hunspell equiv for \"%s\". Skipping." + dict-name) + (setq skip-dict t))) + + (unless skip-dict + (add-to-list 'tmp-dicts-alist + (list + dict-name ; dict name + (nth 1 adict) ; casechars + (nth 2 adict) ; not-casechars + (nth 3 adict) ; otherchars + (nth 4 adict) ; many-otherchars-p + ispell-args ; ispell-args + (nth 6 adict) ; extended-character-mode + (nth 7 adict) ; dict encoding + )))) + (setq ispell-dictionary-base-alist tmp-dicts-alist)))) + (run-hooks 'ispell-initialize-spellchecker-hook) ;; Add dicts to ``ispell-dictionary-alist'' unless already present. @@ -1132,19 +1421,21 @@ aspell is used along with Emacs).") (if ispell-emacs-alpha-regexp (let (tmp-dicts-alist) (dolist (adict ispell-dictionary-alist) - (add-to-list 'tmp-dicts-alist - (list - (nth 0 adict) ; dict name - "[[:alpha:]]" ; casechars - "[^[:alpha:]]" ; not-casechars - (nth 3 adict) ; otherchars - (nth 4 adict) ; many-otherchars-p - (nth 5 adict) ; ispell-args - (nth 6 adict) ; extended-character-mode - (if ispell-encoding8-command - 'utf-8 - (nth 7 adict))))) - (setq ispell-dictionary-alist tmp-dicts-alist))))) + (if (cadr adict) ;; Do not touch hunspell uninitialized entries + (add-to-list 'tmp-dicts-alist + (list + (nth 0 adict) ; dict name + "[[:alpha:]]" ; casechars + "[^[:alpha:]]" ; not-casechars + (nth 3 adict) ; otherchars + (nth 4 adict) ; many-otherchars-p + (nth 5 adict) ; ispell-args + (nth 6 adict) ; extended-character-mode + (if ispell-encoding8-command + 'utf-8 + (nth 7 adict)))) + (add-to-list 'tmp-dicts-alist adict))) + (setq ispell-dictionary-alist tmp-dicts-alist))))) (defun ispell-valid-dictionary-list () "Return a list of valid dictionaries. @@ -1572,8 +1863,8 @@ You can set this variable in hooks in your init file -- eg: (defun ispell-accept-output (&optional timeout-secs timeout-msecs) "Wait for output from ispell process, or TIMEOUT-SECS and TIMEOUT-MSECS. -If asynchronous subprocesses are not supported, call `ispell-filter' and -pass it the output of the last ispell invocation." +If asynchronous subprocesses are not supported, call function `ispell-filter' +and pass it the output of the last ispell invocation." (if ispell-async-processp (accept-process-output ispell-process timeout-secs timeout-msecs) (if (null ispell-process) @@ -2038,10 +2329,14 @@ Global `ispell-quit' set to start location to continue spell session." ((= char ?i) ; accept and insert word into pers dict (ispell-send-string (concat "*" word "\n")) (setq ispell-pdict-modified-p '(t)) ; dictionary modified! + (and (fboundp 'flyspell-unhighlight-at) + (flyspell-unhighlight-at start)) nil) ((or (= char ?a) (= char ?A)) ; accept word without insert (ispell-send-string (concat "@" word "\n")) (add-to-list 'ispell-buffer-session-localwords word) + (and (fboundp 'flyspell-unhighlight-at) + (flyspell-unhighlight-at start)) (or ispell-buffer-local-name ; session localwords might conflict (setq ispell-buffer-local-name (buffer-name))) (if (null ispell-pdict-modified-p) @@ -2630,11 +2925,14 @@ When asynchronous processes are not supported, `run' is always returned." (defun ispell-start-process () "Start the Ispell process, with support for no asynchronous processes. Keeps argument list for future Ispell invocations for no async support." - ;; Local dictionary becomes the global dictionary in use. - (setq ispell-current-dictionary - (or ispell-local-dictionary ispell-dictionary)) - (setq ispell-current-personal-dictionary - (or ispell-local-pdict ispell-personal-dictionary)) + ;; `ispell-current-dictionary' and `ispell-current-personal-dictionary' + ;; are properly set in `ispell-internal-change-dictionary'. + + ;; Parse hunspell affix file if using hunspell and entry is uninitialized. + (if ispell-really-hunspell + (or (cadr (assoc ispell-current-dictionary ispell-dictionary-alist)) + (ispell-hunspell-fill-dictionary-entry ispell-current-dictionary))) + (let* ((default-directory (if (and (file-directory-p default-directory) (file-readable-p default-directory)) @@ -2649,8 +2947,7 @@ Keeps argument list for future Ispell invocations for no async support." (list "-d" ispell-current-dictionary)) orig-args (if ispell-current-personal-dictionary ; Use specified pers dict. - (list "-p" - (expand-file-name ispell-current-personal-dictionary))) + (list "-p" ispell-current-personal-dictionary)) ;; If we are using recent aspell or hunspell, make sure we use the ;; right encoding for communication. ispell or older aspell/hunspell ;; does not support this. @@ -2687,6 +2984,9 @@ Keeps argument list for future Ispell invocations for no async support." (let* (;; Basename of dictionary used by the spell-checker (dict-bname (or (car (cdr (member "-d" (ispell-get-ispell-args)))) ispell-current-dictionary)) + ;; The directory where process was started. + (current-ispell-directory default-directory) + ;; The default directory for the process. ;; Use "~/" as default-directory unless using Ispell with per-dir ;; personal dictionaries and not in a minibuffer under XEmacs (default-directory @@ -2877,13 +3177,15 @@ By just answering RET you can find out what the current dictionary is." "Update the dictionary and the personal dictionary used by Ispell. This may kill the Ispell process; if so, a new one will be started when needed." - (let ((dict (or ispell-local-dictionary ispell-dictionary)) - (pdict (or ispell-local-pdict ispell-personal-dictionary))) + (let* ((dict (or ispell-local-dictionary ispell-dictionary)) + (pdict (or ispell-local-pdict ispell-personal-dictionary)) + (expanded-pdict (if pdict (expand-file-name pdict)))) (unless (and (equal ispell-current-dictionary dict) - (equal ispell-current-personal-dictionary pdict)) + (equal ispell-current-personal-dictionary + expanded-pdict)) (ispell-kill-ispell t) (setq ispell-current-dictionary dict - ispell-current-personal-dictionary pdict)))) + ispell-current-personal-dictionary expanded-pdict)))) ;; Avoid error messages when compiling for these dynamic variables. (defvar ispell-start) @@ -2901,114 +3203,137 @@ amount for last line processed." (if (not recheckp) (ispell-accept-buffer-local-defs)) ; set up dictionary, local words, etc. (let ((skip-region-start (make-marker)) - (rstart (make-marker))) - (unwind-protect - (save-excursion - (message "Spell-checking %s using %s with %s dictionary..." - (if (and (= reg-start (point-min)) (= reg-end (point-max))) - (buffer-name) "region") - (file-name-nondirectory ispell-program-name) - (or ispell-current-dictionary "default")) - ;; Returns cursor to original location. - (save-window-excursion - (goto-char reg-start) - (let ((transient-mark-mode) - (case-fold-search case-fold-search) - (query-fcc t) - in-comment key) - (let (message-log-max) - (message "searching for regions to skip")) - (if (re-search-forward (ispell-begin-skip-region-regexp) reg-end t) - (progn - (setq key (match-string-no-properties 0)) - (set-marker skip-region-start (- (point) (length key))) - (goto-char reg-start))) - (let (message-log-max) - (message - "Continuing spelling check using %s with %s dictionary..." - (file-name-nondirectory ispell-program-name) - (or ispell-current-dictionary "default"))) - (set-marker rstart reg-start) - (set-marker ispell-region-end reg-end) - (while (and (not ispell-quit) - (< (point) ispell-region-end)) - ;; spell-check region with skipping - (if (and (marker-position skip-region-start) - (<= skip-region-start (point))) + (rstart (make-marker)) + (region-type (if (and (= reg-start (point-min)) (= reg-end (point-max))) + (buffer-name) "region")) + (program-basename (file-name-nondirectory ispell-program-name)) + (dictionary (or ispell-current-dictionary "default"))) + (unwind-protect + (save-excursion + (message "Spell-checking %s using %s with %s dictionary..." + region-type program-basename dictionary) + ;; Returns cursor to original location. + (save-window-excursion + (goto-char reg-start) + (let ((transient-mark-mode) + (case-fold-search case-fold-search) + (query-fcc t) + in-comment key) + (ispell-print-if-debug + "ispell-region: (ispell-skip-region-list):\n%s +ispell-region: (ispell-begin-skip-region-regexp):\n%s +ispell-region: Search for first region to skip after (ispell-begin-skip-region-regexp)\n" + (ispell-skip-region-list) + (ispell-begin-skip-region-regexp)) + (if (re-search-forward (ispell-begin-skip-region-regexp) reg-end t) (progn - ;; If region inside line comment, must keep comment start. - (setq in-comment (point) - in-comment - (and comment-start - (or (null comment-end) (string= "" comment-end)) - (save-excursion - (beginning-of-line) - (re-search-forward comment-start in-comment t)) - comment-start)) - ;; Can change skip-regexps (in ispell-message) - (ispell-skip-region key) ; moves pt past region. - (set-marker rstart (point)) - ;; check for saving large attachments... - (setq query-fcc (and query-fcc - (ispell-ignore-fcc skip-region-start - rstart))) - (if (and (< rstart ispell-region-end) - (re-search-forward - (ispell-begin-skip-region-regexp) - ispell-region-end t)) - (progn - (setq key (match-string-no-properties 0)) - (set-marker skip-region-start - (- (point) (length key))) - (goto-char rstart)) - (set-marker skip-region-start nil)))) - (setq reg-end (max (point) - (if (marker-position skip-region-start) - (min skip-region-start ispell-region-end) - (marker-position ispell-region-end)))) - (let* ((ispell-start (point)) - (ispell-end (min (point-at-eol) reg-end)) - (string (ispell-get-line - ispell-start ispell-end in-comment))) - (if in-comment ; account for comment chars added - (setq ispell-start (- ispell-start (length in-comment)) - in-comment nil)) - (setq ispell-end (point)) ; "end" tracks region retrieved. - (if string ; there is something to spell check! - ;; (special start end) - (setq shift (ispell-process-line string - (and recheckp shift)))) - (goto-char ispell-end))))) - (if ispell-quit - nil - (or shift 0))) - ;; protected - (if (and (not (and recheckp ispell-keep-choices-win)) - (get-buffer ispell-choices-buffer)) - (kill-buffer ispell-choices-buffer)) - (set-marker skip-region-start nil) - (set-marker rstart nil) - (if ispell-quit - (progn - ;; preserve or clear the region for ispell-continue. - (if (not (numberp ispell-quit)) - (set-marker ispell-region-end nil) - ;; Ispell-continue enabled - ispell-region-end is set. - (goto-char ispell-quit)) - ;; Check for aborting - (if (and ispell-checking-message (numberp ispell-quit)) - (progn - (setq ispell-quit nil) - (error "Message send aborted"))) - (if (not recheckp) (setq ispell-quit nil))) - (if (not recheckp) (set-marker ispell-region-end nil)) - ;; Only save if successful exit. - (ispell-pdict-save ispell-silently-savep) - (message "Spell-checking %s using %s with %s dictionary...done" - (if (and (= reg-start (point-min)) (= reg-end (point-max))) - (buffer-name) "region") - (file-name-nondirectory ispell-program-name) - (or ispell-current-dictionary "default")))))) + (setq key (match-string-no-properties 0)) + (set-marker skip-region-start (- (point) (length key))) + (goto-char reg-start) + (ispell-print-if-debug + "ispell-region: First skip: %s at (pos,line,column): (%s,%s,%s).\n" + key + (save-excursion (goto-char skip-region-start) (point)) + (line-number-at-pos skip-region-start) + (save-excursion (goto-char skip-region-start) (current-column))))) + (ispell-print-if-debug + "ispell-region: Continue spell-checking with %s and %s dictionary...\n" + program-basename dictionary) + (set-marker rstart reg-start) + (set-marker ispell-region-end reg-end) + (while (and (not ispell-quit) + (< (point) ispell-region-end)) + ;; spell-check region with skipping + (if (and (marker-position skip-region-start) + (<= skip-region-start (point))) + (progn + ;; If region inside line comment, must keep comment start. + (setq in-comment (point) + in-comment + (and comment-start + (or (null comment-end) (string= "" comment-end)) + (save-excursion + (beginning-of-line) + (re-search-forward comment-start in-comment t)) + comment-start)) + ;; Can change skip-regexps (in ispell-message) + (ispell-skip-region key) ; moves pt past region. + (set-marker rstart (point)) + ;; check for saving large attachments... + (setq query-fcc (and query-fcc + (ispell-ignore-fcc skip-region-start + rstart))) + (if (and (< rstart ispell-region-end) + (re-search-forward + (ispell-begin-skip-region-regexp) + ispell-region-end t)) + (progn + (setq key (match-string-no-properties 0)) + (set-marker skip-region-start + (- (point) (length key))) + (goto-char rstart) + (ispell-print-if-debug + "ispell-region: Next skip: %s at (pos,line,column): (%s,%s,%s).\n" + key + (save-excursion (goto-char skip-region-start) (point)) + (line-number-at-pos skip-region-start) + (save-excursion (goto-char skip-region-start) (current-column)))) + (set-marker skip-region-start nil)))) + (setq reg-end (max (point) + (if (marker-position skip-region-start) + (min skip-region-start ispell-region-end) + (marker-position ispell-region-end)))) + (let* ((ispell-start (point)) + (ispell-end (min (point-at-eol) reg-end)) + ;; See if line must be prefixed by comment string to let ispell know this is + ;; part of a comment string. This is only supported in some modes. + ;; In particular, this is not supported in autoconf mode where adding the + ;; comment string messes everything up because ispell tries to spellcheck the + ;; `dnl' string header causing misalignments in some cases (debbugs.gnu.org: #12768). + (add-comment (and in-comment + (not (string= in-comment "dnl ")) + in-comment)) + (string (ispell-get-line + ispell-start ispell-end add-comment))) + (ispell-print-if-debug + "ispell-region: string pos (%s->%s), eol: %s, [in-comment]: [%s], [add-comment]: [%s], [string]: [%s]\n" + ispell-start ispell-end (point-at-eol) in-comment add-comment string) + (if add-comment ; account for comment chars added + (setq ispell-start (- ispell-start (length add-comment)) + add-comment nil)) + (setq ispell-end (point)) ; "end" tracks region retrieved. + (if string ; there is something to spell check! + ;; (special start end) + (setq shift (ispell-process-line string + (and recheckp shift)))) + (goto-char ispell-end))))) + (if ispell-quit + nil + (or shift 0))) + ;; protected + (if (and (not (and recheckp ispell-keep-choices-win)) + (get-buffer ispell-choices-buffer)) + (kill-buffer ispell-choices-buffer)) + (set-marker skip-region-start nil) + (set-marker rstart nil) + (if ispell-quit + (progn + ;; preserve or clear the region for ispell-continue. + (if (not (numberp ispell-quit)) + (set-marker ispell-region-end nil) + ;; Ispell-continue enabled - ispell-region-end is set. + (goto-char ispell-quit)) + ;; Check for aborting + (if (and ispell-checking-message (numberp ispell-quit)) + (progn + (setq ispell-quit nil) + (error "Message send aborted"))) + (if (not recheckp) (setq ispell-quit nil))) + (if (not recheckp) (set-marker ispell-region-end nil)) + ;; Only save if successful exit. + (ispell-pdict-save ispell-silently-savep) + (message "Spell-checking %s using %s with %s dictionary...done" + region-type program-basename dictionary))))) (defun ispell-begin-skip-region-regexp () @@ -3255,113 +3580,122 @@ Returns the sum SHIFT due to changes in word replacements." ;; Alignment cannot be tracked and this error will occur when ;; `query-replace' makes multiple corrections on the starting line. (or (ispell-looking-at (car poss)) - ;; This occurs due to filter pipe problems - (error (concat "Ispell misalignment: word " - "`%s' point %d; probably incompatible versions") - (car poss) (marker-position word-start))) - ;; ispell-cmd-loop can go recursive & change buffer - (if ispell-keep-choices-win - (setq replace (ispell-command-loop - (car (cdr (cdr poss))) - (car (cdr (cdr (cdr poss)))) - (car poss) (marker-position word-start) - (+ word-len (marker-position word-start)))) - (save-window-excursion - (setq replace (ispell-command-loop - (car (cdr (cdr poss))) - (car (cdr (cdr (cdr poss)))) - (car poss) (marker-position word-start) - (+ word-len (marker-position word-start)))))) - - (goto-char word-start) - ;; Recheck when query replace edit changes misspelled word. - ;; Error in tex mode when a potential math mode change exists. - (if (and replace (listp replace) (= 2 (length replace))) - (if (and (eq ispell-parser 'tex) - (string-match "[\\\\][]()[]\\|\\\\begin\\|\\$" - (regexp-quote string))) - (error - "Don't start query replace on a line with math characters" - ) - (set-marker line-end (point)) - (setq ispell-filter nil - recheck-region t))) - - ;; insert correction if needed - (cond - ((or (null replace) - (equal 0 replace)) ; ACCEPT/INSERT - (if (equal 0 replace) ; BUFFER-LOCAL DICT ADD - (ispell-add-per-file-word-list (car poss))) - ;; do not recheck accepted word on this line - (setq accept-list (cons (car poss) accept-list))) - (t ; replacement word selected or entered - (delete-region (point) (+ word-len (point))) - (if (not (listp replace)) - (progn - (insert replace) ; insert dictionary word - (ispell-send-replacement (car poss) replace) - (setq accept-list (cons replace accept-list))) - (let ((replace-word (car replace))) - ;; Recheck hand entered replacement word - (insert replace-word) - (ispell-send-replacement (car poss) replace-word) - (if (car (cdr replace)) - (save-window-excursion - (delete-other-windows) ; to correctly show help. - ;; Assume case-replace & - ;; case-fold-search correct? - (query-replace (car poss) (car replace) t))) - (goto-char word-start) - ;; do not recheck if already accepted - (if (member replace-word accept-list) - (setq accept-list (cons replace-word accept-list) - replace replace-word) - (let ((region-end (copy-marker ispell-region-end))) - (setq recheck-region ispell-filter - ispell-filter nil ; save filter - shift 0 ; already accounted - shift (ispell-region - word-start - (+ word-start (length replace-word)) - t shift)) - (if (null shift) ; quitting check. - (setq shift 0)) - (set-marker ispell-region-end region-end) - (set-marker region-end nil) - (setq ispell-filter recheck-region - recheck-region nil - replace replace-word))))) - - (setq shift (+ shift (- (length replace) word-len))) - - ;; Move line-start across word... - ;; new shift function does this now... - ;;(set-marker line-start (+ line-start - ;; (- (length replace) - ;; (length (car poss))))) - )) - (if (not ispell-quit) + ;; This error occurs due to filter pipe problems + (let* ((ispell-pipe-word (car poss)) + (actual-point (marker-position word-start)) + (actual-line (line-number-at-pos actual-point)) + (actual-column (save-excursion (goto-char actual-point) + (current-column)))) + (ispell-print-if-debug + "ispell-process-line: Ispell misalignment error: + [Word from ispell pipe]: [%s], actual (point,line,column): (%s,%s,%s)\n" + ispell-pipe-word actual-point actual-line actual-column) + (error (concat "Ispell misalignment: word " + "`%s' point %d; probably incompatible versions") + ispell-pipe-word actual-point))) + ;; ispell-cmd-loop can go recursive & change buffer + (if ispell-keep-choices-win + (setq replace (ispell-command-loop + (car (cdr (cdr poss))) + (car (cdr (cdr (cdr poss)))) + (car poss) (marker-position word-start) + (+ word-len (marker-position word-start)))) + (save-window-excursion + (setq replace (ispell-command-loop + (car (cdr (cdr poss))) + (car (cdr (cdr (cdr poss)))) + (car poss) (marker-position word-start) + (+ word-len (marker-position word-start)))))) + + (goto-char word-start) + ;; Recheck when query replace edit changes misspelled word. + ;; Error in tex mode when a potential math mode change exists. + (if (and replace (listp replace) (= 2 (length replace))) + (if (and (eq ispell-parser 'tex) + (string-match "[\\\\][]()[]\\|\\\\begin\\|\\$" + (regexp-quote string))) + (error + "Don't start query replace on a line with math characters" + ) + (set-marker line-end (point)) + (setq ispell-filter nil + recheck-region t))) + + ;; Insert correction if needed. + (cond + ((or (null replace) + (equal 0 replace)) ; ACCEPT/INSERT + (if (equal 0 replace) ; BUFFER-LOCAL DICT ADD + (ispell-add-per-file-word-list (car poss))) + ;; Do not recheck accepted word on this line. + (setq accept-list (cons (car poss) accept-list))) + (t ; Replacement word selected or entered. + (delete-region (point) (+ word-len (point))) + (if (not (listp replace)) + (progn + (insert replace) ; Insert dictionary word. + (ispell-send-replacement (car poss) replace) + (setq accept-list (cons replace accept-list))) + (let ((replace-word (car replace))) + ;; Recheck hand entered replacement word. + (insert replace-word) + (ispell-send-replacement (car poss) replace-word) + (if (car (cdr replace)) + (save-window-excursion + (delete-other-windows) ; to correctly show help. + ;; Assume case-replace & + ;; case-fold-search correct? + (query-replace (car poss) (car replace) t))) + (goto-char word-start) + ;; Do not recheck if already accepted. + (if (member replace-word accept-list) + (setq accept-list (cons replace-word accept-list) + replace replace-word) + (let ((region-end (copy-marker ispell-region-end))) + (setq recheck-region ispell-filter + ispell-filter nil ; Save filter. + shift 0 ; Already accounted. + shift (ispell-region + word-start + (+ word-start (length replace-word)) + t shift)) + (if (null shift) ; Quitting check. + (setq shift 0)) + (set-marker ispell-region-end region-end) + (set-marker region-end nil) + (setq ispell-filter recheck-region + recheck-region nil + replace replace-word))))) + + (setq shift (+ shift (- (length replace) word-len))) + + ;; Move line-start across word... + ;; new shift function does this now... + ;;(set-marker line-start (+ line-start + ;; (- (length replace) + ;; (length (car poss))))) + )) + (if (not ispell-quit) ;; FIXME: remove redundancy with identical code above. - (let (message-log-max) - (message + (let (message-log-max) + (message "Continuing spelling check using %s with %s dictionary..." (file-name-nondirectory ispell-program-name) (or ispell-current-dictionary "default")))) - (sit-for 0) - (setq ispell-start (marker-position line-start) - ispell-end (marker-position line-end)) - ;; Adjust markers when end of region lost from highlighting. - (if (and (not recheck-region) + (sit-for 0) + (setq ispell-start (marker-position line-start) + ispell-end (marker-position line-end)) + ;; Adjust markers when end of region lost from highlighting. + (if (and (not recheck-region) (< ispell-end (+ word-start word-len))) - (setq ispell-end (+ word-start word-len))) - (if (= word-start ispell-region-end) - (set-marker ispell-region-end (+ word-start word-len))) - ;; going out of scope - unneeded - (set-marker line-start nil) - (set-marker word-start nil) - (set-marker line-end nil))) - ;; finished with misspelling! + (setq ispell-end (+ word-start word-len))) + (if (= word-start ispell-region-end) + (set-marker ispell-region-end (+ word-start word-len))) + ;; Going out of scope - unneeded. + (set-marker line-start nil) + (set-marker word-start nil) + (set-marker line-end nil))) + ;; Finished with misspelling! (setq ispell-filter (cdr ispell-filter))) shift)) @@ -3392,6 +3726,13 @@ Returns the sum SHIFT due to changes in word replacements." (interactive) (ispell-region (point-min) (point-max))) +;;;###autoload +(defun ispell-buffer-with-debug (&optional append) + "`ispell-buffer' with some output sent to `ispell-debug-buffer' buffer. +Use APPEND to append the info to previous buffer if exists." + (interactive) + (let ((ispell-debug-buffer (ispell-create-debug-buffer append))) + (ispell-buffer))) ;;;###autoload (defun ispell-continue () @@ -3995,8 +4336,13 @@ Both should not be used to define a buffer-local dictionary." (if (fboundp 'comment-padright) ;; Try and use the proper comment marker, ;; e.g. ";;" rather than ";". - (comment-padright comment-start - (comment-add nil)) + (progn + ;; XEmacs: comment-normalize-vars + ;; (newcomment.el) only in >= 21.5 + (and (fboundp 'comment-normalize-vars) + (comment-normalize-vars)) + (comment-padright comment-start + (comment-add nil))) comment-start) " ") "") diff --git a/lisp/textmodes/po.el b/lisp/textmodes/po.el index 331f220f95b..610227af794 100644 --- a/lisp/textmodes/po.el +++ b/lisp/textmodes/po.el @@ -1,8 +1,8 @@ -;;; po.el --- basic support of PO translation files -*- coding: latin-1; -*- +;;; po.el --- basic support of PO translation files -*- coding: utf-8; -*- ;; Copyright (C) 1995-1998, 2000-2013 Free Software Foundation, Inc. -;; Authors: François Pinard <pinard@iro.umontreal.ca>, +;; Authors: François Pinard <pinard@iro.umontreal.ca>, ;; Greg McGary <gkm@magilla.cichlid.com>, ;; Bruno Haible <bruno@clisp.org>. ;; Keywords: i18n, files diff --git a/lisp/textmodes/reftex-cite.el b/lisp/textmodes/reftex-cite.el index 3b294e62b01..ca29709de2e 100644 --- a/lisp/textmodes/reftex-cite.el +++ b/lisp/textmodes/reftex-cite.el @@ -514,12 +514,6 @@ ;; remove extra whitespace (while (string-match "[\n\t\r]\\|[ \t][ \t]+" field) (setq field (replace-match " " nil t field))) - ;; remove leading garbage - (if (string-match (if raw "^[ \t]+" "^[ \t{]+") field) - (setq field (replace-match "" nil t field))) - ;; remove trailing garbage - (if (string-match (if raw "[ \t]+$" "[ \t}]+$") field) - (setq field (replace-match "" nil t field))) (push (cons key field) alist)))) alist)) @@ -1043,6 +1037,7 @@ While entering the regexp, completion on knows citation keys is possible. ((= l ?k) (reftex-get-bib-field "key" entry)) ((= l ?m) (reftex-get-bib-field "month" entry)) ((= l ?n) (reftex-get-bib-field "number" entry)) + ((= l ?N) (reftex-get-bib-field "note" entry)) ((= l ?o) (reftex-get-bib-field "organization" entry)) ((= l ?p) (reftex-get-bib-field "pages" entry)) ((= l ?P) (car (split-string @@ -1050,6 +1045,7 @@ While entering the regexp, completion on knows citation keys is possible. "[- .]+"))) ((= l ?s) (reftex-get-bib-field "school" entry)) ((= l ?u) (reftex-get-bib-field "publisher" entry)) + ((= l ?U) (reftex-get-bib-field "url" entry)) ((= l ?r) (reftex-get-bib-field "address" entry)) ((= l ?t) (reftex-get-bib-field "title" entry)) ((= l ?T) (reftex-abbreviate-title diff --git a/lisp/textmodes/reftex-parse.el b/lisp/textmodes/reftex-parse.el index 095c5953947..6bfc70c5d44 100644 --- a/lisp/textmodes/reftex-parse.el +++ b/lisp/textmodes/reftex-parse.el @@ -234,8 +234,18 @@ of master file." ((match-end 1) ;; It is a label - (push (reftex-label-info (reftex-match-string 1) file bound) - docstruct)) + (when (or (null reftex-label-ignored-macros-and-environments) + ;; \label{} defs should always be honored, + ;; just no keyval style [label=foo] defs. + (string-equal "\label{" (substring (reftex-match-string 0) 0 7)) + (not (fboundp 'TeX-current-macro)) + (not (fboundp 'LaTeX-current-environment)) + (not (or (member (save-match-data (TeX-current-macro)) + reftex-label-ignored-macros-and-environments) + (member (save-match-data (LaTeX-current-environment)) + reftex-label-ignored-macros-and-environments)))) + (push (reftex-label-info (reftex-match-string 1) file bound) + docstruct))) ((match-end 3) ;; It is a section @@ -251,7 +261,7 @@ of master file." ;; the next parsing iteration. (when (eq (char-before) ?\\) (backward-char)) ;; Insert in List - (setq toc-entry (reftex-section-info file)) + (setq toc-entry (funcall reftex-section-info-function file)) (when toc-entry ;; It can happen that section info returns nil (setq level (nth 5 toc-entry)) diff --git a/lisp/textmodes/reftex-toc.el b/lisp/textmodes/reftex-toc.el index 2beb3af628b..248e36a5299 100644 --- a/lisp/textmodes/reftex-toc.el +++ b/lisp/textmodes/reftex-toc.el @@ -785,7 +785,7 @@ PRO-OR-DE is assumed to be dynamically scoped into this function." (marker (nth 4 data))) (with-current-buffer (marker-buffer marker) (goto-char (marker-position marker)) - (if (looking-at (concat "\\([ \t]*\\\\\\)" (regexp-quote name))) + (if (looking-at (concat "\\([ \t]*" reftex-section-pre-regexp "\\)" (regexp-quote name))) (replace-match (concat "\\1" newname)) (error "Fatal error during %smotion" pro-or-de))))) diff --git a/lisp/textmodes/reftex-vars.el b/lisp/textmodes/reftex-vars.el index db08ca3a514..a68a27bb07e 100644 --- a/lisp/textmodes/reftex-vars.el +++ b/lisp/textmodes/reftex-vars.el @@ -863,6 +863,48 @@ DOWNCASE t: Downcase words before using them." (string :tag "")) (option (boolean :tag "Downcase words ")))) +(defcustom reftex-label-regexps + '(;; Normal \\label{foo} labels + "\\\\label{\\(?1:[^}]*\\)}" + ;; keyvals [..., label = {foo}, ...] forms used by ctable, + ;; listings, minted, ... + "\\[[^]]*\\<label[[:space:]]*=[[:space:]]*{?\\(?1:[^],}]+\\)}?") + "List of regexps matching \\label definitions. +The default value matches usual \\label{...} definitions and +keyval style [..., label = {...}, ...] label definitions. It is +assumed that the regexp group 1 matches the label text, so you +have to define it using \\(?1:...\\) when adding new regexps. + +When changed from Lisp, make sure to call +`reftex-compile-variables' afterwards to make the change +effective." + :set (lambda (symbol value) + (set symbol value) + (when (fboundp 'reftex-compile-variables) + (reftex-compile-variables))) + :group 'reftex-defining-label-environments + :type '(repeat (regexp :tag "Regular Expression"))) + +(defcustom reftex-label-ignored-macros-and-environments nil + "List of macros and environments to be ignored when searching for labels. +The purpose is to ignore environments and macros that use keyval +style label=foo arguments, but the label has a different meaning +than a \\label{foo}. Standard \\label{...} definitions are never +ignored. + +E.g., TikZ defines several macros/environments where [label=foo] +defines the label to be printed at some node or edge, but it's +not a label used for referencing. + +Note that this feature is only supported if you are using AUCTeX +and the functions `TeX-current-macro' and +`LaTeX-current-environment' are bound. Also note that this +feature might slow down the reftex parsing process for large TeX +files." + :version "24.4" + :group 'reftex-defining-label-environments + :type '(repeat string)) + (defcustom reftex-label-illegal-re "[^-a-zA-Z0-9_+=:;,.]" "Regexp matching characters not valid in labels." :group 'reftex-making-and-inserting-labels @@ -1125,12 +1167,12 @@ In the format, the following percent escapes will be expanded. %e Works like %a, but on list of editor names. (%2e and %E work a well) It is also possible to access all other BibTeX database fields: -%b booktitle %c chapter %d edition %h howpublished -%i institution %j journal %k key %m month -%n number %o organization %p pages %P first page -%r address %s school %u publisher %t title -%v volume %y year -%B booktitle, abbreviated %T title, abbreviated +%b booktitle %c chapter %d edition %h howpublished +%i institution %j journal %k key %m month +%n number %N note %o organization %p pages +%P first page %r address %s school %u publisher +%U url %t title %v volume %y year +%B booktitle, abbreviated %T title, abbreviated Usually, only %l is needed. The other stuff is mainly for the echo area display, and for (setq reftex-comment-citations t). diff --git a/lisp/textmodes/reftex.el b/lisp/textmodes/reftex.el index d511bf9ff8b..21083fd188a 100644 --- a/lisp/textmodes/reftex.el +++ b/lisp/textmodes/reftex.el @@ -301,7 +301,9 @@ on the menu bar. (modify-syntax-entry ?\' "." reftex-syntax-table-for-bib) (modify-syntax-entry ?\" "." reftex-syntax-table-for-bib) (modify-syntax-entry ?\[ "." reftex-syntax-table-for-bib) - (modify-syntax-entry ?\] "." reftex-syntax-table-for-bib)) + (modify-syntax-entry ?\] "." reftex-syntax-table-for-bib) + + (run-hooks 'reftex-mode-hook)) ;; Mode was turned off (easy-menu-remove reftex-mode-menu))) @@ -664,6 +666,16 @@ will deactivate it." (defvar reftex-find-label-regexp-format nil) (defvar reftex-find-label-regexp-format2 nil) +;; Constants for making RefTeX open to Texinfo hooking +(defvar reftex-section-pre-regexp "\\\\") +;; Including `\' as a character to be matched at the end of the regexp +;; will allow stuff like \begin{foo}\label{bar} to be matched. This +;; will make the parser to advance one char too much. Therefore +;; `reftex-parse-from-file' will step one char back if a section is +;; found. +(defvar reftex-section-post-regexp "\\*?\\(\\[[^]]*\\]\\)?[[{ \t\r\n\\]") +(defvar reftex-section-info-function 'reftex-section-info) + (defvar reftex-memory nil "Memorizes old variable values to indicate changes in these variables.") @@ -1069,13 +1081,7 @@ This enforces rescanning the buffer on next use." (wbol "\\(^\\)[ \t]*") ; Need to keep the empty group because ; match numbers are hard coded (label-re (concat "\\(?:" - ;; Normal \label{...} - "\\\\label{\\([^}]*\\)}" - "\\|" - ;; keyvals [..., label = {foo}, ...] - ;; forms used by ctable, listings, - ;; minted, ... - "\\[[^]]*label[[:space:]]*=[[:space:]]*{?\\(?1:[^],}]+\\)}?" + (mapconcat 'identity reftex-label-regexps "\\|") "\\)")) (include-re (concat wbol "\\\\\\(" @@ -1083,16 +1089,10 @@ This enforces rescanning the buffer on next use." reftex-include-file-commands "\\|") "\\)[{ \t]+\\([^} \t\n\r]+\\)")) (section-re - ;; Including `\' as a character to be matched at the end - ;; of the regexp will allow stuff like - ;; \begin{foo}\label{bar} to be matched. This will make - ;; the parser to advance one char too much. Therefore - ;; `reftex-parse-from-file' will step one char back if a - ;; section is found. - (concat wbol "\\\\\\(" + (concat wbol reftex-section-pre-regexp "\\(" (mapconcat (lambda (x) (regexp-quote (car x))) reftex-section-levels-all "\\|") - "\\)\\*?\\(\\[[^]]*\\]\\)?[[{ \t\r\n\\]")) + "\\)" reftex-section-post-regexp)) (appendix-re (concat wbol "\\(\\\\appendix\\)")) (macro-re (if macros-with-labels @@ -2458,7 +2458,7 @@ information about your RefTeX version and configuration." (require 'reporter) (let ((reporter-prompt-for-summary-p "Bug report subject: ")) (reporter-submit-bug-report - "bug-auctex@gnu.org" + "bug-auctex@gnu.org, bug-gnu-emacs@gnu.org" reftex-version (list 'window-system 'reftex-plug-into-AUCTeX) diff --git a/lisp/textmodes/remember.el b/lisp/textmodes/remember.el index eeb04ef250f..76ffeaf30be 100644 --- a/lisp/textmodes/remember.el +++ b/lisp/textmodes/remember.el @@ -216,10 +216,11 @@ All functions are run in the remember buffer." Each function is called with the current buffer narrowed to what the user wants remembered. If any function returns non-nil, the data is assumed to have been -recorded somewhere by that function. " +recorded somewhere by that function." :type 'hook :options '(remember-store-in-mailbox remember-append-to-file + remember-store-in-files remember-diary-extract-entries org-remember-handler) :group 'remember) @@ -380,7 +381,7 @@ Subject: %s\n\n" ;; Remembering to plain files -(defcustom remember-data-file (convert-standard-filename "~/.notes") +(defcustom remember-data-file (locate-user-emacs-file "notes" ".notes") "The file in which to store unprocessed data." :type 'file :group 'remember) @@ -429,6 +430,29 @@ If you want to remember a region, supply a universal prefix to (run-hook-with-args-until-success 'remember-handler-functions)) (remember-destroy)))) +(defcustom remember-data-directory "~/remember" + "The directory in which to store remember data as files." + :type 'directory + :version "24.4" + :group 'remember) + +(defcustom remember-directory-file-name-format "%Y-%m-%d_%T-%z" + "Format string for the file name in which to store unprocessed data." + :type 'string + :version "24.4" + :group 'remember) + +(defun remember-store-in-files () + "Store remember data in a file in `remember-data-directory'. +The file is named after `remember-directory-file-name-format'." + (let ((name (format-time-string + remember-directory-file-name-format (current-time))) + (text (buffer-string))) + (with-temp-buffer + (insert text) + (write-file (convert-standard-filename + (format "%s/%s" remember-data-directory name)))))) + ;;;###autoload (defun remember-clipboard () "Remember the contents of the current clipboard. diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el index 74b26db1064..33dfa277330 100644 --- a/lisp/textmodes/sgml-mode.el +++ b/lisp/textmodes/sgml-mode.el @@ -46,9 +46,26 @@ :type 'integer :group 'sgml) +(defcustom sgml-xml-mode nil + "When non-nil, tag insertion functions will be XML-compliant. +It is set to be buffer-local when the file has +a DOCTYPE or an XML declaration." + :type 'boolean + :version "22.1" + :group 'sgml) + (defcustom sgml-transformation-function 'identity "Default value for `skeleton-transformation-function' in SGML mode." :type 'function + :initialize 'custom-initialize-default + :set (lambda (sym val) + (set-default sym val) + (mapc (lambda (buff) + (with-current-buffer buff + (and (derived-mode-p 'sgml-mode) + (not sgml-xml-mode) + (setq skeleton-transformation-function val)))) + (buffer-list))) :group 'sgml) (put 'sgml-transformation-function 'variable-interactive @@ -295,8 +312,8 @@ Any terminating `>' or `/' is not matched.") (defconst sgml-syntax-propertize-function (syntax-propertize-rules - ;; Use the `b' style of comments to avoid interference with the -- ... -- - ;; comments recognized when `sgml-specials' includes ?-. + ;; Use the `b' style of comments to avoid interference with the -- ... -- + ;; comments recognized when `sgml-specials' includes ?-. ;; FIXME: beware of <!--> blabla <!--> !! ("\\(<\\)!--" (1 "< b")) ("--[ \t\n]*\\(>\\)" (1 "> b")) @@ -305,7 +322,7 @@ Any terminating `>' or `/' is not matched.") ;; going to change, so as not to need to flush the data we just computed. ("\"" (0 (if (prog1 (zerop (car (syntax-ppss (match-beginning 0)))) (goto-char (match-end 0))) - ".")))) + (string-to-syntax "."))))) "Syntactic keywords for `sgml-mode'.") ;; internal @@ -364,14 +381,6 @@ an optional alist of possible values." (string :tag "Description"))) :group 'sgml) -(defcustom sgml-xml-mode nil - "When non-nil, tag insertion functions will be XML-compliant. -It is set to be buffer-local when the file has -a DOCTYPE or an XML declaration." - :type 'boolean - :version "22.1" - :group 'sgml) - (defvar sgml-empty-tags nil "List of tags whose !ELEMENT definition says EMPTY.") @@ -463,47 +472,39 @@ Do \\[describe-key] on the following bindings to discover what they do. ;; A start or end tag by itself on a line separates a paragraph. ;; This is desirable because SGML discards a newline that appears ;; immediately after a start tag or immediately before an end tag. - (set (make-local-variable 'paragraph-start) (concat "[ \t]*$\\|\ + (setq-local paragraph-start (concat "[ \t]*$\\|\ \[ \t]*</?\\(" sgml-name-re sgml-attrs-re "\\)?>")) - (set (make-local-variable 'paragraph-separate) - (concat paragraph-start "$")) - (set (make-local-variable 'adaptive-fill-regexp) "[ \t]*") + (setq-local paragraph-separate (concat paragraph-start "$")) + (setq-local adaptive-fill-regexp "[ \t]*") (add-hook 'fill-nobreak-predicate 'sgml-fill-nobreak nil t) - (set (make-local-variable 'indent-line-function) 'sgml-indent-line) - (set (make-local-variable 'comment-start) "<!-- ") - (set (make-local-variable 'comment-end) " -->") - (set (make-local-variable 'comment-indent-function) 'sgml-comment-indent) - (set (make-local-variable 'comment-line-break-function) - 'sgml-comment-indent-new-line) - (set (make-local-variable 'skeleton-further-elements) - '((completion-ignore-case t))) - (set (make-local-variable 'skeleton-end-hook) - (lambda () - (or (eolp) - (not (or (eq v2 '\n) (eq (car-safe v2) '\n))) - (newline-and-indent)))) - (set (make-local-variable 'font-lock-defaults) - '((sgml-font-lock-keywords - sgml-font-lock-keywords-1 - sgml-font-lock-keywords-2) - nil t)) - (set (make-local-variable 'syntax-propertize-function) - sgml-syntax-propertize-function) - (set (make-local-variable 'facemenu-add-face-function) - 'sgml-mode-facemenu-add-face-function) - (set (make-local-variable 'sgml-xml-mode) (sgml-xml-guess)) - (if sgml-xml-mode - () - (set (make-local-variable 'skeleton-transformation-function) - sgml-transformation-function)) + (setq-local indent-line-function 'sgml-indent-line) + (setq-local comment-start "<!-- ") + (setq-local comment-end " -->") + (setq-local comment-indent-function 'sgml-comment-indent) + (setq-local comment-line-break-function 'sgml-comment-indent-new-line) + (setq-local skeleton-further-elements '((completion-ignore-case t))) + (setq-local skeleton-end-hook + (lambda () + (or (eolp) + (not (or (eq v2 '\n) (eq (car-safe v2) '\n))) + (newline-and-indent)))) + (setq font-lock-defaults '((sgml-font-lock-keywords + sgml-font-lock-keywords-1 + sgml-font-lock-keywords-2) + nil t)) + (setq-local syntax-propertize-function sgml-syntax-propertize-function) + (setq-local facemenu-add-face-function 'sgml-mode-facemenu-add-face-function) + (setq-local sgml-xml-mode (sgml-xml-guess)) + (unless sgml-xml-mode + (setq-local skeleton-transformation-function sgml-transformation-function)) ;; This will allow existing comments within declarations to be ;; recognized. ;; I can't find a clear description of SGML/XML comments, but it seems that ;; the only reliable ones are <!-- ... --> although it's not clear what ;; "..." can contain. It used to accept -- ... -- as well, but that was ;; apparently a mistake. - (set (make-local-variable 'comment-start-skip) "<!--[ \t]*") - (set (make-local-variable 'comment-end-skip) "[ \t]*--[ \t\n]*>") + (setq-local comment-start-skip "<!--[ \t]*") + (setq-local comment-end-skip "[ \t]*--[ \t\n]*>") ;; This definition has an HTML leaning but probably fits well for other modes. (setq imenu-generic-expression `((nil @@ -643,10 +644,8 @@ This only works for Latin-1 input." (define-skeleton sgml-tag "Prompt for a tag and insert it, optionally with attributes. Completion and configuration are done according to `sgml-tag-alist'. -If you like tags and attributes in uppercase do \\[set-variable] -`skeleton-transformation-function' RET `upcase' RET, or put this -in your `.emacs': - (setq sgml-transformation-function 'upcase)" +If you like tags and attributes in uppercase, customize +`sgml-transformation-function' to 'upcase." (funcall (or skeleton-transformation-function 'identity) (setq sgml-tag-last (completing-read @@ -671,13 +670,13 @@ in your `.emacs': (if (eq v2 t) (setq v2 nil)) ;; We use `identity' to prevent skeleton from passing ;; `str' through `skeleton-transformation-function' a second time. - '(("") v2 _ v2 "</" (identity ',str) ?>)) + '(("") v2 _ v2 "</" (identity ',str) ?> >)) ((eq (car v2) t) (cons '("") (cdr v2))) (t (append '(("") (car v2)) (cdr v2) - '(resume: (car v2) _ "</" (identity ',str) ?>)))))) + '(resume: (car v2) _ "</" (identity ',str) ?> >)))))) (autoload 'skeleton-read "skeleton") @@ -982,10 +981,10 @@ With prefix argument ARG, repeat this ARG times." (unwind-protect (save-excursion (goto-char (point-min)) - (if (set (make-local-variable 'sgml-tags-invisible) - (if arg - (>= (prefix-numeric-value arg) 0) - (not sgml-tags-invisible))) + (if (setq-local sgml-tags-invisible + (if arg + (>= (prefix-numeric-value arg) 0) + (not sgml-tags-invisible))) (while (re-search-forward sgml-tag-name-re nil t) (setq string (cdr (assq (intern-soft (downcase (match-string 1))) @@ -1564,8 +1563,7 @@ Add this to `sgml-mode-hook' for convenience." (goto-char (point-min)) (if (re-search-forward "^\\([ \t]+\\)<" 500 'noerror) (progn - (set (make-local-variable 'sgml-basic-offset) - (1- (current-column))) + (setq-local sgml-basic-offset (1- (current-column))) (message "Guessed sgml-basic-offset = %d" sgml-basic-offset) )))) @@ -1935,12 +1933,25 @@ This takes effect when first loading the library.") ("ul" . "Unordered list") ("var" . "Math variable face") ("wbr" . "Enable <br> within <nobr>")) - "Value of `sgml-tag-help' for HTML mode.") + "Value of variable `sgml-tag-help' for HTML mode.") (defvar outline-regexp) (defvar outline-heading-end-regexp) (defvar outline-level) +(defun html-current-defun-name () + "Return the name of the last HTML title or heading, or nil." + (save-excursion + (if (re-search-backward + (concat + "<[ \t\r\n]*" + "\\(?:[hH][0-6]\\|title\\|TITLE\\|Title\\)" + "[^>]*>" + "[ \t\r\n]*" + "\\([^<\r\n]*[^ <\t\r\n]+\\)") + nil t) + (match-string-no-properties 1)))) + ;;;###autoload (define-derived-mode html-mode sgml-mode '(sgml-xml-mode "XHTML" "HTML") @@ -1979,33 +1990,29 @@ To work around that, do: (eval-after-load \"sgml-mode\" '(aset sgml-char-names ?' nil)) \\{html-mode-map}" - (set (make-local-variable 'sgml-display-text) html-display-text) - (set (make-local-variable 'sgml-tag-face-alist) html-tag-face-alist) - (make-local-variable 'sgml-tag-alist) - (make-local-variable 'sgml-face-tag-alist) - (make-local-variable 'sgml-tag-help) - (make-local-variable 'outline-regexp) - (make-local-variable 'outline-heading-end-regexp) - (make-local-variable 'outline-level) - (make-local-variable 'sentence-end-base) - (setq sentence-end-base "[.?!][]\"'â€)}]*\\(<[^>]*>\\)*" - sgml-tag-alist html-tag-alist - sgml-face-tag-alist html-face-tag-alist - sgml-tag-help html-tag-help - outline-regexp "^.*<[Hh][1-6]\\>" - outline-heading-end-regexp "</[Hh][1-6]>" - outline-level (lambda () - (char-before (match-end 0)))) + (setq-local sgml-display-text html-display-text) + (setq-local sgml-tag-face-alist html-tag-face-alist) + (setq-local sgml-tag-alist html-tag-alist) + (setq-local sgml-face-tag-alist html-face-tag-alist) + (setq-local sgml-tag-help html-tag-help) + (setq-local outline-regexp "^.*<[Hh][1-6]\\>") + (setq-local outline-heading-end-regexp "</[Hh][1-6]>") + (setq-local outline-level + (lambda () (char-before (match-end 0)))) + (setq-local add-log-current-defun-function #'html-current-defun-name) + (setq-local sentence-end-base "[.?!][]\"'â€)}]*\\(<[^>]*>\\)*") + (setq imenu-create-index-function 'html-imenu-index) - (set (make-local-variable 'sgml-empty-tags) - ;; From HTML-4.01's loose.dtd, parsed with `sgml-parse-dtd', - ;; plus manual addition of "wbr". - '("area" "base" "basefont" "br" "col" "frame" "hr" "img" "input" - "isindex" "link" "meta" "param" "wbr")) - (set (make-local-variable 'sgml-unclosed-tags) - ;; From HTML-4.01's loose.dtd, parsed with `sgml-parse-dtd'. - '("body" "colgroup" "dd" "dt" "head" "html" "li" "option" - "p" "tbody" "td" "tfoot" "th" "thead" "tr")) + + (setq-local sgml-empty-tags + ;; From HTML-4.01's loose.dtd, parsed with + ;; `sgml-parse-dtd', plus manual addition of "wbr". + '("area" "base" "basefont" "br" "col" "frame" "hr" "img" "input" + "isindex" "link" "meta" "param" "wbr")) + (setq-local sgml-unclosed-tags + ;; From HTML-4.01's loose.dtd, parsed with `sgml-parse-dtd'. + '("body" "colgroup" "dd" "dt" "head" "html" "li" "option" + "p" "tbody" "td" "tfoot" "th" "thead" "tr")) ;; It's for the user to decide if it defeats it or not -stef ;; (make-local-variable 'imenu-sort-function) ;; (setq imenu-sort-function nil) ; sorting the menu defeats the purpose diff --git a/lisp/textmodes/table.el b/lisp/textmodes/table.el index 411604088ae..4d8a74323c7 100644 --- a/lisp/textmodes/table.el +++ b/lisp/textmodes/table.el @@ -5215,7 +5215,7 @@ instead of the current buffer and returns the OBJECT." "Update cell face according to the current mode." (if (featurep 'xemacs) (set-face-property 'table-cell 'underline table-fixed-width-mode) - (set-face-inverse-video-p 'table-cell table-fixed-width-mode))) + (set-face-inverse-video 'table-cell table-fixed-width-mode))) (table--update-cell-face) diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el index db012e5cf9b..7b16262233d 100644 --- a/lisp/textmodes/tex-mode.el +++ b/lisp/textmodes/tex-mode.el @@ -271,9 +271,7 @@ otherwise the value of `tex-start-options', the \(shell-quoted\) value of `tex-start-commands', and the file name are added at the end with blanks as separators. -In TeX, LaTeX, and SliTeX Mode this variable becomes buffer local. -In these modes, use \\[set-variable] if you want to change it for the -current buffer.") +In TeX, LaTeX, and SliTeX Mode this variable becomes buffer local.") (defvar tex-trailer nil "String appended after the end of a region sent to TeX by \\[tex-region].") @@ -421,6 +419,17 @@ An alternative value is \" . \", if you use a font with a narrow period." (if (looking-at latex-outline-regexp) (1+ (or (cdr (assoc (match-string 1) latex-section-alist)) -1)) 1000)) + +(defun tex-current-defun-name () + "Return the name of the TeX section/paragraph/chapter at point, or nil." + (save-excursion + (when (re-search-backward + "\\\\\\(sub\\)*\\(section\\|paragraph\\|chapter\\)" + nil t) + (goto-char (match-beginning 0)) + (buffer-substring-no-properties + (1+ (point)) ; without initial backslash + (line-end-position))))) ;;;; ;;;; Font-Lock support @@ -1062,10 +1071,10 @@ tex-show-queue-command Entering Plain-tex mode runs the hook `text-mode-hook', then the hook `tex-mode-hook', and finally the hook `plain-tex-mode-hook'. When the special subshell is initiated, the hook `tex-shell-hook' is run." - (set (make-local-variable 'tex-command) tex-run-command) - (set (make-local-variable 'tex-start-of-header) "%\\*\\*start of header") - (set (make-local-variable 'tex-end-of-header) "%\\*\\*end of header") - (set (make-local-variable 'tex-trailer) "\\bye\n")) + (setq-local tex-command tex-run-command) + (setq-local tex-start-of-header "%\\*\\*start of header") + (setq-local tex-end-of-header "%\\*\\*end of header") + (setq-local tex-trailer "\\bye\n")) ;;;###autoload (define-derived-mode latex-mode tex-mode "LaTeX" @@ -1108,11 +1117,10 @@ tex-show-queue-command Entering Latex mode runs the hook `text-mode-hook', then `tex-mode-hook', and finally `latex-mode-hook'. When the special subshell is initiated, `tex-shell-hook' is run." - (set (make-local-variable 'tex-command) latex-run-command) - (set (make-local-variable 'tex-start-of-header) - "\\\\document\\(style\\|class\\)") - (set (make-local-variable 'tex-end-of-header) "\\\\begin\\s-*{document}") - (set (make-local-variable 'tex-trailer) "\\end{document}\n") + (setq-local tex-command latex-run-command) + (setq-local tex-start-of-header "\\\\document\\(style\\|class\\)") + (setq-local tex-end-of-header "\\\\begin\\s-*{document}") + (setq-local tex-trailer "\\end{document}\n") ;; A line containing just $$ is treated as a paragraph separator. ;; A line starting with $$ starts a paragraph, ;; but does not separate paragraphs if it has more stuff on it. @@ -1138,18 +1146,17 @@ subshell is initiated, `tex-shell-hook' is run." "marginpar" "parbox" "caption")) "\\|\\$\\$\\|[a-z]*\\(space\\|skip\\|page[a-z]*\\)" "\\>\\)[ \t]*\\($\\|%\\)\\)")) - (set (make-local-variable 'imenu-create-index-function) - 'latex-imenu-create-index) - (set (make-local-variable 'tex-face-alist) tex-latex-face-alist) + (setq-local imenu-create-index-function 'latex-imenu-create-index) + (setq-local tex-face-alist tex-latex-face-alist) (add-hook 'fill-nobreak-predicate 'latex-fill-nobreak-predicate nil t) - (set (make-local-variable 'indent-line-function) 'latex-indent) - (set (make-local-variable 'fill-indent-according-to-mode) t) + (setq-local indent-line-function 'latex-indent) + (setq-local fill-indent-according-to-mode t) (add-hook 'completion-at-point-functions 'latex-complete-data nil 'local) - (set (make-local-variable 'outline-regexp) latex-outline-regexp) - (set (make-local-variable 'outline-level) 'latex-outline-level) - (set (make-local-variable 'forward-sexp-function) 'latex-forward-sexp) - (set (make-local-variable 'skeleton-end-hook) nil)) + (setq-local outline-regexp latex-outline-regexp) + (setq-local outline-level 'latex-outline-level) + (setq-local forward-sexp-function 'latex-forward-sexp) + (setq-local skeleton-end-hook nil)) ;;;###autoload (define-derived-mode slitex-mode latex-mode "SliTeX" @@ -1198,39 +1205,36 @@ Entering SliTeX mode runs the hook `text-mode-hook', then the hook (defun tex-common-initialization () ;; Regexp isearch should accept newline and formfeed as whitespace. - (set (make-local-variable 'search-whitespace-regexp) "[ \t\r\n\f]+") + (setq-local search-whitespace-regexp "[ \t\r\n\f]+") ;; A line containing just $$ is treated as a paragraph separator. - (set (make-local-variable 'paragraph-start) - "[ \t]*$\\|[\f\\\\%]\\|[ \t]*\\$\\$") + (setq-local paragraph-start "[ \t]*$\\|[\f\\\\%]\\|[ \t]*\\$\\$") ;; A line starting with $$ starts a paragraph, ;; but does not separate paragraphs if it has more stuff on it. - (set (make-local-variable 'paragraph-separate) - "[ \t]*$\\|[\f\\\\%]\\|[ \t]*\\$\\$[ \t]*$") - (set (make-local-variable 'comment-start) "%") - (set (make-local-variable 'comment-add) 1) - (set (make-local-variable 'comment-start-skip) - "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(%+ *\\)") - (set (make-local-variable 'parse-sexp-ignore-comments) t) - (set (make-local-variable 'compare-windows-whitespace) - 'tex-categorize-whitespace) - (set (make-local-variable 'facemenu-add-face-function) - 'tex-facemenu-add-face-function) - (set (make-local-variable 'facemenu-end-add-face) "}") - (set (make-local-variable 'facemenu-remove-face-function) t) - (set (make-local-variable 'font-lock-defaults) - '((tex-font-lock-keywords tex-font-lock-keywords-1 - tex-font-lock-keywords-2 tex-font-lock-keywords-3) - nil nil nil nil - ;; Who ever uses that anyway ??? - (font-lock-mark-block-function . mark-paragraph) - (font-lock-syntactic-face-function - . tex-font-lock-syntactic-face-function) - (font-lock-unfontify-region-function - . tex-font-lock-unfontify-region))) - (set (make-local-variable 'syntax-propertize-function) - (syntax-propertize-rules latex-syntax-propertize-rules)) + (setq-local paragraph-separate "[ \t]*$\\|[\f\\\\%]\\|[ \t]*\\$\\$[ \t]*$") + (setq-local add-log-current-defun-function #'tex-current-defun-name) + (setq-local comment-start "%") + (setq-local comment-add 1) + (setq-local comment-start-skip + "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(%+ *\\)") + (setq-local parse-sexp-ignore-comments t) + (setq-local compare-windows-whitespace 'tex-categorize-whitespace) + (setq-local facemenu-add-face-function 'tex-facemenu-add-face-function) + (setq-local facemenu-end-add-face "}") + (setq-local facemenu-remove-face-function t) + (setq-local font-lock-defaults + '((tex-font-lock-keywords tex-font-lock-keywords-1 + tex-font-lock-keywords-2 tex-font-lock-keywords-3) + nil nil nil nil + ;; Who ever uses that anyway ??? + (font-lock-mark-block-function . mark-paragraph) + (font-lock-syntactic-face-function + . tex-font-lock-syntactic-face-function) + (font-lock-unfontify-region-function + . tex-font-lock-unfontify-region))) + (setq-local syntax-propertize-function + (syntax-propertize-rules latex-syntax-propertize-rules)) ;; TABs in verbatim environments don't do what you think. - (set (make-local-variable 'indent-tabs-mode) nil) + (setq-local indent-tabs-mode nil) ;; Other vars that should be buffer-local. (make-local-variable 'tex-command) (make-local-variable 'tex-start-of-header) @@ -1523,8 +1527,7 @@ Puts point on a blank line between them." (looking-at bibtex-reference-key)) (push (match-string-no-properties 0) keys))))) ;; Fill the cache. - (set (make-local-variable 'latex-complete-bibtex-cache) - (list files key keys))) + (setq-local latex-complete-bibtex-cache (list files key keys))) (complete-with-action action keys key pred))))) (defun latex-complete-envnames () @@ -1885,8 +1888,7 @@ Mark is left at original location." ;; The utility functions: (define-derived-mode tex-shell shell-mode "TeX-Shell" - (set (make-local-variable 'compilation-error-regexp-alist) - tex-error-regexp-alist) + (setq-local compilation-error-regexp-alist tex-error-regexp-alist) (compilation-shell-minor-mode t)) ;;;###autoload @@ -2099,8 +2101,7 @@ of the current buffer." (with-no-warnings (when (boundp 'TeX-master) (cond ((stringp TeX-master) - (make-local-variable 'tex-main-file) - (setq tex-main-file TeX-master)) + (setq-local tex-main-file TeX-master)) ((and (eq TeX-master t) buffer-file-name) (file-relative-name buffer-file-name))))) ;; Try to guess the main file. @@ -2870,8 +2871,8 @@ There might be text before point." (cons (car x) 'doctex-font-lock-syntactic-face-function)) (_ x))) (cdr font-lock-defaults)))) - (set (make-local-variable 'syntax-propertize-function) - (syntax-propertize-rules doctex-syntax-propertize-rules))) + (setq-local syntax-propertize-function + (syntax-propertize-rules doctex-syntax-propertize-rules))) (run-hooks 'tex-mode-load-hook) diff --git a/lisp/textmodes/texinfo.el b/lisp/textmodes/texinfo.el index abff7f750c5..44e839d2474 100644 --- a/lisp/textmodes/texinfo.el +++ b/lisp/textmodes/texinfo.el @@ -33,6 +33,15 @@ ;;; 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) (defgroup texinfo nil @@ -502,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 @@ -571,66 +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)) - (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 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))))) diff --git a/lisp/textmodes/tildify.el b/lisp/textmodes/tildify.el index 3ba19bb9f40..f25fa87d0ec 100644 --- a/lisp/textmodes/tildify.el +++ b/lisp/textmodes/tildify.el @@ -40,7 +40,7 @@ ;; The default variable settings are suited for Czech, so do not try to ;; understand them if you are not familiar with Czech grammar and spelling. ;; -;; The algorithm was inspired by Petr Ol¹ák's program `vlna'. Abilities of +;; The algorithm was inspired by Petr Olšák's program `vlna'. Abilities of ;; `tildify.el' are a little limited; if you have improvement suggestions, let ;; me know. @@ -349,7 +349,7 @@ further questions)." ;; Local variables: -;; coding: iso-latin-2 +;; coding: utf-8 ;; End: ;;; tildify.el ends here |