emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] emacs-25 5cc4f33: Document multi-mode indentation faciliti


From: Eli Zaretskii
Subject: [Emacs-diffs] emacs-25 5cc4f33: Document multi-mode indentation facilities
Date: Sat, 12 Dec 2015 10:54:16 +0000

branch: emacs-25
commit 5cc4f33b4ad0de0024c11ec41bcefcab34493efb
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    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.
---
 doc/lispref/text.texi       |   78 +++++++++++++++++++++++++++++++++++++++++++
 etc/NEWS                    |   11 +++++-
 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 4d26638..f3679a8 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
 text at point (@pxref{Completion in Buffers}).
 @end defopt
 
address@hidden literate programming
address@hidden multi-mode indentation
+  Some major modes need to support embedded regions of text whose
+syntax belongs to a different major mode.  Examples include
address@hidden programming} source files that combine documentation and
+snippets of source code, Yacc/Bison programs that include snippets of
+plain C code, etc.  To correctly indent the embedded chunks, the major
+mode needs to delegate the indentation to another mode's indentation
+engine (e.g., call @code{c-indent-defun} for C code or
address@hidden for Python), while providing it with some
+context to guide the indentation.  The following facilities support
+such multi-mode indentation.
+
address@hidden prog-indentation-context
+This variable, when address@hidden, holds the indentation context for
+the sub-mode's indentation engine provided by the superior major mode.
+The value should be a list of the form @code{(@var{first-column}
address@hidden(@var{start} . @var{end})} @code{prev-chunk})}.  The members of 
the
+list have the following meaning:
+
address@hidden @var
address@hidden first-column
+The column to be used for top-level constructs.  This replaces the
+default value of the top-level column used by the sub-mode, usually
+zero.
address@hidden start
address@hidden end
+The region of the code chunk to be indented by the sub-mode.  The
+value of @var{end} can be @code{nil}, which stands for the value of
address@hidden
address@hidden prev-chunk
+If this is address@hidden, it should provide the sub-mode's
+indentation engine with a virtual context of the code chunk.  Valid
+values include:
+
address@hidden @minus
address@hidden
+A string whose contents is the text the sub-mode's indentation engine
+should consider to precede the code chunk.  The sub-mode's indentation
+engine can add text properties to that string, to be reused in
+repeated calls with the same string, thus using it as a cache.  An
+example where this is useful is code chunks that need to be indented
+as function bodies, but lack the function's preamble---the string
+could then include that missing preamble.
address@hidden
+A function.  It is expected to be called with the start position of
+the current chunk, and should return a cons cell
address@hidden@code{(@var{prev-start} . @var{prev-end})}} that specifies the
+region of the previous code chunk, or @code{nil} if there is no previous
+chunk.  This is useful in literate-programming sources, where code is
+split into chunks, and correct indentation needs to access previous
+chunks.
address@hidden itemize
address@hidden table
address@hidden defvar
+
+The following convenience functions should be used by major mode's
+indentation engine in support of invocations as sub-modes of another
+major mode.
+
address@hidden prog-first-column
+Call this function instead of using a literal value (usually, zero) of
+the column number for indenting top-level program constructs.  The
+function's value is the column number to use for top-level constructs.
+When no superior mode is in effect, this function returns zero.
address@hidden defun
+
address@hidden prog-widen
+Call this function instead of @code{widen} to remove any restrictions
+imposed by the mode's indentation engine and restore the restrictions
+recorded in @code{prog-indentation-context}.  This prevents the
+indentation engine of a sub-mode from inadvertently operating on text
+outside of the chunk it was supposed to indent, and preserves the
+restriction imposed by the superior mode.  When no superior mode is in
+effect, this function just calls @code{widen}.
address@hidden defun
+
+
 @node Region Indent
 @subsection Indenting an Entire Region
 
