Patch 9.0.0761
Problem: Cannot use 'indentexpr' for Lisp indenting.
Solution: Add the 'lispoptions' option.
Files: runtime/doc/options.txt, src/optiondefs.h, src/optionstr.c,
src/buffer.c, src/option.c, src/option.h, src/change.c,
src/indent.c, src/proto/
indent.pro,
src/testdir/test_lispindent.vim
*** ../vim-9.0.0760/runtime/doc/options.txt 2022-10-13 22:12:07.160673838 +0100
--- runtime/doc/options.txt 2022-10-15 16:00:59.946560589 +0100
***************
*** 4592,4598 ****
in Insert mode as specified with the 'indentkeys' option.
When this option is not empty, it overrules the 'cindent' and
'smartindent' indenting. When 'lisp' is set, this option is
! overridden by the Lisp indentation algorithm.
When 'paste' is set this option is not used for indenting.
The expression is evaluated with |v:lnum| set to the line number for
which the indent is to be computed. The cursor is also in this line
--- 4621,4627 ----
in Insert mode as specified with the 'indentkeys' option.
When this option is not empty, it overrules the 'cindent' and
'smartindent' indenting. When 'lisp' is set, this option is
! is only used when 'lispoptions' contains "expr:1".
When 'paste' is set this option is not used for indenting.
The expression is evaluated with |v:lnum| set to the line number for
which the indent is to be computed. The cursor is also in this line
***************
*** 5034,5044 ****
calling an external program if 'equalprg' is empty.
This option is not used when 'paste' is set.
*'lispwords'* *'lw'*
'lispwords' 'lw' string (default is very long)
global or local to buffer |global-local|
! Comma-separated list of words that influence the Lisp indenting.
! |'lisp'|
*'list'* *'nolist'*
'list' boolean (default off)
--- 5063,5084 ----
calling an external program if 'equalprg' is empty.
This option is not used when 'paste' is set.
+ *'lispoptions'* *'lop'*
+ 'lispoptions' 'lop' string (default "")
+ local to buffer
+ Comma-separated list of items that influence the Lisp indenting when
+ enabled with the |'lisp'| option. Currently only one item is
+ supported:
+ expr:1 use 'indentexpr' for Lisp indenting when it is set
+ expr:0 do not use 'indentexpr' for Lisp indenting (default)
+ Note that when using 'indentexpr' the `=` operator indents all the
+ lines, otherwise the first line is not indented (Vi-compatible).
+
*'lispwords'* *'lw'*
'lispwords' 'lw' string (default is very long)
global or local to buffer |global-local|
! Comma-separated list of words that influence the Lisp indenting when
! enabled with the |'lisp'| option.
*'list'* *'nolist'*
'list' boolean (default off)
*** ../vim-9.0.0760/src/optiondefs.h 2022-10-13 22:12:07.168673806 +0100
--- src/optiondefs.h 2022-10-15 15:37:32.194201589 +0100
***************
*** 41,57 ****
#define PV_BOMB OPT_BUF(BV_BOMB)
#define PV_CI OPT_BUF(BV_CI)
#define PV_CIN OPT_BUF(BV_CIN)
! #define PV_CINK OPT_BUF(BV_CINK)
! #define PV_CINO OPT_BUF(BV_CINO)
#define PV_CINSD OPT_BUF(BV_CINSD)
! #define PV_CINW OPT_BUF(BV_CINW)
#define PV_CM OPT_BOTH(OPT_BUF(BV_CM))
#ifdef FEAT_FOLDING
# define PV_CMS OPT_BUF(BV_CMS)
#endif
#define PV_COM OPT_BUF(BV_COM)
#define PV_CPT OPT_BUF(BV_CPT)
! #define PV_DICT OPT_BOTH(OPT_BUF(BV_DICT))
#define PV_TSR OPT_BOTH(OPT_BUF(BV_TSR))
#define PV_CSL OPT_BUF(BV_CSL)
#ifdef FEAT_COMPL_FUNC
--- 41,57 ----
#define PV_BOMB OPT_BUF(BV_BOMB)
#define PV_CI OPT_BUF(BV_CI)
#define PV_CIN OPT_BUF(BV_CIN)
! #define PV_CINK OPT_BUF(BV_CINK)
! #define PV_CINO OPT_BUF(BV_CINO)
#define PV_CINSD OPT_BUF(BV_CINSD)
! #define PV_CINW OPT_BUF(BV_CINW)
#define PV_CM OPT_BOTH(OPT_BUF(BV_CM))
#ifdef FEAT_FOLDING
# define PV_CMS OPT_BUF(BV_CMS)
#endif
#define PV_COM OPT_BUF(BV_COM)
#define PV_CPT OPT_BUF(BV_CPT)
! #define PV_DICT OPT_BOTH(OPT_BUF(BV_DICT))
#define PV_TSR OPT_BOTH(OPT_BUF(BV_TSR))
#define PV_CSL OPT_BUF(BV_CSL)
#ifdef FEAT_COMPL_FUNC
***************
*** 95,101 ****
# define PV_KMAP OPT_BUF(BV_KMAP)
#endif
#define PV_KP OPT_BOTH(OPT_BUF(BV_KP))
! #define PV_LISP OPT_BUF(BV_LISP)
#define PV_LW OPT_BOTH(OPT_BUF(BV_LW))
#define PV_MENC OPT_BOTH(OPT_BUF(BV_MENC))
#define PV_MA OPT_BUF(BV_MA)
--- 95,102 ----
# define PV_KMAP OPT_BUF(BV_KMAP)
#endif
#define PV_KP OPT_BOTH(OPT_BUF(BV_KP))
! #define PV_LISP OPT_BUF(BV_LISP)
! #define PV_LOP OPT_BUF(BV_LOP)
#define PV_LW OPT_BOTH(OPT_BUF(BV_LW))
#define PV_MENC OPT_BOTH(OPT_BUF(BV_MENC))
#define PV_MA OPT_BUF(BV_MA)
***************
*** 142,148 ****
#endif
#define PV_WM OPT_BUF(BV_WM)
#ifdef FEAT_VARTABS
! # define PV_VSTS OPT_BUF(BV_VSTS)
# define PV_VTS OPT_BUF(BV_VTS)
#endif
--- 143,149 ----
#endif
#define PV_WM OPT_BUF(BV_WM)
#ifdef FEAT_VARTABS
! # define PV_VSTS OPT_BUF(BV_VSTS)
# define PV_VTS OPT_BUF(BV_VTS)
#endif
***************
*** 1522,1527 ****
--- 1523,1531 ----
{"lisp", NULL, P_BOOL|P_VI_DEF,
(char_u *)&p_lisp, PV_LISP,
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
+ {"lispoptions", "lop", P_STRING|P_ALLOCED|P_VI_DEF|P_ONECOMMA|P_NODUP,
+ (char_u *)&p_lop, PV_LOP,
+ {(char_u *)"", (char_u *)0L} SCTX_INIT},
{"lispwords", "lw", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
(char_u *)&p_lispwords, PV_LW,
{(char_u *)LISPWORD_VALUE, (char_u *)0L} SCTX_INIT},
*** ../vim-9.0.0760/src/optionstr.c 2022-10-04 16:23:39.018042176 +0100
--- src/optionstr.c 2022-10-15 15:44:18.478762373 +0100
***************
*** 259,264 ****
--- 259,265 ----
check_string_option(&buf->b_p_cino);
check_string_option(&buf->b_p_cinsd);
parse_cino(buf);
+ check_string_option(&buf->b_p_lop);
check_string_option(&buf->b_p_ft);
check_string_option(&buf->b_p_cinw);
check_string_option(&buf->b_p_cpt);
***************
*** 2102,2107 ****
--- 2103,2116 ----
parse_cino(curbuf);
}
+ // 'lispoptions'
+ else if (gvarp == &p_lop)
+ {
+ if (**varp != NUL && STRCMP(*varp, "expr:0") != 0
+ && STRCMP(*varp, "expr:1") != 0)
+ errmsg = e_invalid_argument;
+ }
+
#if defined(FEAT_RENDER_OPTIONS)
// 'renderoptions'
else if (varp == &p_rop)
*** ../vim-9.0.0760/src/buffer.c 2022-10-13 22:12:07.160673838 +0100
--- src/buffer.c 2022-10-15 15:19:13.082193871 +0100
***************
*** 2390,2395 ****
--- 2390,2396 ----
clear_string_option(&buf->b_p_ft);
clear_string_option(&buf->b_p_cink);
clear_string_option(&buf->b_p_cino);
+ clear_string_option(&buf->b_p_lop);
clear_string_option(&buf->b_p_cinsd);
clear_string_option(&buf->b_p_cinw);
clear_string_option(&buf->b_p_cpt);
*** ../vim-9.0.0760/src/option.c 2022-10-13 22:12:07.168673806 +0100
--- src/option.c 2022-10-15 15:20:26.829879916 +0100
***************
*** 5518,5523 ****
--- 5518,5524 ----
case PV_KEY: return (char_u *)&(curbuf->b_p_key);
#endif
case PV_LISP: return (char_u *)&(curbuf->b_p_lisp);
+ case PV_LOP: return (char_u *)&(curbuf->b_p_lop);
case PV_ML: return (char_u *)&(curbuf->b_p_ml);
case PV_MPS: return (char_u *)&(curbuf->b_p_mps);
case PV_MA: return (char_u *)&(curbuf->b_p_ma);
***************
*** 6047,6052 ****
--- 6048,6055 ----
COPY_OPT_SCTX(buf, BV_CINO);
buf->b_p_cinsd = vim_strsave(p_cinsd);
COPY_OPT_SCTX(buf, BV_CINSD);
+ buf->b_p_lop = vim_strsave(p_lop);
+ COPY_OPT_SCTX(buf, BV_LOP);
// Don't copy 'filetype', it must be detected
buf->b_p_ft = empty_option;
*** ../vim-9.0.0760/src/option.h 2022-10-13 22:12:07.168673806 +0100
--- src/option.h 2022-10-15 15:37:45.606157648 +0100
***************
*** 709,714 ****
--- 709,715 ----
EXTERN long p_linespace; // 'linespace'
#endif
EXTERN int p_lisp; // 'lisp'
+ EXTERN char_u *p_lop; // 'lispoptions'
EXTERN char_u *p_lispwords; // 'lispwords'
EXTERN long p_ls; // 'laststatus'
EXTERN long p_stal; // 'showtabline'
***************
*** 1155,1160 ****
--- 1156,1162 ----
#endif
, BV_KP
, BV_LISP
+ , BV_LOP
, BV_LW
, BV_MENC
, BV_MA
*** ../vim-9.0.0760/src/change.c 2022-10-15 10:49:29.473268697 +0100
--- src/change.c 2022-10-15 15:52:41.351111116 +0100
***************
*** 2269,2288 ****
else
vreplace_mode = 0;
! if (!p_paste
! && leader == NULL
! && curbuf->b_p_lisp
! && curbuf->b_p_ai)
{
! // do lisp indenting
! fixthisline(get_lisp_indent);
! ai_col = (colnr_T)getwhitecols_curline();
! }
! else if (do_cindent)
! {
! // do 'cindent' or 'indentexpr' indenting
! do_c_expr_indent();
! ai_col = (colnr_T)getwhitecols_curline();
}
if (vreplace_mode != 0)
--- 2269,2291 ----
else
vreplace_mode = 0;
! if (!p_paste)
{
! if (leader == NULL
! && !use_indentexpr_for_lisp()
! && curbuf->b_p_lisp
! && curbuf->b_p_ai)
! {
! // do lisp indenting
! fixthisline(get_lisp_indent);
! ai_col = (colnr_T)getwhitecols_curline();
! }
! else if (do_cindent || (curbuf->b_p_ai && use_indentexpr_for_lisp()))
! {
! // do 'cindent' or 'indentexpr' indenting
! do_c_expr_indent();
! ai_col = (colnr_T)getwhitecols_curline();
! }
}
if (vreplace_mode != 0)
*** ../vim-9.0.0760/src/indent.c 2022-10-13 12:29:34.233533860 +0100
--- src/indent.c 2022-10-15 15:52:08.795125369 +0100
***************
*** 2197,2214 ****
}
/*
* Fix indent for 'lisp' and 'cindent'.
*/
void
fix_indent(void)
{
if (p_paste)
! return;
if (curbuf->b_p_lisp && curbuf->b_p_ai)
! fixthisline(get_lisp_indent);
! else
! if (cindent_on())
do_c_expr_indent();
}
#if defined(FEAT_EVAL) || defined(PROTO)
--- 2197,2234 ----
}
/*
+ * Return TRUE if 'indentexpr' should be used for Lisp indenting.
+ * Caller may want to check 'autoindent'.
+ */
+ int
+ use_indentexpr_for_lisp(void)
+ {
+ #ifdef FEAT_EVAL
+ return curbuf->b_p_lisp
+ && *curbuf->b_p_inde != NUL
+ && STRCMP(curbuf->b_p_lop, "expr:1") == 0;
+ #else
+ return FALSE;
+ #endif
+ }
+
+ /*
* Fix indent for 'lisp' and 'cindent'.
*/
void
fix_indent(void)
{
if (p_paste)
! return; // no auto-indenting when 'paste' is set
if (curbuf->b_p_lisp && curbuf->b_p_ai)
! {
! if (use_indentexpr_for_lisp())
do_c_expr_indent();
+ else
+ fixthisline(get_lisp_indent);
+ }
+ else if (cindent_on())
+ do_c_expr_indent();
}
#if defined(FEAT_EVAL) || defined(PROTO)
*** ../vim-9.0.0760/src/proto/
indent.pro 2022-06-27 23:15:11.000000000 +0100
--- src/proto/
indent.pro 2022-10-15 15:36:13.370461005 +0100
***************
*** 31,36 ****
--- 31,37 ----
int get_expr_indent(void);
int get_lisp_indent(void);
void fixthisline(int (*get_the_indent)(void));
+ int use_indentexpr_for_lisp(void);
void fix_indent(void);
void f_indent(typval_T *argvars, typval_T *rettv);
void f_lispindent(typval_T *argvars, typval_T *rettv);
*** ../vim-9.0.0760/src/testdir/test_lispindent.vim 2022-10-15 10:49:29.473268697 +0100
--- src/testdir/test_lispindent.vim 2022-10-15 15:59:25.546700778 +0100
***************
*** 97,104 ****
--- 97,119 ----
exe "normal a(x\<CR>1\<CR>2)\<Esc>"
let expected = ['(x', ' 1', ' 2)']
call assert_equal(expected, getline(1, 3))
+ " with Lisp indenting the first line is not indented
normal 1G=G
call assert_equal(expected, getline(1, 3))
+
+ %del
+ setl lispoptions=expr:1 indentexpr=5
+ exe "normal a(x\<CR>1\<CR>2)\<Esc>"
+ let expected_expr = ['(x', ' 1', ' 2)']
+ call assert_equal(expected_expr, getline(1, 3))
+ normal 2G2<<=G
+ call assert_equal(expected_expr, getline(1, 3))
+
+ setl lispoptions=expr:0
+ " with Lisp indenting the first line is not indented
+ normal 1G3<<=G
+ call assert_equal(expected, getline(1, 3))
+
bwipe!
endfunc
*** ../vim-9.0.0760/src/version.c 2022-10-15 14:24:25.940988629 +0100
--- src/version.c 2022-10-15 15:39:56.713788932 +0100
***************
*** 697,698 ****
--- 697,700 ----
{ /* Add new patch number below this line */
+ /**/
+ 761,
/**/
--
LAUNCELOT: Isn't there a St. Aaaaarrrrrrggghhh's in Cornwall?
ARTHUR: No, that's Saint Ives.
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///