GNU bug report logs - #14285
24.3; New octave feature: octave-update-function-file-comment

Previous Next

Package: emacs;

Reported by: Leo Liu <sdl.web <at> gmail.com>

Date: Sat, 27 Apr 2013 08:16:01 UTC

Severity: wishlist

Found in version 24.3

Done: Leo Liu <sdl.web <at> gmail.com>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Leo Liu <sdl.web <at> gmail.com>
To: 14285 <at> debbugs.gnu.org
Cc: "Jordi GutiƩrrez Hermoso" <jordigh <at> octave.org>, John Eaton <jwe <at> octave.org>, Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: bug#14285: 24.3; New octave feature: octave-update-function-file-comment
Date: Sat, 27 Apr 2013 16:14:26 +0800
[Message part 1 (text/plain, inline)]
Hello Stefan, JordiGH and John,

Based on our discussion on #octave and email, I have made a patch for
review. For convenience octave.el with the patch applied is available
from http://bpaste.net/raw/94528/. Note Emacs 24.3 is required.

The new command octave-update-function-file-comment let users update the
doc-string/doc-comment (per octave's definition) to the function name. I
am only just beginning octave. So please help test and review the patch.

Thanks.
Leo

[patch.diff (text/x-patch, inline)]
diff --git a/lisp/files.el b/lisp/files.el
index 80166961..59eef757 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -4451,7 +4451,8 @@ (defvar auto-save-hook nil
   "Normal hook run just before auto-saving.")
 
 (defcustom before-save-hook nil
-  "Normal hook that is run before a buffer is saved to its file."
+  "Normal hook that is run before a buffer is saved to its file.
+Any error from the hook prevents saving the buffer."
   :options '(copyright-update time-stamp)
   :type 'hook
   :group 'files)
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el
index f8b9e4f6..8a8a6616 100644
--- a/lisp/progmodes/octave.el
+++ b/lisp/progmodes/octave.el
@@ -32,6 +32,7 @@
 ;; information on usage and customization.
 
 ;;; Code:
+(eval-when-compile (require 'cl-lib))
 (require 'comint)
 
 (defgroup octave nil
@@ -1010,25 +1011,103 @@ (defun octave-maybe-insert-continuation-string ()
     (delete-horizontal-space)
     (insert (concat " " octave-continuation-string))))
 
+(defun octave-function-file-p ()
+  "Return non-nil if the first token is \"function\".
+The value is (START END NAME-START NAME-END) of the function."
+  (save-excursion
+    (goto-char (point-min))
+    (when (equal (funcall smie-forward-token-function) "function")
+      (forward-word -1)
+      (let* ((start (point))
+             (end (progn (forward-sexp 1) (point)))
+             (name (when (progn
+                           (goto-char start)
+                           (re-search-forward octave-function-header-regexp
+                                              end t))
+                     (list (match-beginning 3) (match-end 3)))))
+        (cons start (cons end name))))))
+
+;; Like forward-comment but stop at non-comment blank
+(defun octave-skip-comment-forward (limit)
+  (and (comment-beginning)
+       (goto-char (comment-beginning)))
+  (goto-char (or (comment-search-forward limit t) (point)))
+  (while (and (< (point) limit) (looking-at-p "\\s<"))
+    (forward-comment 1)))
+
+;;; First non-copyright comment block
+(defun octave-function-file-comment ()
+  "Beginnning and end positions of the function file comment."
+  (save-excursion
+    (goto-char (point-min))
+    (let ((bound (progn (forward-comment (point-max)) (point))))
+      (goto-char (point-min))
+      ;; Copyright block: octave/libinterp/parse-tree/lex.ll around line 1634
+      (when (save-excursion
+              (comment-search-forward bound t)
+              (when (eq (char-after) ?\{) ; case of block comment
+                (forward-char 1))
+              (skip-syntax-forward "-")
+              (let ((case-fold-search t))
+                (looking-at-p "\\(?:copyright\\|author\\)\\_>")))
+        (octave-skip-comment-forward bound))
+      (let ((beg (comment-search-forward bound t)))
+        (when beg
+          (goto-char beg)
+          (octave-skip-comment-forward bound)
+          (list beg (point)))))))
+
 (defun octave-sync-function-file-names ()
   "Ensure function name agree with function file name.
 See Info node `(octave)Function Files'."
   (interactive)
+  (when buffer-file-name
+    (with-demoted-errors
+      (cl-destructuring-bind (&optional start _end name-start name-end)
+          (octave-function-file-p)
+        (when (and start name-start)
+          (let ((func (buffer-substring name-start name-end))
+                (file (file-name-sans-extension
+                       (file-name-nondirectory buffer-file-name))))
+            (save-excursion
+              (when (and (not (equal file func))
+                         (progn
+                           (goto-char name-start)
+                           (yes-or-no-p
+                            "Function name different from file name. Fix? ")))
+                (delete-region name-start name-end)
+                (insert file)))))))))
+
+(defun octave-update-function-file-comment (beg end &optional no-query)
+  "Update function file comment between BEG and END."
+  (interactive
+   (progn
+     (barf-if-buffer-read-only)
+     (if (use-region-p)
+         (list (region-beginning) (region-end) current-prefix-arg)
+       (append (or (octave-function-file-comment)
+                   (error "No function file comment found"))
+               (list current-prefix-arg)))))
   (save-excursion
-    (when (and buffer-file-name
-               (prog2
-                   (goto-char (point-min))
-                   (equal (funcall smie-forward-token-function) "function")
-                 (forward-word -1)))
-      (let ((file (file-name-sans-extension
-                   (file-name-nondirectory buffer-file-name)))
-            (func (and (re-search-forward octave-function-header-regexp nil t)
-                       (match-string 3))))
-        (when (and func
-                   (not (equal file func))
-                   (yes-or-no-p
-                    "Function name different from file name. Fix? "))
-          (replace-match file nil nil nil 3))))))
+    (let* ((bounds (or (octave-function-file-p)
+                       (error "Not in a function file buffer")))
+           (func (if (cddr bounds)
+                     (apply #'buffer-substring (cddr bounds))
+                   (error "Function name not found")))
+           (old-func (progn
+                       (goto-char beg)
+                       (when (and (re-search-forward "usage:\\|@deftypefn" end t)
+                                  (re-search-forward
+                                   "[=}]\\s-*\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*("
+                                   (line-end-position) t))
+                         (match-string 1))))
+           (old-func (read-string
+                      (format (if old-func "From (default %s): " "From: ")
+                              old-func)
+                      nil nil old-func)))
+      (when (and func old-func (not (equal func old-func)))
+        (perform-replace old-func func
+                         (not no-query) nil 'delimited nil nil beg end)))))
 
 
 ;;; Indentation
@@ -1356,10 +1435,11 @@ (define-skeleton octave-insert-defun
              (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
+  \n octave-block-comment-start "usage: " str \n
+  octave-block-comment-start \n
+  octave-block-comment-start \n
+  "function " > str \n
+  _ \n
   "endfunction" > \n)
 
 ;;; Communication with the inferior Octave process

This bug report was last modified 12 years and 23 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.