diff options
| author | Eli Zaretskii | 2015-12-12 12:53:35 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2015-12-12 12:53:35 +0200 |
| commit | 5cc4f33b4ad0de0024c11ec41bcefcab34493efb (patch) | |
| tree | 179918cb0c05727a0e51a107644826488e13450b | |
| parent | acae1834c619ad1a0c8db8b6421291070087a004 (diff) | |
| download | emacs-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.texi | 78 | ||||
| -rw-r--r-- | etc/NEWS | 11 | ||||
| -rw-r--r-- | lisp/progmodes/prog-mode.el | 56 |
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 | |||
| 2362 | text at point (@pxref{Completion in Buffers}). | 2362 | text 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 | ||
| 2368 | syntax belongs to a different major mode. Examples include | ||
| 2369 | @dfn{literate programming} source files that combine documentation and | ||
| 2370 | snippets of source code, Yacc/Bison programs that include snippets of | ||
| 2371 | plain C code, etc. To correctly indent the embedded chunks, the major | ||
| 2372 | mode needs to delegate the indentation to another mode's indentation | ||
| 2373 | engine (e.g., call @code{c-indent-defun} for C code or | ||
| 2374 | @code{python-indent-line} for Python), while providing it with some | ||
| 2375 | context to guide the indentation. The following facilities support | ||
| 2376 | such multi-mode indentation. | ||
| 2377 | |||
| 2378 | @defvar prog-indentation-context | ||
| 2379 | This variable, when non-@code{nil}, holds the indentation context for | ||
| 2380 | the sub-mode's indentation engine provided by the superior major mode. | ||
| 2381 | The 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 | ||
| 2383 | list have the following meaning: | ||
| 2384 | |||
| 2385 | @table @var | ||
| 2386 | @item first-column | ||
| 2387 | The column to be used for top-level constructs. This replaces the | ||
| 2388 | default value of the top-level column used by the sub-mode, usually | ||
| 2389 | zero. | ||
| 2390 | @item start | ||
| 2391 | @itemx end | ||
| 2392 | The region of the code chunk to be indented by the sub-mode. The | ||
| 2393 | value of @var{end} can be @code{nil}, which stands for the value of | ||
| 2394 | @code{point-max}. | ||
| 2395 | @item prev-chunk | ||
| 2396 | If this is non-@code{nil}, it should provide the sub-mode's | ||
| 2397 | indentation engine with a virtual context of the code chunk. Valid | ||
| 2398 | values include: | ||
| 2399 | |||
| 2400 | @itemize @minus | ||
| 2401 | @item | ||
| 2402 | A string whose contents is the text the sub-mode's indentation engine | ||
| 2403 | should consider to precede the code chunk. The sub-mode's indentation | ||
| 2404 | engine can add text properties to that string, to be reused in | ||
| 2405 | repeated calls with the same string, thus using it as a cache. An | ||
| 2406 | example where this is useful is code chunks that need to be indented | ||
| 2407 | as function bodies, but lack the function's preamble---the string | ||
| 2408 | could then include that missing preamble. | ||
| 2409 | @item | ||
| 2410 | A function. It is expected to be called with the start position of | ||
| 2411 | the current chunk, and should return a cons cell | ||
| 2412 | @w{@code{(@var{prev-start} . @var{prev-end})}} that specifies the | ||
| 2413 | region of the previous code chunk, or @code{nil} if there is no previous | ||
| 2414 | chunk. This is useful in literate-programming sources, where code is | ||
| 2415 | split into chunks, and correct indentation needs to access previous | ||
| 2416 | chunks. | ||
| 2417 | @end itemize | ||
| 2418 | @end table | ||
| 2419 | @end defvar | ||
| 2420 | |||
| 2421 | The following convenience functions should be used by major mode's | ||
| 2422 | indentation engine in support of invocations as sub-modes of another | ||
| 2423 | major mode. | ||
| 2424 | |||
| 2425 | @defun prog-first-column | ||
| 2426 | Call this function instead of using a literal value (usually, zero) of | ||
| 2427 | the column number for indenting top-level program constructs. The | ||
| 2428 | function's value is the column number to use for top-level constructs. | ||
| 2429 | When no superior mode is in effect, this function returns zero. | ||
| 2430 | @end defun | ||
| 2431 | |||
| 2432 | @defun prog-widen | ||
| 2433 | Call this function instead of @code{widen} to remove any restrictions | ||
| 2434 | imposed by the mode's indentation engine and restore the restrictions | ||
| 2435 | recorded in @code{prog-indentation-context}. This prevents the | ||
| 2436 | indentation engine of a sub-mode from inadvertently operating on text | ||
| 2437 | outside of the chunk it was supposed to indent, and preserves the | ||
| 2438 | restriction imposed by the superior mode. When no superior mode is in | ||
| 2439 | effect, 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 | ||
| @@ -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 |
| 322 | object keys sorted alphabetically. | 322 | object 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. |
| 325 | See `prog-indentation-context' and `prog-widen'. | 326 | This allows better indentation support in modes that support multiple |
| 327 | programming languages in the same buffer, like literate programming | ||
| 328 | environments or ANTLR programs with embedded Python code. | ||
| 329 | |||
| 330 | A major mode can provide indentation context for a sub-mode through | ||
| 331 | the `prog-indentation-context' variable. To support this, modes that | ||
| 332 | provide 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 | |||
| 54 | There are languages where part of the code is actually written in | 55 | There are languages where part of the code is actually written in |
| 55 | a sub language, e.g., a Yacc/Bison or ANTLR grammar also consists | 56 | a sub language, e.g., a Yacc/Bison or ANTLR grammar also consists |
| 56 | of plain C code. This variable enables the major mode of the | 57 | of plain C code. This variable enables the major mode of the |
| 57 | main language to use the indentation engine of the sub mode for | 58 | main language to use the indentation engine of the sub-mode for |
| 58 | lines in code chunks written in the sub language. | 59 | lines in code chunks written in the sub-mode's language. |
| 59 | 60 | ||
| 60 | When a major mode of such a main language decides to delegate the | 61 | When a major mode of such a main language decides to delegate the |
| 61 | indentation of a line/region to the indentation engine of the sub | 62 | indentation of a line/region to the indentation engine of the sub |
| 62 | mode, it is supposed to bind this variable to non-nil around the call. | 63 | mode, it should bind this variable to non-nil around the call. |
| 64 | |||
| 65 | The non-nil value should be a list of the form: | ||
| 63 | 66 | ||
| 64 | The non-nil value looks as follows | ||
| 65 | (FIRST-COLUMN (START . END) PREVIOUS-CHUNKS) | 67 | (FIRST-COLUMN (START . END) PREVIOUS-CHUNKS) |
| 66 | 68 | ||
| 67 | FIRST-COLUMN is the column the indentation engine of the sub mode | 69 | FIRST-COLUMN is the column the indentation engine of the sub-mode |
| 68 | should usually choose for top-level language constructs inside | 70 | should use for top-level language constructs inside the code |
| 69 | the code chunk (instead of 0). | 71 | chunk (instead of 0). |
| 70 | 72 | ||
| 71 | START to END is the region of the code chunk. See function | 73 | START and END specify the region of the code chunk. END can be |
| 72 | `prog-widen' for additional info. | 74 | nil, which stands for the value of `point-max'. The function |
| 75 | `prog-widen' uses this to restore restrictions imposed by the | ||
| 76 | sub-mode's indentation engine. | ||
| 73 | 77 | ||
| 74 | PREVIOUS-CHUNKS, if non-nil, provides the indentation engine of | 78 | PREVIOUS-CHUNKS, if non-nil, provides the indentation engine of |
| 75 | the sub mode with the virtual context of the code chunk. Valid | 79 | the sub-mode with the virtual context of the code chunk. Valid |
| 76 | values are: | 80 | values 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. |
| 116 | This function can be used instead of `widen' in any function used | 118 | This function should be used instead of `widen' in any function used |
| 117 | by the indentation engine to make it respect the value | 119 | by the indentation engine to make it respect the value of |
| 118 | `prog-indentation-context'. | 120 | `prog-indentation-context'. |
| 119 | 121 | ||
| 120 | This function (like `widen') is useful inside a | 122 | This function (like `widen') is useful inside a |
| @@ -122,8 +124,8 @@ This function (like `widen') is useful inside a | |||
| 122 | narrowing is in effect." | 124 | narrowing 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 | ||