aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeo Liu2013-04-28 01:07:01 +0800
committerLeo Liu2013-04-28 01:07:01 +0800
commitb7260dd49c5a492411f0ae9318aa6f2f4735109c (patch)
treebc4e46d97d9ce96d77927b6e5dfa09f167c3d877
parentc46da66964f894dd752709bb3b7a6db571a1063d (diff)
downloademacs-b7260dd49c5a492411f0ae9318aa6f2f4735109c.tar.gz
emacs-b7260dd49c5a492411f0ae9318aa6f2f4735109c.zip
* files.el (basic-save-buffer): Don't let errors in
before-save-hook prevent saving buffer. * progmodes/octave.el (octave-function-file-p) (octave-skip-comment-forward, octave-function-file-comment) (octave-update-function-file-comment): New functions. (octave-mode-map): Bind C-c ; to octave-update-function-file-comment. (octave-mode-menu): Add octave-update-function-file-comment. (octave-mode, inferior-octave-mode): Fix doc-string. (octave-insert-defun): Conform to Octave's coding convention. Fixes: debbugs:14285
-rw-r--r--lisp/ChangeLog15
-rw-r--r--lisp/files.el3
-rw-r--r--lisp/progmodes/octave.el212
3 files changed, 128 insertions, 102 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index a90fda0b660..f1dade06c99 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,18 @@
12013-04-27 Leo Liu <sdl.web@gmail.com>
2
3 * progmodes/octave.el (octave-function-file-p)
4 (octave-skip-comment-forward, octave-function-file-comment)
5 (octave-update-function-file-comment): New functions.
6 (octave-mode-map): Bind C-c ; to
7 octave-update-function-file-comment.
8 (octave-mode-menu): Add octave-update-function-file-comment.
9 (octave-mode, inferior-octave-mode): Fix doc-string.
10 (octave-insert-defun): Conform to Octave's coding convention.
11 (Bug#14285)
12
13 * files.el (basic-save-buffer): Don't let errors in
14 before-save-hook prevent saving buffer.
15
12013-04-20 Roland Winkler <winkler@gnu.org> 162013-04-20 Roland Winkler <winkler@gnu.org>
2 17
3 * faces.el (read-face-name): Use completing-read if arg multiple 18 * faces.el (read-face-name): Use completing-read if arg multiple
diff --git a/lisp/files.el b/lisp/files.el
index ae5e5a23161..eebbf15e02e 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -4617,7 +4617,8 @@ Before and after saving the buffer, this function runs
4617 (insert ?\n)))) 4617 (insert ?\n))))
4618 ;; Support VC version backups. 4618 ;; Support VC version backups.
4619 (vc-before-save) 4619 (vc-before-save)
4620 (run-hooks 'before-save-hook) 4620 ;; Don't let errors prevent saving the buffer.
4621 (with-demoted-errors (run-hooks 'before-save-hook))
4621 (or (run-hook-with-args-until-success 'write-contents-functions) 4622 (or (run-hook-with-args-until-success 'write-contents-functions)
4622 (run-hook-with-args-until-success 'local-write-file-hooks) 4623 (run-hook-with-args-until-success 'local-write-file-hooks)
4623 (run-hook-with-args-until-success 'write-file-functions) 4624 (run-hook-with-args-until-success 'write-file-functions)
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el
index f8b9e4f6fab..b8fbe6a90a7 100644
--- a/lisp/progmodes/octave.el
+++ b/lisp/progmodes/octave.el
@@ -198,7 +198,6 @@ parenthetical grouping.")
198 (define-key map "`" 'octave-abbrev-start) 198 (define-key map "`" 'octave-abbrev-start)
199 (define-key map "\e\n" 'octave-indent-new-comment-line) 199 (define-key map "\e\n" 'octave-indent-new-comment-line)
200 (define-key map "\M-\C-q" 'octave-indent-defun) 200 (define-key map "\M-\C-q" 'octave-indent-defun)
201 (define-key map "\C-c\C-b" 'octave-submit-bug-report)
202 (define-key map "\C-c\C-p" 'octave-previous-code-line) 201 (define-key map "\C-c\C-p" 'octave-previous-code-line)
203 (define-key map "\C-c\C-n" 'octave-next-code-line) 202 (define-key map "\C-c\C-n" 'octave-next-code-line)
204 (define-key map "\C-c\C-a" 'octave-beginning-of-line) 203 (define-key map "\C-c\C-a" 'octave-beginning-of-line)
@@ -207,6 +206,7 @@ parenthetical grouping.")
207 (define-key map "\C-c\M-\C-h" 'octave-mark-block) 206 (define-key map "\C-c\M-\C-h" 'octave-mark-block)
208 (define-key map "\C-c]" 'smie-close-block) 207 (define-key map "\C-c]" 'smie-close-block)
209 (define-key map "\C-c/" 'smie-close-block) 208 (define-key map "\C-c/" 'smie-close-block)
209 (define-key map "\C-c;" 'octave-update-function-file-comment)
210 (define-key map "\C-c\C-f" 'octave-insert-defun) 210 (define-key map "\C-c\C-f" 'octave-insert-defun)
211 (define-key map "\C-c\C-il" 'octave-send-line) 211 (define-key map "\C-c\C-il" 'octave-send-line)
212 (define-key map "\C-c\C-ib" 'octave-send-block) 212 (define-key map "\C-c\C-ib" 'octave-send-block)
@@ -241,7 +241,8 @@ parenthetical grouping.")
241 ["Close Block" smie-close-block t]) 241 ["Close Block" smie-close-block t])
242 ("Functions" 242 ("Functions"
243 ["Indent Function" octave-indent-defun t] 243 ["Indent Function" octave-indent-defun t]
244 ["Insert Function" octave-insert-defun t]) 244 ["Insert Function" octave-insert-defun t]
245 ["Update function file comment" octave-update-function-file-comment t])
245 "-" 246 "-"
246 ("Debug" 247 ("Debug"
247 ["Send Current Line" octave-send-line t] 248 ["Send Current Line" octave-send-line t]
@@ -260,10 +261,11 @@ parenthetical grouping.")
260 ["Toggle Auto-Fill Mode" auto-fill-mode 261 ["Toggle Auto-Fill Mode" auto-fill-mode
261 :style toggle :selected auto-fill-function] 262 :style toggle :selected auto-fill-function]
262 "-" 263 "-"
263 ["Submit Bug Report" octave-submit-bug-report t]
264 "-"
265 ["Describe Octave Mode" describe-mode t] 264 ["Describe Octave Mode" describe-mode t]
266 ["Lookup Octave Index" info-lookup-symbol t])) 265 ["Lookup Octave Index" info-lookup-symbol t]
266 ["Customize Octave" (customize-group 'octave) t]
267 "-"
268 ["Submit Bug Report" report-emacs-bug t]))
267 269
268(defvar octave-mode-syntax-table 270(defvar octave-mode-syntax-table
269 (let ((table (make-syntax-table))) 271 (let ((table (make-syntax-table)))
@@ -508,78 +510,10 @@ Non-nil means always go to the next Octave code line after sending."
508(define-derived-mode octave-mode prog-mode "Octave" 510(define-derived-mode octave-mode prog-mode "Octave"
509 "Major mode for editing Octave code. 511 "Major mode for editing Octave code.
510 512
511This mode makes it easier to write Octave code by helping with 513Octave is a high-level language, primarily intended for numerical
512indentation, doing some of the typing for you (with Abbrev mode) and by 514computations. It provides a convenient command line interface
513showing keywords, comments, strings, etc. in different faces (with 515for solving linear and nonlinear problems numerically. Function
514Font Lock mode on terminals that support it). 516definitions can also be stored in files and used in batch mode."
515
516Octave itself is a high-level language, primarily intended for numerical
517computations. It provides a convenient command line interface for
518solving linear and nonlinear problems numerically. Function definitions
519can also be stored in files, and it can be used in a batch mode (which
520is why you need this mode!).
521
522The latest released version of Octave is always available via anonymous
523ftp from ftp.octave.org in the directory `/pub/octave'. Complete
524source and binaries for several popular systems are available.
525
526Type \\[list-abbrevs] to display the built-in abbrevs for Octave keywords.
527
528Keybindings
529===========
530
531\\{octave-mode-map}
532
533Variables you can use to customize Octave mode
534==============================================
535
536`octave-blink-matching-block'
537 Non-nil means show matching begin of block when inserting a space,
538 newline or semicolon after an else or end keyword. Default is t.
539
540`octave-block-offset'
541 Extra indentation applied to statements in block structures.
542 Default is 2.
543
544`octave-continuation-offset'
545 Extra indentation applied to Octave continuation lines.
546 Default is 4.
547
548`octave-continuation-string'
549 String used for Octave continuation lines.
550 Default is a backslash.
551
552`octave-send-echo-input'
553 Non-nil means always display `inferior-octave-buffer' after sending a
554 command to the inferior Octave process.
555
556`octave-send-line-auto-forward'
557 Non-nil means always go to the next unsent line of Octave code after
558 sending a line to the inferior Octave process.
559
560`octave-send-echo-input'
561 Non-nil means echo input sent to the inferior Octave process.
562
563Turning on Octave mode runs the hook `octave-mode-hook'.
564
565To begin using this mode for all `.m' files that you edit, add the
566following lines to your init file:
567
568 (add-to-list 'auto-mode-alist '(\"\\\\.m\\\\'\" . octave-mode))
569
570To automatically turn on the abbrev and auto-fill features,
571add the following lines to your init file as well:
572
573 (add-hook 'octave-mode-hook
574 (lambda ()
575 (abbrev-mode 1)
576 (auto-fill-mode 1)))
577
578To submit a problem report, enter \\[octave-submit-bug-report] from \
579an Octave mode buffer.
580This automatically sets up a mail buffer with version information
581already added. You just need to add a description of the problem,
582including a reproducible test case and send the message."
583 (setq local-abbrev-table octave-abbrev-table) 517 (setq local-abbrev-table octave-abbrev-table)
584 518
585 (smie-setup octave-smie-grammar #'octave-smie-rules 519 (smie-setup octave-smie-grammar #'octave-smie-rules
@@ -724,12 +658,7 @@ in the Inferior Octave buffer.")
724(defvar info-lookup-mode) 658(defvar info-lookup-mode)
725 659
726(define-derived-mode inferior-octave-mode comint-mode "Inferior Octave" 660(define-derived-mode inferior-octave-mode comint-mode "Inferior Octave"
727 "Major mode for interacting with an inferior Octave process. 661 "Major mode for interacting with an inferior Octave process."
728Runs Octave as a subprocess of Emacs, with Octave I/O through an Emacs
729buffer.
730
731Entry to this mode successively runs the hooks `comint-mode-hook' and
732`inferior-octave-mode-hook'."
733 (setq comint-prompt-regexp inferior-octave-prompt 662 (setq comint-prompt-regexp inferior-octave-prompt
734 mode-line-process '(":%s") 663 mode-line-process '(":%s")
735 local-abbrev-table octave-abbrev-table) 664 local-abbrev-table octave-abbrev-table)
@@ -1010,25 +939,105 @@ directory and makes this the current buffer's default directory."
1010 (delete-horizontal-space) 939 (delete-horizontal-space)
1011 (insert (concat " " octave-continuation-string)))) 940 (insert (concat " " octave-continuation-string))))
1012 941
942(defun octave-function-file-p ()
943 "Return non-nil if the first token is \"function\".
944The value is (START END NAME-START NAME-END) of the function."
945 (save-excursion
946 (goto-char (point-min))
947 (when (equal (funcall smie-forward-token-function) "function")
948 (forward-word -1)
949 (let* ((start (point))
950 (end (progn (forward-sexp 1) (point)))
951 (name (when (progn
952 (goto-char start)
953 (re-search-forward octave-function-header-regexp
954 end t))
955 (list (match-beginning 3) (match-end 3)))))
956 (cons start (cons end name))))))
957
958;; Like forward-comment but stop at non-comment blank
959(defun octave-skip-comment-forward (limit)
960 (let ((ppss (syntax-ppss)))
961 (if (nth 4 ppss)
962 (goto-char (nth 8 ppss))
963 (goto-char (or (comment-search-forward limit t) (point)))))
964 (while (and (< (point) limit) (looking-at-p "\\s<"))
965 (forward-comment 1)))
966
967;;; First non-copyright comment block
968(defun octave-function-file-comment ()
969 "Beginnning and end positions of the function file comment."
970 (save-excursion
971 (goto-char (point-min))
972 (let ((bound (progn (forward-comment (point-max)) (point))))
973 (goto-char (point-min))
974 ;; Copyright block: octave/libinterp/parse-tree/lex.ll around line 1634
975 (when (save-excursion
976 (comment-search-forward bound t)
977 (when (eq (char-after) ?\{) ; case of block comment
978 (forward-char 1))
979 (skip-syntax-forward "-")
980 (let ((case-fold-search t))
981 (looking-at-p "\\(?:copyright\\|author\\)\\_>")))
982 (octave-skip-comment-forward bound))
983 (let ((beg (comment-search-forward bound t)))
984 (when beg
985 (goto-char beg)
986 (octave-skip-comment-forward bound)
987 (list beg (point)))))))
988
1013(defun octave-sync-function-file-names () 989(defun octave-sync-function-file-names ()
1014 "Ensure function name agree with function file name. 990 "Ensure function name agree with function file name.
1015See Info node `(octave)Function Files'." 991See Info node `(octave)Function Files'."
1016 (interactive) 992 (interactive)
993 (when buffer-file-name
994 (pcase-let ((`(,start ,_end ,name-start ,name-end)
995 (octave-function-file-p)))
996 (when (and start name-start)
997 (let ((func (buffer-substring name-start name-end))
998 (file (file-name-sans-extension
999 (file-name-nondirectory buffer-file-name))))
1000 (save-excursion
1001 (when (and (not (equal file func))
1002 (progn
1003 (goto-char name-start)
1004 (yes-or-no-p
1005 "Function name different from file name. Fix? ")))
1006 (delete-region name-start name-end)
1007 (insert file))))))))
1008
1009(defun octave-update-function-file-comment (beg end)
1010 "Query replace function names in function file comment."
1011 (interactive
1012 (progn
1013 (barf-if-buffer-read-only)
1014 (if (use-region-p)
1015 (list (region-beginning) (region-end))
1016 (or (octave-function-file-comment)
1017 (error "No function file comment found")))))
1017 (save-excursion 1018 (save-excursion
1018 (when (and buffer-file-name 1019 (let* ((bounds (or (octave-function-file-p)
1019 (prog2 1020 (error "Not in a function file buffer")))
1020 (goto-char (point-min)) 1021 (func (if (cddr bounds)
1021 (equal (funcall smie-forward-token-function) "function") 1022 (apply #'buffer-substring (cddr bounds))
1022 (forward-word -1))) 1023 (error "Function name not found")))
1023 (let ((file (file-name-sans-extension 1024 (old-func (progn
1024 (file-name-nondirectory buffer-file-name))) 1025 (goto-char beg)
1025 (func (and (re-search-forward octave-function-header-regexp nil t) 1026 (when (and (re-search-forward
1026 (match-string 3)))) 1027 "usage:\\|@deftypefn" end t)
1027 (when (and func 1028 (re-search-forward
1028 (not (equal file func)) 1029 "[=}]\\s-*\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>"
1029 (yes-or-no-p 1030 (line-end-position) t))
1030 "Function name different from file name. Fix? ")) 1031 (match-string 1))))
1031 (replace-match file nil nil nil 3)))))) 1032 (old-func (read-string (format (if old-func
1033 "Name to replace (default %s): "
1034 "Name to replace: ")
1035 old-func)
1036 nil nil old-func)))
1037 (if (and func old-func (not (equal func old-func)))
1038 (perform-replace old-func func 'query
1039 nil 'delimited nil nil beg end)
1040 (message "Function names match")))))
1032 1041
1033 1042
1034;;; Indentation 1043;;; Indentation
@@ -1356,10 +1365,11 @@ entered without parens)."
1356 (t (concat vals " = "))) 1365 (t (concat vals " = ")))
1357 name 1366 name
1358 args)) 1367 args))
1359 \n "function " > str \n \n 1368 \n octave-block-comment-start "usage: " str \n
1360 octave-block-comment-start "usage: " str \n 1369 octave-block-comment-start '(delete-horizontal-space) \n
1361 octave-block-comment-start \n octave-block-comment-start 1370 octave-block-comment-start '(delete-horizontal-space) \n
1362 \n _ \n 1371 "function " > str \n
1372 _ \n
1363 "endfunction" > \n) 1373 "endfunction" > \n)
1364 1374
1365;;; Communication with the inferior Octave process 1375;;; Communication with the inferior Octave process