]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/octave-mod.el
Merge from emacs-23
[gnu-emacs] / lisp / progmodes / octave-mod.el
index 30bb304605712cd931cfa570cd60270ae82adb50..12f561c68148392338efd6416df47f0962e4d485 100644 (file)
@@ -1,6 +1,6 @@
 ;;; octave-mod.el --- editing Octave source files under Emacs
 
-;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
 ;; Free Software Foundation, Inc.
 
 ;; Author: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>
@@ -101,11 +101,9 @@ All Octave abbrevs start with a grave accent (`)."
   '("do" "for" "function" "if" "switch" "try" "unwind_protect" "while"))
 (defvar octave-else-keywords
   '("case" "catch" "else" "elseif" "otherwise" "unwind_protect_cleanup"))
-;; FIXME: only use specific "end" tokens here to avoid confusion when "end"
-;; is used in indexing (the real fix is much more complex).
 (defvar octave-end-keywords
   '("endfor" "endfunction" "endif" "endswitch" "end_try_catch"
-    "end_unwind_protect" "endwhile" "until"))
+    "end_unwind_protect" "endwhile" "until" "end"))
 
 (defvar octave-reserved-words
   (append octave-begin-keywords
@@ -216,6 +214,7 @@ parenthetical grouping.")
     (define-key map "\C-c\M-\C-d" 'octave-down-block)
     (define-key map "\C-c\M-\C-h" 'octave-mark-block)
     (define-key map "\C-c]" 'octave-close-block)
+    (define-key map "\C-c/" 'octave-close-block)
     (define-key map "\C-c\C-f" 'octave-insert-defun)
     (define-key map "\C-c\C-h" 'octave-help)
     (define-key map "\C-c\C-il" 'octave-send-line)
@@ -238,27 +237,27 @@ parenthetical grouping.")
 
 (defvar octave-mode-menu
   '("Octave"
-    '("Lines"
+    ("Lines"
       ["Previous Code Line"    octave-previous-code-line t]
       ["Next Code Line"                octave-next-code-line t]
       ["Begin of Continuation" octave-beginning-of-line t]
       ["End of Continuation"   octave-end-of-line t]
       ["Split Line at Point"   octave-indent-new-comment-line t])
-    '("Blocks"
+    ("Blocks"
       ["Next Block"            octave-forward-block t]
       ["Previous Block"                octave-backward-block t]
       ["Down Block"            octave-down-block t]
       ["Up Block"              octave-backward-up-block t]
       ["Mark Block"            octave-mark-block t]
       ["Close Block"           octave-close-block t])
-    '("Functions"
+    ("Functions"
       ["Begin of Function"     octave-beginning-of-defun t]
       ["End of Function"       octave-end-of-defun t]
       ["Mark Function"         octave-mark-defun t]
       ["Indent Function"       octave-indent-defun t]
       ["Insert Function"       octave-insert-defun t])
     "-"
-    '("Debug"
+    ("Debug"
       ["Send Current Line"     octave-send-line t]
       ["Send Current Block"    octave-send-block t]
       ["Send Current Function" octave-send-defun t]
@@ -342,17 +341,15 @@ newline or semicolon after an else or end keyword."
   (concat octave-block-begin-regexp "\\|" octave-block-end-regexp))
 (defvar octave-block-else-or-end-regexp
   (concat octave-block-else-regexp "\\|" octave-block-end-regexp))
-;; FIXME: only use specific "end" tokens here to avoid confusion when "end"
-;; is used in indexing (the real fix is much more complex).
 (defvar octave-block-match-alist
   '(("do" . ("until"))
-    ("for" . ("endfor"))
+    ("for" . ("endfor" "end"))
     ("function" . ("endfunction"))
-    ("if" . ("else" "elseif" "endif"))
-    ("switch" . ("case" "otherwise" "endswitch"))
+    ("if" . ("else" "elseif" "endif" "end"))
+    ("switch" . ("case" "otherwise" "endswitch" "end"))
     ("try" . ("catch" "end_try_catch"))
     ("unwind_protect" . ("unwind_protect_cleanup" "end_unwind_protect"))
-    ("while" . ("endwhile")))
+    ("while" . ("endwhile" "end")))
   "Alist with Octave's matching block keywords.
 Has Octave's begin keywords as keys and a list of the matching else or
 end keywords as associated values.")
@@ -410,7 +407,7 @@ Non-nil means always go to the next Octave code line after sending."
 
 This mode makes it easier to write Octave code by helping with
 indentation, doing some of the typing for you (with Abbrev mode) and by
-showing keywords, comments, strings, etc.. in different faces (with
+showing keywords, comments, strings, etc. in different faces (with
 Font Lock mode on terminals that support it).
 
 Octave itself is a high-level language, primarily intended for numerical
@@ -680,7 +677,10 @@ level."
                        (if (= bot (point))
                            (setq icol (+ icol octave-block-offset))))
                       ((octave-looking-at-kw octave-block-end-regexp)
-                       (if (not (= bot (point)))
+                       (if (and (not (= bot (point)))
+                                ;; special case for `end' keyword,
+                                ;; applied to all keywords
+                                (not (octave-end-as-array-index-p)))
                            (setq icol (- icol
                                          (octave-block-end-offset)))))))
                  (forward-char)))
