aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorEli Zaretskii2013-05-01 20:12:42 +0300
committerEli Zaretskii2013-05-01 20:12:42 +0300
commit9c1a1306117d5c41be1beac981d33085fa0fe5a1 (patch)
tree0e3c9f92704930e26abcd7cab650a041ec0db3ac /lisp
parent2800c4d3155df0768410a675359fb360dfe2e791 (diff)
parent584ea27747d10f9af3d4e3c022153a3d4fc87cc4 (diff)
downloademacs-9c1a1306117d5c41be1beac981d33085fa0fe5a1.tar.gz
emacs-9c1a1306117d5c41be1beac981d33085fa0fe5a1.zip
Merge from trunk.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog74
-rw-r--r--lisp/emacs-lisp/smie.el36
-rw-r--r--lisp/gnus/ChangeLog7
-rw-r--r--lisp/gnus/gnus-sum.el2
-rw-r--r--lisp/gnus/nnir.el1
-rw-r--r--lisp/progmodes/octave-inf.el387
-rw-r--r--lisp/progmodes/octave.el (renamed from lisp/progmodes/octave-mod.el)418
-rw-r--r--lisp/progmodes/opascal.el345
-rw-r--r--lisp/textmodes/reftex-parse.el14
-rw-r--r--lisp/textmodes/reftex-vars.el19
-rw-r--r--lisp/vc/vc-bzr.el20
11 files changed, 614 insertions, 709 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index f69e60e50a7..62424265d96 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,77 @@
12013-04-25 Leo Liu <sdl.web@gmail.com>
2
3 * progmodes/octave.el (octave-completion-at-point-function): Make
4 use of inferior octave process.
5 (octave-initialize-completions): Remove.
6 (inferior-octave-completion-table): New function.
7 (inferior-octave-completion-at-point): Use it.
8 (octave-completion-alist): Remove.
9
102013-04-25 Stefan Monnier <monnier@iro.umontreal.ca>
11
12 * progmodes/opascal.el: Use font-lock and syntax-propertize.
13 (opascal-mode-syntax-table): New var.
14 (opascal-literal-kind, opascal-is-literal-end)
15 (opascal-literal-token-at): Rewrite.
16 (opascal--literal-start-re, opascal-font-lock-keywords)
17 (opascal--syntax-propertize): New constants.
18 (opascal-font-lock-defaults): Adjust.
19 (opascal-mode): Use them. Set comment-<foo> variables as well.
20 (delphi-comment-face, opascal-comment-face, delphi-string-face)
21 (opascal-string-face, delphi-keyword-face, opascal-keyword-face)
22 (delphi-other-face, opascal-other-face): Remove face variables.
23 (opascal-save-state): Remove macro.
24 (opascal-fontifying-progress-step): Remove constant.
25 (opascal--ignore-changes): Remove var.
26 (opascal-set-token-property, opascal-parse-next-literal)
27 (opascal-is-stable-literal, opascal-complete-literal)
28 (opascal-is-literal-start, opascal-face-of)
29 (opascal-parse-region, opascal-parse-region-until-stable)
30 (opascal-fontify-region, opascal-after-change)
31 (opascal-debug-show-is-stable, opascal-debug-unparse-buffer)
32 (opascal-debug-parse-region, opascal-debug-parse-window)
33 (opascal-debug-parse-buffer, opascal-debug-fontify-window)
34 (opascal-debug-fontify-buffer): Remove.
35 (opascal-debug-mode-map): Adjust accordingly.
36
372013-04-25 Leo Liu <sdl.web@gmail.com>
38
39 Merge octave-mod.el and octave-inf.el into octave.el with some
40 cleanups.
41 * progmodes/octave.el: New file renamed from octave-mod.el.
42 * progmodes/octave-inf.el: Merged into octave.el.
43 * progmodes/octave-mod.el: Renamed to octave.el.
44
452013-04-25 Tassilo Horn <tsdh@gnu.org>
46
47 * textmodes/reftex-vars.el
48 (reftex-label-ignored-macros-and-environments): New defcustom.
49
50 * textmodes/reftex-parse.el (reftex-parse-from-file): Use it.
51
522013-04-25 Stefan Monnier <monnier@iro.umontreal.ca>
53
54 * emacs-lisp/smie.el (smie-indent--hanging-p): Don't burp at EOB.
55 (smie-indent-keyword): Improve the check to ensure that the next
56 comment is really on the same line.
57 (smie-indent-comment): Don't align with a subsequent closer (or eob).
58
59 * progmodes/octave-mod.el (octave-smie-forward-token): Only emit
60 semi-colons if the line is not otherwise empty (bug#14218).
61
622013-04-25 Glenn Morris <rgm@gnu.org>
63
64 * vc/vc-bzr.el (vc-bzr-print-log): Tweak LIMIT = 1 case.
65
662013-04-24 Stefan Monnier <monnier@iro.umontreal.ca>
67
68 * progmodes/opascal.el (opascal-set-token-property): Rename from
69 opascal-set-text-properties and only set `token' (bug#14134).
70 Suggested by Erik Knowles <eknowles@geosystemsoftware.com>.
71 (opascal-literal-text-properties): Remove.
72 (opascal-parse-next-literal, opascal-debug-unparse-buffer):
73 Adjust callers.
74
12013-04-24 Reuben Thomas <rrt@sc3d.org> 752013-04-24 Reuben Thomas <rrt@sc3d.org>
2 76
3 * textmodes/remember.el (remember-handler-functions): Add an 77 * textmodes/remember.el (remember-handler-functions): Add an
diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el
index 18cc0e811ce..c59076974e0 100644
--- a/lisp/emacs-lisp/smie.el
+++ b/lisp/emacs-lisp/smie.el
@@ -1067,9 +1067,10 @@ the beginning of a line."
1067 (save-excursion 1067 (save-excursion
1068 (<= (line-end-position) 1068 (<= (line-end-position)
1069 (progn 1069 (progn
1070 (when (zerop (length (funcall smie-forward-token-function))) 1070 (and (zerop (length (funcall smie-forward-token-function)))
1071 ;; Could be an open-paren. 1071 (not (eobp))
1072 (forward-char 1)) 1072 ;; Could be an open-paren.
1073 (forward-char 1))
1073 (skip-chars-forward " \t") 1074 (skip-chars-forward " \t")
1074 (or (eolp) 1075 (or (eolp)
1075 (and (looking-at comment-start-skip) 1076 (and (looking-at comment-start-skip)
@@ -1350,8 +1351,11 @@ should not be computed on the basis of the following token."
1350 (if (and (< pos (line-beginning-position)) 1351 (if (and (< pos (line-beginning-position))
1351 ;; Make sure `token' also *starts* on another line. 1352 ;; Make sure `token' also *starts* on another line.
1352 (save-excursion 1353 (save-excursion
1353 (smie-indent-backward-token) 1354 (let ((endpos (point)))
1354 (< pos (line-beginning-position)))) 1355 (goto-char pos)
1356 (forward-line 1)
1357 (and (equal res (smie-indent-forward-token))
1358 (eq (point) endpos)))))
1355 nil 1359 nil
1356 (goto-char pos) 1360 (goto-char pos)
1357 res))))) 1361 res)))))
@@ -1473,13 +1477,21 @@ should not be computed on the basis of the following token."
1473 (save-excursion 1477 (save-excursion
1474 (forward-comment (point-max)) 1478 (forward-comment (point-max))
1475 (skip-chars-forward " \t\r\n") 1479 (skip-chars-forward " \t\r\n")
1476 ;; FIXME: We assume here that smie-indent-calculate will compute the 1480 (unless
1477 ;; indentation of the next token based on text before the comment, but 1481 ;; Don't align with a closer, since the comment is "within" the
1478 ;; this is not guaranteed, so maybe we should let 1482 ;; closed element. Don't align with EOB either.
1479 ;; smie-indent-calculate return some info about which buffer position 1483 (save-excursion
1480 ;; was used as the "indentation base" and check that this base is 1484 (let ((next (funcall smie-forward-token-function)))
1481 ;; before `pos'. 1485 (or (if (zerop (length next))
1482 (smie-indent-calculate)))) 1486 (or (eobp) (eq (car (syntax-after (point))) 5)))
1487 (rassoc next smie-closer-alist))))
1488 ;; FIXME: We assume here that smie-indent-calculate will compute the
1489 ;; indentation of the next token based on text before the comment,
1490 ;; but this is not guaranteed, so maybe we should let
1491 ;; smie-indent-calculate return some info about which buffer
1492 ;; position was used as the "indentation base" and check that this
1493 ;; base is before `pos'.
1494 (smie-indent-calculate)))))
1483 1495
1484(defun smie-indent-comment-continue () 1496(defun smie-indent-comment-continue ()
1485 ;; indentation of comment-continue lines. 1497 ;; indentation of comment-continue lines.
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index 144b6482b9d..4cdc8a103bd 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,10 @@
12013-04-24 Andrew Cohen <cohen@bu.edu>
2
3 * nnir.el (nnir-close-group): Make sure we are in the right group.
4
5 * gnus-sum.el (gnus-summary-insert-articles): Force updates to the
6 dependency table from all newly retrieved headers.
7
12013-04-16 David Edmondson <dme@dme.org> 82013-04-16 David Edmondson <dme@dme.org>
2 9
3 Support <img src="data:...">. 10 Support <img src="data:...">.
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index 93bc35af3bd..e6366e775df 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -12775,7 +12775,7 @@ returned."
12775 (setq gnus-newsgroup-headers 12775 (setq gnus-newsgroup-headers
12776 (gnus-merge 'list 12776 (gnus-merge 'list
12777 gnus-newsgroup-headers 12777 gnus-newsgroup-headers
12778 (gnus-fetch-headers articles) 12778 (gnus-fetch-headers articles nil t)
12779 'gnus-article-sort-by-number)) 12779 'gnus-article-sort-by-number))
12780 (setq gnus-newsgroup-articles 12780 (setq gnus-newsgroup-articles
12781 (gnus-sorted-nunion gnus-newsgroup-articles articles)) 12781 (gnus-sorted-nunion gnus-newsgroup-articles articles))
diff --git a/lisp/gnus/nnir.el b/lisp/gnus/nnir.el
index 2fa6b600ac1..21f81dc664c 100644
--- a/lisp/gnus/nnir.el
+++ b/lisp/gnus/nnir.el
@@ -892,6 +892,7 @@ skips all prompting."
892 892
893 893
894(deffoo nnir-close-group (group &optional server) 894(deffoo nnir-close-group (group &optional server)
895 (nnir-possibly-change-group group server)
895 (let ((pgroup (gnus-group-guess-full-name-from-command-method group))) 896 (let ((pgroup (gnus-group-guess-full-name-from-command-method group)))
896 (when (and nnir-artlist (not (gnus-ephemeral-group-p pgroup))) 897 (when (and nnir-artlist (not (gnus-ephemeral-group-p pgroup)))
897 (gnus-group-set-parameter pgroup 'nnir-artlist nnir-artlist)) 898 (gnus-group-set-parameter pgroup 'nnir-artlist nnir-artlist))
diff --git a/lisp/progmodes/octave-inf.el b/lisp/progmodes/octave-inf.el
deleted file mode 100644
index 4a227db7164..00000000000
--- a/lisp/progmodes/octave-inf.el
+++ /dev/null
@@ -1,387 +0,0 @@
1;;; octave-inf.el --- running Octave as an inferior Emacs process
2
3;; Copyright (C) 1997, 2001-2013 Free Software Foundation, Inc.
4
5;; Author: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>
6;; John Eaton <jwe@bevo.che.wisc.edu>
7;; Maintainer: FSF
8;; Keywords: languages
9;; Package: octave-mod
10
11;; This file is part of GNU Emacs.
12
13;; GNU Emacs is free software: you can redistribute it and/or modify
14;; it under the terms of the GNU General Public License as published by
15;; the Free Software Foundation, either version 3 of the License, or
16;; (at your option) any later version.
17
18;; GNU Emacs is distributed in the hope that it will be useful,
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;; GNU General Public License for more details.
22
23;; You should have received a copy of the GNU General Public License
24;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
25
26;;; Commentary:
27
28;;; Code:
29
30(require 'octave-mod)
31(require 'comint)
32
33(defgroup octave-inferior nil
34 "Running Octave as an inferior Emacs process."
35 :group 'octave)
36
37(defcustom inferior-octave-program "octave"
38 "Program invoked by `inferior-octave'."
39 :type 'string
40 :group 'octave-inferior)
41
42(defcustom inferior-octave-prompt
43 "\\(^octave\\(\\|.bin\\|.exe\\)\\(-[.0-9]+\\)?\\(:[0-9]+\\)?\\|^debug\\|^\\)>+ "
44 "Regexp to match prompts for the inferior Octave process."
45 :type 'regexp
46 :group 'octave-inferior)
47
48(defcustom inferior-octave-startup-file nil
49 "Name of the inferior Octave startup file.
50The contents of this file are sent to the inferior Octave process on
51startup."
52 :type '(choice (const :tag "None" nil)
53 file)
54 :group 'octave-inferior)
55
56(defcustom inferior-octave-startup-args nil
57 "List of command line arguments for the inferior Octave process.
58For example, for suppressing the startup message and using `traditional'
59mode, set this to (\"-q\" \"--traditional\")."
60 :type '(repeat string)
61 :group 'octave-inferior)
62
63(defvar inferior-octave-mode-map
64 (let ((map (make-sparse-keymap)))
65 (set-keymap-parent map comint-mode-map)
66 (define-key map "\t" 'comint-dynamic-complete)
67 (define-key map "\M-?" 'comint-dynamic-list-filename-completions)
68 (define-key map "\C-c\C-l" 'inferior-octave-dynamic-list-input-ring)
69 (define-key map [menu-bar inout list-history]
70 '("List Input History" . inferior-octave-dynamic-list-input-ring))
71 ;; FIXME: free C-h so it can do the describe-prefix-bindings.
72 (define-key map "\C-c\C-h" 'info-lookup-symbol)
73 map)
74 "Keymap used in Inferior Octave mode.")
75
76(defvar inferior-octave-mode-syntax-table
77 (let ((table (make-syntax-table octave-mode-syntax-table)))
78 table)
79 "Syntax table in use in inferior-octave-mode buffers.")
80
81(defcustom inferior-octave-mode-hook nil
82 "Hook to be run when Inferior Octave mode is started."
83 :type 'hook
84 :group 'octave-inferior)
85
86(defvar inferior-octave-font-lock-keywords
87 (list
88 (cons inferior-octave-prompt 'font-lock-type-face))
89 ;; Could certainly do more font locking in inferior Octave ...
90 "Additional expressions to highlight in Inferior Octave mode.")
91
92
93;;; Compatibility functions
94(if (not (fboundp 'comint-line-beginning-position))
95 ;; comint-line-beginning-position is defined in Emacs 21
96 (defun comint-line-beginning-position ()
97 "Returns the buffer position of the beginning of the line, after any prompt.
98The prompt is assumed to be any text at the beginning of the line matching
99the regular expression `comint-prompt-regexp', a buffer local variable."
100 (save-excursion (comint-bol nil) (point))))
101
102
103(defvar inferior-octave-output-list nil)
104(defvar inferior-octave-output-string nil)
105(defvar inferior-octave-receive-in-progress nil)
106
107(defvar inferior-octave-startup-hook nil)
108
109(defvar inferior-octave-complete-impossible nil
110 "Non-nil means that `inferior-octave-complete' is impossible.")
111
112(defvar inferior-octave-has-built-in-variables nil
113 "Non-nil means that Octave has built-in variables.")
114
115(defvar inferior-octave-dynamic-complete-functions
116 '(inferior-octave-completion-at-point comint-filename-completion)
117 "List of functions called to perform completion for inferior Octave.
118This variable is used to initialize `comint-dynamic-complete-functions'
119in the Inferior Octave buffer.")
120
121(defvar info-lookup-mode)
122
123(define-derived-mode inferior-octave-mode comint-mode "Inferior Octave"
124 "Major mode for interacting with an inferior Octave process.
125Runs Octave as a subprocess of Emacs, with Octave I/O through an Emacs
126buffer.
127
128Entry to this mode successively runs the hooks `comint-mode-hook' and
129`inferior-octave-mode-hook'."
130 (setq comint-prompt-regexp inferior-octave-prompt
131 mode-line-process '(":%s")
132 local-abbrev-table octave-abbrev-table)
133
134 (set (make-local-variable 'comment-start) octave-comment-start)
135 (set (make-local-variable 'comment-end) "")
136 (set (make-local-variable 'comment-column) 32)
137 (set (make-local-variable 'comment-start-skip) octave-comment-start-skip)
138
139 (set (make-local-variable 'font-lock-defaults)
140 '(inferior-octave-font-lock-keywords nil nil))
141
142 (set (make-local-variable 'info-lookup-mode) 'octave-mode)
143
144 (setq comint-input-ring-file-name
145 (or (getenv "OCTAVE_HISTFILE") "~/.octave_hist")
146 comint-input-ring-size (or (getenv "OCTAVE_HISTSIZE") 1024))
147 (set (make-local-variable 'comint-dynamic-complete-functions)
148 inferior-octave-dynamic-complete-functions)
149 (add-hook 'comint-input-filter-functions
150 'inferior-octave-directory-tracker nil t)
151 (comint-read-input-ring t))
152
153;;;###autoload
154(defun inferior-octave (&optional arg)
155 "Run an inferior Octave process, I/O via `inferior-octave-buffer'.
156This buffer is put in Inferior Octave mode. See `inferior-octave-mode'.
157
158Unless ARG is non-nil, switches to this buffer.
159
160The elements of the list `inferior-octave-startup-args' are sent as
161command line arguments to the inferior Octave process on startup.
162
163Additional commands to be executed on startup can be provided either in
164the file specified by `inferior-octave-startup-file' or by the default
165startup file, `~/.emacs-octave'."
166 (interactive "P")
167 (let ((buffer inferior-octave-buffer))
168 (get-buffer-create buffer)
169 (if (comint-check-proc buffer)
170 ()
171 (with-current-buffer buffer
172 (comint-mode)
173 (inferior-octave-startup)
174 (inferior-octave-mode)))
175 (if (not arg)
176 (pop-to-buffer buffer))))
177
178;;;###autoload
179(defalias 'run-octave 'inferior-octave)
180
181(defun inferior-octave-startup ()
182 "Start an inferior Octave process."
183 (let ((proc (comint-exec-1
184 (substring inferior-octave-buffer 1 -1)
185 inferior-octave-buffer
186 inferior-octave-program
187 (append (list "-i" "--no-line-editing")
188 inferior-octave-startup-args))))
189 (set-process-filter proc 'inferior-octave-output-digest)
190 (setq comint-ptyp process-connection-type
191 inferior-octave-process proc
192 inferior-octave-output-list nil
193 inferior-octave-output-string nil
194 inferior-octave-receive-in-progress t)
195
196 ;; This may look complicated ... However, we need to make sure that
197 ;; we additional startup code only AFTER Octave is ready (otherwise,
198 ;; output may be mixed up). Hence, we need to digest the Octave
199 ;; output to see when it issues a prompt.
200 (while inferior-octave-receive-in-progress
201 (accept-process-output inferior-octave-process))
202 (goto-char (point-max))
203 (set-marker (process-mark proc) (point))
204 (insert-before-markers
205 (concat
206 (if (not (bobp)) " \n")
207 (if inferior-octave-output-list
208 (concat (mapconcat
209 'identity inferior-octave-output-list "\n")
210 "\n"))))
211
212 ;; Find out whether Octave has built-in variables.
213 (inferior-octave-send-list-and-digest
214 (list "exist \"LOADPATH\"\n"))
215 (setq inferior-octave-has-built-in-variables
216 (string-match "101$" (car inferior-octave-output-list)))
217
218 ;; An empty secondary prompt, as e.g. obtained by '--braindead',
219 ;; means trouble.
220 (inferior-octave-send-list-and-digest (list "PS2\n"))
221 (if (string-match "\\(PS2\\|ans\\) = *$" (car inferior-octave-output-list))
222 (inferior-octave-send-list-and-digest
223 (list (if inferior-octave-has-built-in-variables
224 "PS2 = \"> \"\n"
225 "PS2 (\"> \");\n"))))
226
227 ;; O.k., now we are ready for the Inferior Octave startup commands.
228 (let* (commands
229 (program (file-name-nondirectory inferior-octave-program))
230 (file (or inferior-octave-startup-file
231 (concat "~/.emacs-" program))))
232 (setq commands
233 (list "more off;\n"
234 (if (not (string-equal
235 inferior-octave-output-string ">> "))
236 (if inferior-octave-has-built-in-variables
237 "PS1=\"\\\\s> \";\n"
238 "PS1 (\"\\\\s> \");\n"))
239 (if (file-exists-p file)
240 (format "source (\"%s\");\n" file))))
241 (inferior-octave-send-list-and-digest commands))
242 (insert-before-markers
243 (concat
244 (if inferior-octave-output-list
245 (concat (mapconcat
246 'identity inferior-octave-output-list "\n")
247 "\n"))
248 inferior-octave-output-string))
249 ;; Next, we check whether Octave supports `completion_matches' ...
250 (inferior-octave-send-list-and-digest
251 (list "exist \"completion_matches\"\n"))
252 (setq inferior-octave-complete-impossible
253 (not (string-match "5$" (car inferior-octave-output-list))))
254
255 ;; And finally, everything is back to normal.
256 (set-process-filter proc 'inferior-octave-output-filter)
257 (run-hooks 'inferior-octave-startup-hook)
258 (run-hooks 'inferior-octave-startup-hook)
259 ;; Just in case, to be sure a cd in the startup file
260 ;; won't have detrimental effects.
261 (inferior-octave-resync-dirs)))
262
263
264(defun inferior-octave-completion-at-point ()
265 "Return the data to complete the Octave symbol at point."
266 (let* ((end (point))
267 (start
268 (save-excursion
269 (skip-syntax-backward "w_" (comint-line-beginning-position))
270 (point))))
271 (cond ((eq start end) nil)
272 (inferior-octave-complete-impossible
273 (message (concat
274 "Your Octave does not have `completion_matches'. "
275 "Please upgrade to version 2.X."))
276 nil)
277 (t
278 (list
279 start end
280 (completion-table-dynamic
281 (lambda (command)
282 (inferior-octave-send-list-and-digest
283 (list (concat "completion_matches (\"" command "\");\n")))
284 (sort (delete-dups inferior-octave-output-list)
285 'string-lessp))))))))
286
287(define-obsolete-function-alias 'inferior-octave-complete
288 'completion-at-point "24.1")
289
290(defun inferior-octave-dynamic-list-input-ring ()
291 "List the buffer's input history in a help buffer."
292 ;; We cannot use `comint-dynamic-list-input-ring', because it replaces
293 ;; "completion" by "history reference" ...
294 (interactive)
295 (if (or (not (ring-p comint-input-ring))
296 (ring-empty-p comint-input-ring))
297 (message "No history")
298 (let ((history nil)
299 (history-buffer " *Input History*")
300 (index (1- (ring-length comint-input-ring)))
301 (conf (current-window-configuration)))
302 ;; We have to build up a list ourselves from the ring vector.
303 (while (>= index 0)
304 (setq history (cons (ring-ref comint-input-ring index) history)
305 index (1- index)))
306 ;; Change "completion" to "history reference"
307 ;; to make the display accurate.
308 (with-output-to-temp-buffer history-buffer
309 (display-completion-list history)
310 (set-buffer history-buffer))
311 (message "Hit space to flush")
312 (let ((ch (read-event)))
313 (if (eq ch ?\ )
314 (set-window-configuration conf)
315 (setq unread-command-events (list ch)))))))
316
317(defun inferior-octave-strip-ctrl-g (string)
318 "Strip leading `^G' character.
319If STRING starts with a `^G', ring the bell and strip it."
320 (if (string-match "^\a" string)
321 (progn
322 (ding)
323 (setq string (substring string 1))))
324 string)
325
326(defun inferior-octave-output-filter (proc string)
327 "Standard output filter for the inferior Octave process.
328Ring Emacs bell if process output starts with an ASCII bell, and pass
329the rest to `comint-output-filter'."
330 (comint-output-filter proc (inferior-octave-strip-ctrl-g string)))
331
332(defun inferior-octave-output-digest (_proc string)
333 "Special output filter for the inferior Octave process.
334Save all output between newlines into `inferior-octave-output-list', and
335the rest to `inferior-octave-output-string'."
336 (setq string (concat inferior-octave-output-string string))
337 (while (string-match "\n" string)
338 (setq inferior-octave-output-list
339 (append inferior-octave-output-list
340 (list (substring string 0 (match-beginning 0))))
341 string (substring string (match-end 0))))
342 (if (string-match inferior-octave-prompt string)
343 (setq inferior-octave-receive-in-progress nil))
344 (setq inferior-octave-output-string string))
345
346(defun inferior-octave-send-list-and-digest (list)
347 "Send LIST to the inferior Octave process and digest the output.
348The elements of LIST have to be strings and are sent one by one. All
349output is passed to the filter `inferior-octave-output-digest'."
350 (let* ((proc inferior-octave-process)
351 string)
352 (add-function :override (process-filter proc)
353 #'inferior-octave-output-digest)
354 (setq inferior-octave-output-list nil)
355 (unwind-protect
356 (while (setq string (car list))
357 (setq inferior-octave-output-string nil
358 inferior-octave-receive-in-progress t)
359 (comint-send-string proc string)
360 (while inferior-octave-receive-in-progress
361 (accept-process-output proc))
362 (setq list (cdr list)))
363 (remove-function (process-filter proc)
364 #'inferior-octave-output-digest))))
365
366(defun inferior-octave-directory-tracker (string)
367 "Tracks `cd' commands issued to the inferior Octave process.
368Use \\[inferior-octave-resync-dirs] to resync if Emacs gets confused."
369 (cond
370 ((string-match "^[ \t]*cd[ \t;]*$" string)
371 (cd "~"))
372 ((string-match "^[ \t]*cd[ \t]+\\([^ \t\n;]*\\)[ \t\n;]*" string)
373 (cd (substring string (match-beginning 1) (match-end 1))))))
374
375(defun inferior-octave-resync-dirs ()
376 "Resync the buffer's idea of the current directory.
377This command queries the inferior Octave process about its current
378directory and makes this the current buffer's default directory."
379 (interactive)
380 (inferior-octave-send-list-and-digest '("disp (pwd ())\n"))
381 (cd (car inferior-octave-output-list)))
382
383;;; provide ourself
384
385(provide 'octave-inf)
386
387;;; octave-inf.el ends here
diff --git a/lisp/progmodes/octave-mod.el b/lisp/progmodes/octave.el
index 4683186e603..0e540ea348a 100644
--- a/lisp/progmodes/octave-mod.el
+++ b/lisp/progmodes/octave.el
@@ -1,4 +1,4 @@
1;;; octave-mod.el --- editing Octave source files under Emacs 1;;; octave.el --- editing octave source files under emacs
2 2
3;; Copyright (C) 1997, 2001-2013 Free Software Foundation, Inc. 3;; Copyright (C) 1997, 2001-2013 Free Software Foundation, Inc.
4 4
@@ -24,30 +24,21 @@
24 24
25;;; Commentary: 25;;; Commentary:
26 26
27;; This package provides Emacs support for Octave. 27;; This package provides emacs support for octave. It defines a major
28;; It defines Octave mode, a major mode for editing 28;; mode for editing octave code and contains code for interacting with
29;; Octave code. 29;; an inferior octave process using comint.
30 30
31;; The file octave-inf.el contains code for interacting with an inferior 31;; See the documentation of `octave-mode' and `run-octave' for further
32;; Octave process using comint. 32;; information on usage and customization.
33
34;; See the documentation of `octave-mode' and
35;; `run-octave' for further information on usage and customization.
36 33
37;;; Code: 34;;; Code:
38(require 'custom) 35(require 'comint)
39 36
40(defgroup octave nil 37(defgroup octave nil
41 "Major mode for editing Octave source files." 38 "Editing Octave code."
42 :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) 39 :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
43 :group 'languages) 40 :group 'languages)
44 41
45(defvar inferior-octave-output-list nil)
46(defvar inferior-octave-output-string nil)
47(defvar inferior-octave-receive-in-progress nil)
48
49(declare-function inferior-octave-send-list-and-digest "octave-inf" (list))
50
51(defconst octave-maintainer-address 42(defconst octave-maintainer-address
52 "Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>, bug-gnu-emacs@gnu.org" 43 "Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>, bug-gnu-emacs@gnu.org"
53 "Current maintainer of the Emacs Octave package.") 44 "Current maintainer of the Emacs Octave package.")
@@ -84,7 +75,7 @@
84 ("`upc" "unwind_protect_cleanup") 75 ("`upc" "unwind_protect_cleanup")
85 ("`w" "while ()"))) 76 ("`w" "while ()")))
86 "Abbrev table for Octave's reserved words. 77 "Abbrev table for Octave's reserved words.
87Used in `octave-mode' and inferior-octave-mode buffers. 78Used in `octave-mode' and `inferior-octave-mode' buffers.
88All Octave abbrevs start with a grave accent (`)." 79All Octave abbrevs start with a grave accent (`)."
89 :regexp "\\(?:[^`]\\|^\\)\\(\\(?:\\<\\|`\\)\\w+\\)\\W*") 80 :regexp "\\(?:[^`]\\|^\\)\\(\\(?:\\<\\|`\\)\\w+\\)\\W*")
90 81
@@ -156,6 +147,7 @@ All Octave abbrevs start with a grave accent (`)."
156The string `function' and its name are given by the first and third 147The string `function' and its name are given by the first and third
157parenthetical grouping.") 148parenthetical grouping.")
158 149
150
159(defvar octave-font-lock-keywords 151(defvar octave-font-lock-keywords
160 (list 152 (list
161 ;; Fontify all builtin keywords. 153 ;; Fontify all builtin keywords.
@@ -201,12 +193,6 @@ parenthetical grouping.")
201 (put-text-property (match-beginning 1) (match-end 1) 193 (put-text-property (match-beginning 1) (match-end 1)
202 'syntax-table (string-to-syntax "\"'"))))) 194 'syntax-table (string-to-syntax "\"'")))))
203 195
204(defcustom inferior-octave-buffer "*Inferior Octave*"
205 "Name of buffer for running an inferior Octave process."
206 :type 'string
207 :group 'octave-inferior)
208
209(defvar inferior-octave-process nil)
210 196
211(defvar octave-mode-map 197(defvar octave-mode-map
212 (let ((map (make-sparse-keymap))) 198 (let ((map (make-sparse-keymap)))
@@ -344,12 +330,6 @@ newline or semicolon after an else or end keyword."
344 :type 'string 330 :type 'string
345 :group 'octave) 331 :group 'octave)
346 332
347(defvar octave-completion-alist nil
348 "Alist of Octave symbols for completion in Octave mode.
349Each element looks like (VAR . VAR), where the car and cdr are the same
350symbol (an Octave command or variable name).
351Currently, only builtin variables can be completed.")
352
353(defvar octave-mode-imenu-generic-expression 333(defvar octave-mode-imenu-generic-expression
354 (list 334 (list
355 ;; Functions 335 ;; Functions
@@ -482,6 +462,7 @@ Non-nil means always go to the next Octave code line after sending."
482 (forward-comment 1)) 462 (forward-comment 1))
483 (cond 463 (cond
484 ((and (looking-at "$\\|[%#]") 464 ((and (looking-at "$\\|[%#]")
465 (not (smie-rule-bolp))
485 ;; Ignore it if it's within parentheses. 466 ;; Ignore it if it's within parentheses.
486 (prog1 (let ((ppss (syntax-ppss))) 467 (prog1 (let ((ppss (syntax-ppss)))
487 (not (and (nth 1 ppss) 468 (not (and (nth 1 ppss)
@@ -652,8 +633,359 @@ including a reproducible test case and send the message."
652 (set (make-local-variable 'beginning-of-defun-function) 633 (set (make-local-variable 'beginning-of-defun-function)
653 'octave-beginning-of-defun) 634 'octave-beginning-of-defun)
654 635
655 (easy-menu-add octave-mode-menu) 636 (easy-menu-add octave-mode-menu))
656 (octave-initialize-completions)) 637
638
639(defcustom inferior-octave-program "octave"
640 "Program invoked by `inferior-octave'."
641 :type 'string
642 :group 'octave)
643
644(defcustom inferior-octave-buffer "*Inferior Octave*"
645 "Name of buffer for running an inferior Octave process."
646 :type 'string
647 :group 'octave)
648
649(defcustom inferior-octave-prompt
650 "\\(^octave\\(\\|.bin\\|.exe\\)\\(-[.0-9]+\\)?\\(:[0-9]+\\)?\\|^debug\\|^\\)>+ "
651 "Regexp to match prompts for the inferior Octave process."
652 :type 'regexp
653 :group 'octave)
654
655(defcustom inferior-octave-startup-file nil
656 "Name of the inferior Octave startup file.
657The contents of this file are sent to the inferior Octave process on
658startup."
659 :type '(choice (const :tag "None" nil)
660 file)
661 :group 'octave)
662
663(defcustom inferior-octave-startup-args nil
664 "List of command line arguments for the inferior Octave process.
665For example, for suppressing the startup message and using `traditional'
666mode, set this to (\"-q\" \"--traditional\")."
667 :type '(repeat string)
668 :group 'octave)
669
670(defcustom inferior-octave-mode-hook nil
671 "Hook to be run when Inferior Octave mode is started."
672 :type 'hook
673 :group 'octave)
674
675(defvar inferior-octave-process nil)
676
677(defvar inferior-octave-mode-map
678 (let ((map (make-sparse-keymap)))
679 (set-keymap-parent map comint-mode-map)
680 (define-key map "\t" 'comint-dynamic-complete)
681 (define-key map "\M-?" 'comint-dynamic-list-filename-completions)
682 (define-key map "\C-c\C-l" 'inferior-octave-dynamic-list-input-ring)
683 (define-key map [menu-bar inout list-history]
684 '("List Input History" . inferior-octave-dynamic-list-input-ring))
685 map)
686 "Keymap used in Inferior Octave mode.")
687
688(defvar inferior-octave-mode-syntax-table
689 (let ((table (make-syntax-table octave-mode-syntax-table)))
690 table)
691 "Syntax table in use in inferior-octave-mode buffers.")
692
693(defvar inferior-octave-font-lock-keywords
694 (list
695 (cons inferior-octave-prompt 'font-lock-type-face))
696 ;; Could certainly do more font locking in inferior Octave ...
697 "Additional expressions to highlight in Inferior Octave mode.")
698
699
700;;; Compatibility functions
701(if (not (fboundp 'comint-line-beginning-position))
702 ;; comint-line-beginning-position is defined in Emacs 21
703 (defun comint-line-beginning-position ()
704 "Returns the buffer position of the beginning of the line, after any prompt.
705The prompt is assumed to be any text at the beginning of the line matching
706the regular expression `comint-prompt-regexp', a buffer local variable."
707 (save-excursion (comint-bol nil) (point))))
708
709
710(defvar inferior-octave-output-list nil)
711(defvar inferior-octave-output-string nil)
712(defvar inferior-octave-receive-in-progress nil)
713
714(defvar inferior-octave-startup-hook nil)
715
716(defvar inferior-octave-complete-impossible nil
717 "Non-nil means that `inferior-octave-complete' is impossible.")
718
719(defvar inferior-octave-has-built-in-variables nil
720 "Non-nil means that Octave has built-in variables.")
721
722(defvar inferior-octave-dynamic-complete-functions
723 '(inferior-octave-completion-at-point comint-filename-completion)
724 "List of functions called to perform completion for inferior Octave.
725This variable is used to initialize `comint-dynamic-complete-functions'
726in the Inferior Octave buffer.")
727
728(defvar info-lookup-mode)
729
730(define-derived-mode inferior-octave-mode comint-mode "Inferior Octave"
731 "Major mode for interacting with an inferior Octave process.
732Runs Octave as a subprocess of Emacs, with Octave I/O through an Emacs
733buffer.
734
735Entry to this mode successively runs the hooks `comint-mode-hook' and
736`inferior-octave-mode-hook'."
737 (setq comint-prompt-regexp inferior-octave-prompt
738 mode-line-process '(":%s")
739 local-abbrev-table octave-abbrev-table)
740
741 (set (make-local-variable 'comment-start) octave-comment-start)
742 (set (make-local-variable 'comment-end) "")
743 (set (make-local-variable 'comment-column) 32)
744 (set (make-local-variable 'comment-start-skip) octave-comment-start-skip)
745
746 (set (make-local-variable 'font-lock-defaults)
747 '(inferior-octave-font-lock-keywords nil nil))
748
749 (set (make-local-variable 'info-lookup-mode) 'octave-mode)
750
751 (setq comint-input-ring-file-name
752 (or (getenv "OCTAVE_HISTFILE") "~/.octave_hist")
753 comint-input-ring-size (or (getenv "OCTAVE_HISTSIZE") 1024))
754 (set (make-local-variable 'comint-dynamic-complete-functions)
755 inferior-octave-dynamic-complete-functions)
756 (add-hook 'comint-input-filter-functions
757 'inferior-octave-directory-tracker nil t)
758 (comint-read-input-ring t))
759
760;;;###autoload
761(defun inferior-octave (&optional arg)
762 "Run an inferior Octave process, I/O via `inferior-octave-buffer'.
763This buffer is put in Inferior Octave mode. See `inferior-octave-mode'.
764
765Unless ARG is non-nil, switches to this buffer.
766
767The elements of the list `inferior-octave-startup-args' are sent as
768command line arguments to the inferior Octave process on startup.
769
770Additional commands to be executed on startup can be provided either in
771the file specified by `inferior-octave-startup-file' or by the default
772startup file, `~/.emacs-octave'."
773 (interactive "P")
774 (let ((buffer inferior-octave-buffer))
775 (get-buffer-create buffer)
776 (if (comint-check-proc buffer)
777 ()
778 (with-current-buffer buffer
779 (comint-mode)
780 (inferior-octave-startup)
781 (inferior-octave-mode)))
782 (if (not arg)
783 (pop-to-buffer buffer))))
784
785;;;###autoload
786(defalias 'run-octave 'inferior-octave)
787
788(defun inferior-octave-startup ()
789 "Start an inferior Octave process."
790 (let ((proc (comint-exec-1
791 (substring inferior-octave-buffer 1 -1)
792 inferior-octave-buffer
793 inferior-octave-program
794 (append (list "-i" "--no-line-editing")
795 inferior-octave-startup-args))))
796 (set-process-filter proc 'inferior-octave-output-digest)
797 (setq comint-ptyp process-connection-type
798 inferior-octave-process proc
799 inferior-octave-output-list nil
800 inferior-octave-output-string nil
801 inferior-octave-receive-in-progress t)
802
803 ;; This may look complicated ... However, we need to make sure that
804 ;; we additional startup code only AFTER Octave is ready (otherwise,
805 ;; output may be mixed up). Hence, we need to digest the Octave
806 ;; output to see when it issues a prompt.
807 (while inferior-octave-receive-in-progress
808 (accept-process-output inferior-octave-process))
809 (goto-char (point-max))
810 (set-marker (process-mark proc) (point))
811 (insert-before-markers
812 (concat
813 (if (not (bobp)) " \n")
814 (if inferior-octave-output-list
815 (concat (mapconcat
816 'identity inferior-octave-output-list "\n")
817 "\n"))))
818
819 ;; Find out whether Octave has built-in variables.
820 (inferior-octave-send-list-and-digest
821 (list "exist \"LOADPATH\"\n"))
822 (setq inferior-octave-has-built-in-variables
823 (string-match "101$" (car inferior-octave-output-list)))
824
825 ;; An empty secondary prompt, as e.g. obtained by '--braindead',
826 ;; means trouble.
827 (inferior-octave-send-list-and-digest (list "PS2\n"))
828 (if (string-match "\\(PS2\\|ans\\) = *$" (car inferior-octave-output-list))
829 (inferior-octave-send-list-and-digest
830 (list (if inferior-octave-has-built-in-variables
831 "PS2 = \"> \"\n"
832 "PS2 (\"> \");\n"))))
833
834 ;; O.k., now we are ready for the Inferior Octave startup commands.
835 (let* (commands
836 (program (file-name-nondirectory inferior-octave-program))
837 (file (or inferior-octave-startup-file
838 (concat "~/.emacs-" program))))
839 (setq commands
840 (list "more off;\n"
841 (if (not (string-equal
842 inferior-octave-output-string ">> "))
843 (if inferior-octave-has-built-in-variables
844 "PS1=\"\\\\s> \";\n"
845 "PS1 (\"\\\\s> \");\n"))
846 (if (file-exists-p file)
847 (format "source (\"%s\");\n" file))))
848 (inferior-octave-send-list-and-digest commands))
849 (insert-before-markers
850 (concat
851 (if inferior-octave-output-list
852 (concat (mapconcat
853 'identity inferior-octave-output-list "\n")
854 "\n"))
855 inferior-octave-output-string))
856 ;; Next, we check whether Octave supports `completion_matches' ...
857 (inferior-octave-send-list-and-digest
858 (list "exist \"completion_matches\"\n"))
859 (setq inferior-octave-complete-impossible
860 (not (string-match "5$" (car inferior-octave-output-list))))
861
862 ;; And finally, everything is back to normal.
863 (set-process-filter proc 'inferior-octave-output-filter)
864 (run-hooks 'inferior-octave-startup-hook)
865 (run-hooks 'inferior-octave-startup-hook)
866 ;; Just in case, to be sure a cd in the startup file
867 ;; won't have detrimental effects.
868 (inferior-octave-resync-dirs)))
869
870(defun inferior-octave-completion-table ()
871 (unless inferior-octave-complete-impossible
872 (completion-table-dynamic
873 (lambda (command)
874 (inferior-octave-send-list-and-digest
875 (list (concat "completion_matches (\"" command "\");\n")))
876 (sort (delete-dups inferior-octave-output-list)
877 'string-lessp)))))
878
879(defun inferior-octave-completion-at-point ()
880 "Return the data to complete the Octave symbol at point."
881 (let* ((end (point))
882 (start
883 (save-excursion
884 (skip-syntax-backward "w_" (comint-line-beginning-position))
885 (point))))
886 (cond ((eq start end) nil)
887 (inferior-octave-complete-impossible
888 (message (concat
889 "Your Octave does not have `completion_matches'. "
890 "Please upgrade to version 2.X."))
891 nil)
892 (t (list start end (inferior-octave-completion-table))))))
893
894(define-obsolete-function-alias 'inferior-octave-complete
895 'completion-at-point "24.1")
896
897(defun inferior-octave-dynamic-list-input-ring ()
898 "List the buffer's input history in a help buffer."
899 ;; We cannot use `comint-dynamic-list-input-ring', because it replaces
900 ;; "completion" by "history reference" ...
901 (interactive)
902 (if (or (not (ring-p comint-input-ring))
903 (ring-empty-p comint-input-ring))
904 (message "No history")
905 (let ((history nil)
906 (history-buffer " *Input History*")
907 (index (1- (ring-length comint-input-ring)))
908 (conf (current-window-configuration)))
909 ;; We have to build up a list ourselves from the ring vector.
910 (while (>= index 0)
911 (setq history (cons (ring-ref comint-input-ring index) history)
912 index (1- index)))
913 ;; Change "completion" to "history reference"
914 ;; to make the display accurate.
915 (with-output-to-temp-buffer history-buffer
916 (display-completion-list history)
917 (set-buffer history-buffer))
918 (message "Hit space to flush")
919 (let ((ch (read-event)))
920 (if (eq ch ?\ )
921 (set-window-configuration conf)
922 (setq unread-command-events (list ch)))))))
923
924(defun inferior-octave-strip-ctrl-g (string)
925 "Strip leading `^G' character.
926If STRING starts with a `^G', ring the bell and strip it."
927 (if (string-match "^\a" string)
928 (progn
929 (ding)
930 (setq string (substring string 1))))
931 string)
932
933(defun inferior-octave-output-filter (proc string)
934 "Standard output filter for the inferior Octave process.
935Ring Emacs bell if process output starts with an ASCII bell, and pass
936the rest to `comint-output-filter'."
937 (comint-output-filter proc (inferior-octave-strip-ctrl-g string)))
938
939(defun inferior-octave-output-digest (_proc string)
940 "Special output filter for the inferior Octave process.
941Save all output between newlines into `inferior-octave-output-list', and
942the rest to `inferior-octave-output-string'."
943 (setq string (concat inferior-octave-output-string string))
944 (while (string-match "\n" string)
945 (setq inferior-octave-output-list
946 (append inferior-octave-output-list
947 (list (substring string 0 (match-beginning 0))))
948 string (substring string (match-end 0))))
949 (if (string-match inferior-octave-prompt string)
950 (setq inferior-octave-receive-in-progress nil))
951 (setq inferior-octave-output-string string))
952
953(defun inferior-octave-send-list-and-digest (list)
954 "Send LIST to the inferior Octave process and digest the output.
955The elements of LIST have to be strings and are sent one by one. All
956output is passed to the filter `inferior-octave-output-digest'."
957 (let* ((proc inferior-octave-process)
958 (filter (process-filter proc))
959 string)
960 (set-process-filter proc 'inferior-octave-output-digest)
961 (setq inferior-octave-output-list nil)
962 (unwind-protect
963 (while (setq string (car list))
964 (setq inferior-octave-output-string nil
965 inferior-octave-receive-in-progress t)
966 (comint-send-string proc string)
967 (while inferior-octave-receive-in-progress
968 (accept-process-output proc))
969 (setq list (cdr list)))
970 (set-process-filter proc filter))))
971
972(defun inferior-octave-directory-tracker (string)
973 "Tracks `cd' commands issued to the inferior Octave process.
974Use \\[inferior-octave-resync-dirs] to resync if Emacs gets confused."
975 (cond
976 ((string-match "^[ \t]*cd[ \t;]*$" string)
977 (cd "~"))
978 ((string-match "^[ \t]*cd[ \t]+\\([^ \t\n;]*\\)[ \t\n;]*" string)
979 (cd (substring string (match-beginning 1) (match-end 1))))))
980
981(defun inferior-octave-resync-dirs ()
982 "Resync the buffer's idea of the current directory.
983This command queries the inferior Octave process about its current
984directory and makes this the current buffer's default directory."
985 (interactive)
986 (inferior-octave-send-list-and-digest '("disp (pwd ())\n"))
987 (cd (car inferior-octave-output-list)))
988
657 989
658;;; Miscellaneous useful functions 990;;; Miscellaneous useful functions
659 991
@@ -958,14 +1290,6 @@ otherwise."
958 1290
959 1291
960;;; Completions 1292;;; Completions
961(defun octave-initialize-completions ()
962 "Create an alist for Octave completions."
963 (if octave-completion-alist
964 ()
965 (setq octave-completion-alist
966 (append octave-reserved-words
967 octave-text-functions
968 octave-variables))))
969 1293
970(defun octave-completion-at-point-function () 1294(defun octave-completion-at-point-function ()
971 "Find the text to complete and the corresponding table." 1295 "Find the text to complete and the corresponding table."
@@ -975,7 +1299,12 @@ otherwise."
975 ;; Extend region past point, if applicable. 1299 ;; Extend region past point, if applicable.
976 (save-excursion (skip-syntax-forward "w_") 1300 (save-excursion (skip-syntax-forward "w_")
977 (setq end (point)))) 1301 (setq end (point))))
978 (list beg end octave-completion-alist))) 1302 (list beg end (or (and inferior-octave-process
1303 (process-live-p inferior-octave-process)
1304 (inferior-octave-completion-table))
1305 (append octave-reserved-words
1306 octave-text-functions
1307 octave-variables)))))
979 1308
980(define-obsolete-function-alias 'octave-complete-symbol 1309(define-obsolete-function-alias 'octave-complete-symbol
981 'completion-at-point "24.1") 1310 'completion-at-point "24.1")
@@ -1142,8 +1471,5 @@ code line."
1142 'octave-send-line-auto-forward 1471 'octave-send-line-auto-forward
1143 'octave-send-show-buffer)))) 1472 'octave-send-show-buffer))))
1144 1473
1145;; provide ourself 1474(provide 'octave)
1146 1475;;; octave.el ends here
1147(provide 'octave-mod)
1148
1149;;; octave-mod.el ends here
diff --git a/lisp/progmodes/opascal.el b/lisp/progmodes/opascal.el
index 5f78b770936..e608ea8af0e 100644
--- a/lisp/progmodes/opascal.el
+++ b/lisp/progmodes/opascal.el
@@ -110,29 +110,6 @@ end; end;"
110regardless of where in the line point is when the TAB command is used." 110regardless of where in the line point is when the TAB command is used."
111 :type 'boolean) 111 :type 'boolean)
112 112
113(define-obsolete-variable-alias
114 'delphi-comment-face 'opascal-comment-face "24.4")
115(defcustom opascal-comment-face 'font-lock-comment-face
116 "Face used to color OPascal comments."
117 :type 'face)
118
119(define-obsolete-variable-alias
120 'delphi-string-face 'opascal-string-face "24.4")
121(defcustom opascal-string-face 'font-lock-string-face
122 "Face used to color OPascal strings."
123 :type 'face)
124
125(define-obsolete-variable-alias
126 'delphi-keyword-face 'opascal-keyword-face "24.4")
127(defcustom opascal-keyword-face 'font-lock-keyword-face
128 "Face used to color OPascal keywords."
129 :type 'face)
130
131(define-obsolete-variable-alias 'delphi-other-face 'opascal-other-face "24.4")
132(defcustom opascal-other-face nil
133 "Face used to color everything else."
134 :type '(choice (const :tag "None" nil) face))
135
136(defconst opascal-directives 113(defconst opascal-directives
137 '(absolute abstract assembler automated cdecl default dispid dynamic 114 '(absolute abstract assembler automated cdecl default dispid dynamic
138 export external far forward index inline message name near nodefault 115 export external far forward index inline message name near nodefault
@@ -274,6 +251,21 @@ routine.")
274(defconst opascal-leading-spaces-re (concat "^" opascal-spaces-re)) 251(defconst opascal-leading-spaces-re (concat "^" opascal-spaces-re))
275(defconst opascal-word-chars "a-zA-Z0-9_") 252(defconst opascal-word-chars "a-zA-Z0-9_")
276 253
254(defvar opascal-mode-syntax-table
255 (let ((st (make-syntax-table)))
256 ;; Strings.
257 (modify-syntax-entry ?\" "\"" st)
258 (modify-syntax-entry ?\' "\"" st)
259 ;; Comments.
260 (modify-syntax-entry ?\{ "<" st)
261 (modify-syntax-entry ?\} ">" st)
262 (modify-syntax-entry ?\( "()1" st)
263 (modify-syntax-entry ?\) ")(4" st)
264 (modify-syntax-entry ?* ". 23b" st)
265 (modify-syntax-entry ?/ ". 12c" st)
266 (modify-syntax-entry ?\n "> c" st)
267 st))
268
277(defmacro opascal-save-excursion (&rest forms) 269(defmacro opascal-save-excursion (&rest forms)
278 ;; Executes the forms such that any movements have no effect, including 270 ;; Executes the forms such that any movements have no effect, including
279 ;; searches. 271 ;; searches.
@@ -283,13 +275,6 @@ routine.")
283 (deactivate-mark nil)) 275 (deactivate-mark nil))
284 (progn ,@forms))))) 276 (progn ,@forms)))))
285 277
286(defmacro opascal-save-state (&rest forms)
287 ;; Executes the forms such that any buffer modifications do not have any side
288 ;; effects beyond the buffer's actual content changes.
289 `(let ((opascal--ignore-changes t))
290 (with-silent-modifications
291 ,@forms)))
292
293(defsubst opascal-is (element in-set) 278(defsubst opascal-is (element in-set)
294 ;; If the element is in the set, the element cdr is returned, otherwise nil. 279 ;; If the element is in the set, the element cdr is returned, otherwise nil.
295 (memq element in-set)) 280 (memq element in-set))
@@ -347,13 +332,6 @@ routine.")
347 ;; Returns the column of the point p. 332 ;; Returns the column of the point p.
348 (save-excursion (goto-char p) (current-column))) 333 (save-excursion (goto-char p) (current-column)))
349 334
350(defun opascal-face-of (token-kind)
351 ;; Returns the face property appropriate for the token kind.
352 (cond ((opascal-is token-kind opascal-comments) opascal-comment-face)
353 ((opascal-is token-kind opascal-strings) opascal-string-face)
354 ((opascal-is token-kind opascal-keywords) opascal-keyword-face)
355 (opascal-other-face)))
356
357(defvar opascal-progress-last-reported-point nil 335(defvar opascal-progress-last-reported-point nil
358 "The last point at which progress was reported.") 336 "The last point at which progress was reported.")
359 337
@@ -361,8 +339,6 @@ routine.")
361 "Number of chars to process before the next parsing progress report.") 339 "Number of chars to process before the next parsing progress report.")
362(defconst opascal-scanning-progress-step 2048 340(defconst opascal-scanning-progress-step 2048
363 "Number of chars to process before the next scanning progress report.") 341 "Number of chars to process before the next scanning progress report.")
364(defconst opascal-fontifying-progress-step opascal-scanning-progress-step
365 "Number of chars to process before the next fontification progress report.")
366 342
367(defun opascal-progress-start () 343(defun opascal-progress-start ()
368 ;; Initializes progress reporting. 344 ;; Initializes progress reporting.
@@ -400,22 +376,30 @@ routine.")
400 (goto-char curr-point) 376 (goto-char curr-point)
401 next)) 377 next))
402 378
403(defvar opascal--ignore-changes t 379(defconst opascal--literal-start-re (regexp-opt '("//" "{" "(*" "'" "\"")))
404 "Internal flag to control if the OPascal mode responds to buffer changes.
405Defaults to t in case the `opascal-after-change' function is called on a
406non-OPascal buffer. Set to nil in OPascal buffers. To override, just do:
407 (let ((opascal--ignore-changes t)) ...)")
408
409(defun opascal-set-text-properties (from to properties)
410 ;; Like `set-text-properties', except we do not consider this to be a buffer
411 ;; modification.
412 (opascal-save-state
413 (set-text-properties from to properties)))
414 380
415(defun opascal-literal-kind (p) 381(defun opascal-literal-kind (p)
416 ;; Returns the literal kind the point p is in (or nil if not in a literal). 382 ;; Returns the literal kind the point p is in (or nil if not in a literal).
417 (if (and (<= (point-min) p) (<= p (point-max))) 383 (when (and (<= (point-min) p) (<= p (point-max)))
418 (get-text-property p 'token))) 384 (save-excursion
385 (let ((ppss (syntax-ppss p)))
386 ;; We want to return non-nil when right in front
387 ;; of a comment/string.
388 (if (null (nth 8 ppss))
389 (when (looking-at opascal--literal-start-re)
390 (pcase (char-after)
391 (`?/ 'comment-single-line)
392 (`?\{ 'comment-multi-line-1)
393 (`?\( 'comment-multi-line-2)
394 (`?\' 'string)
395 (`?\" 'double-quoted-string)))
396 (if (nth 3 ppss) ;String.
397 (if (eq (nth 3 ppss) ?\")
398 'double-quoted-string 'string)
399 (pcase (nth 7 ppss)
400 (`2 'comment-single-line)
401 (`1 'comment-multi-line-2)
402 (_ 'comment-multi-line-1))))))))
419 403
420(defun opascal-literal-start-pattern (literal-kind) 404(defun opascal-literal-start-pattern (literal-kind)
421 ;; Returns the start pattern of the literal kind. 405 ;; Returns the start pattern of the literal kind.
@@ -446,96 +430,27 @@ non-OPascal buffer. Set to nil in OPascal buffers. To override, just do:
446 (string . "['\n]") 430 (string . "['\n]")
447 (double-quoted-string . "[\"\n]"))))) 431 (double-quoted-string . "[\"\n]")))))
448 432
449(defun opascal-is-literal-start (p)
450 ;; True if the point p is at the start point of a (completed) literal.
451 (let* ((kind (opascal-literal-kind p))
452 (pattern (opascal-literal-start-pattern kind)))
453 (or (null kind) ; Non-literals are considered as start points.
454 (opascal-looking-at-string p pattern))))
455
456(defun opascal-is-literal-end (p) 433(defun opascal-is-literal-end (p)
457 ;; True if the point p is at the end point of a (completed) literal. 434 ;; True if the point p is at the end point of a (completed) literal.
458 (let* ((kind (opascal-literal-kind (1- p))) 435 (save-excursion
459 (pattern (opascal-literal-end-pattern kind))) 436 (and (null (nth 8 (syntax-ppss p)))
460 (or (null kind) ; Non-literals are considered as end points. 437 (nth 8 (syntax-ppss (1- p))))))
461
462 (and (opascal-looking-at-string (- p (length pattern)) pattern)
463 (or (not (opascal-is kind opascal-strings))
464 ;; Special case: string delimiters are start/end ambiguous.
465 ;; We have an end only if there is some string content (at
466 ;; least a starting delimiter).
467 (not (opascal-is-literal-end (1- p)))))
468
469 ;; Special case: strings cannot span lines.
470 (and (opascal-is kind opascal-strings) (eq ?\n (char-after (1- p)))))))
471
472(defun opascal-is-stable-literal (p)
473 ;; True if the point p marks a stable point. That is, a point outside of a
474 ;; literal region, inside of a literal region, or adjacent to completed
475 ;; literal regions.
476 (let ((at-start (opascal-is-literal-start p))
477 (at-end (opascal-is-literal-end p)))
478 (or (>= p (point-max))
479 (and at-start at-end)
480 (and (not at-start) (not at-end)
481 (eq (opascal-literal-kind (1- p)) (opascal-literal-kind p))))))
482
483(defun opascal-complete-literal (literal-kind limit)
484 ;; Continues the search for a literal's true end point and returns the
485 ;; point past the end pattern (if found) or the limit (if not found).
486 (let ((pattern (opascal-literal-stop-pattern literal-kind)))
487 (if (not (stringp pattern))
488 (error "Invalid literal kind %S" literal-kind)
489 ;; Search up to the limit.
490 (re-search-forward pattern limit 'goto-limit-on-fail)
491 (point))))
492
493(defun opascal-literal-text-properties (kind)
494 ;; Creates a list of text properties for the literal kind.
495 (if (and (boundp 'font-lock-mode)
496 font-lock-mode)
497 (list 'token kind 'face (opascal-face-of kind) 'lazy-lock t)
498 (list 'token kind)))
499
500(defun opascal-parse-next-literal (limit)
501 ;; Searches for the next literal region (i.e. comment or string) and sets the
502 ;; the point to its end (or the limit, if not found). The literal region is
503 ;; marked as such with a text property, to speed up tokenizing during face
504 ;; coloring and indentation scanning.
505 (let ((search-start (point)))
506 (cond ((not (opascal-is-literal-end search-start))
507 ;; We are completing an incomplete literal.
508 (let ((kind (opascal-literal-kind (1- search-start))))
509 (opascal-complete-literal kind limit)
510 (opascal-set-text-properties
511 search-start (point) (opascal-literal-text-properties kind))))
512
513 ((re-search-forward
514 "\\(//\\)\\|\\({\\)\\|\\((\\*\\)\\|\\('\\)\\|\\(\"\\)"
515 limit 'goto-limit-on-fail)
516 ;; We found the start of a new literal. Find its end and mark it.
517 (let ((kind (cond ((match-beginning 1) 'comment-single-line)
518 ((match-beginning 2) 'comment-multi-line-1)
519 ((match-beginning 3) 'comment-multi-line-2)
520 ((match-beginning 4) 'string)
521 ((match-beginning 5) 'double-quoted-string)))
522 (start (match-beginning 0)))
523 (opascal-set-text-properties search-start start nil)
524 (opascal-complete-literal kind limit)
525 (opascal-set-text-properties
526 start (point) (opascal-literal-text-properties kind))))
527
528 ;; Nothing found. Mark it as a non-literal.
529 ((opascal-set-text-properties search-start limit nil)))
530 (opascal-step-progress (point) "Parsing" opascal-parsing-progress-step)))
531 438
532(defun opascal-literal-token-at (p) 439(defun opascal-literal-token-at (p)
533 ;; Returns the literal token surrounding the point p, or nil if none. 440 "Return the literal token surrounding the point P, or nil if none."
534 (let ((kind (opascal-literal-kind p))) 441 (save-excursion
535 (when kind 442 (let ((ppss (syntax-ppss p)))
536 (let ((start (previous-single-property-change (1+ p) 'token)) 443 (when (or (nth 8 ppss) (looking-at opascal--literal-start-re))
537 (end (next-single-property-change p 'token))) 444 (let* ((new-start (or (nth 8 ppss) p))
538 (opascal-token-of kind (or start (point-min)) (or end (point-max))))))) 445 (new-end (progn
446 (goto-char new-start)
447 (condition-case nil
448 (if (memq (char-after) '(?\' ?\"))
449 (forward-sexp 1)
450 (forward-comment 1))
451 (scan-error (goto-char (point-max))))
452 (point))))
453 (opascal-token-of (opascal-literal-kind p) new-start new-end))))))
539 454
540(defun opascal-point-token-at (p kind) 455(defun opascal-point-token-at (p kind)
541 ;; Returns the single character token at the point p. 456 ;; Returns the single character token at the point p.
@@ -645,55 +560,6 @@ non-OPascal buffer. Set to nil in OPascal buffers. To override, just do:
645 (opascal-is (opascal-token-kind next-token) '(space newline)))) 560 (opascal-is (opascal-token-kind next-token) '(space newline))))
646 next-token)) 561 next-token))
647 562
648(defun opascal-parse-region (from to)
649 ;; Parses the literal tokens in the region. The point is set to "to".
650 (save-restriction
651 (widen)
652 (goto-char from)
653 (while (< (point) to)
654 (opascal-parse-next-literal to))))
655
656(defun opascal-parse-region-until-stable (from to)
657 ;; Parses at least the literal tokens in the region. After that, parsing
658 ;; continues as long as obsolete literal regions are encountered. The point
659 ;; is set to the encountered stable point.
660 (save-restriction
661 (widen)
662 (opascal-parse-region from to)
663 (while (not (opascal-is-stable-literal (point)))
664 (opascal-parse-next-literal (point-max)))))
665
666(defun opascal-fontify-region (from to &optional verbose)
667 ;; Colors the text in the region according to OPascal rules.
668 (opascal-save-excursion
669 (opascal-save-state
670 (let ((p from)
671 (opascal-verbose verbose)
672 (token nil))
673 (opascal-progress-start)
674 (while (< p to)
675 ;; Color the token and move past it.
676 (setq token (opascal-token-at p))
677 (add-text-properties
678 (opascal-token-start token) (opascal-token-end token)
679 (list 'face (opascal-face-of (opascal-token-kind token)) 'lazy-lock t))
680 (setq p (opascal-token-end token))
681 (opascal-step-progress p "Fontifying" opascal-fontifying-progress-step))
682 (opascal-progress-done)))))
683
684(defun opascal-after-change (change-start change-end _old-length)
685 ;; Called when the buffer has changed. Reparses the changed region.
686 (unless opascal--ignore-changes
687 (let ((opascal--ignore-changes t)) ; Prevent recursive calls.
688 (opascal-save-excursion
689 (opascal-progress-start)
690 ;; Reparse at least from the token previous to the change to the end of
691 ;; line after the change.
692 (opascal-parse-region-until-stable
693 (opascal-token-start (opascal-token-at (1- change-start)))
694 (progn (goto-char change-end) (end-of-line) (point)))
695 (opascal-progress-done)))))
696
697(defun opascal-group-start (from-token) 563(defun opascal-group-start (from-token)
698 ;; Returns the token that denotes the start of the ()/[] group. 564 ;; Returns the token that denotes the start of the ()/[] group.
699 (let ((token (opascal-previous-token from-token)) 565 (let ((token (opascal-previous-token from-token))
@@ -1561,41 +1427,6 @@ If before the indent, the point is moved to the indent."
1561 (interactive "r") 1427 (interactive "r")
1562 (opascal-debug-log "String: %S" (buffer-substring from to))) 1428 (opascal-debug-log "String: %S" (buffer-substring from to)))
1563 1429
1564(defun opascal-debug-show-is-stable ()
1565 (interactive)
1566 (opascal-debug-log "stable: %S prev: %S next: %S"
1567 (opascal-is-stable-literal (point))
1568 (opascal-literal-kind (1- (point)))
1569 (opascal-literal-kind (point))))
1570
1571(defun opascal-debug-unparse-buffer ()
1572 (interactive)
1573 (opascal-set-text-properties (point-min) (point-max) nil))
1574
1575(defun opascal-debug-parse-region (from to)
1576 (interactive "r")
1577 (let ((opascal-verbose t))
1578 (opascal-save-excursion
1579 (opascal-progress-start)
1580 (opascal-parse-region from to)
1581 (opascal-progress-done "Parsing done"))))
1582
1583(defun opascal-debug-parse-window ()
1584 (interactive)
1585 (opascal-debug-parse-region (window-start) (window-end)))
1586
1587(defun opascal-debug-parse-buffer ()
1588 (interactive)
1589 (opascal-debug-parse-region (point-min) (point-max)))
1590
1591(defun opascal-debug-fontify-window ()
1592 (interactive)
1593 (opascal-fontify-region (window-start) (window-end) t))
1594
1595(defun opascal-debug-fontify-buffer ()
1596 (interactive)
1597 (opascal-fontify-region (point-min) (point-max) t))
1598
1599(defun opascal-debug-tokenize-region (from to) 1430(defun opascal-debug-tokenize-region (from to)
1600 (interactive) 1431 (interactive)
1601 (opascal-save-excursion 1432 (opascal-save-excursion
@@ -1747,6 +1578,7 @@ An error is raised if not in a comment."
1747 (error "Not in a comment") 1578 (error "Not in a comment")
1748 (let* ((start-comment (opascal-comment-block-start comment)) 1579 (let* ((start-comment (opascal-comment-block-start comment))
1749 (end-comment (opascal-comment-block-end comment)) 1580 (end-comment (opascal-comment-block-end comment))
1581 ;; FIXME: Don't abuse global variables like `comment-end/start'.
1750 (comment-start (opascal-token-start start-comment)) 1582 (comment-start (opascal-token-start start-comment))
1751 (comment-end (opascal-token-end end-comment)) 1583 (comment-end (opascal-token-end end-comment))
1752 (content-start (opascal-comment-content-start start-comment)) 1584 (content-start (opascal-comment-content-start start-comment))
@@ -1814,12 +1646,7 @@ An error is raised if not in a comment."
1814 1646
1815 ;; Restore our position 1647 ;; Restore our position
1816 (goto-char marked-point) 1648 (goto-char marked-point)
1817 (set-marker marked-point nil) 1649 (set-marker marked-point nil)))))))
1818
1819 ;; React to the entire fill change as a whole.
1820 (opascal-progress-start)
1821 (opascal-parse-region comment-start comment-end)
1822 (opascal-progress-done)))))))
1823 1650
1824(defun opascal-new-comment-line () 1651(defun opascal-new-comment-line ()
1825 "If in a // comment, do a newline, indented such that one is still in the 1652 "If in a // comment, do a newline, indented such that one is still in the
@@ -1848,16 +1675,37 @@ comment block. If not in a // comment, just does a normal newline."
1848 (goto-char end) 1675 (goto-char end)
1849 token))) 1676 token)))
1850 1677
1678(defconst opascal-font-lock-keywords
1679 `(("\\_<\\(function\\|pro\\(cedure\\|gram\\)\\)[ \t]+\\([[:alpha:]][[:alnum:]_]*\\)"
1680 (1 font-lock-keyword-face) (3 font-lock-function-name-face))
1681 ,(concat "\\_<" (regexp-opt (mapcar #'symbol-name opascal-keywords))
1682 "\\_>")))
1683
1851(defconst opascal-font-lock-defaults 1684(defconst opascal-font-lock-defaults
1852 '(nil ; We have our own fontify routine, so keywords don't apply. 1685 '(opascal-font-lock-keywords
1853 t ; Syntactic fontification doesn't apply. 1686 nil ; Syntactic fontification does apply.
1854 nil ; Don't care about case since we don't use regexps to find tokens. 1687 nil ; Don't care about case since we don't use regexps to find tokens.
1855 nil ; Syntax alists don't apply. 1688 nil ; Syntax alists don't apply.
1856 nil ; Syntax begin movement doesn't apply 1689 nil ; Syntax begin movement doesn't apply.
1857 (font-lock-fontify-region-function . opascal-fontify-region) 1690 )
1858 (font-lock-verbose . opascal-fontifying-progress-step))
1859 "OPascal mode font-lock defaults. Syntactic fontification is ignored.") 1691 "OPascal mode font-lock defaults. Syntactic fontification is ignored.")
1860 1692
1693(defconst opascal--syntax-propertize
1694 (syntax-propertize-rules
1695 ;; The syntax-table settings are too coarse and end up treating /* and (/
1696 ;; as comment starters. Fix it here by removing the "2" from the syntax
1697 ;; of the second char of such sequences.
1698 ("/\\(\\*\\)" (1 ". 3b"))
1699 ("(\\(\\/\\)" (1 (prog1 ". 1c" (forward-char -1) nil)))
1700 ;; Pascal uses '' and "" rather than \' and \" to escape quotes.
1701 ("''\\|\"\"" (0 (if (save-excursion
1702 (nth 3 (syntax-ppss (match-beginning 0))))
1703 (string-to-syntax ".")
1704 ;; In case of 3 or more quotes in a row, only advance
1705 ;; one quote at a time.
1706 (forward-char -1)
1707 nil)))))
1708
1861(defvar opascal-debug-mode-map 1709(defvar opascal-debug-mode-map
1862 (let ((kmap (make-sparse-keymap))) 1710 (let ((kmap (make-sparse-keymap)))
1863 (dolist (binding '(("n" opascal-debug-goto-next-token) 1711 (dolist (binding '(("n" opascal-debug-goto-next-token)
@@ -1866,14 +1714,7 @@ comment block. If not in a // comment, just does a normal newline."
1866 ("T" opascal-debug-tokenize-buffer) 1714 ("T" opascal-debug-tokenize-buffer)
1867 ("W" opascal-debug-tokenize-window) 1715 ("W" opascal-debug-tokenize-window)
1868 ("g" opascal-debug-goto-point) 1716 ("g" opascal-debug-goto-point)
1869 ("s" opascal-debug-show-current-string) 1717 ("s" opascal-debug-show-current-string)))
1870 ("a" opascal-debug-parse-buffer)
1871 ("w" opascal-debug-parse-window)
1872 ("f" opascal-debug-fontify-window)
1873 ("F" opascal-debug-fontify-buffer)
1874 ("r" opascal-debug-parse-region)
1875 ("c" opascal-debug-unparse-buffer)
1876 ("x" opascal-debug-show-is-stable)))
1877 (define-key kmap (car binding) (cadr binding))) 1718 (define-key kmap (car binding) (cadr binding)))
1878 kmap) 1719 kmap)
1879 "Keystrokes for OPascal mode debug commands.") 1720 "Keystrokes for OPascal mode debug commands.")
@@ -1923,14 +1764,8 @@ Customization:
1923 1764
1924Coloring: 1765Coloring:
1925 1766
1926 `opascal-comment-face' (default font-lock-comment-face)
1927 Face used to color OPascal comments.
1928 `opascal-string-face' (default font-lock-string-face)
1929 Face used to color OPascal strings.
1930 `opascal-keyword-face' (default font-lock-keyword-face) 1767 `opascal-keyword-face' (default font-lock-keyword-face)
1931 Face used to color OPascal keywords. 1768 Face used to color OPascal keywords.
1932 `opascal-other-face' (default nil)
1933 Face used to color everything else.
1934 1769
1935Turning on OPascal mode calls the value of the variable `opascal-mode-hook' 1770Turning on OPascal mode calls the value of the variable `opascal-mode-hook'
1936with no args, if that value is non-nil." 1771with no args, if that value is non-nil."
@@ -1940,21 +1775,13 @@ with no args, if that value is non-nil."
1940 (setq-local comment-indent-function #'opascal-indent-line) 1775 (setq-local comment-indent-function #'opascal-indent-line)
1941 (setq-local case-fold-search t) 1776 (setq-local case-fold-search t)
1942 (setq-local opascal-progress-last-reported-point nil) 1777 (setq-local opascal-progress-last-reported-point nil)
1943 (setq-local opascal--ignore-changes nil)
1944 (setq-local font-lock-defaults opascal-font-lock-defaults) 1778 (setq-local font-lock-defaults opascal-font-lock-defaults)
1945 (setq-local tab-always-indent opascal-tab-always-indents) 1779 (setq-local tab-always-indent opascal-tab-always-indents)
1780 (setq-local syntax-propertize-function opascal--syntax-propertize)
1946 1781
1947 ;; FIXME: Use syntax-propertize-function to tokenize, maybe? 1782 (setq-local comment-start "// ")
1948 1783 (setq-local comment-start-skip "\\(?://\\|(\\*\\|{\\)[ \t]*")
1949 ;; We need to keep track of changes to the buffer to determine if we need 1784 (setq-local comment-end-skip "[ \t]*\\(?:\n\\|\\*)\\|}\\)"))
1950 ;; to retokenize changed text.
1951 (add-hook 'after-change-functions #'opascal-after-change nil t)
1952
1953 (opascal-save-excursion
1954 (let ((opascal-verbose t))
1955 (opascal-progress-start)
1956 (opascal-parse-region (point-min) (point-max))
1957 (opascal-progress-done))))
1958 1785
1959(provide 'opascal) 1786(provide 'opascal)
1960;;; opascal.el ends here 1787;;; opascal.el ends here
diff --git a/lisp/textmodes/reftex-parse.el b/lisp/textmodes/reftex-parse.el
index a86b10e21cc..6bfc70c5d44 100644
--- a/lisp/textmodes/reftex-parse.el
+++ b/lisp/textmodes/reftex-parse.el
@@ -234,8 +234,18 @@ of master file."
234 234
235 ((match-end 1) 235 ((match-end 1)
236 ;; It is a label 236 ;; It is a label
237 (push (reftex-label-info (reftex-match-string 1) file bound) 237 (when (or (null reftex-label-ignored-macros-and-environments)
238 docstruct)) 238 ;; \label{} defs should always be honored,
239 ;; just no keyval style [label=foo] defs.
240 (string-equal "\label{" (substring (reftex-match-string 0) 0 7))
241 (not (fboundp 'TeX-current-macro))
242 (not (fboundp 'LaTeX-current-environment))
243 (not (or (member (save-match-data (TeX-current-macro))
244 reftex-label-ignored-macros-and-environments)
245 (member (save-match-data (LaTeX-current-environment))
246 reftex-label-ignored-macros-and-environments))))
247 (push (reftex-label-info (reftex-match-string 1) file bound)
248 docstruct)))
239 249
240 ((match-end 3) 250 ((match-end 3)
241 ;; It is a section 251 ;; It is a section
diff --git a/lisp/textmodes/reftex-vars.el b/lisp/textmodes/reftex-vars.el
index 7343d86b06f..ab085a3085a 100644
--- a/lisp/textmodes/reftex-vars.el
+++ b/lisp/textmodes/reftex-vars.el
@@ -885,6 +885,25 @@ effective."
885 :group 'reftex-defining-label-environments 885 :group 'reftex-defining-label-environments
886 :type '(repeat (regexp :tag "Regular Expression"))) 886 :type '(repeat (regexp :tag "Regular Expression")))
887 887
888(defcustom reftex-label-ignored-macros-and-environments nil
889 "List of macros and environments to be ignored when searching for labels.
890The purpose is to ignore environments and macros that use keyval
891style label=foo arguments, but the label has a different meaning
892than a \\label{foo}. Standard \\label{...} definitions are never
893ignored.
894
895E.g., TikZ defines several macros/environments where [label=foo]
896defines the label to be printed at some node or edge, but it's
897not a label used for referencing.
898
899Note that this feature is only supported if you are using AUCTeX
900and the functions `TeX-current-macro' and
901`LaTeX-current-environment' are bound. Also note that this
902feature might slow down the reftex parsing process for large TeX
903files."
904 :group 'reftex-defining-label-environments
905 :type '(repeat string))
906
888(defcustom reftex-label-illegal-re "[^-a-zA-Z0-9_+=:;,.]" 907(defcustom reftex-label-illegal-re "[^-a-zA-Z0-9_+=:;,.]"
889 "Regexp matching characters not valid in labels." 908 "Regexp matching characters not valid in labels."
890 :group 'reftex-making-and-inserting-labels 909 :group 'reftex-making-and-inserting-labels
diff --git a/lisp/vc/vc-bzr.el b/lisp/vc/vc-bzr.el
index 06942ad283c..4a08403c93e 100644
--- a/lisp/vc/vc-bzr.el
+++ b/lisp/vc/vc-bzr.el
@@ -710,12 +710,28 @@ If LIMIT is non-nil, show no more than this many entries."
710 (apply 'vc-bzr-command "log" buffer 'async files 710 (apply 'vc-bzr-command "log" buffer 'async files
711 (append 711 (append
712 (when shortlog '("--line")) 712 (when shortlog '("--line"))
713 (when start-revision (list (format "-r..%s" start-revision))) 713 ;; The extra complications here when start-revision and limit
714 ;; are set are due to bzr log's --forward argument, which
715 ;; could be enabled via an alias in bazaar.conf.
716 ;; Svn, for example, does not have this problem, because
717 ;; it doesn't have --forward. Instead, you can use
718 ;; svn --log -r HEAD:0 or -r 0:HEAD as you prefer.
719 ;; Bzr, however, insists in -r X..Y that X come before Y.
720 (if start-revision
721 (list (format
722 (if (and limit (= limit 1))
723 ;; This means we don't have to use --no-aliases.
724 ;; Is -c any different to -r in this case?
725 "-r%s"
726 "-r..%s") start-revision)))
714 (when limit (list "-l" (format "%s" limit))) 727 (when limit (list "-l" (format "%s" limit)))
715 ;; This is to remove --forward, if it has been added by an alias.
716 ;; There is no sensible way to combine --limit and --forward, 728 ;; There is no sensible way to combine --limit and --forward,
717 ;; and it breaks the meaning of START-REVISION as the 729 ;; and it breaks the meaning of START-REVISION as the
718 ;; _newest_ revision. See bug#14168. 730 ;; _newest_ revision. See bug#14168.
731 ;; Eg bzr log --forward -r ..100 --limit 50 prints
732 ;; revisions 1-50 rather than 50-100. There
733 ;; seems no way in general to get bzr to print revisions
734 ;; 50-100 in --forward order in that case.
719 ;; FIXME There may be other alias stuff we want to keep. 735 ;; FIXME There may be other alias stuff we want to keep.
720 ;; Is there a way to just suppress --forward? 736 ;; Is there a way to just suppress --forward?
721 ;; As of 2013/4 the only caller uses limit = 1, so it does 737 ;; As of 2013/4 the only caller uses limit = 1, so it does