diff options
| author | Leo Liu | 2013-04-28 01:07:01 +0800 |
|---|---|---|
| committer | Leo Liu | 2013-04-28 01:07:01 +0800 |
| commit | b7260dd49c5a492411f0ae9318aa6f2f4735109c (patch) | |
| tree | bc4e46d97d9ce96d77927b6e5dfa09f167c3d877 | |
| parent | c46da66964f894dd752709bb3b7a6db571a1063d (diff) | |
| download | emacs-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/ChangeLog | 15 | ||||
| -rw-r--r-- | lisp/files.el | 3 | ||||
| -rw-r--r-- | lisp/progmodes/octave.el | 212 |
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 @@ | |||
| 1 | 2013-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 | |||
| 1 | 2013-04-20 Roland Winkler <winkler@gnu.org> | 16 | 2013-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 | ||
| 511 | This mode makes it easier to write Octave code by helping with | 513 | Octave is a high-level language, primarily intended for numerical |
| 512 | indentation, doing some of the typing for you (with Abbrev mode) and by | 514 | computations. It provides a convenient command line interface |
| 513 | showing keywords, comments, strings, etc. in different faces (with | 515 | for solving linear and nonlinear problems numerically. Function |
| 514 | Font Lock mode on terminals that support it). | 516 | definitions can also be stored in files and used in batch mode." |
| 515 | |||
| 516 | Octave itself is a high-level language, primarily intended for numerical | ||
| 517 | computations. It provides a convenient command line interface for | ||
| 518 | solving linear and nonlinear problems numerically. Function definitions | ||
| 519 | can also be stored in files, and it can be used in a batch mode (which | ||
| 520 | is why you need this mode!). | ||
| 521 | |||
| 522 | The latest released version of Octave is always available via anonymous | ||
| 523 | ftp from ftp.octave.org in the directory `/pub/octave'. Complete | ||
| 524 | source and binaries for several popular systems are available. | ||
| 525 | |||
| 526 | Type \\[list-abbrevs] to display the built-in abbrevs for Octave keywords. | ||
| 527 | |||
| 528 | Keybindings | ||
| 529 | =========== | ||
| 530 | |||
| 531 | \\{octave-mode-map} | ||
| 532 | |||
| 533 | Variables 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 | |||
| 563 | Turning on Octave mode runs the hook `octave-mode-hook'. | ||
| 564 | |||
| 565 | To begin using this mode for all `.m' files that you edit, add the | ||
| 566 | following lines to your init file: | ||
| 567 | |||
| 568 | (add-to-list 'auto-mode-alist '(\"\\\\.m\\\\'\" . octave-mode)) | ||
| 569 | |||
| 570 | To automatically turn on the abbrev and auto-fill features, | ||
| 571 | add 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 | |||
| 578 | To submit a problem report, enter \\[octave-submit-bug-report] from \ | ||
| 579 | an Octave mode buffer. | ||
| 580 | This automatically sets up a mail buffer with version information | ||
| 581 | already added. You just need to add a description of the problem, | ||
| 582 | including 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." |
| 728 | Runs Octave as a subprocess of Emacs, with Octave I/O through an Emacs | ||
| 729 | buffer. | ||
| 730 | |||
| 731 | Entry 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\". | ||
| 944 | The 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. |
| 1015 | See Info node `(octave)Function Files'." | 991 | See 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 |