aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2015-12-12 12:53:35 +0200
committerEli Zaretskii2015-12-12 12:53:35 +0200
commit5cc4f33b4ad0de0024c11ec41bcefcab34493efb (patch)
tree179918cb0c05727a0e51a107644826488e13450b
parentacae1834c619ad1a0c8db8b6421291070087a004 (diff)
downloademacs-5cc4f33b4ad0de0024c11ec41bcefcab34493efb.tar.gz
emacs-5cc4f33b4ad0de0024c11ec41bcefcab34493efb.zip
Document multi-mode indentation facilities
* doc/lispref/text.texi (Mode-Specific Indent): Document 'prog-indentation-context', 'prog-first-column', and 'prog-widen'. * lisp/progmodes/prog-mode.el (prog-indentation-context) (prog-widen): Doc fixes.
-rw-r--r--doc/lispref/text.texi78
-rw-r--r--etc/NEWS11
-rw-r--r--lisp/progmodes/prog-mode.el56
3 files changed, 117 insertions, 28 deletions
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index 4d26638a94c..f3679a88f74 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -2362,6 +2362,84 @@ already indented, it calls @code{completion-at-point} to complete the
2362text at point (@pxref{Completion in Buffers}). 2362text at point (@pxref{Completion in Buffers}).
2363@end defopt 2363@end defopt
2364 2364
2365@cindex literate programming
2366@cindex multi-mode indentation
2367 Some major modes need to support embedded regions of text whose
2368syntax belongs to a different major mode. Examples include
2369@dfn{literate programming} source files that combine documentation and
2370snippets of source code, Yacc/Bison programs that include snippets of
2371plain C code, etc. To correctly indent the embedded chunks, the major
2372mode needs to delegate the indentation to another mode's indentation
2373engine (e.g., call @code{c-indent-defun} for C code or
2374@code{python-indent-line} for Python), while providing it with some
2375context to guide the indentation. The following facilities support
2376such multi-mode indentation.
2377
2378@defvar prog-indentation-context
2379This variable, when non-@code{nil}, holds the indentation context for
2380the sub-mode's indentation engine provided by the superior major mode.
2381The value should be a list of the form @code{(@var{first-column}
2382@w{(@var{start} . @var{end})} @code{prev-chunk})}. The members of the
2383list have the following meaning:
2384
2385@table @var
2386@item first-column
2387The column to be used for top-level constructs. This replaces the
2388default value of the top-level column used by the sub-mode, usually
2389zero.
2390@item start
2391@itemx end
2392The region of the code chunk to be indented by the sub-mode. The
2393value of @var{end} can be @code{nil}, which stands for the value of
2394@code{point-max}.
2395@item prev-chunk
2396If this is non-@code{nil}, it should provide the sub-mode's
2397indentation engine with a virtual context of the code chunk. Valid
2398values include:
2399
2400@itemize @minus
2401@item
2402A string whose contents is the text the sub-mode's indentation engine
2403should consider to precede the code chunk. The sub-mode's indentation
2404engine can add text properties to that string, to be reused in
2405repeated calls with the same string, thus using it as a cache. An
2406example where this is useful is code chunks that need to be indented
2407as function bodies, but lack the function's preamble---the string
2408could then include that missing preamble.
2409@item
2410A function. It is expected to be called with the start position of
2411the current chunk, and should return a cons cell
2412@w{@code{(@var{prev-start} . @var{prev-end})}} that specifies the
2413region of the previous code chunk, or @code{nil} if there is no previous
2414chunk. This is useful in literate-programming sources, where code is
2415split into chunks, and correct indentation needs to access previous
2416chunks.
2417@end itemize
2418@end table
2419@end defvar
2420
2421The following convenience functions should be used by major mode's
2422indentation engine in support of invocations as sub-modes of another
2423major mode.
2424
2425@defun prog-first-column
2426Call this function instead of using a literal value (usually, zero) of
2427the column number for indenting top-level program constructs. The
2428function's value is the column number to use for top-level constructs.
2429When no superior mode is in effect, this function returns zero.
2430@end defun
2431
2432@defun prog-widen
2433Call this function instead of @code{widen} to remove any restrictions
2434imposed by the mode's indentation engine and restore the restrictions
2435recorded in @code{prog-indentation-context}. This prevents the
2436indentation engine of a sub-mode from inadvertently operating on text
2437outside of the chunk it was supposed to indent, and preserves the
2438restriction imposed by the superior mode. When no superior mode is in
2439effect, this function just calls @code{widen}.
2440@end defun
2441
2442
2365@node Region Indent 2443@node Region Indent
2366@subsection Indenting an Entire Region 2444@subsection Indenting an Entire Region
2367 2445
diff --git a/etc/NEWS b/etc/NEWS
index 01447cde163..246ee37a848 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -321,8 +321,17 @@ the ordering of object keys by default.
321`json-pretty-print-buffer-ordered' pretty prints JSON objects with 321`json-pretty-print-buffer-ordered' pretty prints JSON objects with
322object keys sorted alphabetically. 322object keys sorted alphabetically.
323 323
324+++
324** Prog mode has some support for multi-mode indentation. 325** Prog mode has some support for multi-mode indentation.
325See `prog-indentation-context' and `prog-widen'. 326This allows better indentation support in modes that support multiple
327programming languages in the same buffer, like literate programming
328environments or ANTLR programs with embedded Python code.
329
330A major mode can provide indentation context for a sub-mode through
331the `prog-indentation-context' variable. To support this, modes that
332provide indentation should use `prog-widen' instead of `widen' and
333`prog-first-column' instead of a literal zero. See the node
334"Mode-Specific Indent" in the ELisp manual for more details.
326 335
327** Prettify Symbols mode 336** Prettify Symbols mode
328 337
diff --git a/lisp/progmodes/prog-mode.el b/lisp/progmodes/prog-mode.el
index b459cbfd286..d05e6369b86 100644
--- a/lisp/progmodes/prog-mode.el
+++ b/lisp/progmodes/prog-mode.el
@@ -50,49 +50,51 @@
50 "Keymap used for programming modes.") 50 "Keymap used for programming modes.")
51 51
52(defvar prog-indentation-context nil 52(defvar prog-indentation-context nil
53 "Non-nil while indenting embedded code chunks. 53 "When non-nil, provides context for indenting embedded code chunks.
54
54There are languages where part of the code is actually written in 55There are languages where part of the code is actually written in
55a 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
56of plain C code. This variable enables the major mode of the 57of plain C code. This variable enables the major mode of the
57main language to use the indentation engine of the sub mode for 58main language to use the indentation engine of the sub-mode for
58lines in code chunks written in the sub language. 59lines in code chunks written in the sub-mode's language.
59 60
60When a major mode of such a main language decides to delegate the 61When a major mode of such a main language decides to delegate the
61indentation of a line/region to the indentation engine of the sub 62indentation of a line/region to the indentation engine of the sub
62mode, it is supposed to bind this variable to non-nil around the call. 63mode, it should bind this variable to non-nil around the call.
64
65The non-nil value should be a list of the form:
63 66
64The non-nil value looks as follows
65 (FIRST-COLUMN (START . END) PREVIOUS-CHUNKS) 67 (FIRST-COLUMN (START . END) PREVIOUS-CHUNKS)
66 68
67FIRST-COLUMN is the column the indentation engine of the sub mode 69FIRST-COLUMN is the column the indentation engine of the sub-mode
68should usually choose for top-level language constructs inside 70should use for top-level language constructs inside the code
69the code chunk (instead of 0). 71chunk (instead of 0).
70 72
71START to END is the region of the code chunk. See function 73START and END specify the region of the code chunk. END can be
72`prog-widen' for additional info. 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.
73 77
74PREVIOUS-CHUNKS, if non-nil, provides the indentation engine of 78PREVIOUS-CHUNKS, if non-nil, provides the indentation engine of
75the sub mode with the virtual context of the code chunk. Valid 79the sub-mode with the virtual context of the code chunk. Valid
76values are: 80values are:
77 81
78 - A string containing code which the indentation engine can 82 - A string containing text which the indentation engine can
79 consider as standing in front of the code chunk. To cache the 83 consider as standing in front of the code chunk. To cache the
80 string's calculated syntactic information for repeated calls 84 string's calculated syntactic information for repeated calls
81 with the same string, it is valid and expected for the inner 85 with the same string, the sub-mode can add text-properties to
82 mode to add text-properties to the string. 86 the string.
83 87
84 A typical use case is for grammars with code chunks which are 88 A typical use case is for grammars with code chunks which are
85 to be indented like function bodies - the string would contain 89 to be indented like function bodies -- the string would contain
86 a corresponding function header. 90 the corresponding function preamble.
87 91
88 - A function called with the start position of the current 92 - A function, to be called with the start position of the current
89 chunk. It will return either the region of the previous chunk 93 chunk. It should return either the region of the previous chunk
90 as (PREV-START . PREV-END) or nil if there is no further 94 as (PREV-START . PREV-END), or nil if there is no previous chunk.
91 previous chunk.
92 95
93 A typical use case are literate programming sources - the 96 A typical use case are literate programming sources -- the
94 function would successively return the code chunks of the 97 function would successively return the previous code chunks.")
95 previous macro definitions for the same name.")
96 98
97(defun prog-indent-sexp (&optional defun) 99(defun prog-indent-sexp (&optional defun)
98 "Indent the expression after point. 100 "Indent the expression after point.
@@ -113,8 +115,8 @@ instead."
113 115
114(defun prog-widen () 116(defun prog-widen ()
115 "Remove restrictions (narrowing) from current code chunk or buffer. 117 "Remove restrictions (narrowing) from current code chunk or buffer.
116This function can be used instead of `widen' in any function used 118This function should be used instead of `widen' in any function used
117by the indentation engine to make it respect the value 119by the indentation engine to make it respect the value of
118`prog-indentation-context'. 120`prog-indentation-context'.
119 121
120This function (like `widen') is useful inside a 122This function (like `widen') is useful inside a
@@ -122,8 +124,8 @@ This function (like `widen') is useful inside a
122narrowing is in effect." 124narrowing is in effect."
123 (let ((chunk (cadr prog-indentation-context))) 125 (let ((chunk (cadr prog-indentation-context)))
124 (if chunk 126 (if chunk
125 ;; no widen necessary here, as narrow-to-region changes (not 127 ;; No call to `widen' is necessary here, as narrow-to-region
126 ;; just narrows) existing restrictions 128 ;; changes (not just narrows) the existing restrictions
127 (narrow-to-region (car chunk) (or (cdr chunk) (point-max))) 129 (narrow-to-region (car chunk) (or (cdr chunk) (point-max)))
128 (widen)))) 130 (widen))))
129 131