mirror of
https://github.com/zoriya/vim.git
synced 2025-12-09 08:46:17 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74240d3feb | ||
|
|
35c5e8155d | ||
|
|
f405c8fe85 | ||
|
|
620ca2da37 | ||
|
|
05684310a5 | ||
|
|
e4b78e2a42 | ||
|
|
3388d33457 | ||
|
|
6e65d594aa | ||
|
|
23c1b2b018 | ||
|
|
415a6939a4 | ||
|
|
5fe6bdf858 | ||
|
|
3767c6e9ee | ||
|
|
ac112f01a6 | ||
|
|
feeb4d0901 | ||
|
|
1eca6f13d6 | ||
|
|
92467d3351 | ||
|
|
ce6179c799 | ||
|
|
461fe50fea | ||
|
|
1ad022a9b8 |
@@ -1,4 +1,4 @@
|
||||
*eval.txt* For Vim version 8.0. Last change: 2017 Nov 24
|
||||
*eval.txt* For Vim version 8.0. Last change: 2017 Dec 09
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -2031,7 +2031,7 @@ assert_true({actual} [, {msg}]) none assert {actual} is true
|
||||
asin({expr}) Float arc sine of {expr}
|
||||
atan({expr}) Float arc tangent of {expr}
|
||||
atan2({expr1}, {expr2}) Float arc tangent of {expr1} / {expr2}
|
||||
balloon_show({msg}) none show {msg} inside the balloon
|
||||
balloon_show({expr}) none show {expr} inside the balloon
|
||||
balloon_split({msg}) List split {msg} as used for a balloon
|
||||
browse({save}, {title}, {initdir}, {default})
|
||||
String put up a file requester
|
||||
@@ -3056,12 +3056,16 @@ ch_open({address} [, {options}]) *ch_open()*
|
||||
ch_read({handle} [, {options}]) *ch_read()*
|
||||
Read from {handle} and return the received message.
|
||||
{handle} can be a Channel or a Job that has a Channel.
|
||||
For a NL channel this waits for a NL to arrive, except when
|
||||
there is nothing more to read (channel was closed).
|
||||
See |channel-more|.
|
||||
{only available when compiled with the |+channel| feature}
|
||||
|
||||
ch_readraw({handle} [, {options}]) *ch_readraw()*
|
||||
Like ch_read() but for a JS and JSON channel does not decode
|
||||
the message. See |channel-more|.
|
||||
the message. For a NL channel it does not block waiting for
|
||||
the NL to arrive, but otherwise works like ch_read().
|
||||
See |channel-more|.
|
||||
{only available when compiled with the |+channel| feature}
|
||||
|
||||
ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()*
|
||||
@@ -4679,9 +4683,10 @@ getqflist([{what}]) *getqflist()*
|
||||
the last quickfix list
|
||||
size number of entries in the quickfix list
|
||||
title get the list title
|
||||
winid get the |window-ID| (if opened)
|
||||
winid get the quickfix |window-ID|
|
||||
all all of the above quickfix properties
|
||||
Non-string items in {what} are ignored.
|
||||
Non-string items in {what} are ignored. To get the value of a
|
||||
particular item, set it to one.
|
||||
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.
|
||||
@@ -4702,7 +4707,7 @@ getqflist([{what}]) *getqflist()*
|
||||
nr quickfix list number
|
||||
size number of entries in the quickfix list
|
||||
title quickfix list title text
|
||||
winid quickfix |window-ID| (if opened)
|
||||
winid quickfix |window-ID|. If not present, set to 0
|
||||
|
||||
Examples: >
|
||||
:echo getqflist({'all': 1})
|
||||
@@ -8793,8 +8798,8 @@ writefile({list}, {fname} [, {flags}])
|
||||
the file. This flushes the file to disk, if possible. This
|
||||
takes more time but avoids losing the file if the system
|
||||
crashes.
|
||||
When {flags} does not contain "S" or "s" then fsync is called
|
||||
if the 'fsync' option is set.
|
||||
When {flags} does not contain "S" or "s" then fsync() is
|
||||
called if the 'fsync' option is set.
|
||||
When {flags} contains "S" then fsync() is not called, even
|
||||
when 'fsync' is set.
|
||||
|
||||
|
||||
@@ -6122,9 +6122,10 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
geom pixelGeometry int 0 - 2 (see below)
|
||||
renmode renderingMode int 0 - 6 (see below)
|
||||
taamode textAntialiasMode int 0 - 3 (see below)
|
||||
scrlines Scroll Lines int >= 0 (see below)
|
||||
|
||||
See this URL for detail:
|
||||
http://msdn.microsoft.com/en-us/library/dd368190.aspx
|
||||
See this URL for detail (except for scrlines):
|
||||
https://msdn.microsoft.com/en-us/library/dd368190.aspx
|
||||
|
||||
For geom: structure of a device pixel.
|
||||
0 - DWRITE_PIXEL_GEOMETRY_FLAT
|
||||
@@ -6132,7 +6133,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
2 - DWRITE_PIXEL_GEOMETRY_BGR
|
||||
|
||||
See this URL for detail:
|
||||
http://msdn.microsoft.com/en-us/library/dd368114.aspx
|
||||
https://msdn.microsoft.com/en-us/library/dd368114.aspx
|
||||
|
||||
For renmode: method of rendering glyphs.
|
||||
0 - DWRITE_RENDERING_MODE_DEFAULT
|
||||
@@ -6144,7 +6145,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
6 - DWRITE_RENDERING_MODE_OUTLINE
|
||||
|
||||
See this URL for detail:
|
||||
http://msdn.microsoft.com/en-us/library/dd368118.aspx
|
||||
https://msdn.microsoft.com/en-us/library/dd368118.aspx
|
||||
|
||||
For taamode: antialiasing mode used for drawing text.
|
||||
0 - D2D1_TEXT_ANTIALIAS_MODE_DEFAULT
|
||||
@@ -6153,7 +6154,25 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
3 - D2D1_TEXT_ANTIALIAS_MODE_ALIASED
|
||||
|
||||
See this URL for detail:
|
||||
http://msdn.microsoft.com/en-us/library/dd368170.aspx
|
||||
https://msdn.microsoft.com/en-us/library/dd368170.aspx
|
||||
|
||||
For scrlines: threshold for lines to be scrolled.
|
||||
0 - Always use scrolling. (default)
|
||||
1 - Use full page redrawing.
|
||||
> 1 - If the lines to be scrolled is grater or equal to the
|
||||
specified value, use redrawing. Otherwise use
|
||||
scrolling.
|
||||
|
||||
If you feel scrolling a page (CTRL-F) is too slow with DirectX
|
||||
renderer, try this "scrlines" option.
|
||||
When set it "1", Vim uses full page redrawing instead of
|
||||
scrolling. Redrawing a page is faster than scrolling a
|
||||
page in some environments.
|
||||
After that, when you feel scrolling lines (CTRL-Y) becomes
|
||||
slow, please try "2" or greater value for this option.
|
||||
It works threshold line number to switch scrolling to
|
||||
redrawing. Scrolling a few lines might be faster than
|
||||
redrawing a page in some environments.
|
||||
|
||||
Example: >
|
||||
set encoding=utf-8
|
||||
@@ -6162,13 +6181,12 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
<
|
||||
If select a raster font (Courier, Terminal or FixedSys which
|
||||
have ".fon" extension in file name) to 'guifont', it will be
|
||||
drawn by GDI as a fallback. This fallback will cause
|
||||
significant slow down on drawing.
|
||||
drawn by GDI as a fallback.
|
||||
|
||||
NOTE: It is known that some fonts and options combination
|
||||
causes trouble on drawing glyphs.
|
||||
|
||||
- 'rendmode:5' and 'renmode:6' will not work with some
|
||||
- 'renmode:5' and 'renmode:6' will not work with some
|
||||
special made fonts (True-Type fonts which includes only
|
||||
bitmap glyphs).
|
||||
- 'taamode:3' will not work with some vector fonts.
|
||||
|
||||
@@ -341,6 +341,50 @@ use this code: >
|
||||
au QuickfixCmdPost make call QfMakeConv()
|
||||
Another option is using 'makeencoding'.
|
||||
|
||||
*quickfix-title*
|
||||
Every quickfix and location list has a title. By default the title is set to
|
||||
the command that created the list. The |getqflist()| and |getloclist()|
|
||||
functions can be used to get the title of a quickfix and a location list
|
||||
respectively. The |setqflist()| and |setloclist()| functions can be used to
|
||||
modify the title of a quickfix and location list respectively. Examples: >
|
||||
call setqflist([], 'a', {'title' : 'Cmd output'})
|
||||
echo getqflist({'title' : 1})
|
||||
call setloclist(3, [], 'a', {'title' : 'Cmd output'})
|
||||
echo getloclist(3, {'title' : 1})
|
||||
<
|
||||
*quickfix-size*
|
||||
You can get the number of entries (size) in a quickfix and a location list
|
||||
using the |getqflist()| and |getloclist()| functions respectively. Examples: >
|
||||
echo getqflist({'size' : 1})
|
||||
echo getloclist(5, {'size' : 1})
|
||||
<
|
||||
*quickfix-context*
|
||||
Any Vim type can be associated as a context with a quickfix or location list.
|
||||
The |setqflist()| and the |setloclist()| functions can be used to associate a
|
||||
context with a quickfix and a location list respectively. The |getqflist()|
|
||||
and the |getloclist()| functions can be used to retrieve the context of a
|
||||
quickifx and a location list respectively. This is useful for a Vim plugin
|
||||
dealing with multiple quickfix/location lists.
|
||||
Examples: >
|
||||
|
||||
let somectx = {'name' : 'Vim', 'type' : 'Editor'}
|
||||
call setqflist([], 'a', {'context' : somectx})
|
||||
echo getqflist({'context' : 1})
|
||||
|
||||
let newctx = ['red', 'green', 'blue']
|
||||
call setloclist(2, [], 'a', {'id' : qfid, 'context' : newctx})
|
||||
echo getloclist(2, {'id' : qfid, 'context' : 1})
|
||||
<
|
||||
*quickfix-parse*
|
||||
You can parse a list of lines using 'erroformat' without creating or modifying
|
||||
a quickfix list using the |getqflist()| function. Examples: >
|
||||
echo getqflist({'lines' : ["F1:10:Line10", "F2:20:Line20"]})
|
||||
echo getqflist({'lines' : systemlist('grep -Hn quickfix *')})
|
||||
This returns a dictionary where the 'items' key contains the list of quickfix
|
||||
entries parsed from lines. The following shows how to use a custom
|
||||
'errorformat' to parse the lines without modifying the 'erroformat' option: >
|
||||
echo getqflist({'efm' : '%f#%l#%m', 'lines' : ['F1#10#Line']})
|
||||
<
|
||||
|
||||
EXECUTE A COMMAND IN ALL THE BUFFERS IN QUICKFIX OR LOCATION LIST:
|
||||
*:cdo*
|
||||
@@ -542,6 +586,13 @@ In all of the above cases, if the location list for the selected window is not
|
||||
yet set, then it is set to the location list displayed in the location list
|
||||
window.
|
||||
|
||||
*quickfix-window-ID*
|
||||
You can use the |getqflist()| and |getloclist()| functions to obtain the
|
||||
window ID of the quickfix window and location list window respectively (if
|
||||
present). Examples: >
|
||||
echo getqflist({'winid' : 1}).winid
|
||||
echo getloclist(2, {'winid' : 1}).winid
|
||||
<
|
||||
=============================================================================
|
||||
3. Using more than one list of errors *quickfix-error-lists*
|
||||
|
||||
@@ -586,6 +637,14 @@ list, one newer list is overwritten. This is especially useful if you are
|
||||
browsing with ":grep" |grep|. If you want to keep the more recent error
|
||||
lists, use ":cnewer 99" first.
|
||||
|
||||
To get the number of lists in the quickfix and location list stack, you can
|
||||
use the |getqflist()| and |getloclist()| functions respectively with the list
|
||||
number set to the special value '$'. Examples: >
|
||||
echo getqflist({'nr' : '$'}).nr
|
||||
echo getloclist(3, {'nr' : '$'}).nr
|
||||
To get the number of the current list in the stack: >
|
||||
echo getqflist({'nr' : 0}).nr
|
||||
<
|
||||
=============================================================================
|
||||
4. Using :make *:make_makeprg*
|
||||
|
||||
|
||||
@@ -2120,6 +2120,7 @@ test_arglist \
|
||||
test_assign \
|
||||
test_autochdir \
|
||||
test_autocmd \
|
||||
test_autoload \
|
||||
test_backspace_opt \
|
||||
test_breakindent \
|
||||
test_bufline \
|
||||
|
||||
7
src/auto/configure
vendored
7
src/auto/configure
vendored
@@ -4781,8 +4781,13 @@ fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_selinux_is_selinux_enabled" >&5
|
||||
$as_echo "$ac_cv_lib_selinux_is_selinux_enabled" >&6; }
|
||||
if test "x$ac_cv_lib_selinux_is_selinux_enabled" = xyes; then :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "selinux/selinux.h" "ac_cv_header_selinux_selinux_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_selinux_selinux_h" = xyes; then :
|
||||
LIBS="$LIBS -lselinux"
|
||||
$as_echo "#define HAVE_SELINUX 1" >>confdefs.h
|
||||
$as_echo "#define HAVE_SELINUX 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ get_beval_info(
|
||||
}
|
||||
#endif
|
||||
wp = mouse_find_win(&row, &col);
|
||||
if (wp != NULL && row < wp->w_height && col < wp->w_width)
|
||||
if (wp != NULL && row >= 0 && row < wp->w_height && col < wp->w_width)
|
||||
{
|
||||
/* Found a window and the cursor is in the text. Now find the line
|
||||
* number. */
|
||||
|
||||
@@ -3313,11 +3313,12 @@ channel_read(channel_T *channel, ch_part_T part, char *func)
|
||||
/*
|
||||
* Read from RAW or NL "channel"/"part". Blocks until there is something to
|
||||
* read or the timeout expires.
|
||||
* When "raw" is TRUE don't block waiting on a NL.
|
||||
* Returns what was read in allocated memory.
|
||||
* Returns NULL in case of error or timeout.
|
||||
*/
|
||||
char_u *
|
||||
channel_read_block(channel_T *channel, ch_part_T part, int timeout)
|
||||
static char_u *
|
||||
channel_read_block(channel_T *channel, ch_part_T part, int timeout, int raw)
|
||||
{
|
||||
char_u *buf;
|
||||
char_u *msg;
|
||||
@@ -3327,7 +3328,7 @@ channel_read_block(channel_T *channel, ch_part_T part, int timeout)
|
||||
readq_T *node;
|
||||
|
||||
ch_log(channel, "Blocking %s read, timeout: %d msec",
|
||||
mode == MODE_RAW ? "RAW" : "NL", timeout);
|
||||
mode == MODE_RAW ? "RAW" : "NL", timeout);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
@@ -3340,6 +3341,10 @@ channel_read_block(channel_T *channel, ch_part_T part, int timeout)
|
||||
break;
|
||||
if (channel_collapse(channel, part, mode == MODE_NL) == OK)
|
||||
continue;
|
||||
/* If not blocking or nothing more is coming then return what we
|
||||
* have. */
|
||||
if (raw || fd == INVALID_FD)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Wait for up to the channel timeout. */
|
||||
@@ -3366,11 +3371,16 @@ channel_read_block(channel_T *channel, ch_part_T part, int timeout)
|
||||
nl = channel_first_nl(node);
|
||||
|
||||
/* Convert NUL to NL, the internal representation. */
|
||||
for (p = buf; p < nl && p < buf + node->rq_buflen; ++p)
|
||||
for (p = buf; (nl == NULL || p < nl) && p < buf + node->rq_buflen; ++p)
|
||||
if (*p == NUL)
|
||||
*p = NL;
|
||||
|
||||
if (nl + 1 == buf + node->rq_buflen)
|
||||
if (nl == NULL)
|
||||
{
|
||||
/* must be a closed channel with missing NL */
|
||||
msg = channel_get(channel, part);
|
||||
}
|
||||
else if (nl + 1 == buf + node->rq_buflen)
|
||||
{
|
||||
/* get the whole buffer */
|
||||
msg = channel_get(channel, part);
|
||||
@@ -3513,7 +3523,8 @@ common_channel_read(typval_T *argvars, typval_T *rettv, int raw)
|
||||
timeout = opt.jo_timeout;
|
||||
|
||||
if (raw || mode == MODE_RAW || mode == MODE_NL)
|
||||
rettv->vval.v_string = channel_read_block(channel, part, timeout);
|
||||
rettv->vval.v_string = channel_read_block(channel, part,
|
||||
timeout, raw);
|
||||
else
|
||||
{
|
||||
if (opt.jo_set & JO_ID)
|
||||
@@ -3955,7 +3966,8 @@ ch_raw_common(typval_T *argvars, typval_T *rettv, int eval)
|
||||
timeout = opt.jo_timeout;
|
||||
else
|
||||
timeout = channel_get_timeout(channel, part_read);
|
||||
rettv->vval.v_string = channel_read_block(channel, part_read, timeout);
|
||||
rettv->vval.v_string = channel_read_block(channel, part_read,
|
||||
timeout, TRUE);
|
||||
}
|
||||
free_job_options(&opt);
|
||||
}
|
||||
|
||||
@@ -433,8 +433,9 @@ if test "x$found_smack" = "x"; then
|
||||
if test "$enable_selinux" = "yes"; then
|
||||
AC_MSG_RESULT(no)
|
||||
AC_CHECK_LIB(selinux, is_selinux_enabled,
|
||||
[AC_CHECK_HEADER(selinux/selinux.h,
|
||||
[LIBS="$LIBS -lselinux"
|
||||
AC_DEFINE(HAVE_SELINUX)])
|
||||
AC_DEFINE(HAVE_SELINUX)])])
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
fi
|
||||
|
||||
@@ -1956,7 +1956,10 @@ get_lval(
|
||||
|
||||
cc = *p;
|
||||
*p = NUL;
|
||||
v = find_var(lp->ll_name, &ht, flags & GLV_NO_AUTOLOAD);
|
||||
/* Only pass &ht when we would write to the variable, it prevents autoload
|
||||
* as well. */
|
||||
v = find_var(lp->ll_name, (flags & GLV_READ_ONLY) ? NULL : &ht,
|
||||
flags & GLV_NO_AUTOLOAD);
|
||||
if (v == NULL && !quiet)
|
||||
EMSG2(_(e_undefvar), lp->ll_name);
|
||||
*p = cc;
|
||||
@@ -6610,6 +6613,8 @@ get_vim_var_nr(int idx)
|
||||
|
||||
/*
|
||||
* Get string v: variable value. Uses a static buffer, can only be used once.
|
||||
* If the String variable has never been set, return an empty string.
|
||||
* Never returns NULL;
|
||||
*/
|
||||
char_u *
|
||||
get_vim_var_str(int idx)
|
||||
|
||||
@@ -1482,7 +1482,7 @@ do_shell(
|
||||
#endif
|
||||
&& msg_silent == 0)
|
||||
FOR_ALL_BUFFERS(buf)
|
||||
if (bufIsChanged(buf))
|
||||
if (bufIsChangedNotTerm(buf))
|
||||
{
|
||||
#ifdef FEAT_GUI_MSWIN
|
||||
if (!winstart)
|
||||
@@ -6934,13 +6934,10 @@ fix_help_buffer(void)
|
||||
&& fcount > 0)
|
||||
{
|
||||
#ifdef FEAT_MULTI_LANG
|
||||
int i1;
|
||||
int i2;
|
||||
char_u *f1;
|
||||
char_u *f2;
|
||||
char_u *t1;
|
||||
char_u *e1;
|
||||
char_u *e2;
|
||||
int i1, i2;
|
||||
char_u *f1, *f2;
|
||||
char_u *t1, *t2;
|
||||
char_u *e1, *e2;
|
||||
|
||||
/* If foo.abx is found use it instead of foo.txt in
|
||||
* the same directory. */
|
||||
@@ -6955,10 +6952,9 @@ fix_help_buffer(void)
|
||||
f1 = fnames[i1];
|
||||
f2 = fnames[i2];
|
||||
t1 = gettail(f1);
|
||||
if (fnamencmp(f1, f2, t1 - f1) != 0)
|
||||
continue;
|
||||
t2 = gettail(f2);
|
||||
e1 = vim_strrchr(t1, '.');
|
||||
e2 = vim_strrchr(gettail(f2), '.');
|
||||
e2 = vim_strrchr(t2, '.');
|
||||
if (e1 == NULL || e2 == NULL)
|
||||
continue;
|
||||
if (fnamecmp(e1, ".txt") != 0
|
||||
@@ -6969,7 +6965,8 @@ fix_help_buffer(void)
|
||||
fnames[i1] = NULL;
|
||||
continue;
|
||||
}
|
||||
if (fnamencmp(f1, f2, e1 - f1) != 0)
|
||||
if (e1 - f1 != e2 - f2
|
||||
|| fnamencmp(f1, f2, e1 - f1) != 0)
|
||||
continue;
|
||||
if (fnamecmp(e1, ".txt") == 0
|
||||
&& fnamecmp(e2, fname + 4) == 0)
|
||||
|
||||
@@ -1834,6 +1834,26 @@ script_dump_profile(FILE *fd)
|
||||
{
|
||||
if (vim_fgets(IObuff, IOSIZE, sfd))
|
||||
break;
|
||||
/* When a line has been truncated, append NL, taking care
|
||||
* of multi-byte characters . */
|
||||
if (IObuff[IOSIZE - 2] != NUL && IObuff[IOSIZE - 2] != NL)
|
||||
{
|
||||
int n = IOSIZE - 2;
|
||||
# ifdef FEAT_MBYTE
|
||||
if (enc_utf8)
|
||||
{
|
||||
/* Move to the first byte of this char.
|
||||
* utf_head_off() doesn't work, because it checks
|
||||
* for a truncated character. */
|
||||
while (n > 0 && (IObuff[n] & 0xc0) == 0x80)
|
||||
--n;
|
||||
}
|
||||
else if (has_mbyte)
|
||||
n -= mb_head_off(IObuff, IObuff + n);
|
||||
# endif
|
||||
IObuff[n] = NL;
|
||||
IObuff[n + 1] = NUL;
|
||||
}
|
||||
if (i < si->sn_prl_ga.ga_len
|
||||
&& (pp = &PRL_ITEM(si, i))->snp_count > 0)
|
||||
{
|
||||
|
||||
@@ -263,14 +263,24 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
enum DrawingMode {
|
||||
DM_GDI = 0,
|
||||
DM_DIRECTX = 1,
|
||||
DM_INTEROP = 2,
|
||||
};
|
||||
|
||||
struct DWriteContext {
|
||||
HDC mHDC;
|
||||
RECT mBindRect;
|
||||
DrawingMode mDMode;
|
||||
HDC mInteropHDC;
|
||||
bool mDrawing;
|
||||
bool mFallbackDC;
|
||||
|
||||
ID2D1Factory *mD2D1Factory;
|
||||
|
||||
ID2D1DCRenderTarget *mRT;
|
||||
ID2D1GdiInteropRenderTarget *mGDIRT;
|
||||
ID2D1SolidColorBrush *mBrush;
|
||||
|
||||
IDWriteFactory *mDWriteFactory;
|
||||
@@ -292,6 +302,10 @@ struct DWriteContext {
|
||||
|
||||
virtual ~DWriteContext();
|
||||
|
||||
HRESULT CreateDeviceResources();
|
||||
|
||||
void DiscardDeviceResources();
|
||||
|
||||
HRESULT CreateTextFormatFromLOGFONT(const LOGFONTW &logFont,
|
||||
IDWriteTextFormat **ppTextFormat);
|
||||
|
||||
@@ -299,17 +313,21 @@ struct DWriteContext {
|
||||
|
||||
void SetFont(HFONT hFont);
|
||||
|
||||
void BindDC(HDC hdc, RECT *rect);
|
||||
void BindDC(HDC hdc, const RECT *rect);
|
||||
|
||||
void AssureDrawing();
|
||||
HRESULT SetDrawingMode(DrawingMode mode);
|
||||
|
||||
ID2D1Brush* SolidBrush(COLORREF color);
|
||||
|
||||
void DrawText(const WCHAR* text, int len,
|
||||
void DrawText(const WCHAR *text, int len,
|
||||
int x, int y, int w, int h, int cellWidth, COLORREF color,
|
||||
UINT fuOptions, CONST RECT *lprc, CONST INT * lpDx);
|
||||
UINT fuOptions, const RECT *lprc, const INT *lpDx);
|
||||
|
||||
void FillRect(RECT *rc, COLORREF color);
|
||||
void FillRect(const RECT *rc, COLORREF color);
|
||||
|
||||
void DrawLine(int x1, int y1, int x2, int y2, COLORREF color);
|
||||
|
||||
void SetPixel(int x, int y, COLORREF color);
|
||||
|
||||
void Flush();
|
||||
|
||||
@@ -561,10 +579,14 @@ private:
|
||||
|
||||
DWriteContext::DWriteContext() :
|
||||
mHDC(NULL),
|
||||
mBindRect(),
|
||||
mDMode(DM_GDI),
|
||||
mInteropHDC(NULL),
|
||||
mDrawing(false),
|
||||
mFallbackDC(false),
|
||||
mD2D1Factory(NULL),
|
||||
mRT(NULL),
|
||||
mGDIRT(NULL),
|
||||
mBrush(NULL),
|
||||
mDWriteFactory(NULL),
|
||||
mDWriteFactory2(NULL),
|
||||
@@ -584,25 +606,7 @@ DWriteContext::DWriteContext() :
|
||||
_RPT2(_CRT_WARN, "D2D1CreateFactory: hr=%p p=%p\n", hr, mD2D1Factory);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
D2D1_RENDER_TARGET_PROPERTIES props = {
|
||||
D2D1_RENDER_TARGET_TYPE_DEFAULT,
|
||||
{ DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE },
|
||||
0, 0,
|
||||
D2D1_RENDER_TARGET_USAGE_NONE,
|
||||
D2D1_FEATURE_LEVEL_DEFAULT
|
||||
};
|
||||
hr = mD2D1Factory->CreateDCRenderTarget(&props, &mRT);
|
||||
_RPT2(_CRT_WARN, "CreateDCRenderTarget: hr=%p p=%p\n", hr, mRT);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = mRT->CreateSolidColorBrush(
|
||||
D2D1::ColorF(D2D1::ColorF::Black),
|
||||
&mBrush);
|
||||
_RPT2(_CRT_WARN, "CreateSolidColorBrush: hr=%p p=%p\n", hr, mBrush);
|
||||
}
|
||||
hr = CreateDeviceResources();
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
@@ -645,10 +649,66 @@ DWriteContext::~DWriteContext()
|
||||
SafeRelease(&mDWriteFactory);
|
||||
SafeRelease(&mDWriteFactory2);
|
||||
SafeRelease(&mBrush);
|
||||
SafeRelease(&mGDIRT);
|
||||
SafeRelease(&mRT);
|
||||
SafeRelease(&mD2D1Factory);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
DWriteContext::CreateDeviceResources()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (mRT != NULL)
|
||||
return S_OK;
|
||||
|
||||
D2D1_RENDER_TARGET_PROPERTIES props = {
|
||||
D2D1_RENDER_TARGET_TYPE_DEFAULT,
|
||||
{ DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE },
|
||||
0, 0,
|
||||
D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE,
|
||||
D2D1_FEATURE_LEVEL_DEFAULT
|
||||
};
|
||||
hr = mD2D1Factory->CreateDCRenderTarget(&props, &mRT);
|
||||
_RPT2(_CRT_WARN, "CreateDCRenderTarget: hr=%p p=%p\n", hr, mRT);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// This always succeeds.
|
||||
mRT->QueryInterface(
|
||||
__uuidof(ID2D1GdiInteropRenderTarget),
|
||||
reinterpret_cast<void**>(&mGDIRT));
|
||||
_RPT1(_CRT_WARN, "GdiInteropRenderTarget: p=%p\n", mGDIRT);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = mRT->CreateSolidColorBrush(
|
||||
D2D1::ColorF(D2D1::ColorF::Black),
|
||||
&mBrush);
|
||||
_RPT2(_CRT_WARN, "CreateSolidColorBrush: hr=%p p=%p\n", hr, mBrush);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (mHDC != NULL)
|
||||
{
|
||||
mRT->BindDC(mHDC, &mBindRect);
|
||||
mRT->SetTransform(D2D1::IdentityMatrix());
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext::DiscardDeviceResources()
|
||||
{
|
||||
SafeRelease(&mBrush);
|
||||
SafeRelease(&mGDIRT);
|
||||
SafeRelease(&mRT);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
DWriteContext::CreateTextFormatFromLOGFONT(const LOGFONTW &logFont,
|
||||
IDWriteTextFormat **ppTextFormat)
|
||||
@@ -817,27 +877,77 @@ DWriteContext::SetFont(HFONT hFont)
|
||||
item.pTextFormat = mTextFormat;
|
||||
item.fontWeight = mFontWeight;
|
||||
item.fontStyle = mFontStyle;
|
||||
mFallbackDC = false;
|
||||
}
|
||||
else
|
||||
mFallbackDC = true;
|
||||
mFontCache.put(item);
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext::BindDC(HDC hdc, RECT *rect)
|
||||
DWriteContext::BindDC(HDC hdc, const RECT *rect)
|
||||
{
|
||||
Flush();
|
||||
mRT->BindDC(hdc, rect);
|
||||
mRT->SetTransform(D2D1::IdentityMatrix());
|
||||
mHDC = hdc;
|
||||
mBindRect = *rect;
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext::AssureDrawing()
|
||||
HRESULT
|
||||
DWriteContext::SetDrawingMode(DrawingMode mode)
|
||||
{
|
||||
if (mDrawing == false)
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
mRT->BeginDraw();
|
||||
mDrawing = true;
|
||||
default:
|
||||
case DM_GDI:
|
||||
if (mInteropHDC != NULL)
|
||||
{
|
||||
mGDIRT->ReleaseDC(NULL);
|
||||
mInteropHDC = NULL;
|
||||
}
|
||||
if (mDrawing)
|
||||
{
|
||||
hr = mRT->EndDraw();
|
||||
if (hr == D2DERR_RECREATE_TARGET)
|
||||
{
|
||||
hr = S_OK;
|
||||
DiscardDeviceResources();
|
||||
CreateDeviceResources();
|
||||
}
|
||||
mDrawing = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case DM_DIRECTX:
|
||||
if (mInteropHDC != NULL)
|
||||
{
|
||||
mGDIRT->ReleaseDC(NULL);
|
||||
mInteropHDC = NULL;
|
||||
}
|
||||
else if (mDrawing == false)
|
||||
{
|
||||
CreateDeviceResources();
|
||||
mRT->BeginDraw();
|
||||
mDrawing = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case DM_INTEROP:
|
||||
if (mDrawing == false)
|
||||
{
|
||||
CreateDeviceResources();
|
||||
mRT->BeginDraw();
|
||||
mDrawing = true;
|
||||
}
|
||||
if (mInteropHDC == NULL)
|
||||
hr = mGDIRT->GetDC(D2D1_DC_INITIALIZE_MODE_COPY, &mInteropHDC);
|
||||
break;
|
||||
}
|
||||
mDMode = mode;
|
||||
return hr;
|
||||
}
|
||||
|
||||
ID2D1Brush*
|
||||
@@ -849,22 +959,31 @@ DWriteContext::SolidBrush(COLORREF color)
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext::DrawText(const WCHAR* text, int len,
|
||||
DWriteContext::DrawText(const WCHAR *text, int len,
|
||||
int x, int y, int w, int h, int cellWidth, COLORREF color,
|
||||
UINT fuOptions, CONST RECT *lprc, CONST INT * lpDx)
|
||||
UINT fuOptions, const RECT *lprc, const INT *lpDx)
|
||||
{
|
||||
if (mFallbackDC)
|
||||
{
|
||||
Flush();
|
||||
ExtTextOutW(mHDC, x, y, fuOptions, lprc, text, len, lpDx);
|
||||
// Fall back to GDI rendering.
|
||||
HRESULT hr = SetDrawingMode(DM_INTEROP);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
HGDIOBJ hFont = ::GetCurrentObject(mHDC, OBJ_FONT);
|
||||
HGDIOBJ hOldFont = ::SelectObject(mInteropHDC, hFont);
|
||||
::SetTextColor(mInteropHDC, color);
|
||||
::SetBkMode(mInteropHDC, ::GetBkMode(mHDC));
|
||||
::ExtTextOutW(mInteropHDC, x, y, fuOptions, lprc, text, len, lpDx);
|
||||
::SelectObject(mInteropHDC, hOldFont);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
AssureDrawing();
|
||||
|
||||
HRESULT hr;
|
||||
IDWriteTextLayout *textLayout = NULL;
|
||||
|
||||
SetDrawingMode(DM_DIRECTX);
|
||||
|
||||
hr = mDWriteFactory->CreateTextLayout(text, len, mTextFormat,
|
||||
FLOAT(w), FLOAT(h), &textLayout);
|
||||
|
||||
@@ -883,23 +1002,74 @@ DWriteContext::DrawText(const WCHAR* text, int len,
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext::FillRect(RECT *rc, COLORREF color)
|
||||
DWriteContext::FillRect(const RECT *rc, COLORREF color)
|
||||
{
|
||||
AssureDrawing();
|
||||
mRT->FillRectangle(
|
||||
D2D1::RectF(FLOAT(rc->left), FLOAT(rc->top),
|
||||
FLOAT(rc->right), FLOAT(rc->bottom)),
|
||||
SolidBrush(color));
|
||||
if (mDMode == DM_INTEROP)
|
||||
{
|
||||
// GDI functions are used before this call. Keep using GDI.
|
||||
// (Switching to Direct2D causes terrible slowdown.)
|
||||
HBRUSH hbr = ::CreateSolidBrush(color);
|
||||
::FillRect(mInteropHDC, rc, hbr);
|
||||
::DeleteObject(HGDIOBJ(hbr));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDrawingMode(DM_DIRECTX);
|
||||
mRT->FillRectangle(
|
||||
D2D1::RectF(FLOAT(rc->left), FLOAT(rc->top),
|
||||
FLOAT(rc->right), FLOAT(rc->bottom)),
|
||||
SolidBrush(color));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext::DrawLine(int x1, int y1, int x2, int y2, COLORREF color)
|
||||
{
|
||||
if (mDMode == DM_INTEROP)
|
||||
{
|
||||
// GDI functions are used before this call. Keep using GDI.
|
||||
// (Switching to Direct2D causes terrible slowdown.)
|
||||
HPEN hpen = ::CreatePen(PS_SOLID, 1, color);
|
||||
HGDIOBJ old_pen = ::SelectObject(mInteropHDC, HGDIOBJ(hpen));
|
||||
::MoveToEx(mInteropHDC, x1, y1, NULL);
|
||||
::LineTo(mInteropHDC, x2, y2);
|
||||
::SelectObject(mInteropHDC, old_pen);
|
||||
::DeleteObject(HGDIOBJ(hpen));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDrawingMode(DM_DIRECTX);
|
||||
mRT->DrawLine(
|
||||
D2D1::Point2F(FLOAT(x1), FLOAT(y1) + 0.5f),
|
||||
D2D1::Point2F(FLOAT(x2), FLOAT(y2) + 0.5f),
|
||||
SolidBrush(color));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext::SetPixel(int x, int y, COLORREF color)
|
||||
{
|
||||
if (mDMode == DM_INTEROP)
|
||||
{
|
||||
// GDI functions are used before this call. Keep using GDI.
|
||||
// (Switching to Direct2D causes terrible slowdown.)
|
||||
::SetPixel(mInteropHDC, x, y, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDrawingMode(DM_DIRECTX);
|
||||
// Direct2D doesn't have SetPixel API. Use DrawLine instead.
|
||||
mRT->DrawLine(
|
||||
D2D1::Point2F(FLOAT(x), FLOAT(y) + 0.5f),
|
||||
D2D1::Point2F(FLOAT(x+1), FLOAT(y) + 0.5f),
|
||||
SolidBrush(color));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext::Flush()
|
||||
{
|
||||
if (mDrawing)
|
||||
{
|
||||
mRT->EndDraw();
|
||||
mDrawing = false;
|
||||
}
|
||||
SetDrawingMode(DM_GDI);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1000,7 +1170,7 @@ DWriteContext_Open(void)
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext_BindDC(DWriteContext *ctx, HDC hdc, RECT *rect)
|
||||
DWriteContext_BindDC(DWriteContext *ctx, HDC hdc, const RECT *rect)
|
||||
{
|
||||
if (ctx != NULL)
|
||||
ctx->BindDC(hdc, rect);
|
||||
@@ -1016,7 +1186,7 @@ DWriteContext_SetFont(DWriteContext *ctx, HFONT hFont)
|
||||
void
|
||||
DWriteContext_DrawText(
|
||||
DWriteContext *ctx,
|
||||
const WCHAR* text,
|
||||
const WCHAR *text,
|
||||
int len,
|
||||
int x,
|
||||
int y,
|
||||
@@ -1025,8 +1195,8 @@ DWriteContext_DrawText(
|
||||
int cellWidth,
|
||||
COLORREF color,
|
||||
UINT fuOptions,
|
||||
CONST RECT *lprc,
|
||||
CONST INT * lpDx)
|
||||
const RECT *lprc,
|
||||
const INT *lpDx)
|
||||
{
|
||||
if (ctx != NULL)
|
||||
ctx->DrawText(text, len, x, y, w, h, cellWidth, color,
|
||||
@@ -1034,12 +1204,27 @@ DWriteContext_DrawText(
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext_FillRect(DWriteContext *ctx, RECT *rc, COLORREF color)
|
||||
DWriteContext_FillRect(DWriteContext *ctx, const RECT *rc, COLORREF color)
|
||||
{
|
||||
if (ctx != NULL)
|
||||
ctx->FillRect(rc, color);
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext_DrawLine(DWriteContext *ctx, int x1, int y1, int x2, int y2,
|
||||
COLORREF color)
|
||||
{
|
||||
if (ctx != NULL)
|
||||
ctx->DrawLine(x1, y1, x2, y2, color);
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext_SetPixel(DWriteContext *ctx, int x, int y, COLORREF color)
|
||||
{
|
||||
if (ctx != NULL)
|
||||
ctx->SetPixel(x, y, color);
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext_Flush(DWriteContext *ctx)
|
||||
{
|
||||
|
||||
@@ -55,11 +55,11 @@ void DWrite_Init(void);
|
||||
void DWrite_Final(void);
|
||||
|
||||
DWriteContext *DWriteContext_Open(void);
|
||||
void DWriteContext_BindDC(DWriteContext *ctx, HDC hdc, RECT *rect);
|
||||
void DWriteContext_BindDC(DWriteContext *ctx, HDC hdc, const RECT *rect);
|
||||
void DWriteContext_SetFont(DWriteContext *ctx, HFONT hFont);
|
||||
void DWriteContext_DrawText(
|
||||
DWriteContext *ctx,
|
||||
const WCHAR* text,
|
||||
const WCHAR *text,
|
||||
int len,
|
||||
int x,
|
||||
int y,
|
||||
@@ -68,9 +68,12 @@ void DWriteContext_DrawText(
|
||||
int cellWidth,
|
||||
COLORREF color,
|
||||
UINT fuOptions,
|
||||
CONST RECT *lprc,
|
||||
CONST INT * lpDx);
|
||||
void DWriteContext_FillRect(DWriteContext *ctx, RECT *rc, COLORREF color);
|
||||
const RECT *lprc,
|
||||
const INT *lpDx);
|
||||
void DWriteContext_FillRect(DWriteContext *ctx, const RECT *rc, COLORREF color);
|
||||
void DWriteContext_DrawLine(DWriteContext *ctx, int x1, int y1, int x2, int y2,
|
||||
COLORREF color);
|
||||
void DWriteContext_SetPixel(DWriteContext *ctx, int x, int y, COLORREF color);
|
||||
void DWriteContext_Flush(DWriteContext *ctx);
|
||||
void DWriteContext_Close(DWriteContext *ctx);
|
||||
|
||||
|
||||
190
src/gui_w32.c
190
src/gui_w32.c
@@ -33,6 +33,7 @@
|
||||
static DWriteContext *s_dwc = NULL;
|
||||
static int s_directx_enabled = 0;
|
||||
static int s_directx_load_attempted = 0;
|
||||
static int s_directx_scrlines = 0;
|
||||
# define IS_ENABLE_DIRECTX() (s_directx_enabled && s_dwc != NULL)
|
||||
static int directx_enabled(void);
|
||||
static void directx_binddc(void);
|
||||
@@ -57,6 +58,7 @@ gui_mch_set_rendering_options(char_u *s)
|
||||
int dx_geom = 0;
|
||||
int dx_renmode = 0;
|
||||
int dx_taamode = 0;
|
||||
int dx_scrlines = 0;
|
||||
|
||||
/* parse string as rendering options. */
|
||||
for (p = s; p != NULL && *p != NUL; )
|
||||
@@ -117,10 +119,17 @@ gui_mch_set_rendering_options(char_u *s)
|
||||
if (dx_taamode < 0 || dx_taamode > 3)
|
||||
return FAIL;
|
||||
}
|
||||
else if (STRCMP(name, "scrlines") == 0)
|
||||
{
|
||||
dx_scrlines = atoi((char *)value);
|
||||
}
|
||||
else
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (!gui.in_use)
|
||||
return OK; /* only checking the syntax of the value */
|
||||
|
||||
/* Enable DirectX/DirectWrite */
|
||||
if (dx_enable)
|
||||
{
|
||||
@@ -147,6 +156,7 @@ gui_mch_set_rendering_options(char_u *s)
|
||||
}
|
||||
}
|
||||
s_directx_enabled = dx_enable;
|
||||
s_directx_scrlines = dx_scrlines;
|
||||
|
||||
return OK;
|
||||
#else
|
||||
@@ -283,6 +293,7 @@ typedef int UINT_PTR;
|
||||
#endif
|
||||
|
||||
static void _OnPaint( HWND hwnd);
|
||||
static void fill_rect(const RECT *rcp, HBRUSH hbr, COLORREF color);
|
||||
static void clear_rect(RECT *rcp);
|
||||
|
||||
static WORD s_dlgfntheight; /* height of the dialog font */
|
||||
@@ -605,10 +616,7 @@ _OnBlinkTimer(
|
||||
blink_timer = (UINT) SetTimer(NULL, 0, (UINT)blink_ontime,
|
||||
(TIMERPROC)_OnBlinkTimer);
|
||||
}
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_Flush(s_dwc);
|
||||
#endif
|
||||
gui_mch_flush();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -634,7 +642,10 @@ gui_mch_stop_blink(void)
|
||||
{
|
||||
gui_mswin_rm_blink_timer();
|
||||
if (blink_state == BLINK_OFF)
|
||||
{
|
||||
gui_update_cursor(TRUE, FALSE);
|
||||
gui_mch_flush();
|
||||
}
|
||||
blink_state = BLINK_NONE;
|
||||
}
|
||||
|
||||
@@ -654,6 +665,7 @@ gui_mch_start_blink(void)
|
||||
(TIMERPROC)_OnBlinkTimer);
|
||||
blink_state = BLINK_ON;
|
||||
gui_update_cursor(TRUE, FALSE);
|
||||
gui_mch_flush();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1730,7 +1742,6 @@ gui_mch_draw_part_cursor(
|
||||
int h,
|
||||
guicolor_T color)
|
||||
{
|
||||
HBRUSH hbr;
|
||||
RECT rc;
|
||||
|
||||
/*
|
||||
@@ -1746,14 +1757,7 @@ gui_mch_draw_part_cursor(
|
||||
rc.right = rc.left + w;
|
||||
rc.bottom = rc.top + h;
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_Flush(s_dwc);
|
||||
#endif
|
||||
|
||||
hbr = CreateSolidBrush(color);
|
||||
FillRect(s_hdc, &rc, hbr);
|
||||
DeleteBrush(hbr);
|
||||
fill_rect(&rc, NULL, color);
|
||||
}
|
||||
|
||||
|
||||
@@ -3122,13 +3126,8 @@ gui_mch_delete_lines(
|
||||
int num_lines)
|
||||
{
|
||||
RECT rc;
|
||||
|
||||
intel_gpu_workaround();
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
// Commit drawing queue before ScrollWindowEx.
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_Flush(s_dwc);
|
||||
int use_redraw = 0;
|
||||
#endif
|
||||
|
||||
rc.left = FILL_X(gui.scroll_region_left);
|
||||
@@ -3136,8 +3135,24 @@ gui_mch_delete_lines(
|
||||
rc.top = FILL_Y(row);
|
||||
rc.bottom = FILL_Y(gui.scroll_region_bot + 1);
|
||||
|
||||
ScrollWindowEx(s_textArea, 0, -num_lines * gui.char_height,
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
{
|
||||
if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines)
|
||||
{
|
||||
RedrawWindow(s_textArea, &rc, NULL, RDW_INVALIDATE);
|
||||
use_redraw = 1;
|
||||
}
|
||||
else
|
||||
DWriteContext_Flush(s_dwc);
|
||||
}
|
||||
if (!use_redraw)
|
||||
#endif
|
||||
{
|
||||
intel_gpu_workaround();
|
||||
ScrollWindowEx(s_textArea, 0, -num_lines * gui.char_height,
|
||||
&rc, &rc, NULL, NULL, get_scroll_flags());
|
||||
}
|
||||
|
||||
UpdateWindow(s_textArea);
|
||||
/* This seems to be required to avoid the cursor disappearing when
|
||||
@@ -3161,23 +3176,35 @@ gui_mch_insert_lines(
|
||||
int num_lines)
|
||||
{
|
||||
RECT rc;
|
||||
|
||||
intel_gpu_workaround();
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
// Commit drawing queue before ScrollWindowEx.
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_Flush(s_dwc);
|
||||
int use_redraw = 0;
|
||||
#endif
|
||||
|
||||
rc.left = FILL_X(gui.scroll_region_left);
|
||||
rc.right = FILL_X(gui.scroll_region_right + 1);
|
||||
rc.top = FILL_Y(row);
|
||||
rc.bottom = FILL_Y(gui.scroll_region_bot + 1);
|
||||
/* The SW_INVALIDATE is required when part of the window is covered or
|
||||
* off-screen. How do we avoid it when it's not needed? */
|
||||
ScrollWindowEx(s_textArea, 0, num_lines * gui.char_height,
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
{
|
||||
if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines)
|
||||
{
|
||||
RedrawWindow(s_textArea, &rc, NULL, RDW_INVALIDATE);
|
||||
use_redraw = 1;
|
||||
}
|
||||
else
|
||||
DWriteContext_Flush(s_dwc);
|
||||
}
|
||||
if (!use_redraw)
|
||||
#endif
|
||||
{
|
||||
intel_gpu_workaround();
|
||||
/* The SW_INVALIDATE is required when part of the window is covered or
|
||||
* off-screen. How do we avoid it when it's not needed? */
|
||||
ScrollWindowEx(s_textArea, 0, num_lines * gui.char_height,
|
||||
&rc, &rc, NULL, NULL, get_scroll_flags());
|
||||
}
|
||||
|
||||
UpdateWindow(s_textArea);
|
||||
|
||||
@@ -5853,6 +5880,7 @@ _OnImeNotify(HWND hWnd, DWORD dwCommand, DWORD dwData UNUSED)
|
||||
}
|
||||
}
|
||||
gui_update_cursor(TRUE, FALSE);
|
||||
gui_mch_flush();
|
||||
lResult = 0;
|
||||
break;
|
||||
}
|
||||
@@ -6181,6 +6209,67 @@ RevOut( HDC s_hdc,
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
draw_line(
|
||||
int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2,
|
||||
COLORREF color)
|
||||
{
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_DrawLine(s_dwc, x1, y1, x2, y2, color);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
HPEN hpen = CreatePen(PS_SOLID, 1, color);
|
||||
HPEN old_pen = SelectObject(s_hdc, hpen);
|
||||
MoveToEx(s_hdc, x1, y1, NULL);
|
||||
/* Note: LineTo() excludes the last pixel in the line. */
|
||||
LineTo(s_hdc, x2, y2);
|
||||
DeleteObject(SelectObject(s_hdc, old_pen));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_pixel(
|
||||
int x,
|
||||
int y,
|
||||
COLORREF color)
|
||||
{
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_SetPixel(s_dwc, x, y, color);
|
||||
else
|
||||
#endif
|
||||
SetPixel(s_hdc, x, y, color);
|
||||
}
|
||||
|
||||
static void
|
||||
fill_rect(
|
||||
const RECT *rcp,
|
||||
HBRUSH hbr,
|
||||
COLORREF color)
|
||||
{
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_FillRect(s_dwc, rcp, color);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
HBRUSH hbr2;
|
||||
|
||||
if (hbr == NULL)
|
||||
hbr2 = CreateSolidBrush(color);
|
||||
else
|
||||
hbr2 = hbr;
|
||||
FillRect(s_hdc, rcp, hbr2);
|
||||
if (hbr == NULL)
|
||||
DeleteBrush(hbr2);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gui_mch_draw_string(
|
||||
int row,
|
||||
@@ -6200,7 +6289,6 @@ gui_mch_draw_string(
|
||||
static int unibuflen = 0;
|
||||
int n = 0;
|
||||
#endif
|
||||
HPEN hpen, old_pen;
|
||||
int y;
|
||||
|
||||
/*
|
||||
@@ -6263,11 +6351,7 @@ gui_mch_draw_string(
|
||||
brush_lru = !brush_lru;
|
||||
}
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_FillRect(s_dwc, &rc, gui.currBgColor);
|
||||
#endif
|
||||
FillRect(s_hdc, &rc, hbr);
|
||||
fill_rect(&rc, hbr, gui.currBgColor);
|
||||
|
||||
SetBkMode(s_hdc, TRANSPARENT);
|
||||
|
||||
@@ -6462,38 +6546,22 @@ gui_mch_draw_string(
|
||||
foptions, pcliprect, (char *)text, len, padding);
|
||||
}
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX() &&
|
||||
(flags & (DRAW_UNDERL | DRAW_STRIKE | DRAW_UNDERC | DRAW_CURSOR)))
|
||||
DWriteContext_Flush(s_dwc);
|
||||
#endif
|
||||
|
||||
/* Underline */
|
||||
if (flags & DRAW_UNDERL)
|
||||
{
|
||||
hpen = CreatePen(PS_SOLID, 1, gui.currFgColor);
|
||||
old_pen = SelectObject(s_hdc, hpen);
|
||||
/* When p_linespace is 0, overwrite the bottom row of pixels.
|
||||
* Otherwise put the line just below the character. */
|
||||
y = FILL_Y(row + 1) - 1;
|
||||
if (p_linespace > 1)
|
||||
y -= p_linespace - 1;
|
||||
MoveToEx(s_hdc, FILL_X(col), y, NULL);
|
||||
/* Note: LineTo() excludes the last pixel in the line. */
|
||||
LineTo(s_hdc, FILL_X(col + len), y);
|
||||
DeleteObject(SelectObject(s_hdc, old_pen));
|
||||
draw_line(FILL_X(col), y, FILL_X(col + len), y, gui.currFgColor);
|
||||
}
|
||||
|
||||
/* Strikethrough */
|
||||
if (flags & DRAW_STRIKE)
|
||||
{
|
||||
hpen = CreatePen(PS_SOLID, 1, gui.currSpColor);
|
||||
old_pen = SelectObject(s_hdc, hpen);
|
||||
y = FILL_Y(row + 1) - gui.char_height/2;
|
||||
MoveToEx(s_hdc, FILL_X(col), y, NULL);
|
||||
/* Note: LineTo() excludes the last pixel in the line. */
|
||||
LineTo(s_hdc, FILL_X(col + len), y);
|
||||
DeleteObject(SelectObject(s_hdc, old_pen));
|
||||
draw_line(FILL_X(col), y, FILL_X(col + len), y, gui.currSpColor);
|
||||
}
|
||||
|
||||
/* Undercurl */
|
||||
@@ -6507,7 +6575,7 @@ gui_mch_draw_string(
|
||||
for (x = FILL_X(col); x < FILL_X(col + len); ++x)
|
||||
{
|
||||
offset = val[x % 8];
|
||||
SetPixel(s_hdc, x, y - offset, gui.currSpColor);
|
||||
set_pixel(x, y - offset, gui.currSpColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6541,19 +6609,7 @@ gui_mch_flush(void)
|
||||
static void
|
||||
clear_rect(RECT *rcp)
|
||||
{
|
||||
HBRUSH hbr;
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
{
|
||||
DWriteContext_FillRect(s_dwc, rcp, gui.back_pixel);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
hbr = CreateSolidBrush(gui.back_pixel);
|
||||
FillRect(s_hdc, rcp, hbr);
|
||||
DeleteBrush(hbr);
|
||||
fill_rect(rcp, NULL, gui.back_pixel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5433,7 +5433,7 @@ op_addsub(
|
||||
}
|
||||
else /* oap->motion_type == MCHAR */
|
||||
{
|
||||
if (!oap->inclusive)
|
||||
if (pos.lnum == oap->start.lnum && !oap->inclusive)
|
||||
dec(&(oap->end));
|
||||
length = (colnr_T)STRLEN(ml_get(pos.lnum));
|
||||
pos.col = 0;
|
||||
|
||||
@@ -7406,7 +7406,7 @@ did_set_string_option(
|
||||
|
||||
#if defined(FEAT_RENDER_OPTIONS)
|
||||
/* 'renderoptions' */
|
||||
else if (varp == &p_rop && gui.in_use)
|
||||
else if (varp == &p_rop)
|
||||
{
|
||||
if (!gui_mch_set_rendering_options(p_rop))
|
||||
errmsg = e_invarg;
|
||||
|
||||
@@ -1816,9 +1816,18 @@ mch_inchar(
|
||||
typeahead[typeaheadlen] = c;
|
||||
if (ch2 != NUL)
|
||||
{
|
||||
typeahead[typeaheadlen + n] = 3;
|
||||
typeahead[typeaheadlen + n + 1] = (char_u)ch2;
|
||||
n += 2;
|
||||
if (c == K_NUL && (ch2 & 0xff00) != 0)
|
||||
{
|
||||
/* fAnsiKey with modifier keys */
|
||||
typeahead[typeaheadlen + n] = (char_u)ch2;
|
||||
n++;
|
||||
}
|
||||
else
|
||||
{
|
||||
typeahead[typeaheadlen + n] = 3;
|
||||
typeahead[typeaheadlen + n + 1] = (char_u)ch2;
|
||||
n += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use the ALT key to set the 8th bit of the character
|
||||
|
||||
@@ -31,7 +31,6 @@ void channel_close(channel_T *channel, int invoke_close_cb);
|
||||
void channel_close_in(channel_T *channel);
|
||||
void channel_clear(channel_T *channel);
|
||||
void channel_free_all(void);
|
||||
char_u *channel_read_block(channel_T *channel, ch_part_T part, int timeout);
|
||||
void common_channel_read(typval_T *argvars, typval_T *rettv, int raw);
|
||||
channel_T *channel_fd2channel(sock_T fd, ch_part_T *partp);
|
||||
void channel_handle_events(int only_keep_open);
|
||||
|
||||
@@ -25,6 +25,7 @@ void u_clearline(void);
|
||||
void u_undoline(void);
|
||||
void u_blockfree(buf_T *buf);
|
||||
int bufIsChanged(buf_T *buf);
|
||||
int bufIsChangedNotTerm(buf_T *buf);
|
||||
int curbufIsChanged(void);
|
||||
void u_eval_tree(u_header_T *first_uhp, list_T *list);
|
||||
/* vim: set ft=c : */
|
||||
|
||||
@@ -4949,9 +4949,12 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
if ((status == OK) && (flags & QF_GETLIST_WINID))
|
||||
{
|
||||
win_T *win;
|
||||
int win_id = 0;
|
||||
|
||||
win = qf_find_win(qi);
|
||||
if (win != NULL)
|
||||
status = dict_add_nr_str(retdict, "winid", win->w_id, NULL);
|
||||
win_id = win->w_id;
|
||||
status = dict_add_nr_str(retdict, "winid", win_id, NULL);
|
||||
}
|
||||
if ((status == OK) && (flags & QF_GETLIST_ITEMS))
|
||||
{
|
||||
|
||||
@@ -1154,7 +1154,7 @@ win_update(win_T *wp)
|
||||
}
|
||||
|
||||
/* Window is zero-height: nothing to draw. */
|
||||
if (wp->w_height == 0)
|
||||
if (wp->w_height + WINBAR_HEIGHT(wp) == 0)
|
||||
{
|
||||
wp->w_redr_type = 0;
|
||||
return;
|
||||
|
||||
@@ -3510,6 +3510,9 @@ may_req_ambiguous_char_width(void)
|
||||
out_str((char_u *)" ");
|
||||
term_windgoto(0, 0);
|
||||
|
||||
/* Need to reset the known cursor position. */
|
||||
screen_start();
|
||||
|
||||
/* check for the characters now, otherwise they might be eaten by
|
||||
* get_keystroke() */
|
||||
out_flush();
|
||||
@@ -4585,7 +4588,7 @@ check_termcode(
|
||||
is_mac_terminal = TRUE;
|
||||
}
|
||||
# ifdef FEAT_MOUSE_SGR
|
||||
/* Iterm2 sends 0;95;0 */
|
||||
/* iTerm2 sends 0;95;0 */
|
||||
if (STRNCMP(tp + extra - 2, "0;95;0c", 7) == 0)
|
||||
is_iterm2 = TRUE;
|
||||
# endif
|
||||
@@ -4597,7 +4600,7 @@ check_termcode(
|
||||
{
|
||||
# ifdef FEAT_MOUSE_SGR
|
||||
/* Xterm version 277 supports SGR. Also support
|
||||
* Terminal.app and iterm2. */
|
||||
* Terminal.app and iTerm2. */
|
||||
if (version >= 277 || is_iterm2 || is_mac_terminal)
|
||||
set_option_value((char_u *)"ttym", 0L,
|
||||
(char_u *)"sgr", 0);
|
||||
|
||||
@@ -675,7 +675,10 @@ update_cursor(term_T *term, int redraw)
|
||||
out_flush();
|
||||
#ifdef FEAT_GUI
|
||||
if (gui.in_use)
|
||||
{
|
||||
gui_update_cursor(FALSE, FALSE);
|
||||
gui_mch_flush();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1308,12 +1311,13 @@ send_keys_to_term(term_T *term, int c, int typed)
|
||||
case K_MOUSELEFT:
|
||||
case K_MOUSERIGHT:
|
||||
if (mouse_row < W_WINROW(curwin)
|
||||
|| mouse_row > (W_WINROW(curwin) + curwin->w_height)
|
||||
|| mouse_row >= (W_WINROW(curwin) + curwin->w_height)
|
||||
|| mouse_col < curwin->w_wincol
|
||||
|| mouse_col > W_ENDCOL(curwin)
|
||||
|| mouse_col >= W_ENDCOL(curwin)
|
||||
|| dragging_outside)
|
||||
{
|
||||
/* click or scroll outside the current window */
|
||||
/* click or scroll outside the current window or on status line
|
||||
* or vertical separator */
|
||||
if (typed)
|
||||
{
|
||||
stuffcharReadbuff(c);
|
||||
|
||||
@@ -73,6 +73,7 @@ NEW_TESTS = test_arabic.res \
|
||||
test_assert.res \
|
||||
test_autochdir.res \
|
||||
test_autocmd.res \
|
||||
test_autoload.res \
|
||||
test_backspace_opt.res \
|
||||
test_breakindent.res \
|
||||
test_bufwintabinfo.res \
|
||||
|
||||
@@ -251,6 +251,7 @@ let s:flaky = [
|
||||
\ 'Test_exit_callback_interval()',
|
||||
\ 'Test_nb_basic()',
|
||||
\ 'Test_oneshot()',
|
||||
\ 'Test_out_cb()',
|
||||
\ 'Test_paused()',
|
||||
\ 'Test_pipe_through_sort_all()',
|
||||
\ 'Test_pipe_through_sort_some()',
|
||||
|
||||
7
src/testdir/sautest/autoload/foo.vim
Normal file
7
src/testdir/sautest/autoload/foo.vim
Normal file
@@ -0,0 +1,7 @@
|
||||
let g:loaded_foo_vim += 1
|
||||
|
||||
let foo#bar = {}
|
||||
|
||||
func foo#bar.echo()
|
||||
let g:called_foo_bar_echo += 1
|
||||
endfunc
|
||||
1
src/testdir/sautest/autoload/globone.vim
Normal file
1
src/testdir/sautest/autoload/globone.vim
Normal file
@@ -0,0 +1 @@
|
||||
" used by Test_globpath()
|
||||
1
src/testdir/sautest/autoload/globtwo.vim
Normal file
1
src/testdir/sautest/autoload/globtwo.vim
Normal file
@@ -0,0 +1 @@
|
||||
" used by Test_globpath()
|
||||
3
src/testdir/sautest/autoload/sourced.vim
Normal file
3
src/testdir/sautest/autoload/sourced.vim
Normal file
@@ -0,0 +1,3 @@
|
||||
let g:loaded_sourced_vim += 1
|
||||
func! sourced#something()
|
||||
endfunc
|
||||
17
src/testdir/test_autoload.vim
Normal file
17
src/testdir/test_autoload.vim
Normal file
@@ -0,0 +1,17 @@
|
||||
" Tests for autoload
|
||||
|
||||
set runtimepath=./sautest
|
||||
|
||||
func Test_autoload_dict_func()
|
||||
let g:loaded_foo_vim = 0
|
||||
let g:called_foo_bar_echo = 0
|
||||
call g:foo#bar.echo()
|
||||
call assert_equal(1, g:loaded_foo_vim)
|
||||
call assert_equal(1, g:called_foo_bar_echo)
|
||||
endfunc
|
||||
|
||||
func Test_source_autoload()
|
||||
let g:loaded_sourced_vim = 0
|
||||
source sautest/autoload/sourced.vim
|
||||
call assert_equal(1, g:loaded_sourced_vim)
|
||||
endfunc
|
||||
@@ -515,7 +515,7 @@ func Test_nl_pipe()
|
||||
call assert_equal("AND this", ch_readraw(handle))
|
||||
|
||||
call ch_sendraw(handle, "split this line\n")
|
||||
call assert_equal("this linethis linethis line", ch_readraw(handle))
|
||||
call assert_equal("this linethis linethis line", ch_read(handle))
|
||||
|
||||
let reply = ch_evalraw(handle, "quit\n")
|
||||
call assert_equal("Goodbye!", reply)
|
||||
@@ -1266,6 +1266,31 @@ func Test_read_in_close_cb()
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
" Use channel in NL mode but received text does not end in NL.
|
||||
func Test_read_in_close_cb_incomplete()
|
||||
if !has('job')
|
||||
return
|
||||
endif
|
||||
call ch_log('Test_read_in_close_cb_incomplete()')
|
||||
|
||||
let g:Ch_received = ''
|
||||
func! CloseHandler(chan)
|
||||
while ch_status(a:chan, {'part': 'out'}) == 'buffered'
|
||||
let g:Ch_received .= ch_read(a:chan)
|
||||
endwhile
|
||||
endfunc
|
||||
let job = job_start(s:python . " test_channel_pipe.py incomplete",
|
||||
\ {'close_cb': 'CloseHandler'})
|
||||
call assert_equal("run", job_status(job))
|
||||
try
|
||||
call WaitFor('g:Ch_received != ""')
|
||||
call assert_equal('incomplete', g:Ch_received)
|
||||
finally
|
||||
call job_stop(job)
|
||||
delfunc CloseHandler
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
func Test_out_cb_lambda()
|
||||
if !has('job')
|
||||
return
|
||||
|
||||
@@ -14,6 +14,10 @@ if __name__ == "__main__":
|
||||
if sys.argv[1].startswith("err"):
|
||||
print(sys.argv[1], file=sys.stderr)
|
||||
sys.stderr.flush()
|
||||
elif sys.argv[1].startswith("incomplete"):
|
||||
print(sys.argv[1], end='')
|
||||
sys.stdout.flush()
|
||||
sys.exit(0)
|
||||
else:
|
||||
print(sys.argv[1])
|
||||
sys.stdout.flush()
|
||||
|
||||
@@ -25,8 +25,8 @@ function Test_glob()
|
||||
endfunction
|
||||
|
||||
function Test_globpath()
|
||||
call assert_equal("sautest/autoload/Test104.vim\nsautest/autoload/footest.vim",
|
||||
\ globpath('sautest/autoload', '*.vim'))
|
||||
call assert_equal(['sautest/autoload/Test104.vim', 'sautest/autoload/footest.vim'],
|
||||
\ globpath('sautest/autoload', '*.vim', 0, 1))
|
||||
call assert_equal("sautest/autoload/globone.vim\nsautest/autoload/globtwo.vim",
|
||||
\ globpath('sautest/autoload', 'glob*.vim'))
|
||||
call assert_equal(['sautest/autoload/globone.vim', 'sautest/autoload/globtwo.vim'],
|
||||
\ globpath('sautest/autoload', 'glob*.vim', 0, 1))
|
||||
endfunction
|
||||
|
||||
@@ -30,3 +30,22 @@ func Test_help_keyword()
|
||||
close
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_help_local_additions()
|
||||
call mkdir('Xruntime/doc', 'p')
|
||||
call writefile(['*mydoc.txt* my awesome doc'], 'Xruntime/doc/mydoc.txt')
|
||||
call writefile(['*mydoc-ext.txt* my extended awesome doc'], 'Xruntime/doc/mydoc-ext.txt')
|
||||
let rtp_save = &rtp
|
||||
set rtp+=./Xruntime
|
||||
help
|
||||
1
|
||||
call search('mydoc.txt')
|
||||
call assert_equal('|mydoc.txt| my awesome doc', getline('.'))
|
||||
1
|
||||
call search('mydoc-ext.txt')
|
||||
call assert_equal('|mydoc-ext.txt| my extended awesome doc', getline('.'))
|
||||
close
|
||||
|
||||
call delete('Xruntime', 'rf')
|
||||
let &rtp = rtp_save
|
||||
endfunc
|
||||
|
||||
@@ -364,11 +364,25 @@ endfunc
|
||||
" Expected:
|
||||
" 1) Ctrl-a on visually selected zero
|
||||
" 111
|
||||
"
|
||||
" Also: 019 with "01" selected increments to "029".
|
||||
func Test_visual_increment_15()
|
||||
call setline(1, ["101"])
|
||||
exec "norm! lv\<C-A>"
|
||||
call assert_equal(["111"], getline(1, '$'))
|
||||
call assert_equal([0, 1, 2, 0], getpos('.'))
|
||||
|
||||
call setline(1, ["019"])
|
||||
exec "norm! 0vl\<C-A>"
|
||||
call assert_equal("029", getline(1))
|
||||
|
||||
call setline(1, ["01239"])
|
||||
exec "norm! 0vlll\<C-A>"
|
||||
call assert_equal("01249", getline(1))
|
||||
|
||||
call setline(1, ["01299"])
|
||||
exec "norm! 0vlll\<C-A>"
|
||||
call assert_equal("1309", getline(1))
|
||||
endfunc
|
||||
|
||||
" 16) increment right aligned numbers
|
||||
@@ -756,5 +770,12 @@ func Test_normal_increment_03()
|
||||
call assert_equal([0, 3, 25, 0], getpos('.'))
|
||||
endfunc
|
||||
|
||||
func Test_increment_empty_line()
|
||||
new
|
||||
call setline(1, ['0', '0', '0', '0', '0', '0', ''])
|
||||
exe "normal Gvgg\<C-A>"
|
||||
call assert_equal(['1', '1', '1', '1', '1', '1', ''], getline(1, 7))
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -181,3 +181,44 @@ func Test_profile_errors()
|
||||
call assert_fails("profile pause", 'E750:')
|
||||
call assert_fails("profile continue", 'E750:')
|
||||
endfunc
|
||||
|
||||
func Test_profile_truncate_mbyte()
|
||||
if !has('multi_byte') || &enc !=# 'utf-8'
|
||||
return
|
||||
endif
|
||||
|
||||
let lines = [
|
||||
\ 'scriptencoding utf-8',
|
||||
\ 'func! Foo()',
|
||||
\ ' return [',
|
||||
\ ' \ "' . join(map(range(0x4E00, 0x4E00 + 340), 'nr2char(v:val)'), '') . '",',
|
||||
\ ' \ "' . join(map(range(0x4F00, 0x4F00 + 340), 'nr2char(v:val)'), '') . '",',
|
||||
\ ' \ ]',
|
||||
\ 'endfunc',
|
||||
\ 'call Foo()',
|
||||
\ ]
|
||||
|
||||
call writefile(lines, 'Xprofile_file.vim')
|
||||
call system(v:progpath
|
||||
\ . ' -es --clean --cmd "set enc=utf-8"'
|
||||
\ . ' -c "profile start Xprofile_file.log"'
|
||||
\ . ' -c "profile file Xprofile_file.vim"'
|
||||
\ . ' -c "so Xprofile_file.vim"'
|
||||
\ . ' -c "qall!"')
|
||||
call assert_equal(0, v:shell_error)
|
||||
|
||||
split Xprofile_file.log
|
||||
if &fenc != ''
|
||||
call assert_equal('utf-8', &fenc)
|
||||
endif
|
||||
/func! Foo()
|
||||
let lnum = line('.')
|
||||
call assert_match('^\s*return \[$', getline(lnum + 1))
|
||||
call assert_match("\u4F52$", getline(lnum + 2))
|
||||
call assert_match("\u5052$", getline(lnum + 3))
|
||||
call assert_match('^\s*\\ \]$', getline(lnum + 4))
|
||||
bwipe!
|
||||
|
||||
call delete('Xprofile_file.vim')
|
||||
call delete('Xprofile_file.log')
|
||||
endfunc
|
||||
|
||||
@@ -28,7 +28,7 @@ func s:setup_commands(cchar)
|
||||
command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
|
||||
command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
|
||||
command! -nargs=* -bang Xlast <mods>clast<bang> <args>
|
||||
command! -nargs=* -bang Xnfile <mods>cnfile<bang> <args>
|
||||
command! -nargs=* -bang -range Xnfile <mods><count>cnfile<bang> <args>
|
||||
command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
|
||||
command! -nargs=* Xexpr <mods>cexpr <args>
|
||||
command! -range -nargs=* Xvimgrep <mods><count>vimgrep <args>
|
||||
@@ -36,6 +36,7 @@ func s:setup_commands(cchar)
|
||||
command! -nargs=* Xgrep <mods> grep <args>
|
||||
command! -nargs=* Xgrepadd <mods> grepadd <args>
|
||||
command! -nargs=* Xhelpgrep helpgrep <args>
|
||||
command! -nargs=0 -count Xcc <count>cc
|
||||
let g:Xgetlist = function('getqflist')
|
||||
let g:Xsetlist = function('setqflist')
|
||||
call setqflist([], 'f')
|
||||
@@ -60,7 +61,7 @@ func s:setup_commands(cchar)
|
||||
command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
|
||||
command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
|
||||
command! -nargs=* -bang Xlast <mods>llast<bang> <args>
|
||||
command! -nargs=* -bang Xnfile <mods>lnfile<bang> <args>
|
||||
command! -nargs=* -bang -range Xnfile <mods><count>lnfile<bang> <args>
|
||||
command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
|
||||
command! -nargs=* Xexpr <mods>lexpr <args>
|
||||
command! -range -nargs=* Xvimgrep <mods><count>lvimgrep <args>
|
||||
@@ -68,6 +69,7 @@ func s:setup_commands(cchar)
|
||||
command! -nargs=* Xgrep <mods> lgrep <args>
|
||||
command! -nargs=* Xgrepadd <mods> lgrepadd <args>
|
||||
command! -nargs=* Xhelpgrep lhelpgrep <args>
|
||||
command! -nargs=0 -count Xcc <count>ll
|
||||
let g:Xgetlist = function('getloclist', [0])
|
||||
let g:Xsetlist = function('setloclist', [0])
|
||||
call setloclist(0, [], 'f')
|
||||
@@ -382,12 +384,18 @@ endfunc
|
||||
func Xtest_browse(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
call g:Xsetlist([], 'f')
|
||||
" Jumping to first or next location list entry without any error should
|
||||
" result in failure
|
||||
if a:cchar == 'l'
|
||||
call assert_fails('lfirst', 'E776:')
|
||||
call assert_fails('lnext', 'E776:')
|
||||
if a:cchar == 'c'
|
||||
let err = 'E42:'
|
||||
else
|
||||
let err = 'E776:'
|
||||
endif
|
||||
call assert_fails('Xnext', err)
|
||||
call assert_fails('Xprev', err)
|
||||
call assert_fails('Xnfile', err)
|
||||
call assert_fails('Xpfile', err)
|
||||
|
||||
call s:create_test_file('Xqftestfile1')
|
||||
call s:create_test_file('Xqftestfile2')
|
||||
@@ -408,6 +416,12 @@ func Xtest_browse(cchar)
|
||||
Xpfile
|
||||
call assert_equal('Xqftestfile1', bufname('%'))
|
||||
call assert_equal(6, line('.'))
|
||||
5Xcc
|
||||
call assert_equal(5, g:Xgetlist({'idx':0}).idx)
|
||||
2Xcc
|
||||
call assert_equal(2, g:Xgetlist({'idx':0}).idx)
|
||||
10Xcc
|
||||
call assert_equal(6, g:Xgetlist({'idx':0}).idx)
|
||||
Xlast
|
||||
Xprev
|
||||
call assert_equal('Xqftestfile2', bufname('%'))
|
||||
@@ -425,6 +439,23 @@ func Xtest_browse(cchar)
|
||||
call assert_equal('Xqftestfile1', bufname('%'))
|
||||
call assert_equal(5, line('.'))
|
||||
|
||||
" Jumping to an error from the error window using cc command
|
||||
Xgetexpr ['Xqftestfile1:5:Line5',
|
||||
\ 'Xqftestfile1:6:Line6',
|
||||
\ 'Xqftestfile2:10:Line10',
|
||||
\ 'Xqftestfile2:11:Line11']
|
||||
Xopen
|
||||
10Xcc
|
||||
call assert_equal(11, line('.'))
|
||||
call assert_equal('Xqftestfile2', bufname('%'))
|
||||
|
||||
" Jumping to an error from the error window (when only the error window is
|
||||
" present)
|
||||
Xopen | only
|
||||
Xlast 1
|
||||
call assert_equal(5, line('.'))
|
||||
call assert_equal('Xqftestfile1', bufname('%'))
|
||||
|
||||
Xexpr ""
|
||||
call assert_fails('Xnext', 'E42:')
|
||||
|
||||
@@ -1497,13 +1528,18 @@ func Test_switchbuf()
|
||||
set switchbuf=usetab
|
||||
tabedit Xqftestfile1
|
||||
tabedit Xqftestfile2
|
||||
tabedit Xqftestfile3
|
||||
tabfirst
|
||||
cfirst | cnext
|
||||
call assert_equal(2, tabpagenr())
|
||||
2cnext
|
||||
call assert_equal(3, tabpagenr())
|
||||
2cnext
|
||||
call assert_equal(3, tabpagenr())
|
||||
6cnext
|
||||
call assert_equal(4, tabpagenr())
|
||||
2cpfile
|
||||
call assert_equal(2, tabpagenr())
|
||||
2cnfile
|
||||
call assert_equal(4, tabpagenr())
|
||||
tabfirst | tabonly | enew
|
||||
|
||||
set switchbuf=split
|
||||
@@ -2320,7 +2356,7 @@ func XfreeTests(cchar)
|
||||
Xclose
|
||||
endfunc
|
||||
|
||||
" Tests for the quickifx free functionality
|
||||
" Tests for the quickfix free functionality
|
||||
func Test_qf_free()
|
||||
call XfreeTests('c')
|
||||
call XfreeTests('l')
|
||||
@@ -2747,3 +2783,100 @@ func Test_qf_id()
|
||||
call Xqfid_tests('c')
|
||||
call Xqfid_tests('l')
|
||||
endfunc
|
||||
|
||||
func Xqfjump_tests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
call writefile(["Line1\tFoo", "Line2"], 'F1')
|
||||
call writefile(["Line1\tBar", "Line2"], 'F2')
|
||||
call writefile(["Line1\tBaz", "Line2"], 'F3')
|
||||
|
||||
call g:Xsetlist([], 'f')
|
||||
|
||||
" Tests for
|
||||
" Jumping to a line using a pattern
|
||||
" Jumping to a column greater than the last column in a line
|
||||
" Jumping to a line greater than the last line in the file
|
||||
let l = []
|
||||
for i in range(1, 7)
|
||||
call add(l, {})
|
||||
endfor
|
||||
let l[0].filename='F1'
|
||||
let l[0].pattern='Line1'
|
||||
let l[1].filename='F2'
|
||||
let l[1].pattern='Line1'
|
||||
let l[2].filename='F3'
|
||||
let l[2].pattern='Line1'
|
||||
let l[3].filename='F3'
|
||||
let l[3].lnum=1
|
||||
let l[3].col=9
|
||||
let l[3].vcol=1
|
||||
let l[4].filename='F3'
|
||||
let l[4].lnum=99
|
||||
let l[5].filename='F3'
|
||||
let l[5].lnum=1
|
||||
let l[5].col=99
|
||||
let l[5].vcol=1
|
||||
let l[6].filename='F3'
|
||||
let l[6].pattern='abcxyz'
|
||||
|
||||
call g:Xsetlist([], ' ', {'items' : l})
|
||||
Xopen | only
|
||||
2Xnext
|
||||
call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
|
||||
call assert_equal('F3', bufname('%'))
|
||||
Xnext
|
||||
call assert_equal(7, col('.'))
|
||||
Xnext
|
||||
call assert_equal(2, line('.'))
|
||||
Xnext
|
||||
call assert_equal(9, col('.'))
|
||||
2
|
||||
Xnext
|
||||
call assert_equal(2, line('.'))
|
||||
|
||||
if a:cchar == 'l'
|
||||
" When jumping to a location list entry in the location list window and
|
||||
" no usable windows are available, then a new window should be opened.
|
||||
enew! | new | only
|
||||
call g:Xsetlist([], 'f')
|
||||
setlocal buftype=nofile
|
||||
new
|
||||
call g:Xsetlist([], ' ', {'lines' : ['F1:1:1:Line1', 'F1:2:2:Line2', 'F2:1:1:Line1', 'F2:2:2:Line2', 'F3:1:1:Line1', 'F3:2:2:Line2']})
|
||||
Xopen
|
||||
let winid = win_getid()
|
||||
wincmd p
|
||||
close
|
||||
call win_gotoid(winid)
|
||||
Xnext
|
||||
call assert_equal(3, winnr('$'))
|
||||
call assert_equal(1, winnr())
|
||||
call assert_equal(2, line('.'))
|
||||
|
||||
" When jumping to an entry in the location list window and the window
|
||||
" associated with the location list is not present and a window containing
|
||||
" the file is already present, then that window should be used.
|
||||
close
|
||||
belowright new
|
||||
call g:Xsetlist([], 'f')
|
||||
edit F3
|
||||
call win_gotoid(winid)
|
||||
Xlast
|
||||
call assert_equal(3, winnr())
|
||||
call assert_equal(6, g:Xgetlist({'size' : 1}).size)
|
||||
call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
|
||||
endif
|
||||
|
||||
" Cleanup
|
||||
enew!
|
||||
new | only
|
||||
|
||||
call delete('F1')
|
||||
call delete('F2')
|
||||
call delete('F3')
|
||||
endfunc
|
||||
|
||||
func Test_qfjump()
|
||||
call Xqfjump_tests('c')
|
||||
call Xqfjump_tests('l')
|
||||
endfunc
|
||||
|
||||
@@ -673,15 +673,16 @@ func TerminalTmap(remap)
|
||||
else
|
||||
tnoremap 123 456
|
||||
endif
|
||||
tmap 456 abcde
|
||||
" don't use abcde, it's an existing command
|
||||
tmap 456 abxde
|
||||
call assert_equal('456', maparg('123', 't'))
|
||||
call assert_equal('abcde', maparg('456', 't'))
|
||||
call assert_equal('abxde', maparg('456', 't'))
|
||||
call feedkeys("123", 'tx')
|
||||
let g:buf = buf
|
||||
call WaitFor("term_getline(g:buf,term_getcursor(g:buf)[0]) =~ 'abcde\\|456'")
|
||||
call WaitFor("term_getline(g:buf,term_getcursor(g:buf)[0]) =~ 'abxde\\|456'")
|
||||
let lnum = term_getcursor(buf)[0]
|
||||
if a:remap
|
||||
call assert_match('abcde', term_getline(buf, lnum))
|
||||
call assert_match('abxde', term_getline(buf, lnum))
|
||||
else
|
||||
call assert_match('456', term_getline(buf, lnum))
|
||||
endif
|
||||
|
||||
11
src/undo.c
11
src/undo.c
@@ -3523,6 +3523,8 @@ u_save_line(linenr_T lnum)
|
||||
* Check if the 'modified' flag is set, or 'ff' has changed (only need to
|
||||
* check the first character, because it can only be "dos", "unix" or "mac").
|
||||
* "nofile" and "scratch" type buffers are considered to always be unchanged.
|
||||
* Also considers a buffer changed when a terminal window contains a running
|
||||
* job.
|
||||
*/
|
||||
int
|
||||
bufIsChanged(buf_T *buf)
|
||||
@@ -3531,6 +3533,15 @@ bufIsChanged(buf_T *buf)
|
||||
if (term_job_running(buf->b_term))
|
||||
return TRUE;
|
||||
#endif
|
||||
return bufIsChangedNotTerm(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Like bufIsChanged() but ignoring a terminal window.
|
||||
*/
|
||||
int
|
||||
bufIsChangedNotTerm(buf_T *buf)
|
||||
{
|
||||
return !bt_dontwrite(buf)
|
||||
&& (buf->b_changed || file_ff_differs(buf, TRUE));
|
||||
}
|
||||
|
||||
@@ -1594,7 +1594,7 @@ trans_function_name(
|
||||
start += lead;
|
||||
|
||||
/* Note that TFN_ flags use the same values as GLV_ flags. */
|
||||
end = get_lval(start, NULL, &lv, FALSE, skip, flags,
|
||||
end = get_lval(start, NULL, &lv, FALSE, skip, flags | GLV_READ_ONLY,
|
||||
lead > 2 ? 0 : FNE_CHECK_START);
|
||||
if (end == start)
|
||||
{
|
||||
@@ -1886,7 +1886,7 @@ ex_function(exarg_T *eap)
|
||||
* g:func global function name, same as "func"
|
||||
*/
|
||||
p = eap->arg;
|
||||
name = trans_function_name(&p, eap->skip, 0, &fudi, NULL);
|
||||
name = trans_function_name(&p, eap->skip, TFN_NO_AUTOLOAD, &fudi, NULL);
|
||||
paren = (vim_strchr(p, '(') != NULL);
|
||||
if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip)
|
||||
{
|
||||
|
||||
@@ -771,6 +771,44 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1384,
|
||||
/**/
|
||||
1383,
|
||||
/**/
|
||||
1382,
|
||||
/**/
|
||||
1381,
|
||||
/**/
|
||||
1380,
|
||||
/**/
|
||||
1379,
|
||||
/**/
|
||||
1378,
|
||||
/**/
|
||||
1377,
|
||||
/**/
|
||||
1376,
|
||||
/**/
|
||||
1375,
|
||||
/**/
|
||||
1374,
|
||||
/**/
|
||||
1373,
|
||||
/**/
|
||||
1372,
|
||||
/**/
|
||||
1371,
|
||||
/**/
|
||||
1370,
|
||||
/**/
|
||||
1369,
|
||||
/**/
|
||||
1368,
|
||||
/**/
|
||||
1367,
|
||||
/**/
|
||||
1366,
|
||||
/**/
|
||||
1365,
|
||||
/**/
|
||||
|
||||
@@ -1478,8 +1478,10 @@ typedef UINT32_TYPEDEF UINT32_T;
|
||||
#define STATUS_HEIGHT 1 /* height of a status line under a window */
|
||||
#ifdef FEAT_MENU /* height of a status line under a window */
|
||||
# define WINBAR_HEIGHT(wp) (wp)->w_winbar_height
|
||||
# define VISIBLE_HEIGHT(wp) ((wp)->w_height + (wp)->w_winbar_height)
|
||||
#else
|
||||
# define WINBAR_HEIGHT(wp) 0
|
||||
# define VISIBLE_HEIGHT(wp) (wp)->w_height
|
||||
#endif
|
||||
#define QF_WINHEIGHT 10 /* default height for quickfix window */
|
||||
|
||||
|
||||
37
src/window.c
37
src/window.c
@@ -782,7 +782,7 @@ win_split_ins(
|
||||
/* add a status line when p_ls == 1 and splitting the first window */
|
||||
if (ONE_WINDOW && p_ls == 1 && oldwin->w_status_height == 0)
|
||||
{
|
||||
if (oldwin->w_height <= p_wmh && new_wp == NULL)
|
||||
if (VISIBLE_HEIGHT(oldwin) <= p_wmh && new_wp == NULL)
|
||||
{
|
||||
EMSG(_(e_noroom));
|
||||
return FAIL;
|
||||
@@ -892,7 +892,7 @@ win_split_ins(
|
||||
* height.
|
||||
*/
|
||||
/* Current window requires at least 1 space. */
|
||||
wmh1 = (p_wmh == 0 ? 1 : p_wmh);
|
||||
wmh1 = (p_wmh == 0 ? 1 : p_wmh) + WINBAR_HEIGHT(curwin);
|
||||
needed = wmh1 + STATUS_HEIGHT;
|
||||
if (flags & WSP_ROOM)
|
||||
needed += p_wh - wmh1;
|
||||
@@ -1105,7 +1105,7 @@ win_split_ins(
|
||||
{
|
||||
/* height and row of new window is same as current window */
|
||||
wp->w_winrow = oldwin->w_winrow;
|
||||
win_new_height(wp, oldwin->w_height + WINBAR_HEIGHT(oldwin));
|
||||
win_new_height(wp, VISIBLE_HEIGHT(oldwin));
|
||||
wp->w_status_height = oldwin->w_status_height;
|
||||
}
|
||||
frp->fr_height = curfrp->fr_height;
|
||||
@@ -1180,8 +1180,8 @@ win_split_ins(
|
||||
}
|
||||
else /* new window below current one */
|
||||
{
|
||||
wp->w_winrow = oldwin->w_winrow + oldwin->w_height
|
||||
+ STATUS_HEIGHT + WINBAR_HEIGHT(oldwin);
|
||||
wp->w_winrow = oldwin->w_winrow + VISIBLE_HEIGHT(oldwin)
|
||||
+ STATUS_HEIGHT;
|
||||
wp->w_status_height = oldwin->w_status_height;
|
||||
if (!(flags & WSP_BOT))
|
||||
oldwin->w_status_height = STATUS_HEIGHT;
|
||||
@@ -1422,7 +1422,7 @@ make_windows(
|
||||
else
|
||||
{
|
||||
/* Each window needs at least 'winminheight' lines and a status line. */
|
||||
maxcount = (curwin->w_height + curwin->w_status_height
|
||||
maxcount = (VISIBLE_HEIGHT(curwin) + curwin->w_status_height
|
||||
- (p_wh - p_wmh)) / (p_wmh + STATUS_HEIGHT);
|
||||
}
|
||||
|
||||
@@ -3204,8 +3204,7 @@ frame_fix_width(win_T *wp)
|
||||
static void
|
||||
frame_fix_height(win_T *wp)
|
||||
{
|
||||
wp->w_frame->fr_height = wp->w_height + wp->w_status_height
|
||||
+ WINBAR_HEIGHT(wp) ;
|
||||
wp->w_frame->fr_height = VISIBLE_HEIGHT(wp) + wp->w_status_height;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3230,9 +3229,14 @@ frame_minheight(frame_T *topfrp, win_T *next_curwin)
|
||||
{
|
||||
/* window: minimal height of the window plus status line */
|
||||
m = p_wmh + topfrp->fr_win->w_status_height;
|
||||
/* Current window is minimal one line high */
|
||||
if (p_wmh == 0 && topfrp->fr_win == curwin && next_curwin == NULL)
|
||||
++m;
|
||||
if (topfrp->fr_win == curwin && next_curwin == NULL)
|
||||
{
|
||||
/* Current window is minimal one line high and WinBar is
|
||||
* visible. */
|
||||
if (p_wmh == 0)
|
||||
++m;
|
||||
m += WINBAR_HEIGHT(curwin);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (topfrp->fr_layout == FR_ROW)
|
||||
@@ -4972,6 +4976,7 @@ frame_comp_pos(frame_T *topfrp, int *row, int *col)
|
||||
frame_T *frp;
|
||||
int startcol;
|
||||
int startrow;
|
||||
int h;
|
||||
|
||||
wp = topfrp->fr_win;
|
||||
if (wp != NULL)
|
||||
@@ -4984,7 +4989,9 @@ frame_comp_pos(frame_T *topfrp, int *row, int *col)
|
||||
redraw_win_later(wp, NOT_VALID);
|
||||
wp->w_redr_status = TRUE;
|
||||
}
|
||||
*row += wp->w_height + wp->w_status_height;
|
||||
/* WinBar will not show if the window height is zero */
|
||||
h = VISIBLE_HEIGHT(wp) + wp->w_status_height;
|
||||
*row += h > topfrp->fr_height ? topfrp->fr_height : h;
|
||||
*col += wp->w_width + wp->w_vsep_width;
|
||||
}
|
||||
else
|
||||
@@ -5029,6 +5036,7 @@ win_setheight_win(int height, win_T *win)
|
||||
height = p_wmh;
|
||||
if (height == 0)
|
||||
height = 1;
|
||||
height += WINBAR_HEIGHT(curwin);
|
||||
}
|
||||
|
||||
frame_setheight(win->w_frame, height + win->w_status_height);
|
||||
@@ -5126,7 +5134,8 @@ frame_setheight(frame_T *curfrp, int height)
|
||||
else
|
||||
{
|
||||
room_cmdline = Rows - p_ch - (lastwin->w_winrow
|
||||
+ lastwin->w_height + lastwin->w_status_height);
|
||||
+ VISIBLE_HEIGHT(lastwin)
|
||||
+ lastwin->w_status_height);
|
||||
if (room_cmdline < 0)
|
||||
room_cmdline = 0;
|
||||
}
|
||||
@@ -5415,7 +5424,7 @@ win_setminheight(void)
|
||||
/* TODO: handle vertical splits */
|
||||
room = -p_wh;
|
||||
FOR_ALL_WINDOWS(wp)
|
||||
room += wp->w_height - p_wmh;
|
||||
room += VISIBLE_HEIGHT(wp) - p_wmh;
|
||||
if (room >= 0)
|
||||
break;
|
||||
--p_wmh;
|
||||
|
||||
Reference in New Issue
Block a user