summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2013-05-24 15:37:55 -0400
committerStefan Monnier <monnier@iro.umontreal.ca>2013-05-24 15:37:55 -0400
commit650cff3d874e68a8aa80cbdb71ff9f48e10d1cb6 (patch)
treeccd37f50a1ca75b81b3c602937d8be1a71caa0b2
parent9631677d730a314f55378f5da6734db521f8130d (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/ChangeLog12
-rw-r--r--lisp/emacs-lisp/smie.el113
-rw-r--r--lisp/progmodes/octave.el14
-rw-r--r--test/indent/octave.m30
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