0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

patch 9.0.0761: cannot use 'indentexpr' for Lisp indenting

Problem:    Cannot use 'indentexpr' for Lisp indenting.
Solution:   Add the 'lispoptions' option.
This commit is contained in:
Bram Moolenaar
2022-10-15 16:05:33 +01:00
parent 297164cb79
commit 49846fb1a3
11 changed files with 95 additions and 24 deletions

View File

@@ -4621,7 +4621,7 @@ A jump table for the options with a short description can be found at |Q_op|.
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.
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
@@ -5063,6 +5063,17 @@ A jump table for the options with a short description can be found at |Q_op|.
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|

View File

@@ -2390,6 +2390,7 @@ free_buf_options(
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);

View File

@@ -2269,8 +2269,10 @@ open_line(
else
vreplace_mode = 0;
if (!p_paste
&& leader == NULL
if (!p_paste)
{
if (leader == NULL
&& !use_indentexpr_for_lisp()
&& curbuf->b_p_lisp
&& curbuf->b_p_ai)
{
@@ -2278,12 +2280,13 @@ open_line(
fixthisline(get_lisp_indent);
ai_col = (colnr_T)getwhitecols_curline();
}
else if (do_cindent)
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)
State = vreplace_mode;

View File

@@ -2196,6 +2196,22 @@ fixthisline(int (*get_the_indent)(void))
}
}
/*
* 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'.
*/
@@ -2203,11 +2219,15 @@ fixthisline(int (*get_the_indent)(void))
fix_indent(void)
{
if (p_paste)
return;
return; // no auto-indenting when 'paste' is set
if (curbuf->b_p_lisp && curbuf->b_p_ai)
fixthisline(get_lisp_indent);
{
if (use_indentexpr_for_lisp())
do_c_expr_indent();
else
if (cindent_on())
fixthisline(get_lisp_indent);
}
else if (cindent_on())
do_c_expr_indent();
}

View File

@@ -5518,6 +5518,7 @@ get_varp(struct vimoption *p)
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,6 +6048,8 @@ buf_copy_options(buf_T *buf, int flags)
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;

View File

@@ -709,6 +709,7 @@ EXTERN char_u *p_lm; // 'langmenu'
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,6 +1156,7 @@ enum
#endif
, BV_KP
, BV_LISP
, BV_LOP
, BV_LW
, BV_MENC
, BV_MA

View File

@@ -96,6 +96,7 @@
#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)
@@ -1522,6 +1523,9 @@ static struct vimoption options[] =
{"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},

View File

@@ -259,6 +259,7 @@ check_buf_options(buf_T *buf)
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,6 +2103,14 @@ did_set_string_option(
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)

View File

@@ -31,6 +31,7 @@ void ex_retab(exarg_T *eap);
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);

View File

@@ -97,8 +97,23 @@ func Test_lispindent_with_indentexpr()
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

View File

@@ -695,6 +695,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
761,
/**/
760,
/**/