diff --git a/etc/NEWS b/etc/NEWS
index 01447cd..246ee37 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -321,8 +321,17 @@ the ordering of object keys by default.
 `json-pretty-print-buffer-ordered' pretty prints JSON objects with
 object keys sorted alphabetically.
 
++++
 ** Prog mode has some support for multi-mode indentation.
-See `prog-indentation-context' and `prog-widen'.
+This allows better indentation support in modes that support multiple
+programming languages in the same buffer, like literate programming
+environments or ANTLR programs with embedded Python code.
+
+A major mode can provide indentation context for a sub-mode through
+the `prog-indentation-context' variable.  To support this, modes that
+provide indentation should use `prog-widen' instead of `widen' and
+`prog-first-column' instead of a literal zero.  See the node
+"Mode-Specific Indent" in the ELisp manual for more details.
 
 ** Prettify Symbols mode
 
diff --git a/lisp/progmodes/prog-mode.el b/lisp/progmodes/prog-mode.el
index b459cbf..d05e636 100644
--- a/lisp/progmodes/prog-mode.el
+++ b/lisp/progmodes/prog-mode.el
@@ -50,49 +50,51 @@
   "Keymap used for programming modes.")
 
 (defvar prog-indentation-context nil
-  "Non-nil while indenting embedded code chunks.
+  "When non-nil, provides context for indenting embedded code chunks.
+
 There are languages where part of the code is actually written in
 a sub language, e.g., a Yacc/Bison or ANTLR grammar also consists
 of plain C code.  This variable enables the major mode of the
-main language to use the indentation engine of the sub mode for
-lines in code chunks written in the sub language.
+main language to use the indentation engine of the sub-mode for
+lines in code chunks written in the sub-mode's language.
 
 When a major mode of such a main language decides to delegate the
 indentation of a line/region to the indentation engine of the sub
-mode, it is supposed to bind this variable to non-nil around the call.
+mode, it should bind this variable to non-nil around the call.
+
+The non-nil value should be a list of the form:
 
-The non-nil value looks as follows
    (FIRST-COLUMN (START . END) PREVIOUS-CHUNKS)
 
-FIRST-COLUMN is the column the indentation engine of the sub mode
-should usually choose for top-level language constructs inside
-the code chunk (instead of 0).
+FIRST-COLUMN is the column the indentation engine of the sub-mode
+should use for top-level language constructs inside the code
+chunk (instead of 0).
 
-START to END is the region of the code chunk.  See function
-`prog-widen' for additional info.
+START and END specify the region of the code chunk.  END can be
+nil, which stands for the value of `point-max'.  The function
+`prog-widen' uses this to restore restrictions imposed by the
+sub-mode's indentation engine.
 
 PREVIOUS-CHUNKS, if non-nil, provides the indentation engine of
-the sub mode with the virtual context of the code chunk.  Valid
+the sub-mode with the virtual context of the code chunk.  Valid
 values are:
 
- - A string containing code which the indentation engine can
+ - A string containing text which the indentation engine can
    consider as standing in front of the code chunk.  To cache the
    string's calculated syntactic information for repeated calls
-   with the same string, it is valid and expected for the inner
-   mode to add text-properties to the string.
+   with the same string, the sub-mode can add text-properties to
+   the string.
 
    A typical use case is for grammars with code chunks which are
-   to be indented like function bodies - the string would contain
-   a corresponding function header.
+   to be indented like function bodies -- the string would contain
+   the corresponding function preamble.
 
- - A function called with the start position of the current
-   chunk.  It will return either the region of the previous chunk
-   as (PREV-START . PREV-END) or nil if there is no further
-   previous chunk.
+ - A function, to be called with the start position of the current
+   chunk.  It should return either the region of the previous chunk
+   as (PREV-START . PREV-END), or nil if there is no previous chunk.
 
-   A typical use case are literate programming sources - the
-   function would successively return the code chunks of the
-   previous macro definitions for the same name.")
+   A typical use case are literate programming sources -- the
+   function would successively return the previous code chunks.")
 
 (defun prog-indent-sexp (&optional defun)
   "Indent the expression after point.
@@ -113,8 +115,8 @@ instead."
 
 (defun prog-widen ()
   "Remove restrictions (narrowing) from current code chunk or buffer.
-This function can be used instead of `widen' in any function used
-by the indentation engine to make it respect the value
+This function should be used instead of `widen' in any function used
+by the indentation engine to make it respect the value of
 `prog-indentation-context'.
 
 This function (like `widen') is useful inside a
@@ -122,8 +124,8 @@ This function (like `widen') is useful inside a
 narrowing is in effect."
   (let ((chunk (cadr prog-indentation-context)))
     (if chunk
-        ;; no widen necessary here, as narrow-to-region changes (not
-        ;; just narrows) existing restrictions
+        ;; No call to `widen' is necessary here, as narrow-to-region
+        ;; changes (not just narrows) the existing restrictions
         (narrow-to-region (car chunk) (or (cdr chunk) (point-max)))
       (widen))))
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]