diff options
| author | Stefan Monnier | 2013-05-24 15:37:55 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2013-05-24 15:37:55 -0400 |
| commit | 650cff3d874e68a8aa80cbdb71ff9f48e10d1cb6 (patch) | |
| tree | ccd37f50a1ca75b81b3c602937d8be1a71caa0b2 | |
| parent | 9631677d730a314f55378f5da6734db521f8130d (diff) | |
| download | emacs-650cff3d874e68a8aa80cbdb71ff9f48e10d1cb6.tar.gz emacs-650cff3d874e68a8aa80cbdb71ff9f48e10d1cb6.zip | |
* 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 a8d79f958d3..2495620ef1c 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2013-05-24 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * progmodes/octave.el (octave-smie-rules): Return nil rather than | ||
| 4 | 0 after a semi-colon; it works better for smie-auto-fill. | ||
| 5 | (octave--indent-new-comment-line): New function. | ||
| 6 | (octave-indent-new-comment-line): Use it (indirectly). | ||
| 7 | (octave-mode): Don't disable smie-auto-fill. Use add-function to | ||
| 8 | modify comment-line-break-function. | ||
| 9 | |||
| 10 | * emacs-lisp/smie.el (smie-auto-fill): Rework to be more robust. | ||
| 11 | (smie-setup): Use add-function to set it. | ||
| 12 | |||
| 1 | 2013-05-24 Sam Steingold <sds@gnu.org> | 13 | 2013-05-24 Sam Steingold <sds@gnu.org> |
| 2 | 14 | ||
| 3 | * sort.el (delete-duplicate-lines): Accept an optional `keep-blanks' | 15 | * 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 cb93cdf8dc6..9e338a0f4be 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.") | |||
| 1735 | (save-excursion (indent-line-to indent)) | 1735 | (save-excursion (indent-line-to indent)) |
| 1736 | (indent-line-to indent))))) | 1736 | (indent-line-to indent))))) |
| 1737 | 1737 | ||
| 1738 | (defun smie-auto-fill () | 1738 | (defun smie-auto-fill (do-auto-fill) |
| 1739 | (let ((fc (current-fill-column))) | 1739 | (let ((fc (current-fill-column))) |
| 1740 | (while (and fc (> (current-column) fc)) | 1740 | (when (and fc (> (current-column) fc)) |
| 1741 | (or (unless (or (nth 8 (save-excursion | 1741 | ;; The loop below presumes BOL is outside of strings or comments. Also, |
| 1742 | (syntax-ppss (line-beginning-position)))) | 1742 | ;; sometimes we prefer to fill the comment than the code around it. |
| 1743 | (nth 8 (syntax-ppss))) | 1743 | (unless (or (nth 8 (save-excursion |
| 1744 | (save-excursion | 1744 | (syntax-ppss (line-beginning-position)))) |
| 1745 | (let ((end (point)) | 1745 | (nth 4 (save-excursion |
| 1746 | (bsf (progn (beginning-of-line) | 1746 | (move-to-column fc) |
| 1747 | (syntax-ppss)))) | ||
| 1748 | (while | ||
| 1749 | (and (with-demoted-errors | ||
| 1750 | (save-excursion | ||
| 1751 | (let ((end (point)) | ||
| 1752 | (bsf nil) ;Best-so-far. | ||
| 1753 | (gain 0)) | ||
| 1754 | (beginning-of-line) | ||
| 1755 | (while (progn | ||
| 1747 | (smie-indent-forward-token) | 1756 | (smie-indent-forward-token) |
| 1748 | (point))) | 1757 | (and (<= (point) end) |
| 1749 | (gain 0) | 1758 | (<= (current-column) fc))) |
| 1750 | curcol) | 1759 | ;; FIXME? `smie-indent-calculate' can (and often |
| 1751 | (while (and (<= (point) end) | 1760 | ;; does) return a result that actually depends on the |
| 1752 | (<= (setq curcol (current-column)) fc)) | 1761 | ;; presence/absence of a newline, so the gain computed |
| 1753 | ;; FIXME? `smie-indent-calculate' can (and often will) | 1762 | ;; here may not be accurate, but in practice it seems |
| 1754 | ;; return a result that actually depends on the | 1763 | ;; to work well enough. |
| 1755 | ;; presence/absence of a newline, so the gain computed here | 1764 | (skip-chars-forward " \t") |
| 1756 | ;; may not be accurate, but in practice it seems to works | 1765 | (let* ((newcol (smie-indent-calculate)) |
| 1757 | ;; well enough. | 1766 | (newgain (- (current-column) newcol))) |
| 1758 | (let* ((newcol (smie-indent-calculate)) | 1767 | (when (> newgain gain) |
| 1759 | (newgain (- curcol newcol))) | 1768 | (setq gain newgain) |
| 1760 | (when (> newgain gain) | 1769 | (setq bsf (point))))) |
| 1761 | (setq gain newgain) | 1770 | (when (> gain 0) |
| 1762 | (setq bsf (point)))) | 1771 | (goto-char bsf) |
| 1763 | (smie-indent-forward-token)) | 1772 | (newline-and-indent) |
| 1764 | (when (> gain 0) | 1773 | 'done)))) |
| 1765 | (goto-char bsf) | 1774 | (> (current-column) fc)))) |
| 1766 | (newline-and-indent) | 1775 | (when (> (current-column) fc) |
| 1767 | 'done)))) | 1776 | (funcall do-auto-fill))))) |
| 1768 | (do-auto-fill))))) | ||
| 1769 | 1777 | ||
| 1770 | 1778 | ||
| 1771 | (defun smie-setup (grammar rules-function &rest keywords) | 1779 | (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'. | |||
| 1775 | KEYWORDS are additional arguments, which can use the following keywords: | 1783 | KEYWORDS are additional arguments, which can use the following keywords: |
| 1776 | - :forward-token FUN | 1784 | - :forward-token FUN |
| 1777 | - :backward-token FUN" | 1785 | - :backward-token FUN" |
| 1778 | (set (make-local-variable 'smie-rules-function) rules-function) | 1786 | (setq-local smie-rules-function rules-function) |
| 1779 | (set (make-local-variable 'smie-grammar) grammar) | 1787 | (setq-local smie-grammar grammar) |
| 1780 | (set (make-local-variable 'indent-line-function) 'smie-indent-line) | 1788 | (setq-local indent-line-function #'smie-indent-line) |
| 1781 | (set (make-local-variable 'normal-auto-fill-function) 'smie-auto-fill) | 1789 | (add-function :around (local 'normal-auto-fill-function) #'smie-auto-fill) |
| 1782 | (set (make-local-variable 'forward-sexp-function) | 1790 | (setq-local forward-sexp-function #'smie-forward-sexp-command) |
| 1783 | 'smie-forward-sexp-command) | ||
| 1784 | (while keywords | 1791 | (while keywords |
| 1785 | (let ((k (pop keywords)) | 1792 | (let ((k (pop keywords)) |
| 1786 | (v (pop keywords))) | 1793 | (v (pop keywords))) |
| @@ -1792,30 +1799,26 @@ KEYWORDS are additional arguments, which can use the following keywords: | |||
| 1792 | (_ (message "smie-setup: ignoring unknown keyword %s" k))))) | 1799 | (_ (message "smie-setup: ignoring unknown keyword %s" k))))) |
| 1793 | (let ((ca (cdr (assq :smie-closer-alist grammar)))) | 1800 | (let ((ca (cdr (assq :smie-closer-alist grammar)))) |
| 1794 | (when ca | 1801 | (when ca |
| 1795 | (set (make-local-variable 'smie-closer-alist) ca) | 1802 | (setq-local smie-closer-alist ca) |
| 1796 | ;; Only needed for interactive calls to blink-matching-open. | 1803 | ;; Only needed for interactive calls to blink-matching-open. |
| 1797 | (set (make-local-variable 'blink-matching-check-function) | 1804 | (setq-local blink-matching-check-function #'smie-blink-matching-check) |
| 1798 | #'smie-blink-matching-check) | ||
| 1799 | (unless smie-highlight-matching-block-mode | 1805 | (unless smie-highlight-matching-block-mode |
| 1800 | (add-hook 'post-self-insert-hook | 1806 | (add-hook 'post-self-insert-hook |
| 1801 | #'smie-blink-matching-open 'append 'local)) | 1807 | #'smie-blink-matching-open 'append 'local)) |
| 1802 | (set (make-local-variable 'smie-blink-matching-triggers) | 1808 | ;; Setup smie-blink-matching-triggers. Rather than wait for SPC to |
| 1803 | (append smie-blink-matching-triggers | 1809 | ;; blink, try to blink as soon as we type the last char of a block ender. |
| 1804 | ;; Rather than wait for SPC to blink, try to blink as | 1810 | (let ((closers (sort (mapcar #'cdr smie-closer-alist) #'string-lessp)) |
| 1805 | ;; soon as we type the last char of a block ender. | 1811 | (triggers ()) |
| 1806 | (let ((closers (sort (mapcar #'cdr smie-closer-alist) | 1812 | closer) |
| 1807 | #'string-lessp)) | 1813 | (while (setq closer (pop closers)) |
| 1808 | (triggers ()) | 1814 | (unless |
| 1809 | closer) | 1815 | ;; FIXME: this eliminates prefixes of other closers, but we |
| 1810 | (while (setq closer (pop closers)) | 1816 | ;; should probably eliminate prefixes of other keywords as well. |
| 1811 | (unless (and closers | 1817 | (and closers (string-prefix-p closer (car closers))) |
| 1812 | ;; FIXME: this eliminates prefixes of other | 1818 | (push (aref closer (1- (length closer))) triggers))) |
| 1813 | ;; closers, but we should probably | 1819 | (setq-local smie-blink-matching-triggers |
| 1814 | ;; eliminate prefixes of other keywords | 1820 | (append smie-blink-matching-triggers |
| 1815 | ;; as well. | 1821 | (delete-dups triggers))))))) |
| 1816 | (string-prefix-p closer (car closers))) | ||
| 1817 | (push (aref closer (1- (length closer))) triggers))) | ||
| 1818 | (delete-dups triggers))))))) | ||
| 1819 | 1822 | ||
| 1820 | 1823 | ||
| 1821 | (provide 'smie) | 1824 | (provide 'smie) |
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el index 62bef6dfdea..243e3198584 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." | |||
| 438 | (smie-rule-parent octave-block-offset) | 438 | (smie-rule-parent octave-block-offset) |
| 439 | ;; For (invalid) code between switch and case. | 439 | ;; For (invalid) code between switch and case. |
| 440 | ;; (if (smie-parent-p "switch") 4) | 440 | ;; (if (smie-parent-p "switch") 4) |
| 441 | 0)))) | 441 | nil)))) |
| 442 | 442 | ||
| 443 | (defun octave-indent-comment () | 443 | (defun octave-indent-comment () |
| 444 | "A function for `smie-indent-functions' (which see)." | 444 | "A function for `smie-indent-functions' (which see)." |
| @@ -552,11 +552,10 @@ definitions can also be stored in files and used in batch mode." | |||
| 552 | (setq-local paragraph-ignore-fill-prefix t) | 552 | (setq-local paragraph-ignore-fill-prefix t) |
| 553 | (setq-local fill-paragraph-function 'octave-fill-paragraph) | 553 | (setq-local fill-paragraph-function 'octave-fill-paragraph) |
| 554 | 554 | ||
| 555 | ;; Use `smie-auto-fill' after fixing bug#14381. | ||
| 556 | (setq-local normal-auto-fill-function 'do-auto-fill) | ||
| 557 | (setq-local fill-nobreak-predicate | 555 | (setq-local fill-nobreak-predicate |
| 558 | (lambda () (eq (octave-in-string-p) ?'))) | 556 | (lambda () (eq (octave-in-string-p) ?'))) |
| 559 | (setq-local comment-line-break-function #'octave-indent-new-comment-line) | 557 | (add-function :around (local 'comment-line-break-function) |
| 558 | #'octave--indent-new-comment-line) | ||
| 560 | 559 | ||
| 561 | (setq font-lock-defaults '(octave-font-lock-keywords)) | 560 | (setq font-lock-defaults '(octave-font-lock-keywords)) |
| 562 | 561 | ||
| @@ -1112,11 +1111,16 @@ q: Don't fix\n" func file)) | |||
| 1112 | ;;; Indentation | 1111 | ;;; Indentation |
| 1113 | 1112 | ||
| 1114 | (defun octave-indent-new-comment-line (&optional soft) | 1113 | (defun octave-indent-new-comment-line (&optional soft) |
| 1114 | ;; FIXME: C-M-j should probably be bound globally to a function like | ||
| 1115 | ;; this one. | ||
| 1115 | "Break Octave line at point, continuing comment if within one. | 1116 | "Break Octave line at point, continuing comment if within one. |
| 1116 | Insert `octave-continuation-string' before breaking the line | 1117 | Insert `octave-continuation-string' before breaking the line |
| 1117 | unless inside a list. Signal an error if within a single-quoted | 1118 | unless inside a list. Signal an error if within a single-quoted |
| 1118 | string." | 1119 | string." |
| 1119 | (interactive) | 1120 | (interactive) |
| 1121 | (funcall comment-line-break-function soft)) | ||
| 1122 | |||
| 1123 | (defun octave--indent-new-comment-line (orig &rest args) | ||
| 1120 | (cond | 1124 | (cond |
| 1121 | ((octave-in-comment-p) nil) | 1125 | ((octave-in-comment-p) nil) |
| 1122 | ((eq (octave-in-string-p) ?') | 1126 | ((eq (octave-in-string-p) ?') |
| @@ -1128,7 +1132,7 @@ string." | |||
| 1128 | (unless (and (cadr (syntax-ppss)) | 1132 | (unless (and (cadr (syntax-ppss)) |
| 1129 | (eq (char-after (cadr (syntax-ppss))) ?\()) | 1133 | (eq (char-after (cadr (syntax-ppss))) ?\()) |
| 1130 | (insert " " octave-continuation-string)))) | 1134 | (insert " " octave-continuation-string)))) |
| 1131 | (indent-new-comment-line soft) | 1135 | (apply orig args) |
| 1132 | (indent-according-to-mode)) | 1136 | (indent-according-to-mode)) |
| 1133 | 1137 | ||
| 1134 | (define-obsolete-function-alias | 1138 | (define-obsolete-function-alias |
diff --git a/test/indent/octave.m b/test/indent/octave.m index bc7784f1ba2..98be02acd74 100644 --- a/test/indent/octave.m +++ b/test/indent/octave.m | |||
| @@ -1089,13 +1089,13 @@ function [pkg_idx_struct] = parse_pkg_idx (packdir) | |||
| 1089 | 1089 | ||
| 1090 | while (! feof (fid) || line != -1) | 1090 | while (! feof (fid) || line != -1) |
| 1091 | if (! any (! isspace (line)) || line(1) == "#" || any (line == "=")) | 1091 | if (! any (! isspace (line)) || line(1) == "#" || any (line == "=")) |
| 1092 | ## Comments, blank lines or comments about unimplemented | 1092 | ## Comments, blank lines or comments about unimplemented |
| 1093 | ## functions: do nothing | 1093 | ## functions: do nothing |
| 1094 | ## FIXME: probably comments and pointers to external functions | 1094 | ## FIXME: probably comments and pointers to external functions |
| 1095 | ## could be treated better when printing to screen? | 1095 | ## could be treated better when printing to screen? |
| 1096 | elseif (! isempty (strfind (line, ">>"))) | 1096 | elseif (! isempty (strfind (line, ">>"))) |
| 1097 | ## Skip package name and description as they are in DESCRIPTION | 1097 | ## Skip package name and description as they are in DESCRIPTION |
| 1098 | ## already. | 1098 | ## already. |
| 1099 | elseif (! isspace (line(1))) | 1099 | elseif (! isspace (line(1))) |
| 1100 | ## Category. | 1100 | ## Category. |
| 1101 | if (! isempty (pkg_idx_struct{cat_num}.functions)) | 1101 | if (! isempty (pkg_idx_struct{cat_num}.functions)) |
| @@ -1658,7 +1658,7 @@ function desc = get_description (filename) | |||
| 1658 | line = fgetl (fid); | 1658 | line = fgetl (fid); |
| 1659 | while (line != -1) | 1659 | while (line != -1) |
| 1660 | if (line(1) == "#") | 1660 | if (line(1) == "#") |
| 1661 | ## Comments, do nothing. | 1661 | ## Comments, do nothing. |
| 1662 | elseif (isspace(line(1))) | 1662 | elseif (isspace(line(1))) |
| 1663 | ## Continuation lines | 1663 | ## Continuation lines |
| 1664 | if (exist ("keyword", "var") && isfield (desc, keyword)) | 1664 | if (exist ("keyword", "var") && isfield (desc, keyword)) |
| @@ -1752,9 +1752,9 @@ function deps_cell = fix_depends (depends) | |||
| 1752 | endif | 1752 | endif |
| 1753 | version = fix_version (parts{2}); | 1753 | version = fix_version (parts{2}); |
| 1754 | 1754 | ||
| 1755 | ## If no version is specified for the dependency | 1755 | ## If no version is specified for the dependency |
| 1756 | ## we say that the version should be greater than | 1756 | ## we say that the version should be greater than |
| 1757 | ## or equal to "0.0.0". | 1757 | ## or equal to "0.0.0". |
| 1758 | else | 1758 | else |
| 1759 | package = tolower (strip (dep)); | 1759 | package = tolower (strip (dep)); |
| 1760 | operator = ">="; | 1760 | operator = ">="; |
| @@ -1859,7 +1859,7 @@ function bad_deps = get_unsatisfied_deps (desc, installed_pkgs_lst) | |||
| 1859 | if (! compare_versions (OCTAVE_VERSION, dep.version, dep.operator)) | 1859 | if (! compare_versions (OCTAVE_VERSION, dep.version, dep.operator)) |
| 1860 | bad_deps{end+1} = dep; | 1860 | bad_deps{end+1} = dep; |
| 1861 | endif | 1861 | endif |
| 1862 | ## Is the current dependency not Octave? | 1862 | ## Is the current dependency not Octave? |
| 1863 | else | 1863 | else |
| 1864 | ok = false; | 1864 | ok = false; |
| 1865 | for i = 1:length (installed_pkgs_lst) | 1865 | for i = 1:length (installed_pkgs_lst) |
| @@ -2025,7 +2025,7 @@ function load_packages (files, handle_deps, local_list, global_list) | |||
| 2025 | ## Load all. | 2025 | ## Load all. |
| 2026 | if (length (files) == 1 && strcmp (files{1}, "all")) | 2026 | if (length (files) == 1 && strcmp (files{1}, "all")) |
| 2027 | idx = [1:length(installed_pkgs_lst)]; | 2027 | idx = [1:length(installed_pkgs_lst)]; |
| 2028 | ## Load auto. | 2028 | ## Load auto. |
| 2029 | elseif (length (files) == 1 && strcmp (files{1}, "auto")) | 2029 | elseif (length (files) == 1 && strcmp (files{1}, "auto")) |
| 2030 | idx = []; | 2030 | idx = []; |
| 2031 | for i = 1:length (installed_pkgs_lst) | 2031 | for i = 1:length (installed_pkgs_lst) |
| @@ -2033,7 +2033,7 @@ function load_packages (files, handle_deps, local_list, global_list) | |||
| 2033 | idx (end + 1) = i; | 2033 | idx (end + 1) = i; |
| 2034 | endif | 2034 | endif |
| 2035 | endfor | 2035 | endfor |
| 2036 | ## Load package_name1 ... | 2036 | ## Load package_name1 ... |
| 2037 | else | 2037 | else |
| 2038 | idx = []; | 2038 | idx = []; |
| 2039 | for i = 1:length (files) | 2039 | for i = 1:length (files) |
| @@ -2100,8 +2100,8 @@ function unload_packages (files, handle_deps, local_list, global_list) | |||
| 2100 | idx = strcmp (p, d); | 2100 | idx = strcmp (p, d); |
| 2101 | if (any (idx)) | 2101 | if (any (idx)) |
| 2102 | rmpath (d); | 2102 | rmpath (d); |
| 2103 | ## FIXME: We should also check if we need to remove items from | 2103 | ## FIXME: We should also check if we need to remove items from |
| 2104 | ## EXEC_PATH. | 2104 | ## EXEC_PATH. |
| 2105 | endif | 2105 | endif |
| 2106 | endfor | 2106 | endfor |
| 2107 | endfunction | 2107 | endfunction |