aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Gutov2017-12-14 11:18:51 +0200
committerDmitry Gutov2017-12-14 11:18:51 +0200
commit7e9eef0ffd90cd7e39f15b003e4a9770be27b0ce (patch)
tree65c46eac3785849457ba9d989ed4acf19b3e8fac
parent6067f0c702e3652a9d489852752f038320cb91ae (diff)
downloademacs-7e9eef0ffd90cd7e39f15b003e4a9770be27b0ce.tar.gz
emacs-7e9eef0ffd90cd7e39f15b003e4a9770be27b0ce.zip
Consolidate 'widen' calls
* lisp/progmodes/prog-mode.el (prog-indentation-context): Un-document all elements but the first. (prog-widen): Remove. (http://lists.gnu.org/archive/html/emacs-devel/2017-12/msg00321.html) * doc/lispref/text.texi (Mode-Specific Indent): Update. * lisp/progmodes/ruby-mode.el (ruby-calculate-indent): Don't call widen. * lisp/progmodes/python.el (python-indent-guess-indent-offset) (python-info-current-defun): Replace prog-widen with widen; these functions are not called during indentation. (python-indent-context) (python-indent--calculate-indentation) (python-info-dedenter-opening-block-message) (python-info-line-ends-backslash-p) (python-info-beginning-of-backslash) (python-info-continuation-line-p) (python-info-current-defun): Remove 'widen' calls. * lisp/indent.el (indent-according-to-mode) (indent-for-tab-command, indent-region): Move them here. * lisp/textmodes/mhtml-mode.el (mhtml-indent-line): Bind prog-indentation-context to one-element list.
-rw-r--r--doc/lispref/text.texi54
-rw-r--r--etc/NEWS10
-rw-r--r--lisp/indent.el12
-rw-r--r--lisp/progmodes/prog-mode.el47
-rw-r--r--lisp/progmodes/python.el32
-rw-r--r--lisp/progmodes/ruby-mode.el1
-rw-r--r--lisp/textmodes/mhtml-mode.el4
7 files changed, 35 insertions, 125 deletions
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index 1e19f75d682..67a303a5994 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -2396,57 +2396,31 @@ text at point (@pxref{Completion in Buffers}).
2396syntax belongs to a different major mode. Examples include 2396syntax belongs to a different major mode. Examples include
2397@dfn{literate programming} source files that combine documentation and 2397@dfn{literate programming} source files that combine documentation and
2398snippets of source code, Yacc/Bison programs that include snippets of 2398snippets of source code, Yacc/Bison programs that include snippets of
2399plain C code, etc. To correctly indent the embedded chunks, the major 2399plain C code, etc. To correctly indent the embedded chunks, the primary
2400mode needs to delegate the indentation to another mode's indentation 2400mode needs to delegate the indentation to another mode's indentation
2401engine (e.g., call @code{c-indent-defun} for C code or 2401engine (e.g., call @code{c-indent-defun} for C code or
2402@code{python-indent-line} for Python), while providing it with some 2402@code{python-indent-line} for Python), while providing it with some
2403context to guide the indentation. The following facilities support 2403context to guide the indentation. Major modes, for their part, should
2404such multi-mode indentation. 2404avoid calling @code{widen} in their indentation code and obey
2405@code{prog-first-column}.
2405 2406
2406@defvar prog-indentation-context 2407@defvar prog-indentation-context
2407This variable, when non-@code{nil}, holds the indentation context for 2408This variable, when non-@code{nil}, holds the indentation context for
2408the sub-mode's indentation engine provided by the superior major mode. 2409the sub-mode's indentation engine provided by the superior major mode.
2409The value should be a list of the form @code{(@var{first-column} 2410The value should be a list of the form @code{(@var{first-column} . @var{rest}}.
2410@w{(@var{start} . @var{end})} @code{prev-chunk})}. The members of the 2411The members of the list have the following meaning:
2411list have the following meaning:
2412 2412
2413@table @var 2413@table @var
2414@item first-column 2414@item first-column
2415The column to be used for top-level constructs. This replaces the 2415The column to be used for top-level constructs. This replaces the
2416default value of the top-level column used by the sub-mode, usually 2416default value of the top-level column used by the sub-mode, usually
2417zero. 2417zero.
2418@item start 2418@item rest
2419@itemx end 2419This value is currently unused.
2420The region of the code chunk to be indented by the sub-mode. The
2421value of @var{end} can be @code{nil}, which stands for the value of
2422@code{point-max}.
2423@item prev-chunk
2424If this is non-@code{nil}, it should provide the sub-mode's
2425indentation engine with a virtual context of the code chunk. Valid
2426values include:
2427
2428@itemize @minus
2429@item
2430A string whose contents is the text the sub-mode's indentation engine
2431should consider to precede the code chunk. The sub-mode's indentation
2432engine can add text properties to that string, to be reused in
2433repeated calls with the same string, thus using it as a cache. An
2434example where this is useful is code chunks that need to be indented
2435as function bodies, but lack the function's preamble---the string
2436could then include that missing preamble.
2437@item
2438A function. It is expected to be called with the start position of
2439the current chunk, and should return a cons cell
2440@w{@code{(@var{prev-start} . @var{prev-end})}} that specifies the
2441region of the previous code chunk, or @code{nil} if there is no previous
2442chunk. This is useful in literate-programming sources, where code is
2443split into chunks, and correct indentation needs to access previous
2444chunks.
2445@end itemize
2446@end table 2420@end table
2447@end defvar 2421@end defvar
2448 2422
2449The following convenience functions should be used by major mode's 2423The following convenience function should be used by major mode's
2450indentation engine in support of invocations as sub-modes of another 2424indentation engine in support of invocations as sub-modes of another
2451major mode. 2425major mode.
2452 2426
@@ -2457,16 +2431,6 @@ function's value is the column number to use for top-level constructs.
2457When no superior mode is in effect, this function returns zero. 2431When no superior mode is in effect, this function returns zero.
2458@end defun 2432@end defun
2459 2433
2460@defun prog-widen
2461Call this function instead of @code{widen} to remove any restrictions
2462imposed by the mode's indentation engine and restore the restrictions
2463recorded in @code{prog-indentation-context}. This prevents the
2464indentation engine of a sub-mode from inadvertently operating on text
2465outside of the chunk it was supposed to indent, and preserves the
2466restriction imposed by the superior mode. When no superior mode is in
2467effect, this function just calls @code{widen}.
2468@end defun
2469
2470 2434
2471@node Region Indent 2435@node Region Indent
2472@subsection Indenting an Entire Region 2436@subsection Indenting an Entire Region
diff --git a/etc/NEWS b/etc/NEWS
index 4ccf468693c..eb076c943bc 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1107,11 +1107,11 @@ This allows better indentation support in modes that support multiple
1107programming languages in the same buffer, like literate programming 1107programming languages in the same buffer, like literate programming
1108environments or ANTLR programs with embedded Python code. 1108environments or ANTLR programs with embedded Python code.
1109 1109
1110A major mode can provide indentation context for a sub-mode through 1110A major mode can provide indentation context for a sub-mode. To
1111the 'prog-indentation-context' variable. To support this, modes that 1111support this, modes should use 'prog-first-column' instead of a
1112provide indentation should use 'prog-widen' instead of 'widen' and 1112literal zero and never call 'widen' in their indentation functions.
1113'prog-first-column' instead of a literal zero. See the node 1113See the node "(elisp) Mode-Specific Indent" in the ELisp manual for
1114"(elisp) Mode-Specific Indent" in the ELisp manual for more details. 1114more details.
1115 1115
1116** ERC 1116** ERC
1117 1117
diff --git a/lisp/indent.el b/lisp/indent.el
index d5ba0bd8491..ccf0e99c08b 100644
--- a/lisp/indent.el
+++ b/lisp/indent.el
@@ -69,6 +69,8 @@ variable is `indent-relative' or `indent-relative-maybe', handle
69it specially (since those functions are used for tabbing); in 69it specially (since those functions are used for tabbing); in
70that case, indent by aligning to the previous non-blank line." 70that case, indent by aligning to the previous non-blank line."
71 (interactive) 71 (interactive)
72 (save-restriction
73 (widen)
72 (syntax-propertize (line-end-position)) 74 (syntax-propertize (line-end-position))
73 (if (memq indent-line-function 75 (if (memq indent-line-function
74 '(indent-relative indent-relative-maybe)) 76 '(indent-relative indent-relative-maybe))
@@ -84,7 +86,7 @@ that case, indent by aligning to the previous non-blank line."
84 (indent-line-to column) 86 (indent-line-to column)
85 (save-excursion (indent-line-to column)))) 87 (save-excursion (indent-line-to column))))
86 ;; The normal case. 88 ;; The normal case.
87 (funcall indent-line-function))) 89 (funcall indent-line-function))))
88 90
89(defun indent--default-inside-comment () 91(defun indent--default-inside-comment ()
90 (unless (or (> (current-column) (current-indentation)) 92 (unless (or (> (current-column) (current-indentation))
@@ -144,7 +146,9 @@ prefix argument is ignored."
144 (indent--default-inside-comment) 146 (indent--default-inside-comment)
145 (when (or (<= (current-column) (current-indentation)) 147 (when (or (<= (current-column) (current-indentation))
146 (not (eq tab-always-indent 'complete))) 148 (not (eq tab-always-indent 'complete)))
147 (funcall (default-value 'indent-line-function)))) 149 (save-restriction
150 (widen)
151 (funcall (default-value 'indent-line-function)))))
148 152
149 (cond 153 (cond
150 ;; If the text was already indented right, try completion. 154 ;; If the text was already indented right, try completion.
@@ -538,7 +542,9 @@ column to indent to; if it is nil, use one of the three methods above."
538 (forward-line 1))))) 542 (forward-line 1)))))
539 ;; Use indent-region-function is available. 543 ;; Use indent-region-function is available.
540 (indent-region-function 544 (indent-region-function
541 (funcall indent-region-function start end)) 545 (save-restriction
546 (widen)
547 (funcall indent-region-function start end)))
542 ;; Else, use a default implementation that calls indent-line-function on 548 ;; Else, use a default implementation that calls indent-line-function on
543 ;; each line. 549 ;; each line.
544 (t (indent-region-line-by-line start end))) 550 (t (indent-region-line-by-line start end)))
diff --git a/lisp/progmodes/prog-mode.el b/lisp/progmodes/prog-mode.el
index f727e458b2b..4efe443fba8 100644
--- a/lisp/progmodes/prog-mode.el
+++ b/lisp/progmodes/prog-mode.el
@@ -54,7 +54,7 @@
54 54
55There are languages where part of the code is actually written in 55There are languages where part of the code is actually written in
56a sub language, e.g., a Yacc/Bison or ANTLR grammar also consists 56a sub language, e.g., a Yacc/Bison or ANTLR grammar also consists
57of plain C code. This variable enables the major mode of the 57of plain C code. This variable enables the primary mode of the
58main language to use the indentation engine of the sub-mode for 58main language to use the indentation engine of the sub-mode for
59lines in code chunks written in the sub-mode's language. 59lines in code chunks written in the sub-mode's language.
60 60
@@ -64,37 +64,13 @@ mode, it should bind this variable to non-nil around the call.
64 64
65The non-nil value should be a list of the form: 65The non-nil value should be a list of the form:
66 66
67 (FIRST-COLUMN (START . END) PREVIOUS-CHUNKS) 67 (FIRST-COLUMN . REST)
68 68
69FIRST-COLUMN is the column the indentation engine of the sub-mode 69FIRST-COLUMN is the column the indentation engine of the sub-mode
70should use for top-level language constructs inside the code 70should use for top-level language constructs inside the code
71chunk (instead of 0). 71chunk (instead of 0).
72 72
73START and END specify the region of the code chunk. END can be 73REST is currently unused.")
74nil, which stands for the value of `point-max'. The function
75`prog-widen' uses this to restore restrictions imposed by the
76sub-mode's indentation engine.
77
78PREVIOUS-CHUNKS, if non-nil, provides the indentation engine of
79the sub-mode with the virtual context of the code chunk. Valid
80values are:
81
82 - A string containing text which the indentation engine can
83 consider as standing in front of the code chunk. To cache the
84 string's calculated syntactic information for repeated calls
85 with the same string, the sub-mode can add text-properties to
86 the string.
87
88 A typical use case is for grammars with code chunks which are
89 to be indented like function bodies -- the string would contain
90 the corresponding function preamble.
91
92 - A function, to be called with the start position of the current
93 chunk. It should return either the region of the previous chunk
94 as (PREV-START . PREV-END), or nil if there is no previous chunk.
95
96 A typical use case are literate programming sources -- the
97 function would successively return the previous code chunks.")
98 74
99(defun prog-indent-sexp (&optional defun) 75(defun prog-indent-sexp (&optional defun)
100 "Indent the expression after point. 76 "Indent the expression after point.
@@ -113,23 +89,6 @@ instead."
113 "Return the indentation column normally used for top-level constructs." 89 "Return the indentation column normally used for top-level constructs."
114 (or (car prog-indentation-context) 0)) 90 (or (car prog-indentation-context) 0))
115 91
116(defun prog-widen ()
117 "Remove restrictions (narrowing) from current code chunk or buffer.
118This function should be used instead of `widen' in any function used
119by the indentation engine to make it respect the value of
120`prog-indentation-context'.
121
122This function (like `widen') is useful inside a
123`save-restriction' to make the indentation correctly work when
124narrowing is in effect."
125 (let ((chunk (cadr prog-indentation-context)))
126 (if chunk
127 ;; No call to `widen' is necessary here, as narrow-to-region
128 ;; changes (not just narrows) the existing restrictions
129 (narrow-to-region (car chunk) (or (cdr chunk) (point-max)))
130 (widen))))
131
132
133(defvar-local prettify-symbols-alist nil 92(defvar-local prettify-symbols-alist nil
134 "Alist of symbol prettifications. 93 "Alist of symbol prettifications.
135Each element looks like (SYMBOL . CHARACTER), where the symbol 94Each element looks like (SYMBOL . CHARACTER), where the symbol
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index d4226e5ce7b..b8926529d1e 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -287,10 +287,6 @@
287;;; 24.x Compat 287;;; 24.x Compat
288 288
289 289
290(unless (fboundp 'prog-widen)
291 (defun prog-widen ()
292 (widen)))
293
294(unless (fboundp 'prog-first-column) 290(unless (fboundp 'prog-first-column)
295 (defun prog-first-column () 291 (defun prog-first-column ()
296 0)) 292 0))
@@ -785,7 +781,7 @@ work on `python-indent-calculate-indentation' instead."
785 (interactive) 781 (interactive)
786 (save-excursion 782 (save-excursion
787 (save-restriction 783 (save-restriction
788 (prog-widen) 784 (widen)
789 (goto-char (point-min)) 785 (goto-char (point-min))
790 (let ((block-end)) 786 (let ((block-end))
791 (while (and (not block-end) 787 (while (and (not block-end)
@@ -883,8 +879,6 @@ keyword
883:at-dedenter-block-start 879:at-dedenter-block-start
884 - Point is on a line starting a dedenter block. 880 - Point is on a line starting a dedenter block.
885 - START is the position where the dedenter block starts." 881 - START is the position where the dedenter block starts."
886 (save-restriction
887 (prog-widen)
888 (let ((ppss (save-excursion 882 (let ((ppss (save-excursion
889 (beginning-of-line) 883 (beginning-of-line)
890 (syntax-ppss)))) 884 (syntax-ppss))))
@@ -1022,7 +1016,7 @@ keyword
1022 (looking-at (python-rx block-ender))) 1016 (looking-at (python-rx block-ender)))
1023 :after-block-end) 1017 :after-block-end)
1024 (t :after-line)) 1018 (t :after-line))
1025 (point))))))))) 1019 (point))))))))
1026 1020
1027(defun python-indent--calculate-indentation () 1021(defun python-indent--calculate-indentation ()
1028 "Internal implementation of `python-indent-calculate-indentation'. 1022 "Internal implementation of `python-indent-calculate-indentation'.
@@ -1030,8 +1024,6 @@ May return an integer for the maximum possible indentation at
1030current context or a list of integers. The latter case is only 1024current context or a list of integers. The latter case is only
1031happening for :at-dedenter-block-start context since the 1025happening for :at-dedenter-block-start context since the
1032possibilities can be narrowed to specific indentation points." 1026possibilities can be narrowed to specific indentation points."
1033 (save-restriction
1034 (prog-widen)
1035 (save-excursion 1027 (save-excursion
1036 (pcase (python-indent-context) 1028 (pcase (python-indent-context)
1037 (`(:no-indent . ,_) (prog-first-column)) ; usually 0 1029 (`(:no-indent . ,_) (prog-first-column)) ; usually 0
@@ -1081,7 +1073,7 @@ possibilities can be narrowed to specific indentation points."
1081 (`(,(or :inside-paren-newline-start-from-block) . ,start) 1073 (`(,(or :inside-paren-newline-start-from-block) . ,start)
1082 ;; Add two indentation levels to make the suite stand out. 1074 ;; Add two indentation levels to make the suite stand out.
1083 (goto-char start) 1075 (goto-char start)
1084 (+ (current-indentation) (* python-indent-offset 2))))))) 1076 (+ (current-indentation) (* python-indent-offset 2))))))
1085 1077
1086(defun python-indent--calculate-levels (indentation) 1078(defun python-indent--calculate-levels (indentation)
1087 "Calculate levels list given INDENTATION. 1079 "Calculate levels list given INDENTATION.
@@ -4590,7 +4582,7 @@ Optional argument INCLUDE-TYPE indicates to include the type of the defun.
4590This function can be used as the value of `add-log-current-defun-function' 4582This function can be used as the value of `add-log-current-defun-function'
4591since it returns nil if point is not inside a defun." 4583since it returns nil if point is not inside a defun."
4592 (save-restriction 4584 (save-restriction
4593 (prog-widen) 4585 (widen)
4594 (save-excursion 4586 (save-excursion
4595 (end-of-line 1) 4587 (end-of-line 1)
4596 (let ((names) 4588 (let ((names)
@@ -4788,12 +4780,10 @@ likely an invalid python file."
4788 "Message the first line of the block the current statement closes." 4780 "Message the first line of the block the current statement closes."
4789 (let ((point (python-info-dedenter-opening-block-position))) 4781 (let ((point (python-info-dedenter-opening-block-position)))
4790 (when point 4782 (when point
4791 (save-restriction
4792 (prog-widen)
4793 (message "Closes %s" (save-excursion 4783 (message "Closes %s" (save-excursion
4794 (goto-char point) 4784 (goto-char point)
4795 (buffer-substring 4785 (buffer-substring
4796 (point) (line-end-position)))))))) 4786 (point) (line-end-position)))))))
4797 4787
4798(defun python-info-dedenter-statement-p () 4788(defun python-info-dedenter-statement-p ()
4799 "Return point if current statement is a dedenter. 4789 "Return point if current statement is a dedenter.
@@ -4809,8 +4799,6 @@ statement."
4809 "Return non-nil if current line ends with backslash. 4799 "Return non-nil if current line ends with backslash.
4810With optional argument LINE-NUMBER, check that line instead." 4800With optional argument LINE-NUMBER, check that line instead."
4811 (save-excursion 4801 (save-excursion
4812 (save-restriction
4813 (prog-widen)
4814 (when line-number 4802 (when line-number
4815 (python-util-goto-line line-number)) 4803 (python-util-goto-line line-number))
4816 (while (and (not (eobp)) 4804 (while (and (not (eobp))
@@ -4819,14 +4807,12 @@ With optional argument LINE-NUMBER, check that line instead."
4819 (not (equal (char-before (point)) ?\\))) 4807 (not (equal (char-before (point)) ?\\)))
4820 (forward-line 1)) 4808 (forward-line 1))
4821 (when (equal (char-before) ?\\) 4809 (when (equal (char-before) ?\\)
4822 (point-marker))))) 4810 (point-marker))))
4823 4811
4824(defun python-info-beginning-of-backslash (&optional line-number) 4812(defun python-info-beginning-of-backslash (&optional line-number)
4825 "Return the point where the backslashed line start. 4813 "Return the point where the backslashed line start.
4826Optional argument LINE-NUMBER forces the line number to check against." 4814Optional argument LINE-NUMBER forces the line number to check against."
4827 (save-excursion 4815 (save-excursion
4828 (save-restriction
4829 (prog-widen)
4830 (when line-number 4816 (when line-number
4831 (python-util-goto-line line-number)) 4817 (python-util-goto-line line-number))
4832 (when (python-info-line-ends-backslash-p) 4818 (when (python-info-line-ends-backslash-p)
@@ -4835,15 +4821,13 @@ Optional argument LINE-NUMBER forces the line number to check against."
4835 (python-syntax-context 'paren)) 4821 (python-syntax-context 'paren))
4836 (forward-line -1)) 4822 (forward-line -1))
4837 (back-to-indentation) 4823 (back-to-indentation)
4838 (point-marker))))) 4824 (point-marker))))
4839 4825
4840(defun python-info-continuation-line-p () 4826(defun python-info-continuation-line-p ()
4841 "Check if current line is continuation of another. 4827 "Check if current line is continuation of another.
4842When current line is continuation of another return the point 4828When current line is continuation of another return the point
4843where the continued line ends." 4829where the continued line ends."
4844 (save-excursion 4830 (save-excursion
4845 (save-restriction
4846 (prog-widen)
4847 (let* ((context-type (progn 4831 (let* ((context-type (progn
4848 (back-to-indentation) 4832 (back-to-indentation)
4849 (python-syntax-context-type))) 4833 (python-syntax-context-type)))
@@ -4869,7 +4853,7 @@ where the continued line ends."
4869 (python-util-forward-comment -1) 4853 (python-util-forward-comment -1)
4870 (when (and (equal (1- line-start) (line-number-at-pos)) 4854 (when (and (equal (1- line-start) (line-number-at-pos))
4871 (python-info-line-ends-backslash-p)) 4855 (python-info-line-ends-backslash-p))
4872 (point-marker)))))))) 4856 (point-marker)))))))
4873 4857
4874(defun python-info-block-continuation-line-p () 4858(defun python-info-block-continuation-line-p ()
4875 "Return non-nil if current line is a continuation of a block." 4859 "Return non-nil if current line is a continuation of a block."
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index dc1b0f8e2da..7c101143347 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -1364,7 +1364,6 @@ delimiter."
1364 "\\)\\>"))) 1364 "\\)\\>")))
1365 (eq (ruby-deep-indent-paren-p t) 'space) 1365 (eq (ruby-deep-indent-paren-p t) 'space)
1366 (not (bobp))) 1366 (not (bobp)))
1367 (widen)
1368 (goto-char (or begin parse-start)) 1367 (goto-char (or begin parse-start))
1369 (skip-syntax-forward " ") 1368 (skip-syntax-forward " ")
1370 (current-column)) 1369 (current-column))
diff --git a/lisp/textmodes/mhtml-mode.el b/lisp/textmodes/mhtml-mode.el
index 09da155f487..79c1125ff62 100644
--- a/lisp/textmodes/mhtml-mode.el
+++ b/lisp/textmodes/mhtml-mode.el
@@ -341,9 +341,7 @@ This is used by `mhtml--pre-command'.")
341 ((eq mhtml-tag-relative-indent 'ignore) 341 ((eq mhtml-tag-relative-indent 'ignore)
342 (setq base-indent 0))) 342 (setq base-indent 0)))
343 (narrow-to-region region-start (point-max)) 343 (narrow-to-region region-start (point-max))
344 (let ((prog-indentation-context (list base-indent 344 (let ((prog-indentation-context (list base-indent)))
345 (cons (point-min) nil)
346 nil)))
347 (mhtml--with-locals submode 345 (mhtml--with-locals submode
348 ;; indent-line-function was rebound by 346 ;; indent-line-function was rebound by
349 ;; mhtml--with-locals. 347 ;; mhtml--with-locals.