mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
vim-patch:9.0.0761: cannot use 'indentexpr' for Lisp indenting
Problem: Cannot use 'indentexpr' for Lisp indenting. Solution: Add the 'lispoptions' option.49846fb1a3
vim-patch:9.0.0762: build failure Problem: Build failure. Solution: Add missing change.4b082c4bd0
This commit is contained in:
@@ -3352,7 +3352,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.
|
in Insert mode as specified with the 'indentkeys' option.
|
||||||
When this option is not empty, it overrules the 'cindent' and
|
When this option is not empty, it overrules the 'cindent' and
|
||||||
'smartindent' indenting. When 'lisp' is set, this option is
|
'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.
|
When 'paste' is set this option is not used for indenting.
|
||||||
The expression is evaluated with |v:lnum| set to the line number for
|
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
|
which the indent is to be computed. The cursor is also in this line
|
||||||
@@ -3719,6 +3719,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.
|
calling an external program if 'equalprg' is empty.
|
||||||
This option is not used when 'paste' is set.
|
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'*
|
||||||
'lispwords' 'lw' string (default is very long)
|
'lispwords' 'lw' string (default is very long)
|
||||||
global or local to buffer |global-local|
|
global or local to buffer |global-local|
|
||||||
|
@@ -1959,8 +1959,9 @@ void free_buf_options(buf_T *buf, int free_p_ff)
|
|||||||
clear_string_option(&buf->b_p_ft);
|
clear_string_option(&buf->b_p_ft);
|
||||||
clear_string_option(&buf->b_p_cink);
|
clear_string_option(&buf->b_p_cink);
|
||||||
clear_string_option(&buf->b_p_cino);
|
clear_string_option(&buf->b_p_cino);
|
||||||
clear_string_option(&buf->b_p_cinw);
|
clear_string_option(&buf->b_p_lop);
|
||||||
clear_string_option(&buf->b_p_cinsd);
|
clear_string_option(&buf->b_p_cinsd);
|
||||||
|
clear_string_option(&buf->b_p_cinw);
|
||||||
clear_string_option(&buf->b_p_cpt);
|
clear_string_option(&buf->b_p_cpt);
|
||||||
clear_string_option(&buf->b_p_cfu);
|
clear_string_option(&buf->b_p_cfu);
|
||||||
clear_string_option(&buf->b_p_ofu);
|
clear_string_option(&buf->b_p_ofu);
|
||||||
|
@@ -699,6 +699,7 @@ struct file_buffer {
|
|||||||
uint32_t b_p_fex_flags; ///< flags for 'formatexpr'
|
uint32_t b_p_fex_flags; ///< flags for 'formatexpr'
|
||||||
char *b_p_kp; ///< 'keywordprg'
|
char *b_p_kp; ///< 'keywordprg'
|
||||||
int b_p_lisp; ///< 'lisp'
|
int b_p_lisp; ///< 'lisp'
|
||||||
|
char *b_p_lop; ///< 'lispoptions'
|
||||||
char *b_p_menc; ///< 'makeencoding'
|
char *b_p_menc; ///< 'makeencoding'
|
||||||
char *b_p_mps; ///< 'matchpairs'
|
char *b_p_mps; ///< 'matchpairs'
|
||||||
int b_p_ml; ///< 'modeline'
|
int b_p_ml; ///< 'modeline'
|
||||||
|
@@ -1814,17 +1814,19 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
|
|||||||
vreplace_mode = 0;
|
vreplace_mode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p_paste
|
if (!p_paste) {
|
||||||
&& leader == NULL
|
if (leader == NULL
|
||||||
&& curbuf->b_p_lisp
|
&& !use_indentexpr_for_lisp()
|
||||||
&& curbuf->b_p_ai) {
|
&& curbuf->b_p_lisp
|
||||||
// do lisp indenting
|
&& curbuf->b_p_ai) {
|
||||||
fixthisline(get_lisp_indent);
|
// do lisp indenting
|
||||||
ai_col = (colnr_T)getwhitecols_curline();
|
fixthisline(get_lisp_indent);
|
||||||
} else if (do_cindent) {
|
ai_col = (colnr_T)getwhitecols_curline();
|
||||||
// do 'cindent' or 'indentexpr' indenting
|
} else if (do_cindent || (curbuf->b_p_ai && use_indentexpr_for_lisp())) {
|
||||||
do_c_expr_indent();
|
// do 'cindent' or 'indentexpr' indenting
|
||||||
ai_col = (colnr_T)getwhitecols_curline();
|
do_c_expr_indent();
|
||||||
|
ai_col = (colnr_T)getwhitecols_curline();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vreplace_mode != 0) {
|
if (vreplace_mode != 0) {
|
||||||
|
@@ -2993,34 +2993,6 @@ bool cindent_on(void)
|
|||||||
return !p_paste && (curbuf->b_p_cin || *curbuf->b_p_inde != NUL);
|
return !p_paste && (curbuf->b_p_cin || *curbuf->b_p_inde != NUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-indent the current line, based on the current contents of it and the
|
|
||||||
// surrounding lines. Fixing the cursor position seems really easy -- I'm very
|
|
||||||
// confused what all the part that handles Control-T is doing that I'm not.
|
|
||||||
// "get_the_indent" should be get_c_indent, get_expr_indent or get_lisp_indent.
|
|
||||||
void fixthisline(IndentGetter get_the_indent)
|
|
||||||
{
|
|
||||||
int amount = get_the_indent();
|
|
||||||
|
|
||||||
if (amount >= 0) {
|
|
||||||
change_indent(INDENT_SET, amount, false, 0, true);
|
|
||||||
if (linewhite(curwin->w_cursor.lnum)) {
|
|
||||||
did_ai = true; // delete the indent if the line stays empty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check that "cinkeys" contains the key "keytyped",
|
/// Check that "cinkeys" contains the key "keytyped",
|
||||||
/// when == '*': Only if key is preceded with '*' (indent before insert)
|
/// when == '*': Only if key is preceded with '*' (indent before insert)
|
||||||
/// when == '!': Only if key is preceded with '!' (don't insert)
|
/// when == '!': Only if key is preceded with '!' (don't insert)
|
||||||
|
@@ -4,8 +4,6 @@
|
|||||||
#include "nvim/autocmd.h"
|
#include "nvim/autocmd.h"
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
|
|
||||||
typedef int (*IndentGetter)(void);
|
|
||||||
|
|
||||||
// Values for in_cinkeys()
|
// Values for in_cinkeys()
|
||||||
#define KEY_OPEN_FORW 0x101
|
#define KEY_OPEN_FORW 0x101
|
||||||
#define KEY_OPEN_BACK 0x102
|
#define KEY_OPEN_BACK 0x102
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
#include "nvim/eval.h"
|
#include "nvim/eval.h"
|
||||||
#include "nvim/extmark.h"
|
#include "nvim/extmark.h"
|
||||||
#include "nvim/indent.h"
|
#include "nvim/indent.h"
|
||||||
|
#include "nvim/indent_c.h"
|
||||||
#include "nvim/mark.h"
|
#include "nvim/mark.h"
|
||||||
#include "nvim/memline.h"
|
#include "nvim/memline.h"
|
||||||
#include "nvim/memory.h"
|
#include "nvim/memory.h"
|
||||||
@@ -1144,3 +1145,45 @@ static int lisp_match(char_u *p)
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Re-indent the current line, based on the current contents of it and the
|
||||||
|
/// surrounding lines. Fixing the cursor position seems really easy -- I'm very
|
||||||
|
/// confused what all the part that handles Control-T is doing that I'm not.
|
||||||
|
/// "get_the_indent" should be get_c_indent, get_expr_indent or get_lisp_indent.
|
||||||
|
void fixthisline(IndentGetter get_the_indent)
|
||||||
|
{
|
||||||
|
int amount = get_the_indent();
|
||||||
|
|
||||||
|
if (amount >= 0) {
|
||||||
|
change_indent(INDENT_SET, amount, false, 0, true);
|
||||||
|
if (linewhite(curwin->w_cursor.lnum)) {
|
||||||
|
did_ai = true; // delete the indent if the line stays empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return true if 'indentexpr' should be used for Lisp indenting.
|
||||||
|
/// Caller may want to check 'autoindent'.
|
||||||
|
bool use_indentexpr_for_lisp(void)
|
||||||
|
{
|
||||||
|
return curbuf->b_p_lisp
|
||||||
|
&& *curbuf->b_p_inde != NUL
|
||||||
|
&& strcmp(curbuf->b_p_lop, "expr:1") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
|
|
||||||
|
typedef int (*IndentGetter)(void);
|
||||||
|
|
||||||
// flags for set_indent()
|
// flags for set_indent()
|
||||||
#define SIN_CHANGED 1 // call changed_bytes() when line changed
|
#define SIN_CHANGED 1 // call changed_bytes() when line changed
|
||||||
#define SIN_INSERT 2 // insert indent before existing text
|
#define SIN_INSERT 2 // insert indent before existing text
|
||||||
|
@@ -4008,6 +4008,8 @@ static char_u *get_varp(vimoption_T *p)
|
|||||||
return (char_u *)&(curbuf->b_p_fex);
|
return (char_u *)&(curbuf->b_p_fex);
|
||||||
case PV_LISP:
|
case PV_LISP:
|
||||||
return (char_u *)&(curbuf->b_p_lisp);
|
return (char_u *)&(curbuf->b_p_lisp);
|
||||||
|
case PV_LOP:
|
||||||
|
return (char_u *)&(curbuf->b_p_lop);
|
||||||
case PV_ML:
|
case PV_ML:
|
||||||
return (char_u *)&(curbuf->b_p_ml);
|
return (char_u *)&(curbuf->b_p_ml);
|
||||||
case PV_MPS:
|
case PV_MPS:
|
||||||
@@ -4414,6 +4416,8 @@ void buf_copy_options(buf_T *buf, int flags)
|
|||||||
COPY_OPT_SCTX(buf, BV_CINO);
|
COPY_OPT_SCTX(buf, BV_CINO);
|
||||||
buf->b_p_cinsd = xstrdup(p_cinsd);
|
buf->b_p_cinsd = xstrdup(p_cinsd);
|
||||||
COPY_OPT_SCTX(buf, BV_CINSD);
|
COPY_OPT_SCTX(buf, BV_CINSD);
|
||||||
|
buf->b_p_lop = xstrdup(p_lop);
|
||||||
|
COPY_OPT_SCTX(buf, BV_LOP);
|
||||||
|
|
||||||
// Don't copy 'filetype', it must be detected
|
// Don't copy 'filetype', it must be detected
|
||||||
buf->b_p_ft = empty_option;
|
buf->b_p_ft = empty_option;
|
||||||
|
@@ -580,6 +580,7 @@ EXTERN char_u *p_lm; // 'langmenu'
|
|||||||
EXTERN long p_lines; // 'lines'
|
EXTERN long p_lines; // 'lines'
|
||||||
EXTERN long p_linespace; // 'linespace'
|
EXTERN long p_linespace; // 'linespace'
|
||||||
EXTERN int p_lisp; ///< 'lisp'
|
EXTERN int p_lisp; ///< 'lisp'
|
||||||
|
EXTERN char *p_lop; ///< 'lispoptions'
|
||||||
EXTERN char_u *p_lispwords; // 'lispwords'
|
EXTERN char_u *p_lispwords; // 'lispwords'
|
||||||
EXTERN long p_ls; // 'laststatus'
|
EXTERN long p_ls; // 'laststatus'
|
||||||
EXTERN long p_stal; // 'showtabline'
|
EXTERN long p_stal; // 'showtabline'
|
||||||
@@ -878,6 +879,7 @@ enum {
|
|||||||
BV_KMAP,
|
BV_KMAP,
|
||||||
BV_KP,
|
BV_KP,
|
||||||
BV_LISP,
|
BV_LISP,
|
||||||
|
BV_LOP,
|
||||||
BV_LW,
|
BV_LW,
|
||||||
BV_MENC,
|
BV_MENC,
|
||||||
BV_MA,
|
BV_MA,
|
||||||
|
@@ -1363,6 +1363,14 @@ return {
|
|||||||
varname='p_lisp',
|
varname='p_lisp',
|
||||||
defaults={if_true=false}
|
defaults={if_true=false}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
full_name='lispoptions', abbreviation='lop',
|
||||||
|
short_desc=N_("options for lisp indenting"),
|
||||||
|
type='string', list='onecomma', scope={'buffer'},
|
||||||
|
deny_duplicates=true,
|
||||||
|
varname='p_lop', pv_name='p_lop',
|
||||||
|
defaults={if_true=''}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
full_name='lispwords', abbreviation='lw',
|
full_name='lispwords', abbreviation='lw',
|
||||||
short_desc=N_("words that change how lisp indenting works"),
|
short_desc=N_("words that change how lisp indenting works"),
|
||||||
|
@@ -228,6 +228,7 @@ void check_buf_options(buf_T *buf)
|
|||||||
check_string_option(&buf->b_p_cink);
|
check_string_option(&buf->b_p_cink);
|
||||||
check_string_option(&buf->b_p_cino);
|
check_string_option(&buf->b_p_cino);
|
||||||
parse_cino(buf);
|
parse_cino(buf);
|
||||||
|
check_string_option(&buf->b_p_lop);
|
||||||
check_string_option(&buf->b_p_ft);
|
check_string_option(&buf->b_p_ft);
|
||||||
check_string_option(&buf->b_p_cinw);
|
check_string_option(&buf->b_p_cinw);
|
||||||
check_string_option(&buf->b_p_cinsd);
|
check_string_option(&buf->b_p_cinsd);
|
||||||
@@ -1378,6 +1379,10 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
|
|||||||
} else if (gvarp == &p_cino) { // 'cinoptions'
|
} else if (gvarp == &p_cino) { // 'cinoptions'
|
||||||
// TODO(vim): recognize errors
|
// TODO(vim): recognize errors
|
||||||
parse_cino(curbuf);
|
parse_cino(curbuf);
|
||||||
|
} else if (gvarp == &p_lop) { // 'lispoptions'
|
||||||
|
if (**varp != NUL && strcmp(*varp, "expr:0") != 0 && strcmp(*varp, "expr:1") != 0) {
|
||||||
|
errmsg = e_invarg;
|
||||||
|
}
|
||||||
} else if (varp == &p_icm) { // 'inccommand'
|
} else if (varp == &p_icm) { // 'inccommand'
|
||||||
if (check_opt_strings(p_icm, p_icm_values, false) != OK) {
|
if (check_opt_strings(p_icm, p_icm_values, false) != OK) {
|
||||||
errmsg = e_invarg;
|
errmsg = e_invarg;
|
||||||
|
@@ -97,8 +97,23 @@ func Test_lispindent_with_indentexpr()
|
|||||||
exe "normal a(x\<CR>1\<CR>2)\<Esc>"
|
exe "normal a(x\<CR>1\<CR>2)\<Esc>"
|
||||||
let expected = ['(x', ' 1', ' 2)']
|
let expected = ['(x', ' 1', ' 2)']
|
||||||
call assert_equal(expected, getline(1, 3))
|
call assert_equal(expected, getline(1, 3))
|
||||||
|
" with Lisp indenting the first line is not indented
|
||||||
normal 1G=G
|
normal 1G=G
|
||||||
call assert_equal(expected, getline(1, 3))
|
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!
|
bwipe!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user