'inccommand': buftype=nofile, restore cursor/view

- Use a standard scratch buffer instead of a new 'buftype', functions
  like curbufIsChanged() already have special handling for scratch bufs.
- Cleanup some stuff from the previous merge.
- Add support for :smagic, :snomagic. Closes #5578
This commit is contained in:
Justin M. Keyes 2016-11-09 12:08:49 +01:00
parent 0213e99aaf
commit 2e1217da46
9 changed files with 73 additions and 42 deletions

View File

@ -1155,21 +1155,14 @@ A jump table for the options with a short description can be found at |Q_op|.
*'buftype'* *'bt'* *E382*
'buftype' 'bt' string (default: "")
local to buffer
{not available when compiled without the |+quickfix|
feature}
The value of this option specifies the type of a buffer:
<empty> normal buffer
nofile buffer which is not related to a file and will not be
written
nowrite buffer which will not be written
acwrite buffer which will always be written with BufWriteCmd
autocommands.
quickfix quickfix buffer, contains list of errors |:cwindow|
or list of locations |:lwindow|
help help buffer (you are not supposed to set this
manually)
terminal terminal buffer, this is set automatically when a
terminal is created. |terminal-emulator|
acwrite buffer will always be written with |BufWriteCmd|s
help help buffer (do not set this manually)
nofile buffer is not related to a file, will not be written
nowrite buffer will not be written
quickfix list of errors |:cwindow| or locations |:lwindow|
terminal |terminal-emulator| buffer
This option is used together with 'bufhidden' and 'swapfile' to
specify special kinds of buffers. See |special-buffers|.
@ -3420,10 +3413,10 @@ A jump table for the options with a short description can be found at |Q_op|.
'inccommand' 'icm' string (default "")
global
"nosplit" : Shows the effects of a command incrementally, as you type.
"split" : Also shows partial off-screen results in a preview window.
"nosplit": Shows the effects of a command incrementally, as you type.
"split" : Also shows partial off-screen results in a preview window.
Currently only works for |:substitute|. |hl-Substitute|
Works for |:substitute|, |:smagic|, |:snomagic|. |hl-Substitute|
*'include'* *'inc'*
'include' 'inc' string (default "^\s*#\s*include")

View File

@ -56,7 +56,7 @@ syn keyword vimGroup contained Comment Constant String Character Number Boolean
syn keyword vimHLGroup contained ColorColumn Cursor CursorColumn CursorIM CursorLine CursorLineNr DiffAdd DiffChange DiffDelete DiffText Directory ErrorMsg FoldColumn Folded IncSearch LineNr MatchParen Menu ModeMsg MoreMsg NonText Normal Pmenu PmenuSbar PmenuSel PmenuThumb Question Scrollbar Search SignColumn SpecialKey SpellBad SpellCap SpellLocal SpellRare StatusLine StatusLineNC TabLine TabLineFill TabLineSel Title Tooltip VertSplit Visual WarningMsg WildMenu
syn match vimHLGroup contained "Conceal"
syn keyword vimOnlyHLGroup contained VisualNOS
syn keyword nvimHLGroup contained EndOfBuffer IncSubstitute TermCursor TermCursorNC QuickFixLine
syn keyword nvimHLGroup contained EndOfBuffer Substitute TermCursor TermCursorNC QuickFixLine
"}}}2
syn case match
" Special Vim Highlighting (not automatic) {{{1

View File

@ -5273,14 +5273,20 @@ wipe_buffer (
}
}
/// Creates or switches to a special-purpose buffer.
/// Creates or switches to a scratch buffer. :h special-buffers
/// Scratch buffer is:
/// - buftype=nofile bufhidden=hide noswapfile
/// - Always considered 'nomodified'
///
/// @param bufnr Buffer to switch to, or 0 to create a new buffer.
void buf_open_special(handle_T bufnr, char *bufname, char *buftype)
///
/// @see curbufIsChanged()
void buf_open_scratch(handle_T bufnr, char *bufname)
{
(void)do_ecmd((int)bufnr, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
(void)setfname(curbuf, (char_u *)bufname, NULL, true);
set_option_value((char_u *)"bt", 0L, (char_u *)buftype, OPT_LOCAL);
set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL);
set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
RESET_BINDING(curwin);
}

View File

