aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2015-09-29 15:13:44 -0400
committerStefan Monnier2015-09-29 15:13:44 -0400
commit90a6f8d0741eb5391c204f059c845c361e615b49 (patch)
tree30446e80abf227e60bc319a3c63bf79b260fc3d7
parent1fea2f3b743da1db666be7ce34904b74319d3f83 (diff)
downloademacs-90a6f8d0741eb5391c204f059c845c361e615b49.tar.gz
emacs-90a6f8d0741eb5391c204f059c845c361e615b49.zip
* lisp/progmodes/octave.el: Use grammar more; Handle enumeration fun
Remove redundant :group keyword args. (octave-begin-keywords, octave-else-keywords, octave-end-keywords): Remove variables. (octave-operator-table, octave-smie-bnf-table): Use let-when-compile to turn them into compile-time variables. Auto-generate the "foo ... end" rules from the "foo ... endfoo" rules. Add rules for break, continue, return, global, and persistent. Refine the rule for "until". (octave-smie--funcall-p, octave-smie--end-index-p) (octave-smie--in-parens-p): New functions. (octave-smie-backward-token, octave-smie-forward-token): Use them to distinguish the "enumeration" function and the "end" index from their corresponding keywords. (octave--block-offset-keywords): New constant. (octave-smie-rules): Use it. Adjust rules for new global/persistent parsing. (octave-reserved-words): Redefine using octave-smie-grammar. (octave-font-lock-keywords): Use octave-smie--funcall-p and octave-smie--end-index-p.
-rw-r--r--lisp/progmodes/octave.el316
-rw-r--r--test/indent/octave.m22
2 files changed, 186 insertions, 152 deletions
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el
index 70a2b1ab5ad..b54b88dccb5 100644
--- a/lisp/progmodes/octave.el
+++ b/lisp/progmodes/octave.el
@@ -82,25 +82,6 @@ Used in `octave-mode' and `inferior-octave-mode' buffers.")
82(defvar octave-comment-start-skip "\\(^\\|\\S<\\)\\(?:%!\\|\\s<+\\)\\s-*" 82(defvar octave-comment-start-skip "\\(^\\|\\S<\\)\\(?:%!\\|\\s<+\\)\\s-*"
83 "Octave-specific `comment-start-skip' (which see).") 83 "Octave-specific `comment-start-skip' (which see).")
84 84
85(defvar octave-begin-keywords
86 '("classdef" "do" "enumeration" "events" "for" "function" "if" "methods"
87 "parfor" "properties" "switch" "try" "unwind_protect" "while"))
88
89(defvar octave-else-keywords
90 '("case" "catch" "else" "elseif" "otherwise" "unwind_protect_cleanup"))
91
92(defvar octave-end-keywords
93 '("endclassdef" "endenumeration" "endevents" "endfor" "endfunction" "endif"
94 "endmethods" "endparfor" "endproperties" "endswitch" "end_try_catch"
95 "end_unwind_protect" "endwhile" "until" "end"))
96
97(defvar octave-reserved-words
98 (append octave-begin-keywords
99 octave-else-keywords
100 octave-end-keywords
101 '("break" "continue" "global" "persistent" "return"))
102 "Reserved words in Octave.")
103
104(defvar octave-function-header-regexp 85(defvar octave-function-header-regexp
105 (concat "^\\s-*\\_<\\(function\\)\\_>" 86 (concat "^\\s-*\\_<\\(function\\)\\_>"
106 "\\([^=;(\n]*=[ \t]*\\|[ \t]*\\)\\(\\(?:\\w\\|\\s_\\)+\\)\\_>") 87 "\\([^=;(\n]*=[ \t]*\\|[ \t]*\\)\\(\\(?:\\w\\|\\s_\\)+\\)\\_>")
@@ -231,20 +212,17 @@ parenthetical grouping.")
231(defcustom octave-font-lock-texinfo-comment t 212(defcustom octave-font-lock-texinfo-comment t
232 "Control whether to highlight the texinfo comment block." 213 "Control whether to highlight the texinfo comment block."
233 :type 'boolean 214 :type 'boolean
234 :group 'octave
235 :version "24.4") 215 :version "24.4")
236 216
237(defcustom octave-blink-matching-block t 217(defcustom octave-blink-matching-block t
238 "Control the blinking of matching Octave block keywords. 218 "Control the blinking of matching Octave block keywords.
239Non-nil means show matching begin of block when inserting a space, 219Non-nil means show matching begin of block when inserting a space,
240newline or semicolon after an else or end keyword." 220newline or semicolon after an else or end keyword."
241 :type 'boolean 221 :type 'boolean)
242 :group 'octave)
243 222
244(defcustom octave-block-offset 2 223(defcustom octave-block-offset 2
245 "Extra indentation applied to statements in Octave block structures." 224 "Extra indentation applied to statements in Octave block structures."
246 :type 'integer 225 :type 'integer)
247 :group 'octave)
248 226
249(defvar octave-block-comment-start 227(defvar octave-block-comment-start
250 (concat (make-string 2 octave-comment-char) " ") 228 (concat (make-string 2 octave-comment-char) " ")
@@ -252,8 +230,7 @@ newline or semicolon after an else or end keyword."
252 230
253(defcustom octave-continuation-offset 4 231(defcustom octave-continuation-offset 4
254 "Extra indentation applied to Octave continuation lines." 232 "Extra indentation applied to Octave continuation lines."
255 :type 'integer 233 :type 'integer)
256 :group 'octave)
257 234
258(eval-and-compile 235(eval-and-compile
259 (defconst octave-continuation-marker-regexp "\\\\\\|\\.\\.\\.")) 236 (defconst octave-continuation-marker-regexp "\\\\\\|\\.\\.\\."))
@@ -274,109 +251,135 @@ newline or semicolon after an else or end keyword."
274 251
275(defcustom octave-mode-hook nil 252(defcustom octave-mode-hook nil
276 "Hook to be run when Octave mode is started." 253 "Hook to be run when Octave mode is started."
277 :type 'hook 254 :type 'hook)
278 :group 'octave)
279 255
280(defcustom octave-send-show-buffer t 256(defcustom octave-send-show-buffer t
281 "Non-nil means display `inferior-octave-buffer' after sending to it." 257 "Non-nil means display `inferior-octave-buffer' after sending to it."
282 :type 'boolean 258 :type 'boolean)
283 :group 'octave)
284 259
285(defcustom octave-send-line-auto-forward t 260(defcustom octave-send-line-auto-forward t
286 "Control auto-forward after sending to the inferior Octave process. 261 "Control auto-forward after sending to the inferior Octave process.
287Non-nil means always go to the next Octave code line after sending." 262Non-nil means always go to the next Octave code line after sending."
288 :type 'boolean 263 :type 'boolean)
289 :group 'octave)
290 264
291(defcustom octave-send-echo-input t 265(defcustom octave-send-echo-input t
292 "Non-nil means echo input sent to the inferior Octave process." 266 "Non-nil means echo input sent to the inferior Octave process."
293 :type 'boolean 267 :type 'boolean)
294 :group 'octave)
295 268
296 269
297;;; SMIE indentation 270;;; SMIE indentation
298 271
299(require 'smie) 272(require 'smie)
300 273
301;; Use '__operators__' in Octave REPL to get a full list. 274(let-when-compile
302(defconst octave-operator-table 275 ((operator-table
303 '((assoc ";" "\n") (assoc ",") ; The doc claims they have equal precedence!? 276 ;; Use '__operators__' in Octave REPL to get a full list?
304 (right "=" "+=" "-=" "*=" "/=") 277 '((assoc ";" "\n") (assoc ",") ;The doc says they have equal precedence!?
305 (assoc "&&") (assoc "||") ; The doc claims they have equal precedence!? 278 (right "=" "+=" "-=" "*=" "/=")
306 (assoc "&") (assoc "|") ; The doc claims they have equal precedence!? 279 (assoc "&&") (assoc "||") ; The doc claims they have equal precedence!?
307 (nonassoc "<" "<=" "==" ">=" ">" "!=" "~=") 280 (assoc "&") (assoc "|") ; The doc claims they have equal precedence!?
308 (nonassoc ":") ;No idea what this is. 281 (nonassoc "<" "<=" "==" ">=" ">" "!=" "~=")
309 (assoc "+" "-") 282 (nonassoc ":") ;No idea what this is.
310 (assoc "*" "/" "\\" ".\\" ".*" "./") 283 (assoc "+" "-")
311 (nonassoc "'" ".'") 284 (assoc "*" "/" "\\" ".\\" ".*" "./")
312 (nonassoc "++" "--" "!" "~") ;And unary "+" and "-". 285 (nonassoc "'" ".'")
313 (right "^" "**" ".^" ".**") 286 (nonassoc "++" "--" "!" "~") ;And unary "+" and "-".
314 ;; It's not really an operator, but for indentation purposes it 287 (right "^" "**" ".^" ".**")
315 ;; could be convenient to treat it as one. 288 ;; It's not really an operator, but for indentation purposes it
316 (assoc "..."))) 289 ;; could be convenient to treat it as one.
317 290 (assoc "...")))
318(defconst octave-smie-bnf-table 291
319 '((atom) 292 (matchedrules
320 ;; We can't distinguish the first element in a sequence with 293 ;; We can't distinguish the first element in a sequence with
321 ;; precedence grammars, so we can't distinguish the condition 294 ;; precedence grammars, so we can't distinguish the condition
322 ;; if the `if' from the subsequent body, for example. 295 ;; of the `if' from the subsequent body, for example.
323 ;; This has to be done later in the indentation rules. 296 ;; This has to be done later in the indentation rules.
324 (exp (exp "\n" exp) 297 '(("try" exp "catch" exp "end_try_catch")
325 ;; We need to mention at least one of the operators in this part 298 ("unwind_protect" exp
326 ;; of the grammar: if the BNF and the operator table have 299 "unwind_protect_cleanup" exp "end_unwind_protect")
327 ;; no overlap, SMIE can't know how they relate. 300 ("for" exp "endfor")
328 (exp ";" exp) 301 ("parfor" exp "endparfor")
329 ("try" exp "catch" exp "end_try_catch") 302 ("while" exp "endwhile")
330 ("try" exp "catch" exp "end") 303 ("if" exp "endif")
331 ("unwind_protect" exp 304 ("if" exp "else" exp "endif")
332 "unwind_protect_cleanup" exp "end_unwind_protect") 305 ("if" exp "elseif" exp "else" exp "endif")
333 ("unwind_protect" exp "unwind_protect_cleanup" exp "end") 306 ("if" exp "elseif" exp "elseif" exp "else" exp "endif")
334 ("for" exp "endfor") 307 ("switch" exp "case" exp "endswitch")
335 ("for" exp "end") 308 ("switch" exp "case" exp "otherwise" exp "endswitch")
336 ("parfor" exp "endparfor") 309 ("switch" exp "case" exp "case" exp "otherwise" exp "endswitch")
337 ("parfor" exp "end") 310 ("function" exp "endfunction")
338 ("do" exp "until" atom) 311 ("enumeration" exp "endenumeration")
339 ("while" exp "endwhile") 312 ("events" exp "endevents")
340 ("while" exp "end") 313 ("methods" exp "endmethods")
341 ("if" exp "endif") 314 ("properties" exp "endproperties")
342 ("if" exp "else" exp "endif") 315 ("classdef" exp "endclassdef")
343 ("if" exp "elseif" exp "else" exp "endif") 316 ))
344 ("if" exp "elseif" exp "elseif" exp "else" exp "endif") 317
345 ("if" exp "elseif" exp "elseif" exp "else" exp "end") 318 (bnf-table
346 ("switch" exp "case" exp "endswitch") 319 `((atom)
347 ("switch" exp "case" exp "otherwise" exp "endswitch") 320 ;; FIXME: We don't parse these declarations correctly since
348 ("switch" exp "case" exp "case" exp "otherwise" exp "endswitch") 321 ;; SMIE *really* likes to parse "a b = 2 c" as "(a b) = (2 c)".
349 ("switch" exp "case" exp "case" exp "otherwise" exp "end") 322 ;; IOW to do it right, we'd need to change octave-smie-*ward-token
350 ("function" exp "endfunction") 323 ;; so that the spaces between vars in var-decls are lexed as
351 ("function" exp "end") 324 ;; something like ",".
352 ("enumeration" exp "endenumeration") 325 ;; Doesn't seem worth the trouble/slowdown for now.
353 ("enumeration" exp "end") 326 ;; We could hack smie-rules so as to work around the bad parse,
354 ("events" exp "endevents") 327 ;; but even that doesn't seem worth the trouble.
355 ("events" exp "end") 328 (var-decls (atom "=" atom)) ;; (var-decls "," var-decls)
356 ("methods" exp "endmethods") 329 (single-exp (atom "=" atom))
357 ("methods" exp "end") 330 (exp (exp "\n" exp)
358 ("properties" exp "endproperties") 331 ;; We need to mention at least one of the operators in this part
359 ("properties" exp "end") 332 ;; of the grammar: if the BNF and the operator table have
360 ("classdef" exp "endclassdef") 333 ;; no overlap, SMIE can't know how they relate.
361 ("classdef" exp "end")) 334 (exp ";" exp)
362 ;; (fundesc (atom "=" atom)) 335 ("do" exp "until" single-exp)
363 )) 336 ,@matchedrules
337 ;; For every rule that ends in "endfoo", add a corresponding
338 ;; rule which uses "end" instead.
339 ,@(mapcar (lambda (rule) (nconc (butlast rule) '("end")))
340 matchedrules)
341 ("global" var-decls) ("persistent" var-decls)
342 ;; These aren't super-important, but having them here
343 ;; makes it easier to extract all keywords.
344 ("break") ("continue") ("return")
345 ;; The following rules do not correspond to valid code AFAIK,
346 ;; but they lead to a grammar that degrades more gracefully
347 ;; on incomplete/incorrect code. It also helps us in
348 ;; computing octave--block-offset-keywords.
349 ("try" exp "end") ("unwind_protect" exp "end")
350 )
351 ;; (fundesc (atom "=" atom))
352 )))
364 353
365(defconst octave-smie-grammar 354(defconst octave-smie-grammar
366 (smie-prec2->grammar 355 (eval-when-compile
367 (smie-merge-prec2s 356 (smie-prec2->grammar
368 (smie-bnf->prec2 octave-smie-bnf-table 357 (smie-merge-prec2s
369 '((assoc "\n" ";"))) 358 (smie-bnf->prec2 bnf-table '((assoc "\n" ";")))
359 (smie-precs->prec2 operator-table)))))
370 360
371 (smie-precs->prec2 octave-operator-table)))) 361(defconst octave-operator-regexp
362 (eval-when-compile
363 (regexp-opt (remove "\n" (apply #'append
364 (mapcar #'cdr operator-table)))))))
372 365
373;; Tokenizing needs to be refined so that ";;" is treated as two 366;; Tokenizing needs to be refined so that ";;" is treated as two
374;; tokens and also so as to recognize the \n separator (and 367;; tokens and also so as to recognize the \n separator (and
375;; corresponding continuation lines). 368;; corresponding continuation lines).
376 369
377(defconst octave-operator-regexp 370(defun octave-smie--funcall-p ()
378 (regexp-opt (remove "\n" (apply 'append 371 "Return non-nil if we're in an expression context. Moves point."
379 (mapcar 'cdr octave-operator-table))))) 372 (looking-at "[ \t]*("))
373
374(defun octave-smie--end-index-p ()
375 (let ((ppss (syntax-ppss)))
376 (and (nth 1 ppss)
377 (memq (char-after (nth 1 ppss)) '(?\( ?\[ ?\{)))))
378
379(defun octave-smie--in-parens-p ()
380 (let ((ppss (syntax-ppss)))
381 (and (nth 1 ppss)
382 (eq ?\( (char-after (nth 1 ppss))))))
380 383
381(defun octave-smie-backward-token () 384(defun octave-smie-backward-token ()
382 (let ((pos (point))) 385 (let ((pos (point)))
@@ -390,10 +393,7 @@ Non-nil means always go to the next Octave code line after sending."
390 (forward-comment (- (point))) 393 (forward-comment (- (point)))
391 nil) 394 nil)
392 t) 395 t)
393 ;; Ignore it if it's within parentheses. 396 (not (octave-smie--in-parens-p)))
394 (let ((ppss (syntax-ppss)))
395 (not (and (nth 1 ppss)
396 (eq ?\( (char-after (nth 1 ppss)))))))
397 (skip-chars-forward " \t") 397 (skip-chars-forward " \t")
398 ;; Why bother distinguishing \n and ;? 398 ;; Why bother distinguishing \n and ;?
399 ";") ;;"\n" 399 ";") ;;"\n"
@@ -403,7 +403,15 @@ Non-nil means always go to the next Octave code line after sending."
403 (goto-char (match-beginning 0)) 403 (goto-char (match-beginning 0))
404 (match-string-no-properties 0)) 404 (match-string-no-properties 0))
405 (t 405 (t
406 (smie-default-backward-token))))) 406 (let ((tok (smie-default-backward-token)))
407 (cond
408 ((equal tok "enumeration")
409 (if (save-excursion (smie-default-forward-token)
410 (octave-smie--funcall-p))
411 "enumeration (function)"
412 tok))
413 ((equal tok "end") (if (octave-smie--end-index-p) "end (index)" tok))
414 (t tok)))))))
407 415
408(defun octave-smie-forward-token () 416(defun octave-smie-forward-token ()
409 (skip-chars-forward " \t") 417 (skip-chars-forward " \t")
@@ -417,10 +425,7 @@ Non-nil means always go to the next Octave code line after sending."
417 (not (or (save-excursion (skip-chars-backward " \t") 425 (not (or (save-excursion (skip-chars-backward " \t")
418 ;; Only add implicit ; when needed. 426 ;; Only add implicit ; when needed.
419 (or (bolp) (eq (char-before) ?\;))) 427 (or (bolp) (eq (char-before) ?\;)))
420 ;; Ignore it if it's within parentheses. 428 (octave-smie--in-parens-p))))
421 (let ((ppss (syntax-ppss)))
422 (and (nth 1 ppss)
423 (eq ?\( (char-after (nth 1 ppss))))))))
424 (if (eolp) (forward-char 1) (forward-comment 1)) 429 (if (eolp) (forward-char 1) (forward-comment 1))
425 ;; Why bother distinguishing \n and ;? 430 ;; Why bother distinguishing \n and ;?
426 ";") ;;"\n" 431 ";") ;;"\n"
@@ -436,7 +441,25 @@ Non-nil means always go to the next Octave code line after sending."
436 (goto-char (match-end 0)) 441 (goto-char (match-end 0))
437 (match-string-no-properties 0)) 442 (match-string-no-properties 0))
438 (t 443 (t
439 (smie-default-forward-token)))) 444 (let ((tok (smie-default-forward-token)))
445 (cond
446 ((equal tok "enumeration")
447 (if (octave-smie--funcall-p)
448 "enumeration (function)"
449 tok))
450 ((equal tok "end") (if (octave-smie--end-index-p) "end (index)" tok))
451 (t tok))))))
452
453(defconst octave--block-offset-keywords
454 (let* ((end-prec (nth 1 (assoc "end" octave-smie-grammar)))
455 (end-matchers
456 (delq nil
457 (mapcar (lambda (x) (if (eq end-prec (nth 2 x)) (car x)))
458 octave-smie-grammar))))
459 ;; Not sure if it would harm to keep "switch", but the previous code
460 ;; excluded it, presumably because there shouldn't be any code on
461 ;; the lines between "switch" and "case".
462 (delete "switch" end-matchers)))
440 463
441(defun octave-smie-rules (kind token) 464(defun octave-smie-rules (kind token)
442 (pcase (cons kind token) 465 (pcase (cons kind token)
@@ -445,15 +468,12 @@ Non-nil means always go to the next Octave code line after sending."
445 ;; - changes to octave-block-offset wouldn't take effect immediately. 468 ;; - changes to octave-block-offset wouldn't take effect immediately.
446 ;; - edebug wouldn't show the use of this variable. 469 ;; - edebug wouldn't show the use of this variable.
447 (`(:elem . basic) octave-block-offset) 470 (`(:elem . basic) octave-block-offset)
471 (`(:list-intro . ,(or "global" "persistent")) t)
448 ;; Since "case" is in the same BNF rules as switch..end, SMIE by default 472 ;; Since "case" is in the same BNF rules as switch..end, SMIE by default
449 ;; aligns it with "switch". 473 ;; aligns it with "switch".
450 (`(:before . "case") (if (not (smie-rule-sibling-p)) octave-block-offset)) 474 (`(:before . "case") (if (not (smie-rule-sibling-p)) octave-block-offset))
451 (`(:after . ";") 475 (`(:after . ";")
452 (if (smie-rule-parent-p "classdef" "events" "enumeration" "function" "if" 476 (if (apply #'smie-rule-parent-p octave--block-offset-keywords)
453 "while" "else" "elseif" "for" "parfor"
454 "properties" "methods" "otherwise" "case"
455 "try" "catch" "unwind_protect"
456 "unwind_protect_cleanup")
457 (smie-rule-parent octave-block-offset) 477 (smie-rule-parent octave-block-offset)
458 ;; For (invalid) code between switch and case. 478 ;; For (invalid) code between switch and case.
459 ;; (if (smie-rule-parent-p "switch") 4) 479 ;; (if (smie-rule-parent-p "switch") 4)
@@ -473,28 +493,33 @@ Non-nil means always go to the next Octave code line after sending."
473 (comment-choose-indent))))) 493 (comment-choose-indent)))))
474 494
475 495
496(defvar octave-reserved-words
497 (delq nil
498 (mapcar (lambda (x)
499 (setq x (car x))
500 (and (stringp x) (string-match "\\`[[:alpha:]]" x) x))
501 octave-smie-grammar))
502 "Reserved words in Octave.")
503
476(defvar octave-font-lock-keywords 504(defvar octave-font-lock-keywords
477 (list 505 (list
478 ;; Fontify all builtin keywords. 506 ;; Fontify all builtin keywords.
479 (cons (concat "\\_<\\(" 507 (cons (concat "\\_<" (regexp-opt octave-reserved-words) "\\_>")
480 (regexp-opt octave-reserved-words)
481 "\\)\\_>")
482 'font-lock-keyword-face) 508 'font-lock-keyword-face)
483 ;; Note: 'end' also serves as the last index in an indexing expression. 509 ;; Note: 'end' also serves as the last index in an indexing expression,
510 ;; and 'enumerate' is also a function.
484 ;; Ref: http://www.mathworks.com/help/matlab/ref/end.html 511 ;; Ref: http://www.mathworks.com/help/matlab/ref/end.html
512 ;; Ref: http://www.mathworks.com/help/matlab/ref/enumeration.html
485 (list (lambda (limit) 513 (list (lambda (limit)
486 (while (re-search-forward "\\_<end\\_>" limit 'move) 514 (while (re-search-forward "\\_<en\\(?:d\\|umeratio\\(n\\)\\)\\_>"
515 limit 'move)
487 (let ((beg (match-beginning 0)) 516 (let ((beg (match-beginning 0))
488 (end (match-end 0))) 517 (end (match-end 0)))
489 (unless (octave-in-string-or-comment-p) 518 (unless (octave-in-string-or-comment-p)
490 (condition-case nil 519 (when (if (match-end 1)
491 (progn 520 (octave-smie--funcall-p)
492 (goto-char beg) 521 (octave-smie--end-index-p))
493 (backward-up-list) 522 (put-text-property beg end 'face nil)))))
494 (when (memq (char-after) '(?\( ?\[ ?\{))
495 (put-text-property beg end 'face nil))
496 (goto-char end))
497 (error (goto-char end))))))
498 nil)) 523 nil))
499 ;; Fontify all operators. 524 ;; Fontify all operators.
500 (cons octave-operator-regexp 'font-lock-builtin-face) 525 (cons octave-operator-regexp 'font-lock-builtin-face)
@@ -609,27 +634,23 @@ Key bindings:
609 634
610(defcustom inferior-octave-program "octave" 635(defcustom inferior-octave-program "octave"
611 "Program invoked by `inferior-octave'." 636 "Program invoked by `inferior-octave'."
612 :type 'string 637 :type 'string)
613 :group 'octave)
614 638
615(defcustom inferior-octave-buffer "*Inferior Octave*" 639(defcustom inferior-octave-buffer "*Inferior Octave*"
616 "Name of buffer for running an inferior Octave process." 640 "Name of buffer for running an inferior Octave process."
617 :type 'string 641 :type 'string)
618 :group 'octave)
619 642
620(defcustom inferior-octave-prompt 643(defcustom inferior-octave-prompt
621 ;; For Octave >= 3.8, default is always 'octave', see 644 ;; For Octave >= 3.8, default is always 'octave', see
622 ;; http://hg.savannah.gnu.org/hgweb/octave/rev/708173343c50 645 ;; http://hg.savannah.gnu.org/hgweb/octave/rev/708173343c50
623 "\\(?:^octave\\(?:.bin\\|.exe\\)?\\(?:-[.0-9]+\\)?\\(?::[0-9]+\\)?\\|^debug\\|^\\)>+ " 646 "\\(?:^octave\\(?:.bin\\|.exe\\)?\\(?:-[.0-9]+\\)?\\(?::[0-9]+\\)?\\|^debug\\|^\\)>+ "
624 "Regexp to match prompts for the inferior Octave process." 647 "Regexp to match prompts for the inferior Octave process."
625 :type 'regexp 648 :type 'regexp)
626 :group 'octave)
627 649
628(defcustom inferior-octave-prompt-read-only comint-prompt-read-only 650(defcustom inferior-octave-prompt-read-only comint-prompt-read-only
629 "If non-nil, the Octave prompt is read only. 651 "If non-nil, the Octave prompt is read only.
630See `comint-prompt-read-only' for details." 652See `comint-prompt-read-only' for details."
631 :type 'boolean 653 :type 'boolean
632 :group 'octave
633 :version "24.4") 654 :version "24.4")
634 655
635(defcustom inferior-octave-startup-file 656(defcustom inferior-octave-startup-file
@@ -639,7 +660,6 @@ See `comint-prompt-read-only' for details."
639The contents of this file are sent to the inferior Octave process on 660The contents of this file are sent to the inferior Octave process on
640startup." 661startup."
641 :type '(choice (const :tag "None" nil) file) 662 :type '(choice (const :tag "None" nil) file)
642 :group 'octave
643 :version "24.4") 663 :version "24.4")
644 664
645(defcustom inferior-octave-startup-args '("-i" "--no-line-editing") 665(defcustom inferior-octave-startup-args '("-i" "--no-line-editing")
@@ -647,13 +667,11 @@ startup."
647For example, for suppressing the startup message and using `traditional' 667For example, for suppressing the startup message and using `traditional'
648mode, include \"-q\" and \"--traditional\"." 668mode, include \"-q\" and \"--traditional\"."
649 :type '(repeat string) 669 :type '(repeat string)
650 :group 'octave
651 :version "24.4") 670 :version "24.4")
652 671
653(defcustom inferior-octave-mode-hook nil 672(defcustom inferior-octave-mode-hook nil
654 "Hook to be run when Inferior Octave mode is started." 673 "Hook to be run when Inferior Octave mode is started."
655 :type 'hook 674 :type 'hook)
656 :group 'octave)
657 675
658(defcustom inferior-octave-error-regexp-alist 676(defcustom inferior-octave-error-regexp-alist
659 '(("error:\\s-*\\(.*?\\) at line \\([0-9]+\\), column \\([0-9]+\\)" 677 '(("error:\\s-*\\(.*?\\) at line \\([0-9]+\\), column \\([0-9]+\\)"
@@ -663,8 +681,7 @@ mode, include \"-q\" and \"--traditional\"."
663 "Value for `compilation-error-regexp-alist' in inferior octave." 681 "Value for `compilation-error-regexp-alist' in inferior octave."
664 :version "24.4" 682 :version "24.4"
665 :type '(repeat (choice (symbol :tag "Predefined symbol") 683 :type '(repeat (choice (symbol :tag "Predefined symbol")
666 (sexp :tag "Error specification"))) 684 (sexp :tag "Error specification"))))
667 :group 'octave)
668 685
669(defvar inferior-octave-compilation-font-lock-keywords 686(defvar inferior-octave-compilation-font-lock-keywords
670 '(("\\_<PASS\\_>" . compilation-info-face) 687 '(("\\_<PASS\\_>" . compilation-info-face)
@@ -995,7 +1012,6 @@ directory and makes this the current buffer's default directory."
995(defcustom inferior-octave-minimal-columns 80 1012(defcustom inferior-octave-minimal-columns 80
996 "The minimal column width for the inferior Octave process." 1013 "The minimal column width for the inferior Octave process."
997 :type 'integer 1014 :type 'integer
998 :group 'octave
999 :version "24.4") 1015 :version "24.4")
1000 1016
1001(defvar inferior-octave-last-column-width nil) 1017(defvar inferior-octave-last-column-width nil)
@@ -1180,8 +1196,7 @@ q: Don't fix\n" func file))
1180 1196
1181(defface octave-function-comment-block 1197(defface octave-function-comment-block
1182 '((t (:inherit font-lock-doc-face))) 1198 '((t (:inherit font-lock-doc-face)))
1183 "Face used to highlight function comment block." 1199 "Face used to highlight function comment block.")
1184 :group 'octave)
1185 1200
1186(eval-when-compile (require 'texinfo)) 1201(eval-when-compile (require 'texinfo))
1187 1202
@@ -1602,7 +1617,6 @@ code line."
1602 :type '(choice (const :tag "Automatic" auto) 1617 :type '(choice (const :tag "Automatic" auto)
1603 (const :tag "One Line" oneline) 1618 (const :tag "One Line" oneline)
1604 (const :tag "Multi Line" multiline)) 1619 (const :tag "Multi Line" multiline))
1605 :group 'octave
1606 :version "24.4") 1620 :version "24.4")
1607 1621
1608;; (FN SIGNATURE1 SIGNATURE2 ...) 1622;; (FN SIGNATURE1 SIGNATURE2 ...)
@@ -1661,7 +1675,6 @@ code line."
1661(defcustom octave-help-buffer "*Octave Help*" 1675(defcustom octave-help-buffer "*Octave Help*"
1662 "Buffer name for `octave-help'." 1676 "Buffer name for `octave-help'."
1663 :type 'string 1677 :type 'string
1664 :group 'octave
1665 :version "24.4") 1678 :version "24.4")
1666 1679
1667;; Used in a mode derived from help-mode. 1680;; Used in a mode derived from help-mode.
@@ -1786,7 +1799,6 @@ sentence."
1786 "A list of directories for Octave sources. 1799 "A list of directories for Octave sources.
1787If the environment variable OCTAVE_SRCDIR is set, it is searched first." 1800If the environment variable OCTAVE_SRCDIR is set, it is searched first."
1788 :type '(repeat directory) 1801 :type '(repeat directory)
1789 :group 'octave
1790 :version "24.4") 1802 :version "24.4")
1791 1803
1792(defun octave-source-directories () 1804(defun octave-source-directories ()
diff --git a/test/indent/octave.m b/test/indent/octave.m
index a7041462f7f..4758f9933cb 100644
--- a/test/indent/octave.m
+++ b/test/indent/octave.m
@@ -1,6 +1,19 @@
1## -*- mode: octave; coding: utf-8 -*- 1## -*- mode: octave; coding: utf-8 -*-
20; # Don't make this a function file 20; # Don't make this a function file
3function res = tcomp (fn) 3function res = tcomp (fn)
4
5 global x y ...
6 z1 z2
7 persistent x y ...
8 z1 z2
9 global x y = 2 ...
10 z1 z2 # FIXME
11
12 do
13 something
14 until x = ...
15 y
16
4 %% res = tcomp (fn) 17 %% res = tcomp (fn)
5 %% imports components and rearranges them. 18 %% imports components and rearranges them.
6 19
@@ -10,6 +23,15 @@ function res = tcomp (fn)
10 23
11 data = dlmread(fn, 3, 0); 24 data = dlmread(fn, 3, 0);
12 25
26 enumeration
27 first (1)
28 second (2)
29 end
30
31 y = enumeration (x); #Beware: "enumeration" can also be a function!
32 y = foo(enumeration (x),
33 2); #Beware: "enumeration" can also be a function!
34
13 x = data(:,2:end); 35 x = data(:,2:end);
14 y = 'hello'; 36 y = 'hello';
15 z = y'; 37 z = y';