mirror of
https://github.com/vim/vim
synced 2025-07-18 18:21:55 +00:00
Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
dada6d2a8e | |||
ef68e4fa52 | |||
3346cc4ffb | |||
995e4afcfe | |||
9ac9dfa9e2 | |||
2c809b7c7d | |||
9e8dcf9d6f | |||
da73253a0b | |||
3d593c2dc9 | |||
2db0ec4b2e | |||
5c6dbcb03f | |||
4e83961985 | |||
4bebc9a056 | |||
a539f4f1ae | |||
1a333bc44a |
@ -4632,20 +4632,24 @@ getqflist([{what}]) *getqflist()*
|
||||
returns only the items listed in {what} as a dictionary. The
|
||||
following string items are supported in {what}:
|
||||
context get the context stored with |setqflist()|
|
||||
id get information for the quickfix list with
|
||||
|quickfix-ID|; zero means the id for the
|
||||
current list or the list specifed by 'nr'
|
||||
items quickfix list entries
|
||||
lines use 'errorformat' to extract items from a list
|
||||
of lines and return the resulting entries.
|
||||
Only a |List| type is accepted. The current
|
||||
quickfix list is not modified.
|
||||
nr get information for this quickfix list; zero
|
||||
means the current quickfix list and '$' means
|
||||
the last quickfix list
|
||||
text use 'errorformat' to extract items from the
|
||||
text and return the resulting entries. The
|
||||
value can be a string with one line or a list
|
||||
with multiple lines. The current quickfix list
|
||||
is not modified.
|
||||
title get the list title
|
||||
winid get the |window-ID| (if opened)
|
||||
all all of the above quickfix properties
|
||||
Non-string items in {what} are ignored.
|
||||
If "nr" is not present then the current quickfix list is used.
|
||||
If both "nr" and a non-zero "id" are specified, then the list
|
||||
specified by "id" is used.
|
||||
To get the number of lists in the quickfix stack, set 'nr' to
|
||||
'$' in {what}. The 'nr' value in the returned dictionary
|
||||
contains the quickfix stack size.
|
||||
@ -4657,6 +4661,7 @@ getqflist([{what}]) *getqflist()*
|
||||
|
||||
The returned dictionary contains the following entries:
|
||||
context context information stored with |setqflist()|
|
||||
id quickfix list ID |quickfix-ID|
|
||||
items quickfix list entries
|
||||
nr quickfix list number
|
||||
title quickfix list title text
|
||||
@ -4665,6 +4670,7 @@ getqflist([{what}]) *getqflist()*
|
||||
Examples: >
|
||||
:echo getqflist({'all': 1})
|
||||
:echo getqflist({'nr': 2, 'title': 1})
|
||||
:echo getqflist({'lines' : ["F1:10:L10"]})
|
||||
<
|
||||
|
||||
getreg([{regname} [, 1 [, {list}]]]) *getreg()*
|
||||
@ -7065,12 +7071,12 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()*
|
||||
argument is ignored. The following items can be specified in
|
||||
{what}:
|
||||
context any Vim type can be stored as a context
|
||||
text use 'errorformat' to extract items from the
|
||||
text and add the resulting entries to the
|
||||
quickfix list {nr}. The value can be a string
|
||||
with one line or a list with multiple lines.
|
||||
id quickfix list identifier |quickfix-ID|
|
||||
items list of quickfix entries. Same as the {list}
|
||||
argument.
|
||||
lines use 'errorformat' to parse a list of lines and
|
||||
add the resulting entries to the quickfix list
|
||||
{nr} or {id}. Only a |List| value is supported.
|
||||
nr list number in the quickfix stack; zero
|
||||
means the current quickfix list and '$' means
|
||||
the last quickfix list
|
||||
@ -7079,10 +7085,14 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()*
|
||||
If the "nr" item is not present, then the current quickfix list
|
||||
is modified. When creating a new quickfix list, "nr" can be
|
||||
set to a value one greater than the quickfix stack size.
|
||||
When modifying a quickfix list, to guarantee that the correct
|
||||
list is modified, 'id' should be used instead of 'nr' to
|
||||
specify the list.
|
||||
|
||||
Examples: >
|
||||
:call setqflist([], 'r', {'title': 'My search'})
|
||||
:call setqflist([], 'r', {'nr': 2, 'title': 'Errors'})
|
||||
:call setqflist([], 'r', {'title': 'My search'})
|
||||
:call setqflist([], 'r', {'nr': 2, 'title': 'Errors'})
|
||||
:call setqflist([], 'a', {'id':myid, 'lines':["F1:10:L10"]})
|
||||
<
|
||||
Returns zero for success, -1 for failure.
|
||||
|
||||
@ -8131,6 +8141,12 @@ term_start({cmd}, {options}) *term_start()*
|
||||
have "%d" where the buffer number goes,
|
||||
e.g. "10split|buffer %d"; when not
|
||||
specified "botright sbuf %d" is used
|
||||
"eof_chars" Text to send after all buffer lines were
|
||||
written to the terminal. When not set
|
||||
CTRL-D is used. For Python use CTRL-Z or
|
||||
"exit()". For a shell use "exit". A CR
|
||||
is always added.
|
||||
{only on MS-Windows}
|
||||
|
||||
{only available when compiled with the |+terminal| feature}
|
||||
|
||||
|
@ -832,6 +832,9 @@ Use the RPM or port for your system.
|
||||
|
||||
Currently, GUI Vim supports three styles, |OverTheSpot|, |OffTheSpot| and
|
||||
|Root|.
|
||||
When compiled with |+GUI_GTK| feature, GUI Vim supports two styles,
|
||||
|OnTheSpot| and |OverTheSpot|. You can select the style with the 'imstyle'
|
||||
option.
|
||||
|
||||
*. on-the-spot *OnTheSpot*
|
||||
Preedit Area and Status Area are performed by the client application in
|
||||
|
@ -4356,6 +4356,23 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
<
|
||||
NOTE: This function is invoked very often. Keep it fast.
|
||||
|
||||
*'imstyle'* *'imst'*
|
||||
'imstyle' 'imst' number (default 1)
|
||||
global
|
||||
{not in Vi}
|
||||
{only available when compiled with |+xim| and
|
||||
|+GUI_GTK|}
|
||||
This option specifies the input style of Input Method.
|
||||
Set to zero if you want to use on-the-spot style.
|
||||
Set to one if you want to use over-the-spot style.
|
||||
See: |xim-input-style|
|
||||
|
||||
For a long time on-the-spot sytle had been used in GTK version of vim,
|
||||
however, it is known that it causes troubles when using mappings,
|
||||
|single-repeat|, etc. Therefore over-the-spot style becomes the
|
||||
default now. This should work fine for most people, however if you
|
||||
have any problem with it, try using on-the-spot style.
|
||||
|
||||
*'include'* *'inc'*
|
||||
'include' 'inc' string (default "^\s*#\s*include")
|
||||
global or local to buffer |global-local|
|
||||
|
@ -133,6 +133,14 @@ Syntax ~
|
||||
height.
|
||||
++cols={width} Use {width} for the terminal window
|
||||
width.
|
||||
++eof={text} when using [range], text to send after
|
||||
the last line was written. The default
|
||||
is to send CTRL-D. A CR is appended.
|
||||
E.g. for a shell use "++eof=exit" and
|
||||
for Python "++eof=exit()". Special
|
||||
codes can be used like with `:map`,
|
||||
e.g. "<C-Z>" for CTRL-Z.
|
||||
{only on MS-Windows}
|
||||
|
||||
If you want to use more options use the |term_start()|
|
||||
function.
|
||||
@ -141,11 +149,13 @@ When the buffer associated with the terminal is unloaded or wiped out the job
|
||||
is killed, similar to calling `job_stop(job, "kill")`
|
||||
|
||||
So long as the job is running the window behaves like it contains a modified
|
||||
buffer. Trying to close the window with `CTRL-W :close` or `CTRL-W :hide`
|
||||
fails, unless "!" is added, in which case the job is ended. The text in the
|
||||
window is lost. The buffer still exists, but getting it in a window with
|
||||
`:buffer` will show an
|
||||
empty buffer.
|
||||
buffer. Trying to close the window with `CTRL-W :quit` fails. When using
|
||||
`CTRL-W :quit!` the job is ended. The text in the window is lost. The buffer
|
||||
still exists, but getting it in a window with `:buffer` will show an empty
|
||||
buffer.
|
||||
|
||||
Trying to close the window with `CTRL-W :close` also fails. Using
|
||||
`CTRL-W :close!` will close the window and make the buffer hidden.
|
||||
|
||||
You can use `CTRL-W :hide` to close the terminal window and make the buffer
|
||||
hidden, the job keeps running. The `:buffer` command can be used to turn the
|
||||
|
@ -76,6 +76,10 @@ endif
|
||||
# Set to yes to enable terminal support.
|
||||
TERMINAL=no
|
||||
|
||||
ifndef CTAGS
|
||||
# this assumes ctags is Exuberant ctags
|
||||
CTAGS = ctags -I INIT+ --fields=+S
|
||||
endif
|
||||
|
||||
# Link against the shared version of libstdc++ by default. Set
|
||||
# STATIC_STDCPLUS to "yes" to link against static version instead.
|
||||
@ -885,6 +889,12 @@ xxd/xxd.exe: xxd/xxd.c
|
||||
GvimExt/gvimext.dll: GvimExt/gvimext.cpp GvimExt/gvimext.rc GvimExt/gvimext.h
|
||||
$(MAKE) -C GvimExt -f Make_ming.mak CROSS=$(CROSS) CROSS_COMPILE=$(CROSS_COMPILE) CXX='$(CXX)' STATIC_STDCPLUS=$(STATIC_STDCPLUS)
|
||||
|
||||
tags: notags
|
||||
$(CTAGS) *.c *.cpp *.h if_perl.xs
|
||||
|
||||
notags:
|
||||
-$(DEL) tags
|
||||
|
||||
clean:
|
||||
-$(DEL) $(OUTDIR)$(DIRSLASH)*.o
|
||||
-$(DEL) $(OUTDIR)$(DIRSLASH)*.res
|
||||
|
@ -344,7 +344,8 @@ FEATURES = HUGE
|
||||
!endif
|
||||
|
||||
!ifndef CTAGS
|
||||
CTAGS = ctags
|
||||
# this assumes ctags is Exuberant ctags
|
||||
CTAGS = ctags -I INIT+ --fields=+S
|
||||
!endif
|
||||
|
||||
!ifndef CSCOPE
|
||||
@ -1220,7 +1221,7 @@ GvimExt/gvimext.dll: GvimExt/gvimext.cpp GvimExt/gvimext.rc GvimExt/gvimext.h
|
||||
|
||||
|
||||
tags: notags
|
||||
$(CTAGS) *.c *.cpp *.h if_perl.xs proto\*.pro
|
||||
$(CTAGS) *.c *.cpp *.h if_perl.xs
|
||||
|
||||
notags:
|
||||
- if exist tags del tags
|
||||
|
16
src/Makefile
16
src/Makefile
@ -2100,17 +2100,17 @@ test1 \
|
||||
test_listchars \
|
||||
test_search_mbyte \
|
||||
test_wordcount \
|
||||
test3 test4 test5 test6 test7 test8 test9 \
|
||||
test11 test12 test14 test15 test17 test18 test19 \
|
||||
test20 test21 test22 test25 test27 test28 test29 \
|
||||
test3 test4 test5 test7 test8 \
|
||||
test11 test12 test14 test15 test17 test19 \
|
||||
test20 test25 test28 test29 \
|
||||
test30 test31 test32 test33 test34 test36 test37 test38 test39 \
|
||||
test40 test41 test42 test43 test44 test45 test48 test49 \
|
||||
test50 test51 test52 test53 test54 test55 test56 test57 test59 \
|
||||
test50 test52 test53 test54 test55 test56 test57 test59 \
|
||||
test60 test64 test66 test68 test69 \
|
||||
test70 test72 test73 test74 test77 test78 test79 \
|
||||
test80 test83 test84 test85 test86 test87 test88 \
|
||||
test91 test94 test95 test98 test99 \
|
||||
test100 test101 test103 test104 test107 test108:
|
||||
test70 test72 test73 test77 test78 test79 \
|
||||
test83 test85 test86 test87 test88 \
|
||||
test94 test95 test99 \
|
||||
test108:
|
||||
cd testdir; rm -f $@.out; $(MAKE) -f Makefile $@.out VIMPROG=../$(VIMTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
|
||||
|
||||
# Run individual NEW style test, assuming that Vim was already compiled.
|
||||
|
@ -1300,11 +1300,16 @@ write_buf_line(buf_T *buf, linenr_T lnum, channel_T *channel)
|
||||
return;
|
||||
memcpy((char *)p, (char *)line, len);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
if (p[i] == NL)
|
||||
p[i] = NUL;
|
||||
if (channel->ch_write_text_mode)
|
||||
p[len] = CAR;
|
||||
else
|
||||
{
|
||||
for (i = 0; i < len; ++i)
|
||||
if (p[i] == NL)
|
||||
p[i] = NUL;
|
||||
|
||||
p[len] = NL;
|
||||
p[len] = NL;
|
||||
}
|
||||
p[len + 1] = NUL;
|
||||
channel_send(channel, PART_IN, p, len + 1, "write_buf_line");
|
||||
vim_free(p);
|
||||
@ -1417,6 +1422,12 @@ channel_write_in(channel_T *channel)
|
||||
in_part->ch_buf_top = lnum;
|
||||
if (lnum > buf->b_ml.ml_line_count || lnum > in_part->ch_buf_bot)
|
||||
{
|
||||
#if defined(FEAT_TERMINAL)
|
||||
/* Send CTRL-D or "eof_chars" to close stdin on MS-Windows. */
|
||||
if (channel->ch_job != NULL)
|
||||
term_send_eof(channel);
|
||||
#endif
|
||||
|
||||
/* Writing is done, no longer need the buffer. */
|
||||
in_part->ch_bufref.br_buf = NULL;
|
||||
ch_log(channel, "Finished writing all lines to channel");
|
||||
@ -4626,6 +4637,20 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2)
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
else if (STRCMP(hi->hi_key, "eof_chars") == 0)
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
if (!(supported2 & JO2_EOF_CHARS))
|
||||
break;
|
||||
opt->jo_set2 |= JO2_EOF_CHARS;
|
||||
p = opt->jo_eof_chars = get_tv_string_chk(item);
|
||||
if (p == NULL)
|
||||
{
|
||||
EMSG2(_(e_invarg2), "term_opencmd");
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
else if (STRCMP(hi->hi_key, "term_rows") == 0)
|
||||
{
|
||||
if (!(supported2 & JO2_TERM_ROWS))
|
||||
|
@ -9683,7 +9683,7 @@ ins_left(
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
/* Only call start_arrow() when not busy with preediting, it will
|
||||
* break undo. K_LEFT is inserted in im_correct_cursor(). */
|
||||
if (!im_is_preediting())
|
||||
if (p_imst == IM_OVER_THE_SPOT || !im_is_preediting())
|
||||
#endif
|
||||
{
|
||||
start_arrow_with_change(&tpos, end_change);
|
||||
|
@ -2098,11 +2098,16 @@ viminfo_filename(char_u *file)
|
||||
else if ((file = find_viminfo_parameter('n')) == NULL || *file == NUL)
|
||||
{
|
||||
#ifdef VIMINFO_FILE2
|
||||
/* don't use $HOME when not defined (turned into "c:/"!). */
|
||||
# ifdef VMS
|
||||
if (mch_getenv((char_u *)"SYS$LOGIN") == NULL)
|
||||
# else
|
||||
# ifdef MSWIN
|
||||
/* Use $VIM only if $HOME is the default "C:/". */
|
||||
if (STRCMP(vim_getenv((char_u *)"HOME", NULL), "C:/") == 0
|
||||
&& mch_getenv((char_u *)"HOME") == NULL)
|
||||
# else
|
||||
if (mch_getenv((char_u *)"HOME") == NULL)
|
||||
# endif
|
||||
# endif
|
||||
{
|
||||
/* don't use $VIM when not available. */
|
||||
|
@ -11099,7 +11099,7 @@ static int ses_do_frame(frame_T *fr);
|
||||
static int ses_do_win(win_T *wp);
|
||||
static int ses_arglist(FILE *fd, char *cmd, garray_T *gap, int fullname, unsigned *flagp);
|
||||
static int ses_put_fname(FILE *fd, char_u *name, unsigned *flagp);
|
||||
static int ses_fname(FILE *fd, buf_T *buf, unsigned *flagp);
|
||||
static int ses_fname(FILE *fd, buf_T *buf, unsigned *flagp, int add_eol);
|
||||
|
||||
/*
|
||||
* Write openfile commands for the current buffers to an .exrc file.
|
||||
@ -11195,7 +11195,7 @@ makeopens(
|
||||
{
|
||||
if (fprintf(fd, "badd +%ld ", buf->b_wininfo == NULL ? 1L
|
||||
: buf->b_wininfo->wi_fpos.lnum) < 0
|
||||
|| ses_fname(fd, buf, &ssop_flags) == FAIL)
|
||||
|| ses_fname(fd, buf, &ssop_flags, TRUE) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
@ -11289,7 +11289,8 @@ makeopens(
|
||||
)
|
||||
{
|
||||
if (fputs(need_tabnew ? "tabedit " : "edit ", fd) < 0
|
||||
|| ses_fname(fd, wp->w_buffer, &ssop_flags) == FAIL)
|
||||
|| ses_fname(fd, wp->w_buffer, &ssop_flags, TRUE)
|
||||
== FAIL)
|
||||
return FAIL;
|
||||
need_tabnew = FALSE;
|
||||
if (!wp->w_arg_idx_invalid)
|
||||
@ -11636,9 +11637,20 @@ put_view(
|
||||
/*
|
||||
* Editing a file in this buffer: use ":edit file".
|
||||
* This may have side effects! (e.g., compressed or network file).
|
||||
*
|
||||
* Note, if a buffer for that file already exists, use :badd to
|
||||
* edit that buffer, to not lose folding information (:edit resets
|
||||
* folds in other buffers)
|
||||
*/
|
||||
if (fputs("edit ", fd) < 0
|
||||
|| ses_fname(fd, wp->w_buffer, flagp) == FAIL)
|
||||
if (fputs("if bufexists('", fd) < 0
|
||||
|| ses_fname(fd, wp->w_buffer, flagp, FALSE) == FAIL
|
||||
|| fputs("') | buffer ", fd) < 0
|
||||
|| ses_fname(fd, wp->w_buffer, flagp, FALSE) == FAIL
|
||||
|| fputs(" | else | edit ", fd) < 0
|
||||
|| ses_fname(fd, wp->w_buffer, flagp, FALSE) == FAIL
|
||||
|| fputs(" | endif", fd) < 0
|
||||
||
|
||||
put_eol(fd) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
else
|
||||
@ -11651,7 +11663,7 @@ put_view(
|
||||
{
|
||||
/* The buffer does have a name, but it's not a file name. */
|
||||
if (fputs("file ", fd) < 0
|
||||
|| ses_fname(fd, wp->w_buffer, flagp) == FAIL)
|
||||
|| ses_fname(fd, wp->w_buffer, flagp, TRUE) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
@ -11823,11 +11835,11 @@ ses_arglist(
|
||||
|
||||
/*
|
||||
* Write a buffer name to the session file.
|
||||
* Also ends the line.
|
||||
* Also ends the line, if "add_eol" is TRUE.
|
||||
* Returns FAIL if writing fails.
|
||||
*/
|
||||
static int
|
||||
ses_fname(FILE *fd, buf_T *buf, unsigned *flagp)
|
||||
ses_fname(FILE *fd, buf_T *buf, unsigned *flagp, int add_eol)
|
||||
{
|
||||
char_u *name;
|
||||
|
||||
@ -11846,7 +11858,8 @@ ses_fname(FILE *fd, buf_T *buf, unsigned *flagp)
|
||||
name = buf->b_sfname;
|
||||
else
|
||||
name = buf->b_ffname;
|
||||
if (ses_put_fname(fd, name, flagp) == FAIL || put_eol(fd) == FAIL)
|
||||
if (ses_put_fname(fd, name, flagp) == FAIL
|
||||
|| (add_eol && put_eol(fd) == FAIL))
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
|
@ -3468,7 +3468,8 @@ cursorcmd(void)
|
||||
|
||||
windgoto(msg_row, msg_col);
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
redrawcmd_preedit();
|
||||
if (p_imst == IM_ON_THE_SPOT)
|
||||
redrawcmd_preedit();
|
||||
#endif
|
||||
#ifdef MCH_CURSOR_SHAPE
|
||||
mch_update_cursor();
|
||||
|
@ -2,7 +2,7 @@
|
||||
* iscygpty.c -- part of ptycheck
|
||||
* https://github.com/k-takata/ptycheck
|
||||
*
|
||||
* Copyright (c) 2015-2016 K.Takata
|
||||
* Copyright (c) 2015-2017 K.Takata
|
||||
*
|
||||
* You can redistribute it and/or modify it under the terms of either
|
||||
* the MIT license (as described below) or the Vim license.
|
||||
@ -27,6 +27,8 @@
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <ctype.h>
|
||||
#include <io.h>
|
||||
#include <wchar.h>
|
||||
@ -60,19 +62,19 @@
|
||||
//#define USE_DYNFILEID
|
||||
#ifdef USE_DYNFILEID
|
||||
typedef BOOL (WINAPI *pfnGetFileInformationByHandleEx)(
|
||||
HANDLE hFile,
|
||||
HANDLE hFile,
|
||||
FILE_INFO_BY_HANDLE_CLASS FileInformationClass,
|
||||
LPVOID lpFileInformation,
|
||||
DWORD dwBufferSize
|
||||
LPVOID lpFileInformation,
|
||||
DWORD dwBufferSize
|
||||
);
|
||||
static pfnGetFileInformationByHandleEx pGetFileInformationByHandleEx = NULL;
|
||||
|
||||
# ifndef USE_FILEEXTD
|
||||
static BOOL WINAPI stub_GetFileInformationByHandleEx(
|
||||
HANDLE hFile,
|
||||
HANDLE hFile,
|
||||
FILE_INFO_BY_HANDLE_CLASS FileInformationClass,
|
||||
LPVOID lpFileInformation,
|
||||
DWORD dwBufferSize
|
||||
LPVOID lpFileInformation,
|
||||
DWORD dwBufferSize
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
@ -111,7 +113,7 @@ int is_cygpty(int fd)
|
||||
return 0;
|
||||
#else
|
||||
HANDLE h;
|
||||
int size = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * MAX_PATH;
|
||||
int size = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * (MAX_PATH - 1);
|
||||
FILE_NAME_INFO *nameinfo;
|
||||
WCHAR *p = NULL;
|
||||
|
||||
@ -125,7 +127,7 @@ int is_cygpty(int fd)
|
||||
if (GetFileType(h) != FILE_TYPE_PIPE) {
|
||||
return 0;
|
||||
}
|
||||
nameinfo = malloc(size);
|
||||
nameinfo = malloc(size + sizeof(WCHAR));
|
||||
if (nameinfo == NULL) {
|
||||
return 0;
|
||||
}
|
||||
@ -178,4 +180,6 @@ int is_cygpty_used(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* vi:set ts=8 sts=4 sw=4 noet: */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/* vim: set ts=4 sw=4: */
|
||||
|
@ -2,7 +2,7 @@
|
||||
* iscygpty.h -- part of ptycheck
|
||||
* https://github.com/k-takata/ptycheck
|
||||
*
|
||||
* Copyright (c) 2015-2016 K.Takata
|
||||
* Copyright (c) 2015-2017 K.Takata
|
||||
*
|
||||
* You can redistribute it and/or modify it under the terms of either
|
||||
* the MIT license (as described below) or the Vim license.
|
||||
@ -30,7 +30,12 @@
|
||||
#ifndef _ISCYGPTY_H
|
||||
#define _ISCYGPTY_H
|
||||
|
||||
#ifdef _WIN32
|
||||
int is_cygpty(int fd);
|
||||
int is_cygpty_used(void);
|
||||
#else
|
||||
#define is_cygpty(fd) 0
|
||||
#define is_cygpty_used() 0
|
||||
#endif
|
||||
|
||||
#endif /* _ISCYGPTY_H */
|
||||
|
346
src/mbyte.c
346
src/mbyte.c
@ -4788,6 +4788,11 @@ static unsigned long im_commit_handler_id = 0;
|
||||
static unsigned int im_activatekey_keyval = GDK_VoidSymbol;
|
||||
static unsigned int im_activatekey_state = 0;
|
||||
|
||||
static GtkWidget *preedit_window = NULL;
|
||||
static GtkWidget *preedit_label = NULL;
|
||||
|
||||
static void im_preedit_window_set_position(void);
|
||||
|
||||
void
|
||||
im_set_active(int active)
|
||||
{
|
||||
@ -4825,6 +4830,9 @@ im_set_position(int row, int col)
|
||||
area.height = gui.char_height;
|
||||
|
||||
gtk_im_context_set_cursor_location(xic, &area);
|
||||
|
||||
if (p_imst == IM_OVER_THE_SPOT)
|
||||
im_preedit_window_set_position();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4851,6 +4859,95 @@ im_add_to_input(char_u *str, int len)
|
||||
if (input_conv.vc_type != CONV_NONE)
|
||||
vim_free(str);
|
||||
|
||||
if (p_mh) /* blank out the pointer if necessary */
|
||||
gui_mch_mousehide(TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
im_preedit_window_set_position(void)
|
||||
{
|
||||
int x, y, w, h, sw, sh;
|
||||
|
||||
if (preedit_window == NULL)
|
||||
return;
|
||||
|
||||
sw = gdk_screen_get_width(gtk_widget_get_screen(preedit_window));
|
||||
sh = gdk_screen_get_height(gtk_widget_get_screen(preedit_window));
|
||||
#if GTK_CHECK_VERSION(3,0,0)
|
||||
gdk_window_get_origin(gtk_widget_get_window(gui.drawarea), &x, &y);
|
||||
#else
|
||||
gdk_window_get_origin(gui.drawarea->window, &x, &y);
|
||||
#endif
|
||||
gtk_window_get_size(GTK_WINDOW(preedit_window), &w, &h);
|
||||
x = x + FILL_X(gui.col);
|
||||
y = y + FILL_Y(gui.row);
|
||||
if (x + w > sw)
|
||||
x = sw - w;
|
||||
if (y + h > sh)
|
||||
y = sh - h;
|
||||
gtk_window_move(GTK_WINDOW(preedit_window), x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
im_preedit_window_open()
|
||||
{
|
||||
char *preedit_string;
|
||||
char buf[8];
|
||||
PangoAttrList *attr_list;
|
||||
PangoLayout *layout;
|
||||
GdkColor color;
|
||||
gint w, h;
|
||||
|
||||
if (preedit_window == NULL)
|
||||
{
|
||||
preedit_window = gtk_window_new(GTK_WINDOW_POPUP);
|
||||
preedit_label = gtk_label_new("");
|
||||
gtk_container_add(GTK_CONTAINER(preedit_window), preedit_label);
|
||||
}
|
||||
|
||||
gtk_widget_modify_font(preedit_label, gui.norm_font);
|
||||
|
||||
vim_snprintf(buf, sizeof(buf), "#%06X", gui.norm_pixel);
|
||||
gdk_color_parse(buf, &color);
|
||||
gtk_widget_modify_fg(preedit_label, GTK_STATE_NORMAL, &color);
|
||||
|
||||
vim_snprintf(buf, sizeof(buf), "#%06X", gui.back_pixel);
|
||||
gdk_color_parse(buf, &color);
|
||||
gtk_widget_modify_bg(preedit_window, GTK_STATE_NORMAL, &color);
|
||||
|
||||
gtk_im_context_get_preedit_string(xic, &preedit_string, &attr_list, NULL);
|
||||
|
||||
if (preedit_string[0] != NUL)
|
||||
{
|
||||
gtk_label_set_text(GTK_LABEL(preedit_label), preedit_string);
|
||||
gtk_label_set_attributes(GTK_LABEL(preedit_label), attr_list);
|
||||
|
||||
layout = gtk_label_get_layout(GTK_LABEL(preedit_label));
|
||||
pango_layout_get_pixel_size(layout, &w, &h);
|
||||
h = MAX(h, gui.char_height);
|
||||
gtk_window_resize(GTK_WINDOW(preedit_window), w, h);
|
||||
|
||||
gtk_widget_show_all(preedit_window);
|
||||
|
||||
im_preedit_window_set_position();
|
||||
}
|
||||
|
||||
g_free(preedit_string);
|
||||
pango_attr_list_unref(attr_list);
|
||||
}
|
||||
|
||||
static void
|
||||
im_preedit_window_close()
|
||||
{
|
||||
if (preedit_window != NULL)
|
||||
gtk_widget_hide(preedit_window);
|
||||
}
|
||||
|
||||
static void
|
||||
im_show_preedit()
|
||||
{
|
||||
im_preedit_window_open();
|
||||
|
||||
if (p_mh) /* blank out the pointer if necessary */
|
||||
gui_mch_mousehide(TRUE);
|
||||
}
|
||||
@ -4861,6 +4958,12 @@ im_delete_preedit(void)
|
||||
char_u bskey[] = {CSI, 'k', 'b'};
|
||||
char_u delkey[] = {CSI, 'k', 'D'};
|
||||
|
||||
if (p_imst == IM_OVER_THE_SPOT)
|
||||
{
|
||||
im_preedit_window_close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (State & NORMAL)
|
||||
{
|
||||
im_preedit_cursor = 0;
|
||||
@ -4933,40 +5036,43 @@ im_commit_cb(GtkIMContext *context UNUSED,
|
||||
xim_log("im_commit_cb(): %s\n", str);
|
||||
#endif
|
||||
|
||||
/* The imhangul module doesn't reset the preedit string before
|
||||
* committing. Call im_delete_preedit() to work around that. */
|
||||
im_delete_preedit();
|
||||
|
||||
/* Indicate that preediting has finished. */
|
||||
if (preedit_start_col == MAXCOL)
|
||||
if (p_imst == IM_ON_THE_SPOT)
|
||||
{
|
||||
init_preedit_start_col();
|
||||
commit_with_preedit = FALSE;
|
||||
/* The imhangul module doesn't reset the preedit string before
|
||||
* committing. Call im_delete_preedit() to work around that. */
|
||||
im_delete_preedit();
|
||||
|
||||
/* Indicate that preediting has finished. */
|
||||
if (preedit_start_col == MAXCOL)
|
||||
{
|
||||
init_preedit_start_col();
|
||||
commit_with_preedit = FALSE;
|
||||
}
|
||||
|
||||
/* The thing which setting "preedit_start_col" to MAXCOL means that
|
||||
* "preedit_start_col" will be set forcedly when calling
|
||||
* preedit_changed_cb() next time.
|
||||
* "preedit_start_col" should not reset with MAXCOL on this part. Vim
|
||||
* is simulating the preediting by using add_to_input_str(). when
|
||||
* preedit begin immediately before committed, the typebuf is not
|
||||
* flushed to screen, then it can't get correct "preedit_start_col".
|
||||
* Thus, it should calculate the cells by adding cells of the committed
|
||||
* string. */
|
||||
if (input_conv.vc_type != CONV_NONE)
|
||||
{
|
||||
im_str = string_convert(&input_conv, (char_u *)str, &len);
|
||||
g_return_if_fail(im_str != NULL);
|
||||
}
|
||||
else
|
||||
im_str = (char_u *)str;
|
||||
|
||||
clen = mb_string2cells(im_str, len);
|
||||
|
||||
if (input_conv.vc_type != CONV_NONE)
|
||||
vim_free(im_str);
|
||||
preedit_start_col += clen;
|
||||
}
|
||||
|
||||
/* The thing which setting "preedit_start_col" to MAXCOL means that
|
||||
* "preedit_start_col" will be set forcedly when calling
|
||||
* preedit_changed_cb() next time.
|
||||
* "preedit_start_col" should not reset with MAXCOL on this part. Vim
|
||||
* is simulating the preediting by using add_to_input_str(). when
|
||||
* preedit begin immediately before committed, the typebuf is not
|
||||
* flushed to screen, then it can't get correct "preedit_start_col".
|
||||
* Thus, it should calculate the cells by adding cells of the committed
|
||||
* string. */
|
||||
if (input_conv.vc_type != CONV_NONE)
|
||||
{
|
||||
im_str = string_convert(&input_conv, (char_u *)str, &len);
|
||||
g_return_if_fail(im_str != NULL);
|
||||
}
|
||||
else
|
||||
im_str = (char_u *)str;
|
||||
|
||||
clen = mb_string2cells(im_str, len);
|
||||
|
||||
if (input_conv.vc_type != CONV_NONE)
|
||||
vim_free(im_str);
|
||||
preedit_start_col += clen;
|
||||
|
||||
/* Is this a single character that matches a keypad key that's just
|
||||
* been pressed? If so, we don't want it to be entered as such - let
|
||||
* us carry on processing the raw keycode so that it may be used in
|
||||
@ -4990,14 +5096,17 @@ im_commit_cb(GtkIMContext *context UNUSED,
|
||||
if (add_to_input)
|
||||
im_add_to_input((char_u *)str, slen);
|
||||
|
||||
/* Inserting chars while "im_is_active" is set does not cause a change of
|
||||
* buffer. When the chars are committed the buffer must be marked as
|
||||
* changed. */
|
||||
if (!commit_with_preedit)
|
||||
preedit_start_col = MAXCOL;
|
||||
if (p_imst == IM_ON_THE_SPOT)
|
||||
{
|
||||
/* Inserting chars while "im_is_active" is set does not cause a
|
||||
* change of buffer. When the chars are committed the buffer must be
|
||||
* marked as changed. */
|
||||
if (!commit_with_preedit)
|
||||
preedit_start_col = MAXCOL;
|
||||
|
||||
/* This flag is used in changed() at next call. */
|
||||
xim_changed_while_preediting = TRUE;
|
||||
/* This flag is used in changed() at next call. */
|
||||
xim_changed_while_preediting = TRUE;
|
||||
}
|
||||
|
||||
if (gtk_main_level() > 0)
|
||||
gtk_main_quit();
|
||||
@ -5031,7 +5140,8 @@ im_preedit_end_cb(GtkIMContext *context UNUSED, gpointer data UNUSED)
|
||||
im_delete_preedit();
|
||||
|
||||
/* Indicate that preediting has finished */
|
||||
preedit_start_col = MAXCOL;
|
||||
if (p_imst == IM_ON_THE_SPOT)
|
||||
preedit_start_col = MAXCOL;
|
||||
xim_has_preediting = FALSE;
|
||||
|
||||
#if 0
|
||||
@ -5092,9 +5202,14 @@ im_preedit_changed_cb(GtkIMContext *context, gpointer data UNUSED)
|
||||
char_u *p;
|
||||
int i;
|
||||
|
||||
gtk_im_context_get_preedit_string(context,
|
||||
&preedit_string, NULL,
|
||||
&cursor_index);
|
||||
if (p_imst == IM_ON_THE_SPOT)
|
||||
gtk_im_context_get_preedit_string(context,
|
||||
&preedit_string, NULL,
|
||||
&cursor_index);
|
||||
else
|
||||
gtk_im_context_get_preedit_string(context,
|
||||
&preedit_string, NULL,
|
||||
NULL);
|
||||
|
||||
#ifdef XIM_DEBUG
|
||||
xim_log("im_preedit_changed_cb(): %s\n", preedit_string);
|
||||
@ -5102,66 +5217,82 @@ im_preedit_changed_cb(GtkIMContext *context, gpointer data UNUSED)
|
||||
|
||||
g_return_if_fail(preedit_string != NULL); /* just in case */
|
||||
|
||||
/* If preedit_start_col is MAXCOL set it to the current cursor position. */
|
||||
if (preedit_start_col == MAXCOL && preedit_string[0] != '\0')
|
||||
if (p_imst == IM_OVER_THE_SPOT)
|
||||
{
|
||||
xim_has_preediting = TRUE;
|
||||
|
||||
/* Urgh, this breaks if the input buffer isn't empty now */
|
||||
init_preedit_start_col();
|
||||
if (preedit_string[0] == NUL)
|
||||
{
|
||||
xim_has_preediting = FALSE;
|
||||
im_delete_preedit();
|
||||
}
|
||||
else
|
||||
{
|
||||
xim_has_preediting = TRUE;
|
||||
im_show_preedit();
|
||||
}
|
||||
}
|
||||
else if (cursor_index == 0 && preedit_string[0] == '\0')
|
||||
else
|
||||
{
|
||||
xim_has_preediting = FALSE;
|
||||
/* If preedit_start_col is MAXCOL set it to the current cursor position. */
|
||||
if (preedit_start_col == MAXCOL && preedit_string[0] != '\0')
|
||||
{
|
||||
xim_has_preediting = TRUE;
|
||||
|
||||
/* If at the start position (after typing backspace)
|
||||
* preedit_start_col must be reset. */
|
||||
preedit_start_col = MAXCOL;
|
||||
}
|
||||
/* Urgh, this breaks if the input buffer isn't empty now */
|
||||
init_preedit_start_col();
|
||||
}
|
||||
else if (cursor_index == 0 && preedit_string[0] == '\0')
|
||||
{
|
||||
xim_has_preediting = FALSE;
|
||||
|
||||
im_delete_preedit();
|
||||
/* If at the start position (after typing backspace)
|
||||
* preedit_start_col must be reset. */
|
||||
preedit_start_col = MAXCOL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the end of the preediting area: "preedit_end_col".
|
||||
* According to the documentation of gtk_im_context_get_preedit_string(),
|
||||
* the cursor_pos output argument returns the offset in bytes. This is
|
||||
* unfortunately not true -- real life shows the offset is in characters,
|
||||
* and the GTK+ source code agrees with me. Will file a bug later.
|
||||
*/
|
||||
if (preedit_start_col != MAXCOL)
|
||||
preedit_end_col = preedit_start_col;
|
||||
str = (char_u *)preedit_string;
|
||||
for (p = str, i = 0; *p != NUL; p += utf_byte2len(*p), ++i)
|
||||
{
|
||||
int is_composing;
|
||||
im_delete_preedit();
|
||||
|
||||
is_composing = ((*p & 0x80) != 0 && utf_iscomposing(utf_ptr2char(p)));
|
||||
/*
|
||||
* These offsets are used as counters when generating <BS> and <Del>
|
||||
* to delete the preedit string. So don't count composing characters
|
||||
* unless 'delcombine' is enabled.
|
||||
* Compute the end of the preediting area: "preedit_end_col".
|
||||
* According to the documentation of gtk_im_context_get_preedit_string(),
|
||||
* the cursor_pos output argument returns the offset in bytes. This is
|
||||
* unfortunately not true -- real life shows the offset is in characters,
|
||||
* and the GTK+ source code agrees with me. Will file a bug later.
|
||||
*/
|
||||
if (!is_composing || p_deco)
|
||||
{
|
||||
if (i < cursor_index)
|
||||
++im_preedit_cursor;
|
||||
else
|
||||
++im_preedit_trailing;
|
||||
}
|
||||
if (!is_composing && i >= cursor_index)
|
||||
{
|
||||
/* This is essentially the same as im_preedit_trailing, except
|
||||
* composing characters are not counted even if p_deco is set. */
|
||||
++num_move_back;
|
||||
}
|
||||
if (preedit_start_col != MAXCOL)
|
||||
preedit_end_col += utf_ptr2cells(p);
|
||||
}
|
||||
preedit_end_col = preedit_start_col;
|
||||
str = (char_u *)preedit_string;
|
||||
for (p = str, i = 0; *p != NUL; p += utf_byte2len(*p), ++i)
|
||||
{
|
||||
int is_composing;
|
||||
|
||||
if (p > str)
|
||||
{
|
||||
im_add_to_input(str, (int)(p - str));
|
||||
im_correct_cursor(num_move_back);
|
||||
is_composing = ((*p & 0x80) != 0 && utf_iscomposing(utf_ptr2char(p)));
|
||||
/*
|
||||
* These offsets are used as counters when generating <BS> and <Del>
|
||||
* to delete the preedit string. So don't count composing characters
|
||||
* unless 'delcombine' is enabled.
|
||||
*/
|
||||
if (!is_composing || p_deco)
|
||||
{
|
||||
if (i < cursor_index)
|
||||
++im_preedit_cursor;
|
||||
else
|
||||
++im_preedit_trailing;
|
||||
}
|
||||
if (!is_composing && i >= cursor_index)
|
||||
{
|
||||
/* This is essentially the same as im_preedit_trailing, except
|
||||
* composing characters are not counted even if p_deco is set. */
|
||||
++num_move_back;
|
||||
}
|
||||
if (preedit_start_col != MAXCOL)
|
||||
preedit_end_col += utf_ptr2cells(p);
|
||||
}
|
||||
|
||||
if (p > str)
|
||||
{
|
||||
im_add_to_input(str, (int)(p - str));
|
||||
im_correct_cursor(num_move_back);
|
||||
}
|
||||
}
|
||||
|
||||
g_free(preedit_string);
|
||||
@ -5310,7 +5441,8 @@ im_shutdown(void)
|
||||
}
|
||||
im_is_active = FALSE;
|
||||
im_commit_handler_id = 0;
|
||||
preedit_start_col = MAXCOL;
|
||||
if (p_imst == IM_ON_THE_SPOT)
|
||||
preedit_start_col = MAXCOL;
|
||||
xim_has_preediting = FALSE;
|
||||
}
|
||||
|
||||
@ -5465,7 +5597,8 @@ xim_reset(void)
|
||||
}
|
||||
}
|
||||
|
||||
preedit_start_col = MAXCOL;
|
||||
if (p_imst == IM_ON_THE_SPOT)
|
||||
preedit_start_col = MAXCOL;
|
||||
xim_has_preediting = FALSE;
|
||||
}
|
||||
|
||||
@ -5570,19 +5703,22 @@ xim_queue_key_press_event(GdkEventKey *event, int down)
|
||||
{
|
||||
int imresult = gtk_im_context_filter_keypress(xic, event);
|
||||
|
||||
/* Some XIM send following sequence:
|
||||
* 1. preedited string.
|
||||
* 2. committed string.
|
||||
* 3. line changed key.
|
||||
* 4. preedited string.
|
||||
* 5. remove preedited string.
|
||||
* if 3, Vim can't move back the above line for 5.
|
||||
* thus, this part should not parse the key. */
|
||||
if (!imresult && preedit_start_col != MAXCOL
|
||||
&& event->keyval == GDK_Return)
|
||||
if (p_imst == IM_ON_THE_SPOT)
|
||||
{
|
||||
im_synthesize_keypress(GDK_Return, 0U);
|
||||
return FALSE;
|
||||
/* Some XIM send following sequence:
|
||||
* 1. preedited string.
|
||||
* 2. committed string.
|
||||
* 3. line changed key.
|
||||
* 4. preedited string.
|
||||
* 5. remove preedited string.
|
||||
* if 3, Vim can't move back the above line for 5.
|
||||
* thus, this part should not parse the key. */
|
||||
if (!imresult && preedit_start_col != MAXCOL
|
||||
&& event->keyval == GDK_Return)
|
||||
{
|
||||
im_synthesize_keypress(GDK_Return, 0U);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If XIM tried to commit a keypad key as a single char.,
|
||||
|
15
src/misc1.c
15
src/misc1.c
@ -2730,12 +2730,15 @@ skip_to_option_part(char_u *p)
|
||||
changed(void)
|
||||
{
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
/* The text of the preediting area is inserted, but this doesn't
|
||||
* mean a change of the buffer yet. That is delayed until the
|
||||
* text is committed. (this means preedit becomes empty) */
|
||||
if (im_is_preediting() && !xim_changed_while_preediting)
|
||||
return;
|
||||
xim_changed_while_preediting = FALSE;
|
||||
if (p_imst == IM_ON_THE_SPOT)
|
||||
{
|
||||
/* The text of the preediting area is inserted, but this doesn't
|
||||
* mean a change of the buffer yet. That is delayed until the
|
||||
* text is committed. (this means preedit becomes empty) */
|
||||
if (im_is_preediting() && !xim_changed_while_preediting)
|
||||
return;
|
||||
xim_changed_while_preediting = FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!curbuf->b_changed)
|
||||
|
24
src/option.c
24
src/option.c
@ -1606,13 +1606,22 @@ static struct vimoption options[] =
|
||||
#endif
|
||||
SCRIPTID_INIT},
|
||||
{"imstatusfunc","imsf",P_STRING|P_VI_DEF|P_SECURE,
|
||||
# if defined(FEAT_EVAL) && defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
#if defined(FEAT_EVAL) && defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
(char_u *)&p_imsf, PV_NONE,
|
||||
{(char_u *)"", (char_u *)NULL}
|
||||
# else
|
||||
#else
|
||||
(char_u *)NULL, PV_NONE,
|
||||
{(char_u *)NULL, (char_u *)0L}
|
||||
# endif
|
||||
#endif
|
||||
SCRIPTID_INIT},
|
||||
{"imstyle", "imst", P_NUM|P_VI_DEF|P_SECURE,
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
(char_u *)&p_imst, PV_NONE,
|
||||
{(char_u *)IM_OVER_THE_SPOT, (char_u *)0L}
|
||||
#else
|
||||
(char_u *)NULL, PV_NONE,
|
||||
{(char_u *)0L, (char_u *)0L}
|
||||
#endif
|
||||
SCRIPTID_INIT},
|
||||
{"include", "inc", P_STRING|P_ALLOCED|P_VI_DEF,
|
||||
#ifdef FEAT_FIND_ID
|
||||
@ -8990,6 +8999,15 @@ set_num_option(
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
/* 'imstyle' */
|
||||
else if (pp == &p_imst)
|
||||
{
|
||||
if (p_imst != IM_ON_THE_SPOT && p_imst != IM_OVER_THE_SPOT)
|
||||
errmsg = e_invarg;
|
||||
}
|
||||
#endif
|
||||
|
||||
else if (pp == &p_window)
|
||||
{
|
||||
if (p_window < 1)
|
||||
|
@ -581,6 +581,9 @@ EXTERN int p_ic; /* 'ignorecase' */
|
||||
EXTERN char_u *p_imak; /* 'imactivatekey' */
|
||||
EXTERN char_u *p_imaf; /* 'imactivatefunc' */
|
||||
EXTERN char_u *p_imsf; /* 'imstatusfunc' */
|
||||
EXTERN long p_imst; /* 'imstyle' */
|
||||
# define IM_ON_THE_SPOT 0L
|
||||
# define IM_OVER_THE_SPOT 1L
|
||||
#endif
|
||||
#ifdef USE_IM_CONTROL
|
||||
EXTERN int p_imcmdline; /* 'imcmdline' */
|
||||
|
@ -2280,6 +2280,7 @@ vim_is_xterm(char_u *name)
|
||||
|| STRNICMP(name, "kterm", 5) == 0
|
||||
|| STRNICMP(name, "mlterm", 6) == 0
|
||||
|| STRNICMP(name, "rxvt", 4) == 0
|
||||
|| STRNICMP(name, "screen.xterm", 12) == 0
|
||||
|| STRCMP(name, "builtin_xterm") == 0);
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ int term_update_window(win_T *wp);
|
||||
int term_is_finished(buf_T *buf);
|
||||
int term_show_buffer(buf_T *buf);
|
||||
void term_change_in_curbuf(void);
|
||||
void term_send_eof(channel_T *ch);
|
||||
int term_get_attr(buf_T *buf, linenr_T lnum, int col);
|
||||
char_u *term_get_status_text(term_T *term);
|
||||
int set_ref_in_term(int copyID);
|
||||
|
137
src/quickfix.c
137
src/quickfix.c
@ -58,6 +58,7 @@ struct qfline_S
|
||||
*/
|
||||
typedef struct qf_list_S
|
||||
{
|
||||
int_u qf_id; /* Unique identifier for this list */
|
||||
qfline_T *qf_start; /* pointer to the first error */
|
||||
qfline_T *qf_last; /* pointer to the last error */
|
||||
qfline_T *qf_ptr; /* pointer to the current error */
|
||||
@ -96,6 +97,7 @@ struct qf_info_S
|
||||
};
|
||||
|
||||
static qf_info_T ql_info; /* global quickfix list */
|
||||
static int_u last_qf_id = 0; /* Last used quickfix list id */
|
||||
|
||||
#define FMT_PATTERNS 10 /* maximum number of % recognized */
|
||||
|
||||
@ -1399,6 +1401,7 @@ qf_new_list(qf_info_T *qi, char_u *qf_title)
|
||||
qi->qf_curlist = qi->qf_listcount++;
|
||||
vim_memset(&qi->qf_lists[qi->qf_curlist], 0, (size_t)(sizeof(qf_list_T)));
|
||||
qf_store_title(qi, qi->qf_curlist, qf_title);
|
||||
qi->qf_lists[qi->qf_curlist].qf_id = ++last_qf_id;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1672,6 +1675,9 @@ copy_loclist(win_T *from, win_T *to)
|
||||
|
||||
to_qfl->qf_index = from_qfl->qf_index; /* current index in the list */
|
||||
|
||||
/* Assign a new ID for the location list */
|
||||
to_qfl->qf_id = ++last_qf_id;
|
||||
|
||||
/* When no valid entries are present in the list, qf_ptr points to
|
||||
* the first item in the list */
|
||||
if (to_qfl->qf_nonevalid)
|
||||
@ -2808,6 +2814,7 @@ qf_free(qf_info_T *qi, int idx)
|
||||
qfl->qf_title = NULL;
|
||||
free_tv(qfl->qf_ctx);
|
||||
qfl->qf_ctx = NULL;
|
||||
qfl->qf_id = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4628,6 +4635,7 @@ enum {
|
||||
QF_GETLIST_NR = 0x4,
|
||||
QF_GETLIST_WINID = 0x8,
|
||||
QF_GETLIST_CONTEXT = 0x10,
|
||||
QF_GETLIST_ID = 0x20,
|
||||
QF_GETLIST_ALL = 0xFF
|
||||
};
|
||||
|
||||
@ -4635,16 +4643,19 @@ enum {
|
||||
* Parse text from 'di' and return the quickfix list items
|
||||
*/
|
||||
static int
|
||||
qf_get_list_from_text(dictitem_T *di, dict_T *retdict)
|
||||
qf_get_list_from_lines(dictitem_T *di, dict_T *retdict)
|
||||
{
|
||||
int status = FAIL;
|
||||
qf_info_T *qi;
|
||||
|
||||
/* Only string and list values are supported */
|
||||
if ((di->di_tv.v_type == VAR_STRING && di->di_tv.vval.v_string != NULL)
|
||||
|| (di->di_tv.v_type == VAR_LIST
|
||||
&& di->di_tv.vval.v_list != NULL))
|
||||
/* Only a List value is supported */
|
||||
if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL)
|
||||
{
|
||||
list_T *l = list_alloc();
|
||||
|
||||
if (l == NULL)
|
||||
return FAIL;
|
||||
|
||||
qi = (qf_info_T *)alloc((unsigned)sizeof(qf_info_T));
|
||||
if (qi != NULL)
|
||||
{
|
||||
@ -4654,17 +4665,13 @@ qf_get_list_from_text(dictitem_T *di, dict_T *retdict)
|
||||
if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, p_efm,
|
||||
TRUE, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0)
|
||||
{
|
||||
list_T *l = list_alloc();
|
||||
if (l != NULL)
|
||||
{
|
||||
(void)get_errorlist(qi, NULL, 0, l);
|
||||
dict_add_list(retdict, "items", l);
|
||||
status = OK;
|
||||
}
|
||||
(void)get_errorlist(qi, NULL, 0, l);
|
||||
qf_free(qi, 0);
|
||||
}
|
||||
free(qi);
|
||||
}
|
||||
dict_add_list(retdict, "items", l);
|
||||
status = OK;
|
||||
}
|
||||
|
||||
return status;
|
||||
@ -4684,21 +4691,21 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
dictitem_T *di;
|
||||
int flags = QF_GETLIST_NONE;
|
||||
|
||||
if ((di = dict_find(what, (char_u *)"text", -1)) != NULL)
|
||||
return qf_get_list_from_text(di, retdict);
|
||||
if ((di = dict_find(what, (char_u *)"lines", -1)) != NULL)
|
||||
return qf_get_list_from_lines(di, retdict);
|
||||
|
||||
if (wp != NULL)
|
||||
{
|
||||
qi = GET_LOC_LIST(wp);
|
||||
if (qi == NULL)
|
||||
{
|
||||
/* If querying for the size of the location list, return 0 */
|
||||
if (((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
|
||||
&& (di->di_tv.v_type == VAR_STRING)
|
||||
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0))
|
||||
return dict_add_nr_str(retdict, "nr", 0, NULL);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/* List is not present or is empty */
|
||||
if (qi == NULL || qi->qf_listcount == 0)
|
||||
{
|
||||
/* If querying for the size of the list, return 0 */
|
||||
if (((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
|
||||
&& (di->di_tv.v_type == VAR_STRING)
|
||||
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0))
|
||||
return dict_add_nr_str(retdict, "nr", 0, NULL);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
qf_idx = qi->qf_curlist; /* default is the current list */
|
||||
@ -4714,41 +4721,52 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
|
||||
return FAIL;
|
||||
}
|
||||
else if (qi->qf_listcount == 0) /* stack is empty */
|
||||
return FAIL;
|
||||
flags |= QF_GETLIST_NR;
|
||||
}
|
||||
else if ((di->di_tv.v_type == VAR_STRING)
|
||||
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0))
|
||||
{
|
||||
/* Get the last quickfix list number */
|
||||
if (qi->qf_listcount > 0)
|
||||
qf_idx = qi->qf_listcount - 1;
|
||||
else
|
||||
qf_idx = -1; /* Quickfix stack is empty */
|
||||
flags |= QF_GETLIST_NR;
|
||||
qf_idx = qi->qf_listcount - 1;
|
||||
else
|
||||
return FAIL;
|
||||
flags |= QF_GETLIST_NR;
|
||||
}
|
||||
|
||||
if ((di = dict_find(what, (char_u *)"id", -1)) != NULL)
|
||||
{
|
||||
/* Look for a list with the specified id */
|
||||
if (di->di_tv.v_type == VAR_NUMBER)
|
||||
{
|
||||
/* For zero, use the current list or the list specifed by 'nr' */
|
||||
if (di->di_tv.vval.v_number != 0)
|
||||
{
|
||||
for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++)
|
||||
{
|
||||
if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number)
|
||||
break;
|
||||
}
|
||||
if (qf_idx == qi->qf_listcount)
|
||||
return FAIL; /* List not found */
|
||||
}
|
||||
flags |= QF_GETLIST_ID;
|
||||
}
|
||||
else
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (qf_idx != -1)
|
||||
{
|
||||
if (dict_find(what, (char_u *)"all", -1) != NULL)
|
||||
flags |= QF_GETLIST_ALL;
|
||||
if (dict_find(what, (char_u *)"all", -1) != NULL)
|
||||
flags |= QF_GETLIST_ALL;
|
||||
|
||||
if (dict_find(what, (char_u *)"title", -1) != NULL)
|
||||
flags |= QF_GETLIST_TITLE;
|
||||
if (dict_find(what, (char_u *)"title", -1) != NULL)
|
||||
flags |= QF_GETLIST_TITLE;
|
||||
|
||||
if (dict_find(what, (char_u *)"winid", -1) != NULL)
|
||||
flags |= QF_GETLIST_WINID;
|
||||
if (dict_find(what, (char_u *)"winid", -1) != NULL)
|
||||
flags |= QF_GETLIST_WINID;
|
||||
|
||||
if (dict_find(what, (char_u *)"context", -1) != NULL)
|
||||
flags |= QF_GETLIST_CONTEXT;
|
||||
if (dict_find(what, (char_u *)"context", -1) != NULL)
|
||||
flags |= QF_GETLIST_CONTEXT;
|
||||
|
||||
if (dict_find(what, (char_u *)"items", -1) != NULL)
|
||||
flags |= QF_GETLIST_ITEMS;
|
||||
}
|
||||
if (dict_find(what, (char_u *)"items", -1) != NULL)
|
||||
flags |= QF_GETLIST_ITEMS;
|
||||
|
||||
if (flags & QF_GETLIST_TITLE)
|
||||
{
|
||||
@ -4798,6 +4816,10 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
status = dict_add_nr_str(retdict, "context", 0L, (char_u *)"");
|
||||
}
|
||||
|
||||
if ((status == OK) && (flags & QF_GETLIST_ID))
|
||||
status = dict_add_nr_str(retdict, "id", qi->qf_lists[qf_idx].qf_id,
|
||||
NULL);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -4983,6 +5005,21 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (!newlist && (di = dict_find(what, (char_u *)"id", -1)) != NULL)
|
||||
{
|
||||
/* Use the quickfix/location list with the specified id */
|
||||
if (di->di_tv.v_type == VAR_NUMBER)
|
||||
{
|
||||
for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++)
|
||||
if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number)
|
||||
break;
|
||||
if (qf_idx == qi->qf_listcount)
|
||||
return FAIL; /* List not found */
|
||||
}
|
||||
else
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (newlist)
|
||||
{
|
||||
qi->qf_curlist = qf_idx;
|
||||
@ -5014,12 +5051,10 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
|
||||
}
|
||||
}
|
||||
|
||||
if ((di = dict_find(what, (char_u *)"text", -1)) != NULL)
|
||||
if ((di = dict_find(what, (char_u *)"lines", -1)) != NULL)
|
||||
{
|
||||
/* Only string and list values are supported */
|
||||
if ((di->di_tv.v_type == VAR_STRING && di->di_tv.vval.v_string != NULL)
|
||||
|| (di->di_tv.v_type == VAR_LIST
|
||||
&& di->di_tv.vval.v_list != NULL))
|
||||
/* Only a List value is supported */
|
||||
if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL)
|
||||
{
|
||||
if (action == 'r')
|
||||
qf_free_items(qi, qf_idx);
|
||||
|
@ -5197,7 +5197,8 @@ win_line(
|
||||
/* XIM don't send preedit_start and preedit_end, but they send
|
||||
* preedit_changed and commit. Thus Vim can't set "im_is_active", use
|
||||
* im_is_preediting() here. */
|
||||
if (xic != NULL
|
||||
if (p_imst == IM_ON_THE_SPOT
|
||||
&& xic != NULL
|
||||
&& lnum == wp->w_cursor.lnum
|
||||
&& (State & INSERT)
|
||||
&& !p_imdisable
|
||||
|
@ -1632,6 +1632,7 @@ struct channel_S {
|
||||
int ch_last_msg_id; /* ID of the last message */
|
||||
|
||||
chanpart_T ch_part[PART_COUNT]; /* info for socket, out, err and in */
|
||||
int ch_write_text_mode; /* write buffer lines with CR, not NL */
|
||||
|
||||
char *ch_hostname; /* only for socket, allocated */
|
||||
int ch_port; /* only for socket */
|
||||
@ -1713,7 +1714,8 @@ struct channel_S {
|
||||
#define JO2_CURWIN 0x0200 /* "curwin" */
|
||||
#define JO2_HIDDEN 0x0400 /* "hidden" */
|
||||
#define JO2_TERM_OPENCMD 0x0800 /* "term_opencmd" */
|
||||
#define JO2_ALL 0x0FFF
|
||||
#define JO2_EOF_CHARS 0x1000 /* "eof_chars" */
|
||||
#define JO2_ALL 0x1FFF
|
||||
|
||||
#define JO_MODE_ALL (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE)
|
||||
#define JO_CB_ALL \
|
||||
@ -1779,6 +1781,7 @@ typedef struct
|
||||
char_u *jo_term_name;
|
||||
char_u *jo_term_opencmd;
|
||||
int jo_term_finish;
|
||||
char_u *jo_eof_chars;
|
||||
#endif
|
||||
} jobopt_T;
|
||||
|
||||
|
37
src/term.c
37
src/term.c
@ -4496,6 +4496,8 @@ check_termcode(
|
||||
/* eat it when at least one digit and ending in 'c' */
|
||||
if (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c')
|
||||
{
|
||||
int version = col;
|
||||
|
||||
LOG_TR("Received CRV response");
|
||||
crv_status = STATUS_GOT;
|
||||
# ifdef FEAT_AUTOCMD
|
||||
@ -4508,10 +4510,11 @@ check_termcode(
|
||||
switch_to_8bit();
|
||||
|
||||
/* rxvt sends its version number: "20703" is 2.7.3.
|
||||
* Screen sends 40500.
|
||||
* Ignore it for when the user has set 'term' to xterm,
|
||||
* even though it's an rxvt. */
|
||||
if (col > 20000)
|
||||
col = 0;
|
||||
if (version > 20000)
|
||||
version = 0;
|
||||
|
||||
if (tp[1 + (tp[0] != CSI)] == '>' && semicols == 2)
|
||||
{
|
||||
@ -4522,19 +4525,19 @@ check_termcode(
|
||||
if (!option_was_set((char_u *)"ttym"))
|
||||
{
|
||||
# ifdef TTYM_SGR
|
||||
if (col >= 277)
|
||||
if (version >= 277)
|
||||
set_option_value((char_u *)"ttym", 0L,
|
||||
(char_u *)"sgr", 0);
|
||||
else
|
||||
# endif
|
||||
/* if xterm version >= 95 use mouse dragging */
|
||||
if (col >= 95)
|
||||
if (version >= 95)
|
||||
set_option_value((char_u *)"ttym", 0L,
|
||||
(char_u *)"xterm2", 0);
|
||||
}
|
||||
|
||||
/* if xterm version >= 141 try to get termcap codes */
|
||||
if (col >= 141)
|
||||
if (version >= 141)
|
||||
{
|
||||
LOG_TR("Enable checking for XT codes");
|
||||
check_for_codes = TRUE;
|
||||
@ -4543,7 +4546,7 @@ check_termcode(
|
||||
}
|
||||
|
||||
/* libvterm sends 0;100;0 */
|
||||
if (col == 100
|
||||
if (version == 100
|
||||
&& STRNCMP(tp + extra - 2, "0;100;0c", 8) == 0)
|
||||
{
|
||||
/* If run from Vim $COLORS is set to the number of
|
||||
@ -4558,14 +4561,26 @@ check_termcode(
|
||||
* compatible. */
|
||||
# ifdef MACOS
|
||||
/* Mac Terminal.app sends 1;95;0 */
|
||||
if (col == 95
|
||||
if (version == 95
|
||||
&& STRNCMP(tp + extra - 2, "1;95;0c", 7) == 0)
|
||||
is_not_xterm = TRUE;
|
||||
# endif
|
||||
/* Gnome Terminal.app sends 1;3801;0 or 1;4402;0,
|
||||
* assuming any version number over 3000 is not an
|
||||
* xterm. */
|
||||
if (col >= 3000)
|
||||
/* Gnome terminal sends 1;3801;0 or 1;4402;0.
|
||||
* xfce4-terminal sends 1;2802;0.
|
||||
* screen sends 83;40500;0
|
||||
* Assuming any version number over 2800 is not an
|
||||
* xterm (without the limit for rxvt and screen). */
|
||||
if (col >= 2800)
|
||||
is_not_xterm = TRUE;
|
||||
|
||||
/* PuTTY sends 0;136;0 */
|
||||
if (version == 136
|
||||
&& STRNCMP(tp + extra - 2, "0;136;0c", 8) == 0)
|
||||
is_not_xterm = TRUE;
|
||||
|
||||
/* Konsole sends 0;115;0 */
|
||||
if (version == 115
|
||||
&& STRNCMP(tp + extra - 2, "0;115;0c", 8) == 0)
|
||||
is_not_xterm = TRUE;
|
||||
|
||||
/* Only request the cursor style if t_SH and t_RS are
|
||||
|
@ -110,6 +110,7 @@ struct terminal_S {
|
||||
int tl_channel_closed;
|
||||
int tl_finish; /* 'c' for ++close, 'o' for ++open */
|
||||
char_u *tl_opencmd;
|
||||
char_u *tl_eof_chars;
|
||||
|
||||
#ifdef WIN3264
|
||||
void *tl_winpty_config;
|
||||
@ -389,6 +390,9 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
|
||||
if (opt->jo_term_opencmd != NULL)
|
||||
term->tl_opencmd = vim_strsave(opt->jo_term_opencmd);
|
||||
|
||||
if (opt->jo_eof_chars != NULL)
|
||||
term->tl_eof_chars = vim_strsave(opt->jo_eof_chars);
|
||||
|
||||
set_string_option_direct((char_u *)"buftype", -1,
|
||||
(char_u *)"terminal", OPT_FREE|OPT_LOCAL, 0);
|
||||
|
||||
@ -490,6 +494,20 @@ ex_terminal(exarg_T *eap)
|
||||
opt.jo_term_cols = atoi((char *)ep + 1);
|
||||
p = skiptowhite(cmd);
|
||||
}
|
||||
else if ((int)(p - cmd) == 3 && STRNICMP(cmd, "eof", 3) == 0
|
||||
&& ep != NULL)
|
||||
{
|
||||
char_u *buf = NULL;
|
||||
char_u *keys;
|
||||
|
||||
p = skiptowhite(cmd);
|
||||
*p = NUL;
|
||||
keys = replace_termcodes(ep + 1, &buf, TRUE, TRUE, TRUE);
|
||||
opt.jo_set2 |= JO2_EOF_CHARS;
|
||||
opt.jo_eof_chars = vim_strsave(keys);
|
||||
vim_free(buf);
|
||||
*p = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*p)
|
||||
@ -570,6 +588,7 @@ free_terminal(buf_T *buf)
|
||||
vim_free(term->tl_title);
|
||||
vim_free(term->tl_status_text);
|
||||
vim_free(term->tl_opencmd);
|
||||
vim_free(term->tl_eof_chars);
|
||||
vim_free(term->tl_cursor_color);
|
||||
vim_free(term);
|
||||
buf->b_term = NULL;
|
||||
@ -2821,7 +2840,7 @@ f_term_start(typval_T *argvars, typval_T *rettv)
|
||||
+ JO_EXIT_CB + JO_CLOSE_CALLBACK,
|
||||
JO2_TERM_NAME + JO2_TERM_FINISH + JO2_HIDDEN + JO2_TERM_OPENCMD
|
||||
+ JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN
|
||||
+ JO2_CWD + JO2_ENV) == FAIL)
|
||||
+ JO2_CWD + JO2_ENV + JO2_EOF_CHARS) == FAIL)
|
||||
return;
|
||||
|
||||
if (opt.jo_vertical)
|
||||
@ -2890,6 +2909,32 @@ f_term_wait(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when a channel has sent all the lines to a terminal.
|
||||
* Send a CTRL-D to mark the end of the text.
|
||||
*/
|
||||
void
|
||||
term_send_eof(channel_T *ch)
|
||||
{
|
||||
term_T *term;
|
||||
|
||||
for (term = first_term; term != NULL; term = term->tl_next)
|
||||
if (term->tl_job == ch->ch_job)
|
||||
{
|
||||
if (term->tl_eof_chars != NULL)
|
||||
{
|
||||
channel_send(ch, PART_IN, term->tl_eof_chars,
|
||||
(int)STRLEN(term->tl_eof_chars), NULL);
|
||||
channel_send(ch, PART_IN, (char_u *)"\r", 1, NULL);
|
||||
}
|
||||
# ifdef WIN3264
|
||||
else
|
||||
/* Default: CTRL-D */
|
||||
channel_send(ch, PART_IN, (char_u *)"\004\r", 2, NULL);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
# if defined(WIN3264) || defined(PROTO)
|
||||
|
||||
/**************************************
|
||||
@ -3060,8 +3105,6 @@ term_and_job_init(
|
||||
if (job == NULL)
|
||||
goto failed;
|
||||
|
||||
/* TODO: when all lines are written and the fd is closed, the command
|
||||
* doesn't get EOF and hangs. */
|
||||
if (opt->jo_set & JO_IN_BUF)
|
||||
job->jv_in_buf = buflist_findnr(opt->jo_io_buf[PART_IN]);
|
||||
|
||||
@ -3083,6 +3126,9 @@ term_and_job_init(
|
||||
GENERIC_READ, 0, NULL,
|
||||
OPEN_EXISTING, 0, NULL));
|
||||
|
||||
/* Write lines with CR instead of NL. */
|
||||
channel->ch_write_text_mode = TRUE;
|
||||
|
||||
jo = CreateJobObject(NULL, NULL);
|
||||
if (jo == NULL)
|
||||
goto failed;
|
||||
@ -3188,7 +3234,6 @@ terminal_enabled(void)
|
||||
return dyn_winpty_init(FALSE) == OK;
|
||||
}
|
||||
|
||||
|
||||
# else
|
||||
|
||||
/**************************************
|
||||
|
@ -50,7 +50,6 @@ SCRIPTS_ALL = \
|
||||
test70.out \
|
||||
test73.out \
|
||||
test79.out \
|
||||
test80.out \
|
||||
test88.out \
|
||||
test94.out \
|
||||
test95.out \
|
||||
|
@ -86,7 +86,7 @@ SCRIPT = test1.out test3.out test4.out test5.out \
|
||||
test64.out \
|
||||
test66.out test68.out test69.out \
|
||||
test72.out \
|
||||
test77a.out test78.out test79.out test80.out \
|
||||
test77a.out test78.out test79.out \
|
||||
test88.out \
|
||||
test94.out \
|
||||
test95.out test99.out \
|
||||
|
@ -31,6 +31,7 @@ let test_values = {
|
||||
\ 'history': [[0, 1, 100], [-1, 10001]],
|
||||
\ 'iminsert': [[0, 1], [-1, 3, 999]],
|
||||
\ 'imsearch': [[-1, 0, 1], [-2, 3, 999]],
|
||||
\ 'imstyle': [[0, 1], [-1, 2, 999]],
|
||||
\ 'lines': [[2, 24], [-1, 0, 1]],
|
||||
\ 'linespace': [[0, 2, 4], ['']],
|
||||
\ 'numberwidth': [[1, 4, 8, 10], [-1, 0, 11]],
|
||||
|
@ -1,201 +0,0 @@
|
||||
Test for *sub-replace-special* and *sub-replace-expression* on substitute().
|
||||
Test for submatch() on substitute().
|
||||
Test for *:s%* on :substitute.
|
||||
|
||||
STARTTEST
|
||||
:so small.vim
|
||||
ENDTEST
|
||||
|
||||
TEST_1:
|
||||
|
||||
STARTTEST
|
||||
:set magic
|
||||
:set cpo&
|
||||
:$put =\"\n\nTEST_1:\"
|
||||
:$put =substitute('A', 'A', '&&', '')
|
||||
:$put =substitute('B', 'B', '\&', '')
|
||||
:$put =substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', '')
|
||||
:$put =substitute('D', 'D', 'd', '')
|
||||
:$put =substitute('E', 'E', '~', '')
|
||||
:$put =substitute('F', 'F', '\~', '')
|
||||
:$put =substitute('G', 'G', '\ugg', '')
|
||||
:$put =substitute('H', 'H', '\Uh\Eh', '')
|
||||
:$put =substitute('I', 'I', '\lII', '')
|
||||
:$put =substitute('J', 'J', '\LJ\EJ', '')
|
||||
:$put =substitute('K', 'K', '\Uk\ek', '')
|
||||
:$put =substitute('lLl', 'L', '
|
||||
', '')
|
||||
:$put =substitute('mMm', 'M', '\r', '')
|
||||
:$put =substitute('nNn', 'N', '\
|
||||
', '')
|
||||
:$put =substitute('oOo', 'O', '\n', '')
|
||||
:$put =substitute('pPp', 'P', '\b', '')
|
||||
:$put =substitute('qQq', 'Q', '\t', '')
|
||||
:$put =substitute('rRr', 'R', '\\', '')
|
||||
:$put =substitute('sSs', 'S', '\c', '')
|
||||
:$put =substitute('uUu', 'U', \"\n\", '')
|
||||
:$put =substitute('vVv', 'V', \"\b\", '')
|
||||
:$put =substitute('wWw', 'W', \"\\\", '')
|
||||
:$put =substitute('xXx', 'X', \"\r\", '')
|
||||
:$put =substitute('Y', 'Y', '\L\uyYy\l\EY', '')
|
||||
:$put =substitute('Z', 'Z', '\U\lZzZ\u\Ez', '')
|
||||
/^TEST_2
|
||||
ENDTEST
|
||||
|
||||
TEST_2:
|
||||
|
||||
STARTTEST
|
||||
:set nomagic
|
||||
:set cpo&
|
||||
:$put =\"\n\nTEST_2:\"
|
||||
:$put =substitute('A', 'A', '&&', '')
|
||||
:$put =substitute('B', 'B', '\&', '')
|
||||
:$put =substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', '')
|
||||
:$put =substitute('D', 'D', 'd', '')
|
||||
:$put =substitute('E', 'E', '~', '')
|
||||
:$put =substitute('F', 'F', '\~', '')
|
||||
:$put =substitute('G', 'G', '\ugg', '')
|
||||
:$put =substitute('H', 'H', '\Uh\Eh', '')
|
||||
:$put =substitute('I', 'I', '\lII', '')
|
||||
:$put =substitute('J', 'J', '\LJ\EJ', '')
|
||||
:$put =substitute('K', 'K', '\Uk\ek', '')
|
||||
:$put =substitute('lLl', 'L', '
|
||||
', '')
|
||||
:$put =substitute('mMm', 'M', '\r', '')
|
||||
:$put =substitute('nNn', 'N', '\
|
||||
', '')
|
||||
:$put =substitute('oOo', 'O', '\n', '')
|
||||
:$put =substitute('pPp', 'P', '\b', '')
|
||||
:$put =substitute('qQq', 'Q', '\t', '')
|
||||
:$put =substitute('rRr', 'R', '\\', '')
|
||||
:$put =substitute('sSs', 'S', '\c', '')
|
||||
:$put =substitute('tTt', 'T', \"\r\", '')
|
||||
:$put =substitute('uUu', 'U', \"\n\", '')
|
||||
:$put =substitute('vVv', 'V', \"\b\", '')
|
||||
:$put =substitute('wWw', 'W', \"\\\", '')
|
||||
:$put =substitute('X', 'X', '\L\uxXx\l\EX', '')
|
||||
:$put =substitute('Y', 'Y', '\U\lYyY\u\Ey', '')
|
||||
/^TEST_3
|
||||
ENDTEST
|
||||
|
||||
TEST_3:
|
||||
|
||||
STARTTEST
|
||||
:set magic&
|
||||
:set cpo&
|
||||
:$put =\"\n\nTEST_3:\"
|
||||
:let y = substitute('aAa', 'A', '\="\\"', '') | $put =y
|
||||
:let y = substitute('bBb', 'B', '\="\\\\"', '') | $put =y
|
||||
:let y = substitute('cCc', 'C', '\="
|
||||
"', '') | $put =y
|
||||
:let y = substitute('dDd', 'D', '\="\\
|
||||
"', '') | $put =y
|
||||
:let y = substitute('eEe', 'E', '\="\\\\
|
||||
"', '') | $put =y
|
||||
:let y = substitute('fFf', 'F', '\="\\r"', '') | $put =y
|
||||
:let y = substitute('jJj', 'J', '\="\\n"', '') | $put =y
|
||||
:let y = substitute('kKk', 'K', '\="\r"', '') | $put =y
|
||||
:let y = substitute('lLl', 'L', '\="\n"', '') | $put =y
|
||||
/^TEST_4
|
||||
ENDTEST
|
||||
|
||||
TEST_4:
|
||||
|
||||
STARTTEST
|
||||
:set magic&
|
||||
:set cpo&
|
||||
:$put =\"\n\nTEST_4:\"
|
||||
:let y = substitute('aAa', 'A', '\=substitute(submatch(0), ".", "\\", "")', '') | $put =y
|
||||
:let y = substitute('bBb', 'B', '\=substitute(submatch(0), ".", "\\\\", "")', '') | $put =y
|
||||
:let y = substitute('cCc', 'C', '\=substitute(submatch(0), ".", "
|
||||
", "")', '') | $put =y
|
||||
:let y = substitute('dDd', 'D', '\=substitute(submatch(0), ".", "\\
|
||||
", "")', '') | $put =y
|
||||
:let y = substitute('eEe', 'E', '\=substitute(submatch(0), ".", "\\\\
|
||||
", "")', '') | $put =y
|
||||
:let y = substitute('fFf', 'F', '\=substitute(submatch(0), ".", "\\r", "")', '') | $put =y
|
||||
:let y = substitute('jJj', 'J', '\=substitute(submatch(0), ".", "\\n", "")', '') | $put =y
|
||||
:let y = substitute('kKk', 'K', '\=substitute(submatch(0), ".", "\r", "")', '') | $put =y
|
||||
:let y = substitute('lLl', 'L', '\=substitute(submatch(0), ".", "\n", "")', '') | $put =y
|
||||
/^TEST_5
|
||||
ENDTEST
|
||||
|
||||
TEST_5:
|
||||
|
||||
STARTTEST
|
||||
:set magic&
|
||||
:set cpo&
|
||||
:$put =\"\n\nTEST_5:\"
|
||||
:$put =substitute('A123456789', 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\=submatch(0) . submatch(9) . submatch(8) . submatch(7) . submatch(6) . submatch(5) . submatch(4) . submatch(3) . submatch(2) . submatch(1)', '')
|
||||
:$put =substitute('A123456789', 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\=string([submatch(0, 1), submatch(9, 1), submatch(8, 1), submatch(7, 1), submatch(6, 1), submatch(5, 1), submatch(4, 1), submatch(3, 1), submatch(2, 1), submatch(1, 1)])', '')
|
||||
/^TEST_6
|
||||
ENDTEST
|
||||
|
||||
TEST_6:
|
||||
|
||||
STARTTEST
|
||||
:set magic&
|
||||
:$put =\"\n\nTEST_6:\"
|
||||
:set cpo+=/
|
||||
:$put =substitute('A', 'A', 'a', '')
|
||||
:$put =substitute('B', 'B', '%', '')
|
||||
:set cpo-=/
|
||||
:$put =substitute('C', 'C', 'c', '')
|
||||
:$put =substitute('D', 'D', '%', '')
|
||||
/^TEST_7
|
||||
ENDTEST
|
||||
|
||||
TEST_7:
|
||||
|
||||
STARTTEST
|
||||
:set magic&
|
||||
:set cpo&
|
||||
:$put =\"\n\nTEST_7:\"
|
||||
:$put =substitute('A
|
||||
A', 'A.', '\=submatch(0)', '')
|
||||
:$put =substitute(\"B\nB\", 'B.', '\=submatch(0)', '')
|
||||
:$put =substitute(\"B\nB\", 'B.', '\=string(submatch(0, 1))', '')
|
||||
:$put =substitute('-bb', '\zeb', 'a', 'g')
|
||||
:$put =substitute('-bb', '\ze', 'c', 'g')
|
||||
/^TEST_8
|
||||
ENDTEST
|
||||
|
||||
TEST_8:
|
||||
|
||||
STARTTEST
|
||||
:set magic&
|
||||
:set cpo&
|
||||
:$put =\"\n\nTEST_8:\"
|
||||
:$put =',,X'
|
||||
:s/\(^\|,\)\ze\(,\|X\)/\1N/g
|
||||
:$put =',,Y'
|
||||
:s/\(^\|,\)\ze\(,\|Y\)/\1N/gc
|
||||
a:$put =',,Z'
|
||||
:s/\(^\|,\)\ze\(,\|Z\)/\1N/gc
|
||||
yy/^TEST_9:
|
||||
ENDTEST
|
||||
|
||||
TEST_9:
|
||||
|
||||
STARTTEST
|
||||
:set magic&
|
||||
:set cpo&
|
||||
:$put =\"\n\nTEST_9:\"
|
||||
:$put ='xxx'
|
||||
:s/x/X/gc
|
||||
yyq/^TEST_10:
|
||||
ENDTEST
|
||||
|
||||
TEST_10:
|
||||
|
||||
STARTTEST
|
||||
:set magic&
|
||||
:set cpo&
|
||||
:$put =\"\n\nTEST_10:\"
|
||||
:let y = substitute('123', '\zs', 'a', 'g') | $put =y
|
||||
:let y = substitute('123', '\zs.', 'a', 'g') | $put =y
|
||||
:let y = substitute('123', '.\zs', 'a', 'g') | $put =y
|
||||
:let y = substitute('123', '\ze', 'a', 'g') | $put =y
|
||||
:let y = substitute('123', '\ze.', 'a', 'g') | $put =y
|
||||
:let y = substitute('123', '.\ze', 'a', 'g') | $put =y
|
||||
:let y = substitute('123', '1\|\ze', 'a', 'g') | $put =y
|
@ -1,131 +0,0 @@
|
||||
Results of test72:
|
||||
|
||||
|
||||
TEST_1:
|
||||
AA
|
||||
&
|
||||
C123456789987654321
|
||||
d
|
||||
~
|
||||
~
|
||||
Gg
|
||||
Hh
|
||||
iI
|
||||
jJ
|
||||
Kk
|
||||
l
|
||||
l
|
||||
m
|
||||
m
|
||||
n
|
||||
n
|
||||
o
|
||||
o
|
||||
pp
|
||||
q q
|
||||
r\r
|
||||
scs
|
||||
u
|
||||
u
|
||||
vv
|
||||
w\w
|
||||
x
|
||||
x
|
||||
YyyY
|
||||
zZZz
|
||||
|
||||
|
||||
TEST_2:
|
||||
AA
|
||||
&
|
||||
C123456789987654321
|
||||
d
|
||||
~
|
||||
~
|
||||
Gg
|
||||
Hh
|
||||
iI
|
||||
jJ
|
||||
Kk
|
||||
l
|
||||
l
|
||||
m
|
||||
m
|
||||
n
|
||||
n
|
||||
o
|
||||
o
|
||||
pp
|
||||
q q
|
||||
r\r
|
||||
scs
|
||||
t
|
||||
t
|
||||
u
|
||||
u
|
||||
vv
|
||||
w\w
|
||||
XxxX
|
||||
yYYy
|
||||
|
||||
|
||||
TEST_3:
|
||||
a\a
|
||||
b\\b
|
||||
c
|
||||
c
|
||||
d\
|
||||
d
|
||||
e\\
|
||||
e
|
||||
f\rf
|
||||
j\nj
|
||||
k
|
||||
k
|
||||
l
|
||||
l
|
||||
|
||||
|
||||
TEST_4:
|
||||
a\a
|
||||
b\b
|
||||
c
|
||||
c
|
||||
d
|
||||
d
|
||||
e\
|
||||
e
|
||||
f
|
||||
f
|
||||
j
|
||||
j
|
||||
k
|
||||
k
|
||||
l
|
||||
l
|
||||
|
||||
|
||||
TEST_5:
|
||||
A123456789987654321
|
||||
[['A123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], ['2'], ['1']]
|
||||
|
||||
|
||||
TEST_6:
|
||||
a
|
||||
%
|
||||
c
|
||||
%
|
||||
|
||||
|
||||
TEST_7:
|
||||
A
|
||||
A
|
||||
B
|
||||
B
|
||||
['B
|
||||
']B
|
||||
-abab
|
||||
c-cbcbc
|
||||
|
||||
|
||||
TEST_8:
|
@ -121,5 +121,35 @@ func Test_mksession_arglist()
|
||||
argdel *
|
||||
endfunc
|
||||
|
||||
func Test_mksession_one_buffer_two_windows()
|
||||
edit Xtest1
|
||||
new Xtest2
|
||||
split
|
||||
mksession! Xtest_mks.out
|
||||
let lines = readfile('Xtest_mks.out')
|
||||
let count1 = 0
|
||||
let count2 = 0
|
||||
let count2buf = 0
|
||||
for line in lines
|
||||
if line =~ 'edit \f*Xtest1$'
|
||||
let count1 += 1
|
||||
endif
|
||||
if line =~ 'edit \f\{-}Xtest2'
|
||||
let count2 += 1
|
||||
endif
|
||||
if line =~ 'buffer \f\{-}Xtest2'
|
||||
let count2buf += 1
|
||||
endif
|
||||
endfor
|
||||
call assert_equal(1, count1, 'Xtest1 count')
|
||||
call assert_equal(2, count2, 'Xtest2 count')
|
||||
call assert_equal(2, count2buf, 'Xtest2 buffer count')
|
||||
|
||||
close
|
||||
bwipe!
|
||||
call delete('Xtest_mks.out')
|
||||
endfunc
|
||||
|
||||
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -1897,8 +1897,9 @@ func Xproperty_tests(cchar)
|
||||
call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
|
||||
let l1=g:Xgetlist({'nr':1,'all':1})
|
||||
let l2=g:Xgetlist({'nr':2,'all':1})
|
||||
let l1.nr=2
|
||||
let l2.nr=1
|
||||
let save_id = l1.id
|
||||
let l1.id=l2.id
|
||||
let l2.id=save_id
|
||||
call g:Xsetlist([], 'r', l1)
|
||||
call g:Xsetlist([], 'r', l2)
|
||||
let newl1=g:Xgetlist({'nr':1,'all':1})
|
||||
@ -2298,25 +2299,26 @@ func Xsetexpr_tests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
let t = ["File1:10:Line10", "File1:20:Line20"]
|
||||
call g:Xsetlist([], ' ', {'text' : t})
|
||||
call g:Xsetlist([], 'a', {'text' : "File1:30:Line30"})
|
||||
call g:Xsetlist([], ' ', {'lines' : t})
|
||||
call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
|
||||
|
||||
let l = g:Xgetlist()
|
||||
call assert_equal(3, len(l))
|
||||
call assert_equal(20, l[1].lnum)
|
||||
call assert_equal('Line30', l[2].text)
|
||||
call g:Xsetlist([], 'r', {'text' : "File2:5:Line5"})
|
||||
call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
|
||||
let l = g:Xgetlist()
|
||||
call assert_equal(1, len(l))
|
||||
call assert_equal('Line5', l[0].text)
|
||||
call assert_equal(-1, g:Xsetlist([], 'a', {'text' : 10}))
|
||||
call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
|
||||
call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
|
||||
|
||||
call g:Xsetlist([], 'f')
|
||||
" Add entries to multiple lists
|
||||
call g:Xsetlist([], 'a', {'nr' : 1, 'text' : ["File1:10:Line10"]})
|
||||
call g:Xsetlist([], 'a', {'nr' : 2, 'text' : ["File2:20:Line20"]})
|
||||
call g:Xsetlist([], 'a', {'nr' : 1, 'text' : ["File1:15:Line15"]})
|
||||
call g:Xsetlist([], 'a', {'nr' : 2, 'text' : ["File2:25:Line25"]})
|
||||
call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
|
||||
call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
|
||||
call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
|
||||
call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
|
||||
call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
|
||||
call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
|
||||
endfunc
|
||||
@ -2333,10 +2335,10 @@ func Xmultidirstack_tests(cchar)
|
||||
call g:Xsetlist([], 'f')
|
||||
Xexpr "" | Xexpr ""
|
||||
|
||||
call g:Xsetlist([], 'a', {'nr' : 1, 'text' : "Entering dir 'Xone/a'"})
|
||||
call g:Xsetlist([], 'a', {'nr' : 2, 'text' : "Entering dir 'Xtwo/a'"})
|
||||
call g:Xsetlist([], 'a', {'nr' : 1, 'text' : "one.txt:3:one one one"})
|
||||
call g:Xsetlist([], 'a', {'nr' : 2, 'text' : "two.txt:5:two two two"})
|
||||
call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
|
||||
call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
|
||||
call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
|
||||
call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
|
||||
|
||||
let l1 = g:Xgetlist({'nr':1, 'items':1})
|
||||
let l2 = g:Xgetlist({'nr':2, 'items':1})
|
||||
@ -2370,10 +2372,10 @@ func Xmultifilestack_tests(cchar)
|
||||
call g:Xsetlist([], 'f')
|
||||
Xexpr "" | Xexpr ""
|
||||
|
||||
call g:Xsetlist([], 'a', {'nr' : 1, 'text' : "[one.txt]"})
|
||||
call g:Xsetlist([], 'a', {'nr' : 2, 'text' : "[two.txt]"})
|
||||
call g:Xsetlist([], 'a', {'nr' : 1, 'text' : "(3,5) one one one"})
|
||||
call g:Xsetlist([], 'a', {'nr' : 2, 'text' : "(5,9) two two two"})
|
||||
call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
|
||||
call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
|
||||
call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
|
||||
call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
|
||||
|
||||
let l1 = g:Xgetlist({'nr':1, 'items':1})
|
||||
let l2 = g:Xgetlist({'nr':2, 'items':1})
|
||||
@ -2522,26 +2524,59 @@ endfunc
|
||||
|
||||
" Test for getting the quickfix list items from some text without modifying
|
||||
" the quickfix stack
|
||||
func XgetListFromText(cchar)
|
||||
func XgetListFromLines(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
call g:Xsetlist([], 'f')
|
||||
|
||||
let l = g:Xgetlist({'text' : "File1:10:Line10"}).items
|
||||
call assert_equal(1, len(l))
|
||||
call assert_equal('Line10', l[0].text)
|
||||
|
||||
let l = g:Xgetlist({'text' : ["File2:20:Line20", "File2:30:Line30"]}).items
|
||||
let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
|
||||
call assert_equal(2, len(l))
|
||||
call assert_equal(30, l[1].lnum)
|
||||
|
||||
call assert_equal({}, g:Xgetlist({'text' : 10}))
|
||||
call assert_equal({}, g:Xgetlist({'text' : []}))
|
||||
call assert_equal({}, g:Xgetlist({'lines' : 10}))
|
||||
call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
|
||||
call assert_equal([], g:Xgetlist({'lines' : []}).items)
|
||||
call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
|
||||
|
||||
" Make sure that the quickfix stack is not modified
|
||||
call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
|
||||
endfunc
|
||||
|
||||
func Test_get_list_from_text()
|
||||
call XgetListFromText('c')
|
||||
call XgetListFromText('l')
|
||||
func Test_get_list_from_lines()
|
||||
call XgetListFromLines('c')
|
||||
call XgetListFromLines('l')
|
||||
endfunc
|
||||
|
||||
" Tests for the quickfix list id
|
||||
func Xqfid_tests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
call g:Xsetlist([], 'f')
|
||||
call assert_equal({}, g:Xgetlist({'id':0}))
|
||||
Xexpr ''
|
||||
let start_id = g:Xgetlist({'id' : 0}).id
|
||||
Xexpr '' | Xexpr ''
|
||||
Xolder
|
||||
call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
|
||||
call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
|
||||
call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
|
||||
call assert_equal({}, g:Xgetlist({'id':0, 'nr':99}))
|
||||
call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
|
||||
call assert_equal({}, g:Xgetlist({'id':99, 'nr':0}))
|
||||
call assert_equal({}, g:Xgetlist({'id':"abc", 'nr':0}))
|
||||
|
||||
call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
|
||||
call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
|
||||
call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
|
||||
call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
|
||||
call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
|
||||
call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
|
||||
|
||||
let qfid = g:Xgetlist({'id':0, 'nr':0})
|
||||
call g:Xsetlist([], 'f')
|
||||
call assert_equal({}, g:Xgetlist({'id':qfid, 'nr':0}))
|
||||
endfunc
|
||||
|
||||
func Test_qf_id()
|
||||
call Xqfid_tests('c')
|
||||
call Xqfid_tests('l')
|
||||
endfunc
|
||||
|
@ -114,3 +114,183 @@ func Test_substitute_repeat()
|
||||
call feedkeys("Qsc\<CR>y", 'tx')
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test for *sub-replace-special* and *sub-replace-expression* on substitute().
|
||||
func Test_sub_replace_1()
|
||||
" Run the tests with 'magic' on
|
||||
set magic
|
||||
set cpo&
|
||||
call assert_equal('AA', substitute('A', 'A', '&&', ''))
|
||||
call assert_equal('&', substitute('B', 'B', '\&', ''))
|
||||
call assert_equal('C123456789987654321', substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', ''))
|
||||
call assert_equal('d', substitute('D', 'D', 'd', ''))
|
||||
call assert_equal('~', substitute('E', 'E', '~', ''))
|
||||
call assert_equal('~', substitute('F', 'F', '\~', ''))
|
||||
call assert_equal('Gg', substitute('G', 'G', '\ugg', ''))
|
||||
call assert_equal('Hh', substitute('H', 'H', '\Uh\Eh', ''))
|
||||
call assert_equal('iI', substitute('I', 'I', '\lII', ''))
|
||||
call assert_equal('jJ', substitute('J', 'J', '\LJ\EJ', ''))
|
||||
call assert_equal('Kk', substitute('K', 'K', '\Uk\ek', ''))
|
||||
call assert_equal("l\<C-V>\<C-M>l",
|
||||
\ substitute('lLl', 'L', "\<C-V>\<C-M>", ''))
|
||||
call assert_equal("m\<C-M>m", substitute('mMm', 'M', '\r', ''))
|
||||
call assert_equal("n\<C-V>\<C-M>n",
|
||||
\ substitute('nNn', 'N', "\\\<C-V>\<C-M>", ''))
|
||||
call assert_equal("o\no", substitute('oOo', 'O', '\n', ''))
|
||||
call assert_equal("p\<C-H>p", substitute('pPp', 'P', '\b', ''))
|
||||
call assert_equal("q\tq", substitute('qQq', 'Q', '\t', ''))
|
||||
call assert_equal('r\r', substitute('rRr', 'R', '\\', ''))
|
||||
call assert_equal('scs', substitute('sSs', 'S', '\c', ''))
|
||||
call assert_equal("u\nu", substitute('uUu', 'U', "\n", ''))
|
||||
call assert_equal("v\<C-H>v", substitute('vVv', 'V', "\b", ''))
|
||||
call assert_equal("w\\w", substitute('wWw', 'W', "\\", ''))
|
||||
call assert_equal("x\<C-M>x", substitute('xXx', 'X', "\r", ''))
|
||||
call assert_equal("YyyY", substitute('Y', 'Y', '\L\uyYy\l\EY', ''))
|
||||
call assert_equal("zZZz", substitute('Z', 'Z', '\U\lZzZ\u\Ez', ''))
|
||||
endfunc
|
||||
|
||||
func Test_sub_replace_2()
|
||||
" Run the tests with 'magic' off
|
||||
set nomagic
|
||||
set cpo&
|
||||
call assert_equal('AA', substitute('A', 'A', '&&', ''))
|
||||
call assert_equal('&', substitute('B', 'B', '\&', ''))
|
||||
call assert_equal('C123456789987654321', substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', ''))
|
||||
call assert_equal('d', substitute('D', 'D', 'd', ''))
|
||||
call assert_equal('~', substitute('E', 'E', '~', ''))
|
||||
call assert_equal('~', substitute('F', 'F', '\~', ''))
|
||||
call assert_equal('Gg', substitute('G', 'G', '\ugg', ''))
|
||||
call assert_equal('Hh', substitute('H', 'H', '\Uh\Eh', ''))
|
||||
call assert_equal('iI', substitute('I', 'I', '\lII', ''))
|
||||
call assert_equal('jJ', substitute('J', 'J', '\LJ\EJ', ''))
|
||||
call assert_equal('Kk', substitute('K', 'K', '\Uk\ek', ''))
|
||||
call assert_equal("l\<C-V>\<C-M>l",
|
||||
\ substitute('lLl', 'L', "\<C-V>\<C-M>", ''))
|
||||
call assert_equal("m\<C-M>m", substitute('mMm', 'M', '\r', ''))
|
||||
call assert_equal("n\<C-V>\<C-M>n",
|
||||
\ substitute('nNn', 'N', "\\\<C-V>\<C-M>", ''))
|
||||
call assert_equal("o\no", substitute('oOo', 'O', '\n', ''))
|
||||
call assert_equal("p\<C-H>p", substitute('pPp', 'P', '\b', ''))
|
||||
call assert_equal("q\tq", substitute('qQq', 'Q', '\t', ''))
|
||||
call assert_equal('r\r', substitute('rRr', 'R', '\\', ''))
|
||||
call assert_equal('scs', substitute('sSs', 'S', '\c', ''))
|
||||
call assert_equal("t\<C-M>t", substitute('tTt', 'T', "\r", ''))
|
||||
call assert_equal("u\nu", substitute('uUu', 'U', "\n", ''))
|
||||
call assert_equal("v\<C-H>v", substitute('vVv', 'V', "\b", ''))
|
||||
call assert_equal('w\w', substitute('wWw', 'W', "\\", ''))
|
||||
call assert_equal('XxxX', substitute('X', 'X', '\L\uxXx\l\EX', ''))
|
||||
call assert_equal('yYYy', substitute('Y', 'Y', '\U\lYyY\u\Ey', ''))
|
||||
endfunc
|
||||
|
||||
func Test_sub_replace_3()
|
||||
set magic&
|
||||
set cpo&
|
||||
call assert_equal('a\a', substitute('aAa', 'A', '\="\\"', ''))
|
||||
call assert_equal('b\\b', substitute('bBb', 'B', '\="\\\\"', ''))
|
||||
call assert_equal("c\rc", substitute('cCc', 'C', "\\=\"\r\"", ''))
|
||||
call assert_equal("d\\\rd", substitute('dDd', 'D', "\\=\"\\\\\r\"", ''))
|
||||
call assert_equal("e\\\\\re", substitute('eEe', 'E', "\\=\"\\\\\\\\\r\"", ''))
|
||||
call assert_equal('f\rf', substitute('fFf', 'F', '\="\\r"', ''))
|
||||
call assert_equal('j\nj', substitute('jJj', 'J', '\="\\n"', ''))
|
||||
call assert_equal("k\<C-M>k", substitute('kKk', 'K', '\="\r"', ''))
|
||||
call assert_equal("l\nl", substitute('lLl', 'L', '\="\n"', ''))
|
||||
endfunc
|
||||
|
||||
" Test for submatch() on substitute().
|
||||
func Test_sub_replace_4()
|
||||
set magic&
|
||||
set cpo&
|
||||
call assert_equal('a\a', substitute('aAa', 'A',
|
||||
\ '\=substitute(submatch(0), ".", "\\", "")', ''))
|
||||
call assert_equal('b\b', substitute('bBb', 'B',
|
||||
\ '\=substitute(submatch(0), ".", "\\\\", "")', ''))
|
||||
call assert_equal("c\<C-V>\<C-M>c", substitute('cCc', 'C', '\=substitute(submatch(0), ".", "\<C-V>\<C-M>", "")', ''))
|
||||
call assert_equal("d\<C-V>\<C-M>d", substitute('dDd', 'D', '\=substitute(submatch(0), ".", "\\\<C-V>\<C-M>", "")', ''))
|
||||
call assert_equal("e\\\<C-V>\<C-M>e", substitute('eEe', 'E', '\=substitute(submatch(0), ".", "\\\\\<C-V>\<C-M>", "")', ''))
|
||||
call assert_equal("f\<C-M>f", substitute('fFf', 'F', '\=substitute(submatch(0), ".", "\\r", "")', ''))
|
||||
call assert_equal("j\nj", substitute('jJj', 'J', '\=substitute(submatch(0), ".", "\\n", "")', ''))
|
||||
call assert_equal("k\rk", substitute('kKk', 'K', '\=substitute(submatch(0), ".", "\r", "")', ''))
|
||||
call assert_equal("l\nl", substitute('lLl', 'L', '\=substitute(submatch(0), ".", "\n", "")', ''))
|
||||
endfunc
|
||||
|
||||
func Test_sub_replace_5()
|
||||
set magic&
|
||||
set cpo&
|
||||
call assert_equal('A123456789987654321', substitute('A123456789',
|
||||
\ 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)',
|
||||
\ '\=submatch(0) . submatch(9) . submatch(8) . ' .
|
||||
\ 'submatch(7) . submatch(6) . submatch(5) . ' .
|
||||
\ 'submatch(4) . submatch(3) . submatch(2) . submatch(1)',
|
||||
\ ''))
|
||||
call assert_equal("[['A123456789'], ['9'], ['8'], ['7'], ['6'], " .
|
||||
\ "['5'], ['4'], ['3'], ['2'], ['1']]",
|
||||
\ substitute('A123456789',
|
||||
\ 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)',
|
||||
\ '\=string([submatch(0, 1), submatch(9, 1), ' .
|
||||
\ 'submatch(8, 1), submatch(7, 1), submatch(6, 1), ' .
|
||||
\ 'submatch(5, 1), submatch(4, 1), submatch(3, 1), ' .
|
||||
\ 'submatch(2, 1), submatch(1, 1)])',
|
||||
\ ''))
|
||||
endfunc
|
||||
|
||||
func Test_sub_replace_6()
|
||||
set magic&
|
||||
set cpo+=/
|
||||
call assert_equal('a', substitute('A', 'A', 'a', ''))
|
||||
call assert_equal('%', substitute('B', 'B', '%', ''))
|
||||
set cpo-=/
|
||||
call assert_equal('c', substitute('C', 'C', 'c', ''))
|
||||
call assert_equal('%', substitute('D', 'D', '%', ''))
|
||||
endfunc
|
||||
|
||||
func Test_sub_replace_7()
|
||||
set magic&
|
||||
set cpo&
|
||||
call assert_equal('AA', substitute('AA', 'A.', '\=submatch(0)', ''))
|
||||
call assert_equal("B\nB", substitute("B\nB", 'B.', '\=submatch(0)', ''))
|
||||
call assert_equal("['B\n']B", substitute("B\nB", 'B.', '\=string(submatch(0, 1))', ''))
|
||||
call assert_equal('-abab', substitute('-bb', '\zeb', 'a', 'g'))
|
||||
call assert_equal('c-cbcbc', substitute('-bb', '\ze', 'c', 'g'))
|
||||
endfunc
|
||||
|
||||
" Test for *:s%* on :substitute.
|
||||
func Test_sub_replace_8()
|
||||
new
|
||||
set magic&
|
||||
set cpo&
|
||||
$put =',,X'
|
||||
s/\(^\|,\)\ze\(,\|X\)/\1N/g
|
||||
call assert_equal('N,,NX', getline("$"))
|
||||
$put =',,Y'
|
||||
let cmd = ':s/\(^\|,\)\ze\(,\|Y\)/\1N/gc'
|
||||
call feedkeys(cmd . "\<CR>a", "xt")
|
||||
call assert_equal('N,,NY', getline("$"))
|
||||
:$put =',,Z'
|
||||
let cmd = ':s/\(^\|,\)\ze\(,\|Z\)/\1N/gc'
|
||||
call feedkeys(cmd . "\<CR>yy", "xt")
|
||||
call assert_equal('N,,NZ', getline("$"))
|
||||
enew! | close
|
||||
endfunc
|
||||
|
||||
func Test_sub_replace_9()
|
||||
new
|
||||
set magic&
|
||||
set cpo&
|
||||
$put ='xxx'
|
||||
call feedkeys(":s/x/X/gc\<CR>yyq", "xt")
|
||||
call assert_equal('XXx', getline("$"))
|
||||
enew! | close
|
||||
endfunc
|
||||
|
||||
func Test_sub_replace_10()
|
||||
set magic&
|
||||
set cpo&
|
||||
call assert_equal('a1a2a3a', substitute('123', '\zs', 'a', 'g'))
|
||||
call assert_equal('aaa', substitute('123', '\zs.', 'a', 'g'))
|
||||
call assert_equal('1a2a3a', substitute('123', '.\zs', 'a', 'g'))
|
||||
call assert_equal('a1a2a3a', substitute('123', '\ze', 'a', 'g'))
|
||||
call assert_equal('a1a2a3', substitute('123', '\ze.', 'a', 'g'))
|
||||
call assert_equal('aaa', substitute('123', '.\ze', 'a', 'g'))
|
||||
call assert_equal('aa2a3a', substitute('123', '1\|\ze', 'a', 'g'))
|
||||
call assert_equal('1aaa', substitute('123', '1\zs\|[23]', 'a', 'g'))
|
||||
endfunc
|
||||
|
@ -489,25 +489,48 @@ func Test_terminal_noblock()
|
||||
endfunc
|
||||
|
||||
func Test_terminal_write_stdin()
|
||||
" Todo: make this work on all systems.
|
||||
if !has('unix')
|
||||
return
|
||||
if !executable('wc')
|
||||
throw 'skipped: wc command not available'
|
||||
endif
|
||||
new
|
||||
call setline(1, ['one', 'two', 'three'])
|
||||
%term wc
|
||||
call WaitFor('getline(1) != ""')
|
||||
let nrs = split(getline(1))
|
||||
call WaitFor('getline("$") =~ "3"')
|
||||
let nrs = split(getline('$'))
|
||||
call assert_equal(['3', '3', '14'], nrs)
|
||||
bwipe
|
||||
|
||||
new
|
||||
call setline(1, ['one', 'two', 'three', 'four'])
|
||||
2,3term wc
|
||||
call WaitFor('getline(1) != ""')
|
||||
let nrs = split(getline(1))
|
||||
call WaitFor('getline("$") =~ "2"')
|
||||
let nrs = split(getline('$'))
|
||||
call assert_equal(['2', '2', '10'], nrs)
|
||||
bwipe
|
||||
|
||||
if executable('python')
|
||||
new
|
||||
call setline(1, ['print("hello")'])
|
||||
1term ++eof=exit() python
|
||||
" MS-Windows echoes the input, Unix doesn't.
|
||||
call WaitFor('getline("$") =~ "exit" || getline(1) =~ "hello"')
|
||||
if getline(1) =~ 'hello'
|
||||
call assert_equal('hello', getline(1))
|
||||
else
|
||||
call assert_equal('hello', getline(line('$') - 1))
|
||||
endif
|
||||
bwipe
|
||||
|
||||
if has('win32')
|
||||
new
|
||||
call setline(1, ['print("hello")'])
|
||||
1term ++eof=<C-Z> python
|
||||
call WaitFor('getline("$") =~ "Z"')
|
||||
call assert_equal('hello', getline(line('$') - 1))
|
||||
bwipe
|
||||
endif
|
||||
endif
|
||||
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
|
@ -2984,7 +2984,7 @@ u_sync(
|
||||
if (curbuf->b_u_synced || (!force && no_u_sync > 0))
|
||||
return;
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
if (im_is_preediting())
|
||||
if (p_imst == IM_ON_THE_SPOT && im_is_preediting())
|
||||
return; /* XIM is busy, don't break an undo sequence */
|
||||
#endif
|
||||
if (get_undolevel() < 0)
|
||||
|
@ -769,6 +769,36 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1036,
|
||||
/**/
|
||||
1035,
|
||||
/**/
|
||||
1034,
|
||||
/**/
|
||||
1033,
|
||||
/**/
|
||||
1032,
|
||||
/**/
|
||||
1031,
|
||||
/**/
|
||||
1030,
|
||||
/**/
|
||||
1029,
|
||||
/**/
|
||||
1028,
|
||||
/**/
|
||||
1027,
|
||||
/**/
|
||||
1026,
|
||||
/**/
|
||||
1025,
|
||||
/**/
|
||||
1024,
|
||||
/**/
|
||||
1023,
|
||||
/**/
|
||||
1022,
|
||||
/**/
|
||||
1021,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user