changeset 109754:47ffebe76e42

Misc code cleanup of octave-mode.el. * lisp/progmodes/octave-mod.el (octave-mode-map): Remove special bindings for (un)commenting the region and performing completion. (octave-mode-menu): Use standard commands for help and completion. (octave-mode-syntax-table): Support %{..%} comments (sort of). (octave-mode): Use define-derived-mode. Set completion-at-point-functions and don't set columns. Don't disable adaptive-fill-regexp. (octave-describe-major-mode, octave-comment-region) (octave-uncomment-region, octave-comment-indent) (octave-indent-for-comment): Remove. (octave-indent-calculate): Rename from calculate-octave-indent. (octave-indent-line): Update caller. (octave-initialize-completions): No need to make an alist. (octave-completion-at-point-function): New function. (octave-complete-symbol): Use it. (octave-insert-defun): Use define-skeleton.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Thu, 12 Aug 2010 13:22:16 +0200
parents 8646a04a2d97
children 1aa7bc345918
files lisp/ChangeLog lisp/progmodes/octave-mod.el
diffstat 2 files changed, 97 insertions(+), 139 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Thu Aug 12 12:46:44 2010 +0200
+++ b/lisp/ChangeLog	Thu Aug 12 13:22:16 2010 +0200
@@ -1,7 +1,24 @@
 2010-08-12  Stefan Monnier  <monnier@iro.umontreal.ca>
 
