diff options
author | Stefan Monnier <monnier@iro.umontreal.ca> | 2013-05-24 15:37:55 -0400 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2013-05-24 15:37:55 -0400 |
commit | 650cff3d874e68a8aa80cbdb71ff9f48e10d1cb6 (patch) | |
tree | ccd37f50a1ca75b81b3c602937d8be1a71caa0b2 | |
parent | 9631677d730a314f55378f5da6734db521f8130d (diff) |
* lisp/emacs-lisp/smie.el (smie-auto-fill): Rework to be more robust.
(smie-setup): Use add-function to set it.
* lisp/progmodes/octave.el (octave-smie-rules): Return nil rather than
0 after a semi-colon; it works better for smie-auto-fill.
(octave--indent-new-comment-line): New function.
(octave-indent-new-comment-line): Use it (indirectly).
(octave-mode): Don't disable smie-auto-fill. Use add-function to
modify comment-line-break-function.
-rw-r--r-- | lisp/ChangeLog | 12 | ||||
-rw-r--r-- | lisp/emacs-lisp/smie.el | 113 | ||||
-rw-r--r-- | lisp/progmodes/octave.el | 14 | ||||
-rw-r--r-- | test/indent/octave.m | 30 |
4 files changed, 94 insertions, 75 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index a8d79f958d..2495620ef1 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,15 @@ +2013-05-24 Stefan Monnier <monnier@iro.umontreal.ca> + + * progmodes/octave.el (octave-smie-rules): Return nil rather than + 0 after a semi-colon; it works better for smie-auto-fill. + (octave--indent-new-comment-line): New function. + (octave-indent-new-comment-line): Use it (indirectly). + (octave-mode): Don't disable smie-auto-fill. Use add-function to + modify comment-line-break-function. + + * emacs-lisp/smie.el (smie-auto-fill): Rework to be more robust. + (smie-setup): Use add-function to set it. + 2013-05-24 Sam Steingold <sds@gnu.org> * sort.el (delete-duplicate-lines): Accept an optional `keep-blanks' diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el index cb93cdf8dc..9e338a0f4b 100644 --- a/lisp/emacs-lisp/smie.el +++ b/lisp/emacs-lisp/smie.el @@ -1735,37 +1735,45 @@ to which that point should be aligned, if we were to reindent it.") (save-excursion (indent-line-to indent)) (indent-line-to indent))))) -(defun smie-auto-fill () +(defun smie-auto-fill (do-auto-fill) (let ((fc (current-fill-column))) - (while (and fc (> (current-column) fc)) - (or (unless (or (nth 8 (save-excursion - (syntax-ppss (line-beginning-position)))) - (nth 8 (syntax-ppss))) - (save-excursion - (let ((end (point)) - (bsf (progn (beginning-of-line) + (when (and fc (> (current-column) fc)) + ;; The loop below presumes BOL is outside of strings or comments. Also, + ;; sometimes we prefer to fill the comment than the code around it. + (unless (or (nth 8 (save-excursion + (syntax-ppss (line-beginning-position)))) + (nth 4 (save-excursion + (move-to-column fc) + (syntax-ppss)))) + (while + (and (with-demoted-errors + (save-excursion + (let ((end (point)) + (bsf nil) ;Best-so-far. + (gain 0)) + (beginning-of-line) + (while (progn (smie-indent-forward-token) - (point))) - (gain 0) - curcol) - (while (and (<= (point) end) - (<= (setq curcol (current-column)) fc)) - ;; FIXME? `smie-indent-calculate' can (and often will) - ;; return a result that actually depends on the - ;; presence/absence of a newline, so the gain computed here - ;; may not be accurate, but in practice it seems to works - ;; well enough. - (let* ((newcol (smie-indent-calculate)) - (newgain (- curcol newcol))) - (when (> newgain gain) - (setq gain newgain) - (setq bsf (point)))) - (smie-indent-forward-token)) - (when (> gain 0) - (goto-char bsf) - (newline-and-indent) - 'done)))) - (do-auto-fill))))) + (and (<= (point) end) + (<= (current-column) fc))) + ;; FIXME? `smie-indent-calculate' can (and often + ;; does) return a result that actually depends on the + ;; presence/absence of a newline, so the gain computed + ;; here may not be accurate, but in practice it seems + ;; to work well enough. + (skip-chars-forward " \t") + (let* ((newcol (smie-indent-calculate)) + (newgain (- (current-column) newcol))) + (when (> newgain gain) + (setq gain newgain) + (setq bsf (point))))) + (when (> gain 0) + (goto-char bsf) + (newline-and-indent) + 'done)))) + (> (current-column) fc)))) + (when (> (current-column) fc) + (funcall do-auto-fill))))) (defun smie-setup (grammar rules-function &rest keywords) @@ -1775,12 +1783,11 @@ RULES-FUNCTION is a set of indentation rules for use on `smie-rules-function'. KEYWORDS are additional arguments, which can use the following keywords: - :forward-token FUN - :backward-token FUN" - (set (make-local-variable 'smie-rules-function) rules-function) - (set (make-local-variable 'smie-grammar) grammar) - (set (make-local-variable 'indent-line-function) 'smie-indent-line) - (set (make-local-variable 'normal-auto-fill-function) 'smie-auto-fill) - (set (make-local-variable 'forward-sexp-function) - 'smie-forward-sexp-command) + (setq-local smie-rules-function rules-function) + (setq-local smie-grammar grammar) + (setq-local indent-line-function #'smie-indent-line) + (add-function :around (local 'normal-auto-fill-function) #'smie-auto-fill) + (setq-local forward-sexp-function #'smie-forward-sexp-command) (while keywords (let ((k (pop keywords)) (v (pop keywords))) @@ -1792,30 +1799,26 @@ KEYWORDS are additional arguments, which can use the following keywords: (_ (message "smie-setup: ignoring unknown keyword %s" k))))) (let ((ca (cdr (assq :smie-closer-alist grammar)))) (when ca - (set (make-local-variable 'smie-closer-alist) ca) + (setq-local smie-closer-alist ca) ;; Only needed for interactive calls to blink-matching-open. - (set (make-local-variable 'blink-matching-check-function) - #'smie-blink-matching-check) + (setq-local blink-matching-check-function #'smie-blink-matching-check) (unless smie-highlight-matching-block-mode (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 to blink, try to blink as - ;; soon as we type the last char of a block ender. - (let ((closers (sort (mapcar #'cdr smie-closer-alist) - #'string-lessp)) - (triggers ()) - closer) - (while (setq closer (pop closers)) - (unless (and closers - ;; FIXME: this eliminates prefixes of other - ;; closers, but we should probably - ;; eliminate prefixes of other keywords - ;; as well. - (string-prefix-p closer (car closers))) - (push (aref closer (1- (length closer))) triggers))) - (delete-dups triggers))))))) + ;; Setup smie-blink-matching-triggers. Rather than wait for SPC to + ;; blink, try to blink as soon as we type the last char of a block ender. + (let ((closers (sort (mapcar #'cdr smie-closer-alist) #'string-lessp)) + (triggers ()) + closer) + (while (setq closer (pop closers)) + (unless + ;; FIXME: this eliminates prefixes of other closers, but we + ;; should probably eliminate prefixes of other keywords as well. + (and closers (string-prefix-p closer (car closers))) + (push (aref closer (1- (length closer))) triggers))) + (setq-local smie-blink-matching-triggers + (append smie-blink-matching-triggers + (delete-dups triggers))))))) (provide 'smie) diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el index 62bef6dfde..243e319858 100644 --- a/lisp/progmodes/octave.el +++ b/lisp/progmodes/octave.el @@ -438,7 +438,7 @@ Non-nil means always go to the next Octave code line after sending." (smie-rule-parent octave-block-offset) ;; For (invalid) code between switch and case. ;; (if (smie-parent-p "switch") 4) - 0)))) + nil)))) (defun octave-indent-comment () "A function for `smie-indent-functions' (which see)." @@ -552,11 +552,10 @@ definitions can also be stored in files and used in batch mode." (setq-local paragraph-ignore-fill-prefix t) (setq-local fill-paragraph-function 'octave-fill-paragraph) - ;; Use `smie-auto-fill' after fixing bug#14381. - (setq-local normal-auto-fill-function 'do-auto-fill) (setq-local fill-nobreak-predicate (lambda () (eq (octave-in-string-p) ?'))) - (setq-local comment-line-break-function #'octave-indent-new-comment-line) + (add-function :around (local 'comment-line-break-function) + #'octave--indent-new-comment-line) (setq font-lock-defaults '(octave-font-lock-keywords)) @@ -1112,11 +1111,16 @@ q: Don't fix\n" func file)) ;;; Indentation (defun octave-indent-new-comment-line (&optional soft) + ;; FIXME: C-M-j should probably be bound globally to a function like + ;; this one. "Break Octave line at point, continuing comment if within one. Insert `octave-continuation-string' before breaking the line unless inside a list. Signal an error if within a single-quoted string." (interactive) + (funcall comment-line-break-function soft)) + +(defun octave--indent-new-comment-line (orig &rest args) (cond ((octave-in-comment-p) nil) ((eq (octave-in-string-p) ?') @@ -1128,7 +1132,7 @@ string." (unless (and (cadr (syntax-ppss)) (eq (char-after (cadr (syntax-ppss))) ?\()) (insert " " octave-continuation-string)))) - (indent-new-comment-line soft) + (apply orig args) (indent-according-to-mode)) (define-obsolete-function-alias diff --git a/test/indent/octave.m b/test/indent/octave.m index bc7784f1ba..98be02acd7 100644 --- a/test/indent/octave.m +++ b/test/indent/octave.m @@ -1089,13 +1089,13 @@ function [pkg_idx_struct] = parse_pkg_idx (packdir) while (! feof (fid) || line != -1) if (! any (! isspace (line)) || line(1) == "#" || any (line == "=")) - ## Comments, blank lines or comments about unimplemented - ## functions: do nothing - ## FIXME: probably comments and pointers to external functions - ## could be treated better when printing to screen? + ## Comments, blank lines or comments about unimplemented + ## functions: do nothing + ## FIXME: probably comments and pointers to external functions + ## could be treated better when printing to screen? elseif (! isempty (strfind (line, ">>"))) - ## Skip package name and description as they are in DESCRIPTION - ## already. + ## Skip package name and description as they are in DESCRIPTION + ## already. elseif (! isspace (line(1))) ## Category. if (! isempty (pkg_idx_struct{cat_num}.functions)) @@ -1658,7 +1658,7 @@ function desc = get_description (filename) line = fgetl (fid); while (line != -1) if (line(1) == "#") - ## Comments, do nothing. + ## Comments, do nothing. elseif (isspace(line(1))) ## Continuation lines if (exist ("keyword", "var") && isfield (desc, keyword)) @@ -1752,9 +1752,9 @@ function deps_cell = fix_depends (depends) endif version = fix_version (parts{2}); - ## If no version is specified for the dependency - ## we say that the version should be greater than - ## or equal to "0.0.0". + ## If no version is specified for the dependency + ## we say that the version should be greater than + ## or equal to "0.0.0". else package = tolower (strip (dep)); operator = ">="; @@ -1859,7 +1859,7 @@ function bad_deps = get_unsatisfied_deps (desc, installed_pkgs_lst) if (! compare_versions (OCTAVE_VERSION, dep.version, dep.operator)) bad_deps{end+1} = dep; endif - ## Is the current dependency not Octave? + ## Is the current dependency not Octave? else ok = false; for i = 1:length (installed_pkgs_lst) @@ -2025,7 +2025,7 @@ function load_packages (files, handle_deps, local_list, global_list) ## Load all. if (length (files) == 1 && strcmp (files{1}, "all")) idx = [1:length(installed_pkgs_lst)]; - ## Load auto. + ## Load auto. elseif (length (files) == 1 && strcmp (files{1}, "auto")) idx = []; for i = 1:length (installed_pkgs_lst) @@ -2033,7 +2033,7 @@ function load_packages (files, handle_deps, local_list, global_list) idx (end + 1) = i; endif endfor - ## Load package_name1 ... + ## Load package_name1 ... else idx = []; for i = 1:length (files) @@ -2100,8 +2100,8 @@ function unload_packages (files, handle_deps, local_list, global_list) idx = strcmp (p, d); if (any (idx)) rmpath (d); - ## FIXME: We should also check if we need to remove items from - ## EXEC_PATH. + ## FIXME: We should also check if we need to remove items from + ## EXEC_PATH. endif endfor endfunction |