@@ -702,6 +702,15 @@ level."
        (setq icol (list comment-column icol)))))
     icol))
 
+;; FIXME: this should probably also make sure we are actually looking
+;; at the "end" keyword.
+(defun octave-end-as-array-index-p ()
+  (save-excursion
+    (condition-case nil
+       ;; Check if point is between parens
+       (progn (up-list 1) t)
+      (error nil))))
+
 (defun octave-block-end-offset ()
   (save-excursion
     (octave-backward-up-block 1)
@@ -1237,43 +1246,10 @@ otherwise."
   "Perform completion on Octave symbol preceding point.
 Compare that symbol against Octave's reserved words and builtin
 variables."
-  ;; This code taken from lisp-complete-symbol
   (interactive)
   (let* ((end (point))
-        (beg (save-excursion (backward-sexp 1) (point)))
-        (string (buffer-substring-no-properties beg end))
-        (completion (try-completion string octave-completion-alist)))
-    (cond ((eq completion t))          ; ???
-         ((null completion)
-          (message "Can't find completion for \"%s\"" string)
-          (ding))
-         ((not (string= string completion))
-           (delete-region beg end)
-           (insert completion))
-         (t
-          (let ((list (all-completions string octave-completion-alist))
-                (conf (current-window-configuration)))
-            ;; Taken from comint.el
-            (message "Making completion list...")
-            (with-output-to-temp-buffer "*Completions*"
-              (display-completion-list list string))
-            (message "Hit space to flush")
-            (let (key first)
-              (if (with-current-buffer (get-buffer "*Completions*")
-                    (setq key (read-key-sequence nil)
-                          first (aref key 0))
-                    (and (consp first) (consp (event-start first))
-                         (eq (window-buffer (posn-window (event-start
-                                                          first)))
-                             (get-buffer "*Completions*"))
-                         (eq (key-binding key) 'mouse-choose-completion)))
-                  (progn
-                    (mouse-choose-completion first)
-                    (set-window-configuration conf))
-                (if (eq first ?\ )
-                    (set-window-configuration conf)
-                  (setq unread-command-events
-                        (listify-key-sequence key))))))))))
+        (beg (save-excursion (backward-sexp 1) (point))))
+    (completion-in-region beg end octave-completion-alist)))
 
 \f
 ;;; Electric characters && friends
@@ -1293,7 +1269,7 @@ If Abbrev mode is on, expand abbrevs first."
 (defun octave-electric-semi ()
   "Insert a semicolon in Octave mode.
 Maybe expand abbrevs and blink matching block open keywords.
-Reindent the line of `octave-auto-indent' is non-nil.
+Reindent the line if `octave-auto-indent' is non-nil.
 Insert a newline if `octave-auto-newline' is non-nil."
   (interactive)
   (if (not (octave-not-in-string-or-comment-p))
@@ -1310,9 +1286,9 @@ Insert a newline if `octave-auto-newline' is non-nil."
 (defun octave-electric-space ()
   "Insert a space in Octave mode.
 Maybe expand abbrevs and blink matching block open keywords.
-Reindent the line of `octave-auto-indent' is non-nil."
+Reindent the line if `octave-auto-indent' is non-nil."
   (interactive)
-  (setq last-command-char ? )
+  (setq last-command-event ? )
   (if (and octave-auto-indent
           (not (octave-not-in-string-or-comment-p)))
       (progn
@@ -1338,7 +1314,7 @@ Note that all Octave mode abbrevs start with a grave accent."
   (if (not abbrev-mode)
       (self-insert-command 1)
     (let (c)
-      (insert last-command-char)
+      (insert last-command-event)
       (if (if (featurep 'xemacs)
              (or (eq (event-to-character (setq c (next-event))) ??)
                  (eq (event-to-character c) help-char))