X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/ca3fa30248b923c17c021c0fcdb945271d14e8c2..73b0cd50031a714347109169ceb8bacae338612a:/lisp/progmodes/octave-mod.el diff --git a/lisp/progmodes/octave-mod.el b/lisp/progmodes/octave-mod.el index 56de9b869d..7ec4cf3d94 100644 --- a/lisp/progmodes/octave-mod.el +++ b/lisp/progmodes/octave-mod.el @@ -1,7 +1,6 @@ ;;; octave-mod.el --- editing Octave source files under Emacs -;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 -;; Free Software Foundation, Inc. +;; Copyright (C) 1997, 2001-2011 Free Software Foundation, Inc. ;; Author: Kurt Hornik ;; Author: John Eaton @@ -212,9 +211,6 @@ parenthetical grouping.") (defvar octave-mode-map (let ((map (make-sparse-keymap))) (define-key map "`" 'octave-abbrev-start) - (define-key map ";" 'octave-electric-semi) - (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 "\M-\C-q" 'octave-indent-defun) (define-key map "\C-c\C-b" 'octave-submit-bug-report) @@ -319,16 +315,6 @@ parenthetical grouping.") table) "Syntax table in use in `octave-mode' buffers.") -(defcustom octave-auto-indent nil - "Non-nil means indent line after a semicolon or space in Octave mode." - :type 'boolean - :group 'octave) - -(defcustom octave-auto-newline nil - "Non-nil means automatically newline after a semicolon in Octave mode." - :type 'boolean - :group 'octave) - (defcustom octave-blink-matching-block t "Control the blinking of matching Octave block keywords. Non-nil means show matching begin of block when inserting a space, @@ -446,17 +432,13 @@ Non-nil means always go to the next Octave code line after sending." ;; (fundesc (atom "=" atom)) )) -(defconst octave-smie-closer-alist - (smie-bnf-closer-alist octave-smie-bnf-table)) - -(defconst octave-smie-op-levels - (smie-prec2-levels +(defconst octave-smie-grammar + (smie-prec2->grammar (smie-merge-prec2s - (smie-bnf-precedence-table - octave-smie-bnf-table - '((assoc "\n" ";"))) + (smie-bnf->prec2 octave-smie-bnf-table + '((assoc "\n" ";"))) - (smie-precs-precedence-table octave-operator-table)))) + (smie-precs->prec2 octave-operator-table)))) ;; Tokenizing needs to be refined so that ";;" is treated as two ;; tokens and also so as to recognize the \n separator (and @@ -521,17 +503,26 @@ Non-nil means always go to the next Octave code line after sending." (t (smie-default-forward-token)))) -(defconst octave-smie-indent-rules - '((";" - (:parent ("function" "if" "while" "else" "elseif" "for" "otherwise" - "case" "try" "catch" "unwind_protect" "unwind_protect_cleanup") - ;; FIXME: don't hardcode 2. - (+ parent octave-block-offset)) - ;; (:parent "switch" 4) ;For (invalid) code between switch and case. - 0) - ((:before . "case") octave-block-offset))) - -(defvar electric-indent-chars) +(defun octave-smie-rules (kind token) + (pcase (cons kind token) + ;; We could set smie-indent-basic instead, but that would have two + ;; disadvantages: + ;; - changes to octave-block-offset wouldn't take effect immediately. + ;; - edebug wouldn't show the use of this variable. + (`(:elem . basic) octave-block-offset) + ;; Since "case" is in the same BNF rules as switch..end, SMIE by default + ;; aligns it with "switch". + (`(:before . "case") (if (not (smie-rule-sibling-p)) octave-block-offset)) + (`(:after . ";") + (if (smie-rule-parent-p "function" "if" "while" "else" "elseif" "for" + "otherwise" "case" "try" "catch" "unwind_protect" + "unwind_protect_cleanup") + (smie-rule-parent octave-block-offset) + ;; For (invalid) code between switch and case. + ;; (if (smie-parent-p "switch") 4) + 0)))) + +(defvar electric-layout-rules) ;;;###autoload (define-derived-mode octave-mode prog-mode "Octave" @@ -562,14 +553,6 @@ Keybindings Variables you can use to customize Octave mode ============================================== -`octave-auto-indent' - Non-nil means indent current line after a semicolon or space. - Default is nil. - -`octave-auto-newline' - Non-nil means auto-insert a newline and indent after a semicolon. - Default is nil. - `octave-blink-matching-block' Non-nil means show matching begin of block when inserting a space, newline or semicolon after an else or end keyword. Default is t. @@ -619,36 +602,21 @@ already added. You just need to add a description of the problem, including a reproducible test case and send the message." (setq local-abbrev-table octave-abbrev-table) - (smie-setup octave-smie-op-levels octave-smie-indent-rules) + (smie-setup octave-smie-grammar #'octave-smie-rules + :forward-token #'octave-smie-forward-token + :backward-token #'octave-smie-backward-token) (set (make-local-variable 'smie-indent-basic) 'octave-block-offset) - (set (make-local-variable 'smie-backward-token-function) - 'octave-smie-backward-token) - (set (make-local-variable 'smie-forward-token-function) - 'octave-smie-forward-token) - (set (make-local-variable 'forward-sexp-function) - 'smie-forward-sexp-command) - (set (make-local-variable 'smie-closer-alist) octave-smie-closer-alist) - ;; Only needed for interactive calls to blink-matching-open. - (set (make-local-variable 'blink-matching-check-function) - #'smie-blink-matching-check) - - (when octave-blink-matching-block - (add-hook 'post-self-insert-hook #'smie-blink-matching-open 'append 'local) + (set (make-local-variable 'smie-blink-matching-triggers) - (append smie-blink-matching-triggers '(\;) - ;; Rather than wait for SPC or ; to blink, try to blink as - ;; soon as we type the last char of a block ender. - ;; But strip ?d from this list so that we don't blink twice - ;; when the user writes "endif" (once at "end" and another - ;; time at "endif"). - (delq ?d (delete-dups - (mapcar (lambda (kw) - (aref (cdr kw) (1- (length (cdr kw))))) - smie-closer-alist)))))) - - ;; FIXME: maybe we should use (cons ?\; electric-indent-chars) - ;; since only ; is really octave-specific. - (set (make-local-variable 'electric-indent-chars) '(?\; ?\s ?\n)) + (cons ?\; smie-blink-matching-triggers)) + (unless octave-blink-matching-block + (remove-hook 'post-self-insert-hook #'smie-blink-matching-open 'local)) + + (set (make-local-variable 'electric-indent-chars) + (cons ?\; electric-indent-chars)) + ;; IIUC matlab-mode takes the opposite approach: it makes RET insert + ;; a ";" at those places where it's correct (i.e. outside of parens). + (set (make-local-variable 'electric-layout-rules) '((?\; . after))) (set (make-local-variable 'comment-start) octave-comment-start) (set (make-local-variable 'comment-end) "") @@ -686,8 +654,7 @@ including a reproducible test case and send the message." 'octave-beginning-of-defun) (easy-menu-add octave-mode-menu) - (octave-initialize-completions) - (run-mode-hooks 'octave-mode-hook)) + (octave-initialize-completions)) (defvar info-lookup-mode) @@ -749,7 +716,7 @@ The new line is properly indented." (error "Cannot split a code line inside a string")) (t (insert (concat " " octave-continuation-string)) - (octave-reindent-then-newline-and-indent)))) + (reindent-then-newline-and-indent)))) (defun octave-indent-defun () "Properly indent the Octave function which contains point." @@ -842,7 +809,7 @@ The block marked is the one that contains point or follows point." (unless (or (looking-at "\\s(") (save-excursion (let* ((token (funcall smie-forward-token-function)) - (level (assoc token smie-op-levels))) + (level (assoc token smie-grammar))) (and level (null (cadr level)))))) (backward-up-list 1)) (mark-sexp)) @@ -1030,45 +997,6 @@ variables." (apply 'completion-in-region (octave-completion-at-point-function))) ;;; Electric characters && friends -(defun octave-reindent-then-newline-and-indent () - "Reindent current Octave line, insert newline, and indent the new line. -If Abbrev mode is on, expand abbrevs first." - ;; FIXME: None of this is Octave-specific. - (interactive) - (reindent-then-newline-and-indent)) - -(defun octave-electric-semi () - "Insert a semicolon in Octave mode. -Maybe expand abbrevs and blink matching block open keywords. -Reindent the line if `octave-auto-indent' is non-nil. -Insert a newline if `octave-auto-newline' is non-nil." - (interactive) - (setq last-command-event ?\;) - (if (not (octave-not-in-string-or-comment-p)) - (self-insert-command 1) - (if octave-auto-indent - (indent-according-to-mode)) - (self-insert-command 1) - (if octave-auto-newline - (newline-and-indent)))) - -(defun octave-electric-space () - "Insert a space in Octave mode. -Maybe expand abbrevs and blink matching block open keywords. -Reindent the line if `octave-auto-indent' is non-nil." - (interactive) - (setq last-command-event ? ) - (if (and octave-auto-indent - (not (octave-not-in-string-or-comment-p))) - (progn - (indent-according-to-mode) - (self-insert-command 1)) - (if (and octave-auto-indent - (save-excursion - (skip-syntax-backward " ") - (not (bolp)))) - (indent-according-to-mode)) - (self-insert-command 1))) (defun octave-abbrev-start () "Start entering an Octave abbreviation. @@ -1226,8 +1154,6 @@ code line." octave-maintainer-address (concat "Emacs version " emacs-version) (list - 'octave-auto-indent - 'octave-auto-newline 'octave-blink-matching-block 'octave-block-offset 'octave-comment-char @@ -1241,5 +1167,4 @@ code line." (provide 'octave-mod) -;; arch-tag: 05f1ce09-be87-4c00-803e-4919ffa26c23 ;;; octave-mod.el ends here