Compare commits

...

15 Commits

Author SHA1 Message Date
Bram Moolenaar
6e65d594aa patch 8.0.1377: cannot call a dict function in autoloaded dict
Problem:    Cannot call a dict function in autoloaded dict.
Solution:   Call get_lval() passing the read-only flag.
2017-12-07 22:11:27 +01:00
Bram Moolenaar
23c1b2b018 patch 8.0.1376: cursor in terminal not always updated
Problem:    Cursor in terminal not always updated.
Solution:   Call gui_mch_flush(). (Ken Takata)
2017-12-05 21:32:33 +01:00
Bram Moolenaar
415a6939a4 patch 8.0.1375: window size wrong after maximizing with WinBar
Problem:    Window size wrong after maximizing with WinBar. (Lifepillar)
Solution:   Fix height computations. Redraw window when it is zero height but
            has a WinBar. (closes #2356)
2017-12-05 20:31:07 +01:00
Bram Moolenaar
5fe6bdf858 patch 8.0.1374: CTRL-A does not work with an empty line
Problem:    CTRL-A does not work with an empty line. (Alex)
Solution:   Decrement the end only once. (Hirohito Higashi, closes #2387)
2017-12-05 17:22:12 +01:00
Bram Moolenaar
3767c6e9ee patch 8.0.1373: no error when settting 'renderoptions' before starting GUI
Problem:    No error when settting 'renderoptions' to an invalid value before
            starting the GUI.
Solution:   Always check the value. (Ken Takata, closes #2413)
2017-12-05 16:57:56 +01:00
Bram Moolenaar
ac112f01a6 patch 8.0.1372: profile log may be truncated halfway a character
Problem:    Profile log may be truncated halfway a character.
Solution:   Find the start of the character. (Ozaki Kiichi, closes #2385)
2017-12-05 16:46:28 +01:00
Bram Moolenaar
feeb4d0901 patch 8.0.1371: Shift-Insert doesn't always work in MS-Windows console
Problem:    Shift-Insert doesn't always work in MS-Windows console.
Solution:   Handle K_NUL differently if the second character is more than one
            byte. (Yasuhiro Matsumoto, closes #2381)
2017-12-05 15:14:46 +01:00
Bram Moolenaar
1eca6f13d6 patch 8.0.1370: channel test for callback is flaky
Problem:    Channel test for callback is flaky.
Solution:   Add the test to thelist of flaky tests.
2017-12-05 14:04:27 +01:00
Bram Moolenaar
92467d3351 patch 8.0.1369: MS-Windows: drawing underline slow, mFallbackDC not updated
Problem:    MS-Windows: drawing underline, curl and strike-throw is slow,
            mFallbackDC not properly updated.
Solution:   Several performance improvements. (Ken Takata, Taro Muraoka,
            Yasuhiro Matsumoto, closes #2401)
2017-12-05 13:22:16 +01:00
Bram Moolenaar
ce6179c799 patch 8.0.1368: cannot drag status or separator of new terminal window
Problem:    Cannot drag status line or vertical separator of new terminal
            window. (UncleBill)
Solution:   Adjust mouse row and column computation. (Yasuhiro Matsumoto,
            closes #2410)
2017-12-05 13:06:16 +01:00
Bram Moolenaar
461fe50fea patch 8.0.1367: terminal test hangs, executing abcde
Problem:    terminal test hangs, executing abcde. (Stucki)
Solution:   Rename abcde to abxde.
2017-12-05 12:30:03 +01:00
Bram Moolenaar
1ad022a9b8 patch 8.0.1367 2017-12-03 18:20:32 +01:00
Bram Moolenaar
24820691e6 patch 8.0.1365: when one channel test fails others fail as well
Problem:    When one channel test fails others fail as well.
Solution:   Stop the job after a failure.  Also add a couple of tests to the
            list of flaky tests.
2017-12-02 16:38:12 +01:00
Bram Moolenaar
22044dc317 patch 8.0.1364: there is no easy way to get the window position
Problem:    There is no easy way to get the window position.
Solution:   Add win_screenpos().
2017-12-02 15:43:37 +01:00
Bram Moolenaar
af903e5d49 patch 8.0.1363: recovering does not work when swap file ends in .stz
Problem:    Recovering does not work when swap file ends in .stz.
Solution:   Check for all possible swap file names. (Elfling, closes #2395,
            closes #2396)
2017-12-02 15:11:22 +01:00
32 changed files with 654 additions and 179 deletions

View File

@@ -2452,6 +2452,7 @@ win_getid([{win} [, {tab}]]) Number get window ID for {win} in {tab}
win_gotoid({expr}) Number go to window with ID {expr}
win_id2tabwin({expr}) List get tab and window nr from window ID
win_id2win({expr}) Number get window nr from window ID
win_screenpos({nr}) List get screen position of window {nr}
winbufnr({nr}) Number buffer number of window {nr}
wincol() Number window column of the cursor
winheight({nr}) Number height of window {nr}
@@ -8633,6 +8634,14 @@ win_id2win({expr}) *win_id2win()*
Return the window number of window with ID {expr}.
Return 0 if the window cannot be found in the current tabpage.
win_screenpos({nr}) *win_screenpos()*
Return the screen position of window {nr} as a list with two
numbers: [row, col]. The first window always has position
[1, 1].
{nr} can be the window number or the |window-ID|.
Return [0, 0] if the window cannot be found in the current
tabpage.
*winbufnr()*
winbufnr({nr}) The result is a Number, which is the number of the buffer
associated with window {nr}. {nr} can be the window number or

View File

@@ -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.

View File

@@ -2120,6 +2120,7 @@ test_arglist \
test_assign \
test_autochdir \
test_autocmd \
test_autoload \
test_backspace_opt \
test_breakindent \
test_bufline \

View File

@@ -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. */

View File

@@ -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)

View File

@@ -441,6 +441,7 @@ static void f_win_getid(typval_T *argvars, typval_T *rettv);
static void f_win_gotoid(typval_T *argvars, typval_T *rettv);
static void f_win_id2tabwin(typval_T *argvars, typval_T *rettv);
static void f_win_id2win(typval_T *argvars, typval_T *rettv);
static void f_win_screenpos(typval_T *argvars, typval_T *rettv);
static void f_winbufnr(typval_T *argvars, typval_T *rettv);
static void f_wincol(typval_T *argvars, typval_T *rettv);
static void f_winheight(typval_T *argvars, typval_T *rettv);
@@ -899,6 +900,7 @@ static struct fst
{"win_gotoid", 1, 1, f_win_gotoid},
{"win_id2tabwin", 1, 1, f_win_id2tabwin},
{"win_id2win", 1, 1, f_win_id2win},
{"win_screenpos", 1, 1, f_win_screenpos},
{"winbufnr", 1, 1, f_winbufnr},
{"wincol", 0, 0, f_wincol},
{"winheight", 1, 1, f_winheight},
@@ -5378,6 +5380,22 @@ f_win_id2win(typval_T *argvars, typval_T *rettv)
rettv->vval.v_number = win_id2win(argvars);
}
/*
* "win_screenpos()" function
*/
static void
f_win_screenpos(typval_T *argvars, typval_T *rettv)
{
win_T *wp;
if (rettv_list_alloc(rettv) == FAIL)
return;
wp = find_win_by_nr(&argvars[0], NULL);
list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_winrow + 1);
list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_wincol + 1);
}
/*
* "getwinposx()" function
*/

View File

@@ -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)
{

View File

@@ -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)
{

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -1139,7 +1139,7 @@ ml_recover(void)
attr = HL_ATTR(HLF_E);
/*
* If the file name ends in ".s[uvw][a-z]" we assume this is the swap file.
* If the file name ends in ".s[a-w][a-z]" we assume this is the swap file.
* Otherwise a search is done to find the swap file(s).
*/
fname = curbuf->b_fname;
@@ -1153,7 +1153,8 @@ ml_recover(void)
STRNICMP(fname + len - 4, ".s", 2)
#endif
== 0
&& vim_strchr((char_u *)"UVWuvw", fname[len - 2]) != NULL
&& vim_strchr((char_u *)"abcdefghijklmnopqrstuvw",
TOLOWER_ASC(fname[len - 2])) != NULL
&& ASCII_ISALPHA(fname[len - 1]))
{
directly = TRUE;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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 \

View File

@@ -251,6 +251,8 @@ 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()',
\ 'Test_quoteplus()',
@@ -259,6 +261,7 @@ let s:flaky = [
\ 'Test_terminal_composing_unicode()',
\ 'Test_terminal_noblock()',
\ 'Test_terminal_redir_file()',
\ 'Test_terminal_tmap()',
\ 'Test_with_partial_callback()',
\ ]

View 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

View File

@@ -0,0 +1 @@
" used by Test_globpath()

View File

@@ -0,0 +1 @@
" used by Test_globpath()

View File

@@ -0,0 +1,11 @@
" 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

View File

@@ -1694,19 +1694,23 @@ func Test_cwd()
let g:envstr = ''
if has('win32')
let expect = $TEMP
call job_start(['cmd', '/c', 'echo %CD%'], {'callback': {ch,msg->execute(":let g:envstr .= msg")}, 'cwd': expect})
let job = job_start(['cmd', '/c', 'echo %CD%'], {'callback': {ch,msg->execute(":let g:envstr .= msg")}, 'cwd': expect})
else
let expect = $HOME
call job_start(['pwd'], {'callback': {ch,msg->execute(":let g:envstr .= msg")}, 'cwd': expect})
let job = job_start(['pwd'], {'callback': {ch,msg->execute(":let g:envstr .= msg")}, 'cwd': expect})
endif
call WaitFor('"" != g:envstr')
let expect = substitute(expect, '[/\\]$', '', '')
let g:envstr = substitute(g:envstr, '[/\\]$', '', '')
if $CI != '' && stridx(g:envstr, '/private/') == 0
let g:envstr = g:envstr[8:]
endif
call assert_equal(expect, g:envstr)
unlet g:envstr
try
call WaitFor('"" != g:envstr')
let expect = substitute(expect, '[/\\]$', '', '')
let g:envstr = substitute(g:envstr, '[/\\]$', '', '')
if $CI != '' && stridx(g:envstr, '/private/') == 0
let g:envstr = g:envstr[8:]
endif
call assert_equal(expect, g:envstr)
finally
call job_stop(job)
unlet g:envstr
endtry
endfunc
function Ch_test_close_lambda(port)
@@ -1731,7 +1735,7 @@ endfunc
func s:test_list_args(cmd, out, remove_lf)
try
let g:out = ''
call job_start([s:python, '-c', a:cmd], {'callback': {ch, msg -> execute('let g:out .= msg')}, 'out_mode': 'raw'})
let job = job_start([s:python, '-c', a:cmd], {'callback': {ch, msg -> execute('let g:out .= msg')}, 'out_mode': 'raw'})
call WaitFor('"" != g:out')
if has('win32')
let g:out = substitute(g:out, '\r', '', 'g')
@@ -1741,6 +1745,7 @@ func s:test_list_args(cmd, out, remove_lf)
endif
call assert_equal(a:out, g:out)
finally
call job_stop(job)
unlet g:out
endtry
endfunc

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -362,6 +362,19 @@ func Test_equalalways_on_close()
set equalalways&
endfunc
func Test_win_screenpos()
call assert_equal(1, winnr('$'))
split
vsplit
10wincmd _
30wincmd |
call assert_equal([1, 1], win_screenpos(1))
call assert_equal([1, 32], win_screenpos(2))
call assert_equal([12, 1], win_screenpos(3))
call assert_equal([0, 0], win_screenpos(4))
only
endfunc
func Test_window_jump_tag()
help
/iccf

View File

@@ -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)
{

View File

@@ -771,6 +771,36 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1377,
/**/
1376,
/**/
1375,
/**/
1374,
/**/
1373,
/**/
1372,
/**/
1371,
/**/
1370,
/**/
1369,
/**/
1368,
/**/
1367,
/**/
1366,
/**/
1365,
/**/
1364,
/**/
1363,
/**/
1362,
/**/

View File

@@ -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 */

View File

@@ -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;