-	* progmodes/octave-mod.el (octave-mode-map): Use comment-dwim (bug#6829).
-	(octave-mode): Set comment-add.
+	* progmodes/octave-mod.el (octave-mode-map): Remove special bindings
+	for (un)commenting the region and performing completion.
+	(octave-mode-menu): Use standard commands for help and completion.
+	(octave-mode-syntax-table): Support %{..%} comments (sort of).
+	(octave-mode): Use define-derived-mode.
+	Set completion-at-point-functions and don't set columns.
+	Don't disable adaptive-fill-regexp.
+	(octave-describe-major-mode, octave-comment-region)
+	(octave-uncomment-region, octave-comment-indent)
+	(octave-indent-for-comment): Remove.
+	(octave-indent-calculate): Rename from calculate-octave-indent.
+	(octave-indent-line): Update caller.
+	(octave-initialize-completions): No need to make an alist.
+	(octave-completion-at-point-function): New function.
+	(octave-complete-symbol): Use it.
+	(octave-insert-defun): Use define-skeleton.
+
+	* progmodes/octave-mod.el (octave-mode): Set comment-add.
+	(octave-mode-map): Use comment-dwim (bug#6829).
 
 2010-08-12  Antoine Levitt  <antoine.levitt@gmail.com>  (tiny change)
 
--- a/lisp/progmodes/octave-mod.el	Thu Aug 12 12:46:44 2010 +0200
+++ b/lisp/progmodes/octave-mod.el	Thu Aug 12 13:22:16 2010 +0200
@@ -4,7 +4,7 @@
 ;; Free Software Foundation, Inc.
 
 ;; Author: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>
-;; Author: John Eaton <jwe@bevo.che.wisc.edu>
+;; Author: John Eaton <jwe@octave.org>
 ;; Maintainer: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>
 ;; Keywords: languages
 
@@ -92,7 +92,7 @@
 (defvar octave-comment-char ?#
   "Character to start an Octave comment.")
 (defvar octave-comment-start
-  (string octave-comment-char ?\ )
+  (string octave-comment-char ?\s)
   "String to insert to start a new Octave in-line comment.")
 (defvar octave-comment-start-skip "\\s<+\\s-*"
   "Regexp to match the start of an Octave comment up to its body.")
@@ -195,13 +195,10 @@
     (define-key map " " 'octave-electric-space)
     (define-key map "\n" 'octave-reindent-then-newline-and-indent)
     (define-key map "\e\n" 'octave-indent-new-comment-line)
-    (define-key map "\e\t" 'octave-complete-symbol)
     (define-key map "\M-\C-a" 'octave-beginning-of-defun)
     (define-key map "\M-\C-e" 'octave-end-of-defun)
     (define-key map "\M-\C-h" 'octave-mark-defun)
     (define-key map "\M-\C-q" 'octave-indent-defun)
-    (define-key map "\C-c;" 'octave-comment-region)
-    (define-key map "\C-c:" 'octave-uncomment-region)
     (define-key map "\C-c\C-b" 'octave-submit-bug-report)
     (define-key map "\C-c\C-p" 'octave-previous-code-line)
     (define-key map "\C-c\C-n" 'octave-next-code-line)
@@ -266,14 +263,14 @@
       ["Kill Process"		octave-kill-process t])
     "-"
     ["Indent Line"		indent-according-to-mode t]
-    ["Complete Symbol"		octave-complete-symbol t]
+    ["Complete Symbol"		completion-at-point t]
     "-"
     ["Toggle Abbrev Mode"	abbrev-mode t]
     ["Toggle Auto-Fill Mode"	auto-fill-mode t]
     "-"
     ["Submit Bug Report"	octave-submit-bug-report t]
     "-"
-    ["Describe Octave Mode"	octave-describe-major-mode t]
+    ["Describe Octave Mode"	describe-mode t]
     ["Lookup Octave Index"	octave-help t])
   "Menu for Octave mode.")
 
@@ -297,8 +294,17 @@
     (modify-syntax-entry ?\" "\"" table)
     (modify-syntax-entry ?. "w"   table)
     (modify-syntax-entry ?_ "w"   table)
-    (modify-syntax-entry ?\% "<"  table)
-    (modify-syntax-entry ?\# "<"  table)
+    ;; FIXME: The < property of # and % makes Emacs-23 ignore any subsequent
+    ;; char including {, so it never gets to see the multi-line comments.
+    ;; This is a shortcoming in syntax.c.  In Twelf-mode (which also suffers
+    ;; from this problem) we work around the issue by setting "% " rather than
+    ;; just "%" as a comment-starter, but it seems this wouldn't cut it
+    ;; for Octave.
+    ;; Hopefully we'll get to fix this in Emacs-24.
+    (modify-syntax-entry ?\% "< 13"  table)
+    (modify-syntax-entry ?\# "< 13"  table)
+    (modify-syntax-entry ?\{ "(} 2b"  table)
+    (modify-syntax-entry ?\} "){ 4"  table)
     (modify-syntax-entry ?\n ">"  table)
     table)
   "Syntax table in use in `octave-mode' buffers.")
@@ -401,7 +407,7 @@
 
 
 ;;;###autoload
-(defun octave-mode ()
+(define-derived-mode octave-mode prog-mode "Octave"
   "Major mode for editing Octave code.
 
 This mode makes it easier to write Octave code by helping with
@@ -484,53 +490,39 @@
 This automatically sets up a mail buffer with version information
 already added.  You just need to add a description of the problem,
 including a reproducible test case and send the message."
-  (interactive)
-  (kill-all-local-variables)
+  (setq local-abbrev-table octave-abbrev-table)
 
-  (use-local-map octave-mode-map)
-  (setq major-mode 'octave-mode)
-  (setq mode-name "Octave")
-  (setq local-abbrev-table octave-abbrev-table)
-  (set-syntax-table octave-mode-syntax-table)
+  (set (make-local-variable 'indent-line-function) 'octave-indent-line)
 
-  (make-local-variable 'indent-line-function)
-  (setq indent-line-function 'octave-indent-line)
-
-  (make-local-variable 'comment-start)
-  (setq comment-start octave-comment-start)
-  (make-local-variable 'comment-end)
-  (setq comment-end "")
-  (make-local-variable 'comment-column)
-  (setq comment-column 32)
-  (make-local-variable 'comment-start-skip)
-  (setq comment-start-skip "\\s<+\\s-*")
-  (make-local-variable 'comment-indent-function)
-  (setq comment-indent-function 'octave-comment-indent)
+  (set (make-local-variable 'comment-start) octave-comment-start)
+  (set (make-local-variable 'comment-end) "")
+  ;; Don't set it here: it's not really a property of the language,
+  ;; just a personal preference of the author.
+  ;; (set (make-local-variable 'comment-column) 32)
+  (set (make-local-variable 'comment-start-skip) "\\s<+\\s-*")
   (set (make-local-variable 'comment-add) 1)
 
-  (make-local-variable 'parse-sexp-ignore-comments)
-  (setq parse-sexp-ignore-comments t)
-  (make-local-variable 'paragraph-start)
-  (setq paragraph-start (concat "\\s-*$\\|" page-delimiter))
-  (make-local-variable 'paragraph-separate)
-  (setq paragraph-separate paragraph-start)
-  (make-local-variable 'paragraph-ignore-fill-prefix)
-  (setq paragraph-ignore-fill-prefix t)
-  (make-local-variable 'fill-paragraph-function)
-  (setq fill-paragraph-function 'octave-fill-paragraph)
-  (make-local-variable 'adaptive-fill-regexp)
-  (setq adaptive-fill-regexp nil)
-  (make-local-variable 'fill-column)
-  (setq fill-column 72)
-  (make-local-variable 'normal-auto-fill-function)
-  (setq normal-auto-fill-function 'octave-auto-fill)
+  (set (make-local-variable 'parse-sexp-ignore-comments) t)
+  (set (make-local-variable 'paragraph-start)
+       (concat "\\s-*$\\|" page-delimiter))
+  (set (make-local-variable 'paragraph-separate) paragraph-start)
+  (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
+  (set (make-local-variable 'fill-paragraph-function) 'octave-fill-paragraph)
+  ;; FIXME: Why disable it?
+  ;; (set (make-local-variable 'adaptive-fill-regexp) nil)
+  ;; Again, this is not a property of the language, don't set it here.
+  ;; (set (make-local-variable 'fill-column) 72)
+  (set (make-local-variable 'normal-auto-fill-function) 'octave-auto-fill)
 
-  (make-local-variable 'font-lock-defaults)
-  (setq font-lock-defaults '(octave-font-lock-keywords nil nil))
+  (set (make-local-variable 'font-lock-defaults)
+       '(octave-font-lock-keywords nil nil))
 
-  (make-local-variable 'imenu-generic-expression)
-  (setq imenu-generic-expression octave-mode-imenu-generic-expression
-        imenu-case-fold-search nil)
+  (set (make-local-variable 'imenu-generic-expression)
+       octave-mode-imenu-generic-expression)
+  (set (make-local-variable 'imenu-case-fold-search) nil)
+
+  (add-hook 'completion-at-point-functions
+            'octave-completion-at-point-function nil t)
 
   (octave-add-octave-menu)
   (octave-initialize-completions)
@@ -543,25 +535,22 @@
     (call-interactively 'info-lookup-symbol)))
 
 ;;; Miscellaneous useful functions
-(defun octave-describe-major-mode ()
-  "Describe the current major mode."
-  (interactive)
-  (describe-function major-mode))
 
 (defsubst octave-in-comment-p ()
   "Return t if point is inside an Octave comment."
-  (interactive)
   (save-excursion
+    ;; FIXME: use syntax-ppss?
     (nth 4 (parse-partial-sexp (line-beginning-position) (point)))))
 
 (defsubst octave-in-string-p ()
   "Return t if point is inside an Octave string."
-  (interactive)
   (save-excursion
+    ;; FIXME: use syntax-ppss?
     (nth 3 (parse-partial-sexp (line-beginning-position) (point)))))
 
 (defsubst octave-not-in-string-or-comment-p ()
   "Return t if point is not inside an Octave string or comment."
+  ;; FIXME: Use syntax-ppss?
   (let ((pps (parse-partial-sexp (line-beginning-position) (point))))
     (not (or (nth 3 pps) (nth 4 pps)))))
 
@@ -620,23 +609,9 @@
     (delete-horizontal-space)
     (insert (concat " " octave-continuation-string))))
 
-;;; Comments
-(defun octave-comment-region (beg end &optional arg)
-  "Comment or uncomment each line in the region as Octave code.
-See `comment-region'."
-  (interactive "r\nP")
-  (let ((comment-start (char-to-string octave-comment-char)))
-    (comment-region beg end arg)))
-
-(defun octave-uncomment-region (beg end &optional arg)
-  "Uncomment each line in the region as Octave code."
-  (interactive "r\nP")
-  (or arg (setq arg 1))
-  (octave-comment-region beg end (- arg)))
-
 
 ;;; Indentation
-(defun calculate-octave-indent ()
+(defun octave-indent-calculate ()
   "Return appropriate indentation for current line as Octave code.
 Returns an integer (the column to indent to) unless the line is a
 comment line with fixed goal golumn.  In that case, returns a list whose
@@ -722,36 +697,13 @@
     (beginning-of-line)
     (and (bobp) (looking-at "\\s-*#!"))))
 
-(defun octave-comment-indent ()
-  (if (or (looking-at "\\s<\\s<\\s<")
-	  (octave-before-magic-comment-p))
-      0
-    (if (looking-at "\\s<\\s<")
-	(calculate-octave-indent)
-      (skip-syntax-backward " ")
-      (max (if (bolp) 0 (+ 1 (current-column)))
-	   comment-column))))
-
-(defun octave-indent-for-comment ()
-  "Maybe insert and indent an Octave comment.
-If there is no comment already on this line, create a code-level comment
-\(started by two comment characters) if the line is empty, or an in-line
-comment (started by one comment character) otherwise.
-Point is left after the start of the comment which is properly aligned."
-  (interactive)
-  (beginning-of-line)
-  (if (looking-at "^\\s-*$")
-      (insert octave-block-comment-start)
-    (indent-for-comment))
-  (indent-according-to-mode))
-
 (defun octave-indent-line (&optional arg)
   "Indent current line as Octave code.
 With optional ARG, use this as offset unless this line is a comment with
 fixed goal column."
   (interactive)
   (or arg (setq arg 0))
-  (let ((icol (calculate-octave-indent))
+  (let ((icol (octave-indent-calculate))
 	(relpos (- (current-column) (current-indentation))))
     (if (listp icol)
 	(setq icol (car icol))
@@ -1237,20 +1189,24 @@
   (if octave-completion-alist
       ()
     (setq octave-completion-alist
-	  (mapcar '(lambda (var) (cons var var))
-		  (append octave-reserved-words
-			  octave-text-functions
-			  octave-variables)))))
+          (append octave-reserved-words
+                  octave-text-functions
+                  octave-variables))))
+
+(defun octave-completion-at-point-function ()
+  "Find the text to complete and the corresponding table."
+  (let ((beg (save-excursion (backward-sexp 1) (point)))
+        (end (if (< beg (point))
+                 (save-excursion (goto-char beg) (forward-sexp 1) (point))
+               (point))))
+    (list beg end octave-completion-alist)))
 
 (defun octave-complete-symbol ()
   "Perform completion on Octave symbol preceding point.
 Compare that symbol against Octave's reserved words and builtin
 variables."
   (interactive)
-  (let* ((end (point))
-	 (beg (save-excursion (backward-sexp 1) (point))))
-    (completion-in-region beg end octave-completion-alist)))
-
+  (apply 'completion-in-region (octave-completion-at-point-function)))
 
 ;;; Electric characters && friends
 (defun octave-reindent-then-newline-and-indent ()
@@ -1324,42 +1280,27 @@
 	    (list-abbrevs))
 	(setq unread-command-events (list c))))))
 
-(defun octave-insert-defun (name args vals)
+(define-skeleton octave-insert-defun
   "Insert an Octave function skeleton.
 Prompt for the function's name, arguments and return values (to be
 entered without parens)."
-  (interactive
-   (list
-    (read-from-minibuffer "Function name: "
-			  (substring (buffer-name) 0 -2))
-    (read-from-minibuffer "Arguments: ")
-    (read-from-minibuffer "Return values: ")))
-  (let ((string (format "%s %s (%s)"
-			(cond
-			 ((string-equal vals "")
-			  vals)
-			 ((string-match "[ ,]" vals)
-			  (concat " [" vals "] ="))
-			 (t
-			  (concat " " vals " =")))
-			name
-			args))
-	(prefix octave-block-comment-start))
-    (if (not (bobp)) (newline))
-    (insert "function" string)
-    (indent-according-to-mode)
-    (newline 2)
-    (insert prefix "usage: " string)
-    (reindent-then-newline-and-indent)
-    (insert prefix)
-    (reindent-then-newline-and-indent)
-    (insert prefix)
-    (indent-according-to-mode)
-    (save-excursion
-      (newline 2)
-      (insert "endfunction")
-      (indent-according-to-mode))))
-
+  (let* ((defname (substring (buffer-name) 0 -2))
+         (name (read-string (format "Function name (default %s): " defname)
+                            nil nil defname))
+         (args (read-string "Arguments: "))
+         (vals (read-string "Return values: ")))
+    (format "%s%s (%s)"
+            (cond
+             ((string-equal vals "") vals)
+             ((string-match "[ ,]" vals) (concat "[" vals "] = "))
+             (t (concat vals " = ")))
+            name
+            args))
+  \n "function " > str \n \n
+  octave-block-comment-start "usage: " str \n
+  octave-block-comment-start \n octave-block-comment-start
+  \n _ \n
+  "endfunction" > \n)
 
 ;;; Menu
 (defun octave-add-octave-menu ()