@ -2188,7 +2188,6 @@ int do_ecmd(
if (fnum) {
buf = buflist_findnr(fnum);
} else {
ILOG("here");
if (flags & ECMD_ADDBUF) {
linenr_T tlnum = 1L;
@ -3275,8 +3274,7 @@ buf_T *do_sub(exarg_T *eap)
return NULL;
}
int search_options = eap->is_live ? 0 : SEARCH_HIS;
if (search_regcomp(pat, RE_SUBST, which_pat, search_options,
if (search_regcomp(pat, RE_SUBST, which_pat, (eap->is_live ? 0 : SEARCH_HIS),
&regmatch) == FAIL) {
if (subflags.do_error) {
EMSG(_(e_invcmd));
@ -3951,13 +3949,10 @@ skip:
// Show 'inccommand' preview if there are matched lines.
buf_T *preview_buf = NULL;
if (eap->is_live && matched_lines.size != 0 && pat != NULL && *p_icm != NUL) {
if (eap->is_live && *p_icm != NUL && matched_lines.size != 0 && pat != NULL) {
curbuf->b_changed = save_b_changed; // preserve 'modified' during preview
preview_buf = show_sub(old_cursor, pat, sub, eap->line1, eap->line2,
&matched_lines);
} else if (*p_icm != NUL && eap->is_live) {
curwin->w_cursor = old_cursor; // don't move the cursor
}
for (MatchedLine m; kv_size(matched_lines);) {
@ -6058,10 +6053,9 @@ static buf_T *show_sub(pos_T old_cusr, char_u *pat, char_u *sub, linenr_T line1,
}
if (split && win_split((int)p_cwh, WSP_BOT) != FAIL) {
buf_open_special(preview_buf ? bufnr : 0, "[Preview]", "incsub");
buf_open_scratch(preview_buf ? bufnr : 0, "[Preview]");
buf_clear();
preview_buf = curbuf;
set_option_value((char_u *)"bufhidden", 0L, (char_u *)"hide", OPT_LOCAL);
bufnr = preview_buf->handle;
curbuf->b_p_bl = false;
curbuf->b_p_ma = true;
@ -6092,7 +6086,7 @@ static buf_T *show_sub(pos_T old_cusr, char_u *pat, char_u *sub, linenr_T line1,
old_line_size = line_size;
}
// put " | lnum|line" into str and append it to the preview buffer
// Put "|lnum| line" into `str` and append it to the preview buffer.
snprintf(str, line_size, "|%*ld| %s", col_width - 3, mat.lnum, mat.line);
ml_append(line, (char_u *)str, (colnr_T)line_size, false);
@ -6155,6 +6149,7 @@ void ex_substitute(exarg_T *eap)
buf_T *preview_buf = do_sub(eap);
if (save_changedtick != curbuf->b_changedtick) {
// Undo invisibly. This also moves the cursor!
if (!u_undo_and_forget(1)) { abort(); }
// Restore newhead. It is meaningless when curhead is valid, but we must
// restore it so that undotree() is identical before/after the preview.

View File

@ -14,7 +14,6 @@
#define ECMD_OLDBUF 0x04 // use existing buffer if it exists
#define ECMD_FORCEIT 0x08 // ! used in Ex command
#define ECMD_ADDBUF 0x10 // don't edit, just add to buffer list
#define ECMD_RESERVED_BUFNR 0x20 // bufnr argument is reserved bufnr
/* for lnum argument in do_ecmd() */

View File

@ -7295,15 +7295,13 @@ void ex_may_print(exarg_T *eap)
}
}
/*
* ":smagic" and ":snomagic".
*/
/// ":smagic" and ":snomagic".
static void ex_submagic(exarg_T *eap)
{
int magic_save = p_magic;
p_magic = (eap->cmdidx == CMD_smagic);
do_sub(eap);
ex_substitute(eap);
p_magic = magic_save;
}
@ -9669,5 +9667,7 @@ bool cmd_is_live(char_u *cmd)
}
find_command(&ea, NULL);
return (ea.cmdidx == CMD_substitute);
return ea.cmdidx == CMD_substitute
|| ea.cmdidx == CMD_smagic
|| ea.cmdidx == CMD_snomagic;
}

View File

@ -5147,7 +5147,9 @@ static int ex_window(void)
cmdwin_type = get_cmdline_type();
// Create empty command-line buffer.
buf_open_special(0, "[Command Line]", "nofile");
buf_open_scratch(0, "[Command Line]");
// Command-line buffer has bufhidden=wipe, unlike a true "scratch" buffer.
set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL);
curwin->w_p_rl = cmdmsg_rl;
cmdmsg_rl = false;
curbuf->b_p_ma = true;

View File

@ -1685,7 +1685,8 @@ void u_redo(int count)
u_doit(count, false);
}
/// undo, and remove the undo branch from the undo tree.
/// Undo and remove the branch from the undo tree.
/// Also moves the cursor (as a "normal" undo would).
bool u_undo_and_forget(int count)
{
if (curbuf->b_u_synced == false) {

View File

@ -944,7 +944,7 @@ describe(":substitute, inccommand=split", function()
end)
describe(":substitute, inccommand=nosplit", function()
describe("inccommand=nosplit", function()
if helpers.pending_win32(pending) then return end
local screen = Screen.new(20,10)
@ -958,7 +958,42 @@ describe(":substitute, inccommand=nosplit", function()
if screen then screen:detach() end
end)
it('does not show a split window anytime', function()
it("works with :smagic, :snomagic", function()
execute("set hlsearch")
insert("Line *.3.* here")
feed(":%smagic/3.*/X") -- start :smagic command
screen:expect([[
Inc substitution on |
two lines |
Inc substitution on |
two lines |
Line *.X |
{15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
:%smagic/3.*/X^ |
]])
feed([[<C-\><C-N>]]) -- cancel
feed(":%snomagic/3.*/X") -- start :snomagic command
screen:expect([[
Inc substitution on |
two lines |
Inc substitution on |
two lines |
Line *.X here |
{15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
:%snomagic/3.*/X^ |
]])
end)
it('never shows preview buffer', function()
execute("set hlsearch")
feed(":%s/tw")
@ -1163,7 +1198,7 @@ describe("'inccommand' and :cnoremap", function()
end)
describe("'inccommand': autocommands", function()
describe("'inccommand' autocommands", function()
before_each(clear)
-- keys are events to be tested
@ -1251,7 +1286,7 @@ describe("'inccommand': autocommands", function()
end)
describe("'inccommand': split windows", function()
describe("'inccommand' split windows", function()
if helpers.pending_win32(pending) then return end
local screen