mirror of
https://github.com/vim/vim
synced 2025-07-16 17:22:00 +00:00
Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
7f88b65f6c | |||
a6d4849c71 | |||
fae8ed1fc8 | |||
a703aaee4d | |||
8e6a31df81 | |||
59eb016dff | |||
74240d3feb | |||
35c5e8155d | |||
f405c8fe85 | |||
620ca2da37 | |||
05684310a5 | |||
e4b78e2a42 | |||
3388d33457 |
@ -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()*
|
||||
@ -4169,6 +4173,7 @@ getbufinfo([{dict}])
|
||||
be specified in {dict}:
|
||||
buflisted include only listed buffers.
|
||||
bufloaded include only loaded buffers.
|
||||
bufmodified include only modified buffers.
|
||||
|
||||
Otherwise, {expr} specifies a particular buffer to return
|
||||
information for. For the use of {expr}, see |bufname()|
|
||||
@ -4679,9 +4684,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 zero.
|
||||
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.
|
||||
@ -4691,18 +4697,22 @@ getqflist([{what}]) *getqflist()*
|
||||
When "lines" is specified, all the other items except "efm"
|
||||
are ignored. The returned dictionary contains the entry
|
||||
"items" with the list of entries.
|
||||
In case of error processing {what}, an empty dictionary is
|
||||
returned.
|
||||
|
||||
The returned dictionary contains the following entries:
|
||||
context context information stored with |setqflist()|
|
||||
id quickfix list ID |quickfix-ID|
|
||||
idx index of the current entry in the list
|
||||
items quickfix list entries
|
||||
nr quickfix list number
|
||||
size number of entries in the quickfix list
|
||||
title quickfix list title text
|
||||
winid quickfix |window-ID| (if opened)
|
||||
context context information stored with |setqflist()|.
|
||||
If not present, set to "".
|
||||
id quickfix list ID |quickfix-ID|. If not
|
||||
present, set to 0.
|
||||
idx index of the current entry in the list. If not
|
||||
present, set to 0.
|
||||
items quickfix list entries. If not present, set to
|
||||
an empty list.
|
||||
nr quickfix list number. If not present, set to 0
|
||||
size number of entries in the quickfix list. If not
|
||||
present, set to 0.
|
||||
title quickfix list title text. If not present, set
|
||||
to "".
|
||||
winid quickfix |window-ID|. If not present, set to 0
|
||||
|
||||
Examples: >
|
||||
:echo getqflist({'all': 1})
|
||||
@ -8793,8 +8803,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.
|
||||
|
||||
|
@ -736,8 +736,8 @@ or 'pythonthreedll' option can be also used to specify the Python DLL.
|
||||
|
||||
The name of the DLL should match the Python version Vim was compiled with.
|
||||
Currently the name for Python 2 is "python27.dll", that is for Python 2.7.
|
||||
That is the default value for 'pythondll'. For Python 3 it is python35.dll
|
||||
(Python 3.5). To know for sure edit "gvim.exe" and search for
|
||||
That is the default value for 'pythondll'. For Python 3 it is python36.dll
|
||||
(Python 3.6). To know for sure edit "gvim.exe" and search for
|
||||
"python\d*.dll\c".
|
||||
|
||||
|
||||
|
@ -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*
|
||||
|
||||
|
@ -34,10 +34,11 @@ Contents:
|
||||
11. Building with Ruby support
|
||||
12. Building with Tcl support
|
||||
13. Building with Terminal support
|
||||
14. Windows 3.1
|
||||
15. MS-DOS
|
||||
14. Building with DirectX (DirectWrite) support
|
||||
15. Windows 3.1
|
||||
16. MS-DOS
|
||||
|
||||
16. Installing after building from sources
|
||||
17. Installing after building from sources
|
||||
|
||||
|
||||
The currently recommended way (that means it has been verified to work) is
|
||||
@ -438,18 +439,31 @@ You will end up with a Python-enabled, Win32 version. Enjoy!
|
||||
================================
|
||||
|
||||
For building with MSVC 2008 the "Windows Installer" from www.python.org
|
||||
works fine. Python 3.4 is recommended.
|
||||
works fine. Python 3.6 is recommended.
|
||||
|
||||
When building, you need to set the following variables at least:
|
||||
|
||||
PYTHON3: Where Python3 is installed. E.g. C:\Python34
|
||||
PYTHON3: Where Python3 is installed. E.g. C:\Python36
|
||||
DYNAMIC_PYTHON3: Whether dynamic linking is used. Usually, set to yes.
|
||||
PYTHON3_VER: Python3 version. E.g. 34 for Python 3.4.X.
|
||||
PYTHON3_VER: Python3 version. E.g. 36 for Python 3.6.X.
|
||||
|
||||
E.g. When using MSVC (as one line):
|
||||
|
||||
nmake -f Make_mvc.mak
|
||||
PYTHON3=C:\Python34 DYNAMIC_PYTHON3=yes PYTHON3_VER=34
|
||||
PYTHON3=C:\Python36 DYNAMIC_PYTHON3=yes PYTHON3_VER=36
|
||||
|
||||
|
||||
When using msys2 and link with Python3 bundled with msys2 (as one line):
|
||||
|
||||
mingw32-make -f Make_ming.mak PYTHON3=c:/msys64/mingw64
|
||||
PYTHON3_HOME=c:/msys64/mingw64
|
||||
PYTHON3INC=-Ic:/msys64/mingw64/include/python3.6m
|
||||
DYNAMIC_PYTHON3=yes
|
||||
PYTHON3_VER=36
|
||||
DYNAMIC_PYTHON3_DLL=libpython3.6m.dll
|
||||
STATIC_STDCPLUS=yes
|
||||
|
||||
(This is for 64-bit builds. For 32-bit builds, replace mingw64 with mingw32.)
|
||||
|
||||
|
||||
8. Building with Racket or MzScheme support
|
||||
@ -684,21 +698,33 @@ config.h and Ruby's DLL name. Here are the steps for working around them:
|
||||
There is no need to build whole Ruby, just config.h is needed.
|
||||
If you use 32-bit MSVC 2015, the config.h is generated in the
|
||||
.ext\include\i386-mswin32_140 directory.
|
||||
If you use 64-bit MSVC 2015, the config.h is generated in the
|
||||
.ext\include\x64-mswin64_140 directory.
|
||||
|
||||
3) Install the generated config.h.
|
||||
|
||||
For 32-bit version:
|
||||
|
||||
xcopy /s .ext\include C:\Ruby24\include\ruby-2.4.0
|
||||
|
||||
For 64-bit version:
|
||||
|
||||
xcopy /s .ext\include C:\Ruby24-x64\include\ruby-2.4.0
|
||||
|
||||
Note that 2.4.0 is Ruby API version of Ruby 2.4.X.
|
||||
You may need to close the console and reopen it to pick up the new $PATH.
|
||||
|
||||
4) Build Vim. Note that you need to adjust some variables (as one line):
|
||||
|
||||
For 32-bit version:
|
||||
|
||||
nmake -f Make_mvc.mak
|
||||
RUBY=C:\Ruby24 DYNAMIC_RUBY=yes RUBY_VER=24 RUBY_API_VER_LONG=2.4.0
|
||||
RUBY_MSVCRT_NAME=msvcrt
|
||||
WINVER=0x501
|
||||
|
||||
For 64-bit version, replace RUBY=C:\Ruby24 with RUBY=C:\Ruby24-x64.
|
||||
|
||||
If you set WINVER explicitly, it must be set to >=0x500, when building
|
||||
with Ruby 2.1 or later. (Default is 0x501.)
|
||||
When using this trick, you also need to set RUBY_MSVCRT_NAME to msvcrt
|
||||
@ -713,6 +739,7 @@ After you install RubyInstaller, just type this (as one line):
|
||||
RUBY=C:/Ruby24 DYNAMIC_RUBY=yes RUBY_VER=24 RUBY_API_VER_LONG=2.4.0
|
||||
WINVER=0x501
|
||||
|
||||
For 64-bit version, replace RUBY=C:/Ruby24 with RUBY=C:/Ruby24-x64.
|
||||
If you set WINVER explicitly, it must be set to >=0x500, when building with
|
||||
Ruby 2.1 or later. (Default is 0x501.)
|
||||
|
||||
@ -761,25 +788,59 @@ E.g. When using MSVC:
|
||||
|
||||
nmake -f Make_mvc.mak TERMINAL=yes
|
||||
|
||||
Or when using MinGW (as one line):
|
||||
Or when using MinGW:
|
||||
|
||||
mingw32-make -f Make_ming.mak TERMINAL=yes
|
||||
|
||||
|
||||
14. Windows 3.1x
|
||||
14. Building with DirectX (DirectWrite) support
|
||||
===============================================
|
||||
|
||||
Vim with DirectX (DirectWrite) support can be built with either MSVC or MinGW.
|
||||
This requires dwrite_2.h and some other header files which come with Windows
|
||||
SDK 8.1 or later (or MinGW-w64), if you want to enable color emoji support.
|
||||
This also requires MBYTE=yes which is enabled by default.
|
||||
|
||||
A) Using MSVC
|
||||
|
||||
If you use MSVC 2013 or later, Windows SDK 8.1 or later is used by default.
|
||||
You just need to specify DIRECTX=yes:
|
||||
|
||||
nmake -f Make_mvc.mak DIRECTX=yes
|
||||
|
||||
If you use MSVC 2012 or earlier, the required header files are not available
|
||||
by default. However, you can use the header files from newer SDKs with older
|
||||
compilers. E.g.:
|
||||
|
||||
set "INCLUDE=%INCLUDE%;C:\Program Files (x86)\Windows Kits\8.1\Include\um"
|
||||
nmake -f Make_mvc.mak DIRECTX=yes
|
||||
|
||||
If you don't need color emoji support, only dwrite.h is required. You can use
|
||||
older compilers (e.g. VC2010) without Windows SDK 8.1. E.g.:
|
||||
|
||||
nmake -f Make_mvc.mak DIRECTX=yes COLOR_EMOJI=no
|
||||
|
||||
B) Using MinGW-w64
|
||||
|
||||
Just set DIRECTX to yes:
|
||||
|
||||
mingw32-make -f Make_ming.mak DIRECTX=yes
|
||||
|
||||
|
||||
15. Windows 3.1x
|
||||
================
|
||||
|
||||
The Windows 3.1x support was removed in patch 7.4.1364.
|
||||
|
||||
|
||||
15. MS-DOS
|
||||
16. MS-DOS
|
||||
==========
|
||||
|
||||
The MS-DOS support was removed in patch 7.4.1399. Only very old Vim versions
|
||||
work on MS-DOS because of the limited amount of memory available.
|
||||
|
||||
|
||||
16. Installing after building from sources
|
||||
17. Installing after building from sources
|
||||
==========================================
|
||||
|
||||
[provided by Michael Soyka, updated by Ken Takata]
|
||||
|
@ -316,14 +316,14 @@ endif
|
||||
# Python3 interface:
|
||||
# PYTHON3=[Path to Python3 directory] (Set inside Make_cyg.mak or Make_ming.mak)
|
||||
# DYNAMIC_PYTHON3=yes (to load the Python3 DLL dynamically)
|
||||
# PYTHON3_VER=[Python3 version, eg 31, 32] (default is 35)
|
||||
# PYTHON3_VER=[Python3 version, eg 31, 32] (default is 36)
|
||||
ifdef PYTHON3
|
||||
ifndef DYNAMIC_PYTHON3
|
||||
DYNAMIC_PYTHON3=yes
|
||||
endif
|
||||
|
||||
ifndef PYTHON3_VER
|
||||
PYTHON3_VER=35
|
||||
PYTHON3_VER=36
|
||||
endif
|
||||
ifndef DYNAMIC_PYTHON3_DLL
|
||||
DYNAMIC_PYTHON3_DLL=python$(PYTHON3_VER).dll
|
||||
@ -588,7 +588,7 @@ endif
|
||||
ifeq ($(DIRECTX),yes)
|
||||
# Only allow DirectWrite for a GUI build.
|
||||
ifeq (yes, $(GUI))
|
||||
DEFINES += -DFEAT_DIRECTX -DDYNAMIC_DIRECTX
|
||||
DEFINES += -DFEAT_DIRECTX -DDYNAMIC_DIRECTX -DFEAT_DIRECTX_COLOR_EMOJI
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -25,12 +25,15 @@
|
||||
#
|
||||
# GUI interface: GUI=yes (default is no)
|
||||
#
|
||||
# GUI with DirectWrite(DirectX): DIRECTX=yes
|
||||
# (default is no, requires GUI=yes)
|
||||
# GUI with DirectWrite (DirectX): DIRECTX=yes
|
||||
# (default is no, requires GUI=yes and MBYTE=yes)
|
||||
#
|
||||
# Color emoji support: COLOR_EMOJI=yes
|
||||
# (default is yes if DIRECTX=yes, requires WinSDK 8.1 or later.)
|
||||
#
|
||||
# OLE interface: OLE=yes (usually with GUI=yes)
|
||||
#
|
||||
# Multibyte support: MBYTE=yes (default is no)
|
||||
# Multibyte support: MBYTE=yes (default is yes for NORMAL, BIG, HUGE)
|
||||
#
|
||||
# IME support: IME=yes (requires GUI=yes)
|
||||
# DYNAMIC_IME=[yes or no] (to load the imm32.dll dynamically, default
|
||||
@ -67,7 +70,7 @@
|
||||
# Python3 interface:
|
||||
# PYTHON3=[Path to Python3 directory]
|
||||
# DYNAMIC_PYTHON3=yes (to load the Python3 DLL dynamically)
|
||||
# PYTHON3_VER=[Python3 version, eg 30, 31] (default is 35)
|
||||
# PYTHON3_VER=[Python3 version, eg 30, 31] (default is 36)
|
||||
#
|
||||
# Ruby interface:
|
||||
# RUBY=[Path to Ruby directory]
|
||||
@ -419,9 +422,12 @@ NBDEBUG_SRC = nbdebug.c
|
||||
NETBEANS_LIB = WSock32.lib
|
||||
!endif
|
||||
|
||||
# DirectWrite(DirectX)
|
||||
# DirectWrite (DirectX)
|
||||
!if "$(DIRECTX)" == "yes"
|
||||
DIRECTX_DEFS = -DFEAT_DIRECTX -DDYNAMIC_DIRECTX
|
||||
!if "$(COLOR_EMOJI)" != "no"
|
||||
DIRECTX_DEFS = $(DIRECTX_DEFS) -DFEAT_DIRECTX_COLOR_EMOJI
|
||||
!endif
|
||||
DIRECTX_INCL = gui_dwrite.h
|
||||
DIRECTX_OBJ = $(OUTDIR)\gui_dwrite.obj
|
||||
!endif
|
||||
@ -906,7 +912,7 @@ PYTHON_LIB = $(PYTHON)\libs\python$(PYTHON_VER).lib
|
||||
# PYTHON3 interface
|
||||
!ifdef PYTHON3
|
||||
!ifndef PYTHON3_VER
|
||||
PYTHON3_VER = 35
|
||||
PYTHON3_VER = 36
|
||||
!endif
|
||||
!message Python3 requested (version $(PYTHON3_VER)) - root dir is "$(PYTHON3)"
|
||||
!if "$(DYNAMIC_PYTHON3)" == "yes"
|
||||
|
@ -2101,7 +2101,6 @@ run_message_test: $(MESSAGE_TEST_TARGET)
|
||||
# These do not depend on the executable, compile it when needed.
|
||||
test1 \
|
||||
test_eval \
|
||||
test_wordcount \
|
||||
test3 test11 test14 test15 test17 \
|
||||
test29 test30 test36 test37 test39 \
|
||||
test42 test44 test48 test49 \
|
||||
@ -2296,6 +2295,7 @@ test_arglist \
|
||||
test_window_cmd \
|
||||
test_window_id \
|
||||
test_windows_home \
|
||||
test_wordcount \
|
||||
test_writefile \
|
||||
test_alot_latin \
|
||||
test_alot_utf8 \
|
||||
|
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
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
:: command to build big Vim with OLE, Lua, Perl, Python, Racket, Ruby and Tcl
|
||||
SET VCDIR="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\"
|
||||
SET TOOLDIR=E:\
|
||||
%VCDIR%nmake -f Make_mvc.mak GUI=yes OLE=yes LUA=%TOOLDIR%lua53 DYNAMIC_LUA=yes LUA_VER=53 PERL=%TOOLDIR%perl524 DYNAMIC_PERL=yes PERL_VER=524 PYTHON=%TOOLDIR%python27 DYNAMIC_PYTHON=yes PYTHON_VER=27 PYTHON3=%TOOLDIR%python35 DYNAMIC_PYTHON3=yes PYTHON3_VER=35 MZSCHEME=%TOOLDIR%Racket DYNAMIC_MZSCHEME=yes MZSCHEME_VER=3m_a36fs8 RUBY=%TOOLDIR%ruby24 DYNAMIC_RUBY=yes RUBY_VER=24 RUBY_API_VER_LONG=2.4.0 RUBY_MSVCRT_NAME=msvcrt TCL=%TOOLDIR%ActiveTcl TCL_VER=86 TCL_VER_LONG=8.6 DYNAMIC_TCL=yes TCL_DLL=tcl86t.dll %1 IME=yes CSCOPE=yes DIRECTX=yes
|
||||
%VCDIR%nmake -f Make_mvc.mak GUI=yes OLE=yes LUA=%TOOLDIR%lua53 DYNAMIC_LUA=yes LUA_VER=53 PERL=%TOOLDIR%perl524 DYNAMIC_PERL=yes PERL_VER=524 PYTHON=%TOOLDIR%python27 DYNAMIC_PYTHON=yes PYTHON_VER=27 PYTHON3=%TOOLDIR%python36 DYNAMIC_PYTHON3=yes PYTHON3_VER=36 MZSCHEME=%TOOLDIR%Racket DYNAMIC_MZSCHEME=yes MZSCHEME_VER=3m_a36fs8 RUBY=%TOOLDIR%ruby24 DYNAMIC_RUBY=yes RUBY_VER=24 RUBY_API_VER_LONG=2.4.0 RUBY_MSVCRT_NAME=msvcrt TCL=%TOOLDIR%ActiveTcl TCL_VER=86 TCL_VER_LONG=8.6 DYNAMIC_TCL=yes TCL_DLL=tcl86t.dll %1 IME=yes CSCOPE=yes DIRECTX=yes
|
||||
|
||||
|
@ -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
|
||||
|
@ -4137,6 +4137,7 @@ f_getbufinfo(typval_T *argvars, typval_T *rettv)
|
||||
int filtered = FALSE;
|
||||
int sel_buflisted = FALSE;
|
||||
int sel_bufloaded = FALSE;
|
||||
int sel_bufmodified = FALSE;
|
||||
|
||||
if (rettv_list_alloc(rettv) != OK)
|
||||
return;
|
||||
@ -4159,6 +4160,10 @@ f_getbufinfo(typval_T *argvars, typval_T *rettv)
|
||||
di = dict_find(sel_d, (char_u *)"bufloaded", -1);
|
||||
if (di != NULL && get_tv_number(&di->di_tv))
|
||||
sel_bufloaded = TRUE;
|
||||
|
||||
di = dict_find(sel_d, (char_u *)"bufmodified", -1);
|
||||
if (di != NULL && get_tv_number(&di->di_tv))
|
||||
sel_bufmodified = TRUE;
|
||||
}
|
||||
}
|
||||
else if (argvars[0].v_type != VAR_UNKNOWN)
|
||||
@ -4178,7 +4183,8 @@ f_getbufinfo(typval_T *argvars, typval_T *rettv)
|
||||
if (argbuf != NULL && argbuf != buf)
|
||||
continue;
|
||||
if (filtered && ((sel_bufloaded && buf->b_ml.ml_mfp == NULL)
|
||||
|| (sel_buflisted && !buf->b_p_bl)))
|
||||
|| (sel_buflisted && !buf->b_p_bl)
|
||||
|| (sel_bufmodified && !buf->b_changed)))
|
||||
continue;
|
||||
|
||||
d = get_buffer_info(buf);
|
||||
|
@ -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)
|
||||
|
@ -38,7 +38,11 @@
|
||||
# define _Outptr_
|
||||
#endif
|
||||
|
||||
#include <dwrite_2.h>
|
||||
#ifdef FEAT_DIRECTX_COLOR_EMOJI
|
||||
# include <dwrite_2.h>
|
||||
#else
|
||||
# include <dwrite.h>
|
||||
#endif
|
||||
|
||||
#include "gui_dwrite.h"
|
||||
|
||||
@ -284,7 +288,9 @@ struct DWriteContext {
|
||||
ID2D1SolidColorBrush *mBrush;
|
||||
|
||||
IDWriteFactory *mDWriteFactory;
|
||||
#ifdef FEAT_DIRECTX_COLOR_EMOJI
|
||||
IDWriteFactory2 *mDWriteFactory2;
|
||||
#endif
|
||||
|
||||
IDWriteGdiInterop *mGdiInterop;
|
||||
IDWriteRenderingParams *mRenderingParams;
|
||||
@ -481,6 +487,7 @@ public:
|
||||
AdjustedGlyphRun adjustedGlyphRun(glyphRun, context->cellWidth,
|
||||
context->offsetX);
|
||||
|
||||
#ifdef FEAT_DIRECTX_COLOR_EMOJI
|
||||
if (pDWC_->mDWriteFactory2 != NULL)
|
||||
{
|
||||
IDWriteColorGlyphRunEnumerator *enumerator = NULL;
|
||||
@ -517,6 +524,7 @@ public:
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Draw by IDWriteFactory (without color emoji)
|
||||
pDWC_->mRT->DrawGlyphRun(
|
||||
@ -589,7 +597,9 @@ DWriteContext::DWriteContext() :
|
||||
mGDIRT(NULL),
|
||||
mBrush(NULL),
|
||||
mDWriteFactory(NULL),
|
||||
#ifdef FEAT_DIRECTX_COLOR_EMOJI
|
||||
mDWriteFactory2(NULL),
|
||||
#endif
|
||||
mGdiInterop(NULL),
|
||||
mRenderingParams(NULL),
|
||||
mFontCache(8),
|
||||
@ -618,6 +628,7 @@ DWriteContext::DWriteContext() :
|
||||
mDWriteFactory);
|
||||
}
|
||||
|
||||
#ifdef FEAT_DIRECTX_COLOR_EMOJI
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
DWriteCreateFactory(
|
||||
@ -626,6 +637,7 @@ DWriteContext::DWriteContext() :
|
||||
reinterpret_cast<IUnknown**>(&mDWriteFactory2));
|
||||
_RPT1(_CRT_WARN, "IDWriteFactory2: %s\n", SUCCEEDED(hr) ? "available" : "not available");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
@ -647,7 +659,9 @@ DWriteContext::~DWriteContext()
|
||||
SafeRelease(&mRenderingParams);
|
||||
SafeRelease(&mGdiInterop);
|
||||
SafeRelease(&mDWriteFactory);
|
||||
#ifdef FEAT_DIRECTX_COLOR_EMOJI
|
||||
SafeRelease(&mDWriteFactory2);
|
||||
#endif
|
||||
SafeRelease(&mBrush);
|
||||
SafeRelease(&mGDIRT);
|
||||
SafeRelease(&mRT);
|
||||
@ -995,7 +1009,7 @@ DWriteContext::DrawText(const WCHAR *text, int len,
|
||||
|
||||
TextRenderer renderer(this);
|
||||
TextRendererContext context = { color, FLOAT(cellWidth), 0.0f };
|
||||
textLayout->Draw(&context, &renderer, FLOAT(x), FLOAT(y));
|
||||
textLayout->Draw(&context, &renderer, FLOAT(x), FLOAT(y) - 0.5f);
|
||||
}
|
||||
|
||||
SafeRelease(&textLayout);
|
||||
|
@ -30,11 +30,14 @@
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
# ifndef FEAT_MBYTE
|
||||
# error FEAT_MBYTE is required for FEAT_DIRECTX.
|
||||
# endif
|
||||
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)
|
||||
# define IS_ENABLE_DIRECTX() (s_directx_enabled && s_dwc != NULL && enc_utf8)
|
||||
static int directx_enabled(void);
|
||||
static void directx_binddc(void);
|
||||
#endif
|
||||
@ -47,7 +50,7 @@ static int gui_mswin_get_menu_height(int fix_window);
|
||||
int
|
||||
gui_mch_set_rendering_options(char_u *s)
|
||||
{
|
||||
#ifdef FEAT_DIRECTX
|
||||
# ifdef FEAT_DIRECTX
|
||||
char_u *p, *q;
|
||||
|
||||
int dx_enable = 0;
|
||||
@ -159,9 +162,9 @@ gui_mch_set_rendering_options(char_u *s)
|
||||
s_directx_scrlines = dx_scrlines;
|
||||
|
||||
return OK;
|
||||
#else
|
||||
# else
|
||||
return FAIL;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3140,7 +3143,8 @@ gui_mch_delete_lines(
|
||||
{
|
||||
if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines)
|
||||
{
|
||||
RedrawWindow(s_textArea, &rc, NULL, RDW_INVALIDATE);
|
||||
gui_redraw(rc.left, rc.top,
|
||||
rc.right - rc.left + 1, rc.bottom - rc.top + 1);
|
||||
use_redraw = 1;
|
||||
}
|
||||
else
|
||||
@ -3152,9 +3156,9 @@ gui_mch_delete_lines(
|
||||
intel_gpu_workaround();
|
||||
ScrollWindowEx(s_textArea, 0, -num_lines * gui.char_height,
|
||||
&rc, &rc, NULL, NULL, get_scroll_flags());
|
||||
UpdateWindow(s_textArea);
|
||||
}
|
||||
|
||||
UpdateWindow(s_textArea);
|
||||
/* This seems to be required to avoid the cursor disappearing when
|
||||
* scrolling such that the cursor ends up in the top-left character on
|
||||
* the screen... But why? (Webb) */
|
||||
@ -3190,7 +3194,8 @@ gui_mch_insert_lines(
|
||||
{
|
||||
if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines)
|
||||
{
|
||||
RedrawWindow(s_textArea, &rc, NULL, RDW_INVALIDATE);
|
||||
gui_redraw(rc.left, rc.top,
|
||||
rc.right - rc.left + 1, rc.bottom - rc.top + 1);
|
||||
use_redraw = 1;
|
||||
}
|
||||
else
|
||||
@ -3204,10 +3209,9 @@ gui_mch_insert_lines(
|
||||
* 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);
|
||||
}
|
||||
|
||||
UpdateWindow(s_textArea);
|
||||
|
||||
gui_clear_block(row, gui.scroll_region_left,
|
||||
row + num_lines - 1, gui.scroll_region_right);
|
||||
}
|
||||
@ -6401,13 +6405,13 @@ gui_mch_draw_string(
|
||||
if (text[n] >= 0x80)
|
||||
break;
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
# if defined(FEAT_DIRECTX)
|
||||
/* Quick hack to enable DirectWrite. To use DirectWrite (antialias), it is
|
||||
* required that unicode drawing routine, currently. So this forces it
|
||||
* enabled. */
|
||||
if (enc_utf8 && IS_ENABLE_DIRECTX())
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
n = 0; /* Keep n < len, to enter block for unicode. */
|
||||
#endif
|
||||
# endif
|
||||
|
||||
/* Check if the Unicode buffer exists and is big enough. Create it
|
||||
* with the same length as the multi-byte string, the number of wide
|
||||
@ -6480,7 +6484,7 @@ gui_mch_draw_string(
|
||||
i += utf_ptr2len_len(text + i, len - i);
|
||||
++clen;
|
||||
}
|
||||
#if defined(FEAT_DIRECTX)
|
||||
# if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
{
|
||||
/* Add one to "cells" for italics. */
|
||||
@ -6490,7 +6494,7 @@ gui_mch_draw_string(
|
||||
foptions, pcliprect, unicodepdy);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
# endif
|
||||
ExtTextOutW(s_hdc, TEXT_X(col), TEXT_Y(row),
|
||||
foptions, pcliprect, unicodebuf, wlen, unicodepdy);
|
||||
len = cells; /* used for underlining */
|
||||
|
@ -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 : */
|
||||
|
134
src/quickfix.c
134
src/quickfix.c
@ -4863,70 +4863,24 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
if (wp != NULL)
|
||||
qi = GET_LOC_LIST(wp);
|
||||
|
||||
/* List is not present or is empty */
|
||||
if (qi == NULL || qi->qf_listcount == 0)
|
||||
{
|
||||
/* If querying for the size of the list, return 0 */
|
||||
if (((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
|
||||
&& (di->di_tv.v_type == VAR_STRING)
|
||||
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0))
|
||||
return dict_add_nr_str(retdict, "nr", 0, NULL);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
qf_idx = qi->qf_curlist; /* default is the current list */
|
||||
if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
|
||||
{
|
||||
/* Use the specified quickfix/location list */
|
||||
if (di->di_tv.v_type == VAR_NUMBER)
|
||||
{
|
||||
/* for zero use the current list */
|
||||
if (di->di_tv.vval.v_number != 0)
|
||||
{
|
||||
qf_idx = di->di_tv.vval.v_number - 1;
|
||||
if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
else if ((di->di_tv.v_type == VAR_STRING)
|
||||
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0))
|
||||
/* Get the last quickfix list number */
|
||||
qf_idx = qi->qf_listcount - 1;
|
||||
else
|
||||
return FAIL;
|
||||
flags |= QF_GETLIST_NR;
|
||||
}
|
||||
|
||||
if ((di = dict_find(what, (char_u *)"id", -1)) != NULL)
|
||||
{
|
||||
/* Look for a list with the specified id */
|
||||
if (di->di_tv.v_type == VAR_NUMBER)
|
||||
{
|
||||
/* For zero, use the current list or the list specifed by 'nr' */
|
||||
if (di->di_tv.vval.v_number != 0)
|
||||
{
|
||||
qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number);
|
||||
if (qf_idx == -1)
|
||||
return FAIL; /* List not found */
|
||||
}
|
||||
flags |= QF_GETLIST_ID;
|
||||
}
|
||||
else
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (dict_find(what, (char_u *)"all", -1) != NULL)
|
||||
flags |= QF_GETLIST_ALL;
|
||||
|
||||
if (dict_find(what, (char_u *)"title", -1) != NULL)
|
||||
flags |= QF_GETLIST_TITLE;
|
||||
|
||||
if (dict_find(what, (char_u *)"nr", -1) != NULL)
|
||||
flags |= QF_GETLIST_NR;
|
||||
|
||||
if (dict_find(what, (char_u *)"winid", -1) != NULL)
|
||||
flags |= QF_GETLIST_WINID;
|
||||
|
||||
if (dict_find(what, (char_u *)"context", -1) != NULL)
|
||||
flags |= QF_GETLIST_CONTEXT;
|
||||
|
||||
if (dict_find(what, (char_u *)"id", -1) != NULL)
|
||||
flags |= QF_GETLIST_ID;
|
||||
|
||||
if (dict_find(what, (char_u *)"items", -1) != NULL)
|
||||
flags |= QF_GETLIST_ITEMS;
|
||||
|
||||
@ -4936,6 +4890,77 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
if (dict_find(what, (char_u *)"size", -1) != NULL)
|
||||
flags |= QF_GETLIST_SIZE;
|
||||
|
||||
if (qi != NULL && qi->qf_listcount != 0)
|
||||
{
|
||||
qf_idx = qi->qf_curlist; /* default is the current list */
|
||||
if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
|
||||
{
|
||||
/* Use the specified quickfix/location list */
|
||||
if (di->di_tv.v_type == VAR_NUMBER)
|
||||
{
|
||||
/* for zero use the current list */
|
||||
if (di->di_tv.vval.v_number != 0)
|
||||
{
|
||||
qf_idx = di->di_tv.vval.v_number - 1;
|
||||
if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
|
||||
qf_idx = -1;
|
||||
}
|
||||
}
|
||||
else if ((di->di_tv.v_type == VAR_STRING)
|
||||
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0))
|
||||
/* Get the last quickfix list number */
|
||||
qf_idx = qi->qf_listcount - 1;
|
||||
else
|
||||
qf_idx = -1;
|
||||
flags |= QF_GETLIST_NR;
|
||||
}
|
||||
|
||||
if ((di = dict_find(what, (char_u *)"id", -1)) != NULL)
|
||||
{
|
||||
/* Look for a list with the specified id */
|
||||
if (di->di_tv.v_type == VAR_NUMBER)
|
||||
{
|
||||
/*
|
||||
* For zero, use the current list or the list specifed by 'nr'
|
||||
*/
|
||||
if (di->di_tv.vval.v_number != 0)
|
||||
qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number);
|
||||
flags |= QF_GETLIST_ID;
|
||||
}
|
||||
else
|
||||
qf_idx = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* List is not present or is empty */
|
||||
if (qi == NULL || qi->qf_listcount == 0 || qf_idx == -1)
|
||||
{
|
||||
if (flags & QF_GETLIST_TITLE)
|
||||
status = dict_add_nr_str(retdict, "title", 0L, (char_u *)"");
|
||||
if ((status == OK) && (flags & QF_GETLIST_ITEMS))
|
||||
{
|
||||
list_T *l = list_alloc();
|
||||
if (l != NULL)
|
||||
status = dict_add_list(retdict, "items", l);
|
||||
else
|
||||
status = FAIL;
|
||||
}
|
||||
if ((status == OK) && (flags & QF_GETLIST_NR))
|
||||
status = dict_add_nr_str(retdict, "nr", 0L, NULL);
|
||||
if ((status == OK) && (flags & QF_GETLIST_WINID))
|
||||
status = dict_add_nr_str(retdict, "winid", 0L, NULL);
|
||||
if ((status == OK) && (flags & QF_GETLIST_CONTEXT))
|
||||
status = dict_add_nr_str(retdict, "context", 0L, (char_u *)"");
|
||||
if ((status == OK) && (flags & QF_GETLIST_ID))
|
||||
status = dict_add_nr_str(retdict, "id", 0L, NULL);
|
||||
if ((status == OK) && (flags & QF_GETLIST_IDX))
|
||||
status = dict_add_nr_str(retdict, "idx", 0L, NULL);
|
||||
if ((status == OK) && (flags & QF_GETLIST_SIZE))
|
||||
status = dict_add_nr_str(retdict, "size", 0L, NULL);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
if (flags & QF_GETLIST_TITLE)
|
||||
{
|
||||
char_u *t;
|
||||
@ -4949,9 +4974,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))
|
||||
{
|
||||
|
24
src/screen.c
24
src/screen.c
@ -8317,15 +8317,29 @@ screen_char(unsigned off, int row, int col)
|
||||
{
|
||||
char_u buf[MB_MAXBYTES + 1];
|
||||
|
||||
/* Convert UTF-8 character to bytes and write it. */
|
||||
|
||||
buf[utfc_char2bytes(off, buf)] = NUL;
|
||||
|
||||
out_str(buf);
|
||||
if (utf_ambiguous_width(ScreenLinesUC[off]))
|
||||
{
|
||||
if (*p_ambw == 'd'
|
||||
# ifdef FEAT_GUI
|
||||
&& !gui.in_use
|
||||
# endif
|
||||
)
|
||||
{
|
||||
/* Clear the two screen cells. If the character is actually
|
||||
* single width it won't change the second cell. */
|
||||
out_str((char_u *)" ");
|
||||
term_windgoto(row, col);
|
||||
}
|
||||
/* not sure where the cursor is after drawing the ambiguous width
|
||||
* character */
|
||||
screen_cur_col = 9999;
|
||||
}
|
||||
else if (utf_char2cells(ScreenLinesUC[off]) > 1)
|
||||
++screen_cur_col;
|
||||
|
||||
/* Convert the UTF-8 character to bytes and write it. */
|
||||
buf[utfc_char2bytes(off, buf)] = NUL;
|
||||
out_str(buf);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -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);
|
||||
|
@ -31,8 +31,7 @@ SCRIPTS_ALL = \
|
||||
test95.out \
|
||||
test99.out \
|
||||
test108.out \
|
||||
test_eval.out \
|
||||
test_wordcount.out
|
||||
test_eval.out
|
||||
|
||||
|
||||
# Tests that run on most systems, but not on Amiga.
|
||||
@ -183,6 +182,7 @@ NEW_TESTS = test_arabic.res \
|
||||
test_winbuf_close.res \
|
||||
test_window_id.res \
|
||||
test_windows_home.res \
|
||||
test_wordcount.res \
|
||||
test_writefile.res \
|
||||
test_alot_latin.res \
|
||||
test_alot_utf8.res \
|
||||
|
@ -63,7 +63,7 @@ win32: fixff nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_WIN32) newtests
|
||||
fixff:
|
||||
-$(VIMPROG) -u dos.vim $(NO_INITS) "+argdo set ff=dos|upd" +q *.in *.ok
|
||||
-$(VIMPROG) -u dos.vim $(NO_INITS) "+argdo set ff=unix|upd" +q \
|
||||
dotest.in test_wordcount.ok
|
||||
dotest.in
|
||||
|
||||
clean:
|
||||
-@if exist *.out $(DEL) *.out
|
||||
|
@ -81,13 +81,7 @@ SCRIPT = test1.out test3.out \
|
||||
test64.out test69.out \
|
||||
test72.out test77a.out test88.out \
|
||||
test94.out test95.out test99.out test108.out \
|
||||
test_autocmd_option.out \
|
||||
test_breakindent.out \
|
||||
test_eval.out \
|
||||
test_listlbr.out \
|
||||
test_listlbr_utf8.out \
|
||||
test_utf8.out \
|
||||
test_wordcount.out
|
||||
test_eval.out
|
||||
|
||||
# Known problems:
|
||||
# test17: ?
|
||||
|
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
|
@ -2,10 +2,16 @@
|
||||
|
||||
set runtimepath=./sautest
|
||||
|
||||
func! Test_autoload_dict_func()
|
||||
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
|
||||
|
@ -20,6 +20,13 @@ function Test_getbufwintabinfo()
|
||||
call assert_equal('vim', l[0].variables.editor)
|
||||
call assert_notequal(-1, index(l[0].windows, bufwinid('%')))
|
||||
|
||||
" Test for getbufinfo() with 'bufmodified'
|
||||
call assert_equal(0, len(getbufinfo({'bufmodified' : 1})))
|
||||
call setbufline('Xtestfile1', 1, ["Line1"])
|
||||
let l = getbufinfo({'bufmodified' : 1})
|
||||
call assert_equal(1, len(l))
|
||||
call assert_equal(bufnr('Xtestfile1'), l[0].bufnr)
|
||||
|
||||
if has('signs')
|
||||
call append(0, ['Linux', 'Windows', 'Mac'])
|
||||
sign define Mark text=>> texthl=Search
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -1797,8 +1833,8 @@ func Xproperty_tests(cchar)
|
||||
call assert_equal(-1, s)
|
||||
|
||||
call assert_equal({}, g:Xgetlist({'abc':1}))
|
||||
call assert_equal({}, g:Xgetlist({'nr':99, 'title':1}))
|
||||
call assert_equal({}, g:Xgetlist({'nr':[], 'title':1}))
|
||||
call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
|
||||
call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
|
||||
|
||||
if a:cchar == 'l'
|
||||
call assert_equal({}, getloclist(99, {'title': 1}))
|
||||
@ -1834,7 +1870,7 @@ func Xproperty_tests(cchar)
|
||||
call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
|
||||
only
|
||||
call setloclist(0, [], 'f')
|
||||
call assert_equal({}, getloclist(0, {'context':1}))
|
||||
call assert_equal('', getloclist(0, {'context':1}).context)
|
||||
endif
|
||||
|
||||
" Test for changing the context of previous quickfix lists
|
||||
@ -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')
|
||||
@ -2347,8 +2383,8 @@ func XsizeTests(cchar)
|
||||
|
||||
call g:Xsetlist([], 'f')
|
||||
call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
|
||||
call assert_equal(1, len(g:Xgetlist({'nr':'$', 'all':1})))
|
||||
call assert_equal(0, len(g:Xgetlist({'nr':0})))
|
||||
call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
|
||||
call assert_equal(0, g:Xgetlist({'nr':0}).nr)
|
||||
|
||||
Xexpr "File1:10:Line1"
|
||||
Xexpr "File2:20:Line2"
|
||||
@ -2718,7 +2754,7 @@ func Xqfid_tests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
call g:Xsetlist([], 'f')
|
||||
call assert_equal({}, g:Xgetlist({'id':0}))
|
||||
call assert_equal(0, g:Xgetlist({'id':0}).id)
|
||||
Xexpr ''
|
||||
let start_id = g:Xgetlist({'id' : 0}).id
|
||||
Xexpr '' | Xexpr ''
|
||||
@ -2726,10 +2762,10 @@ func Xqfid_tests(cchar)
|
||||
call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
|
||||
call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
|
||||
call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
|
||||
call assert_equal({}, g:Xgetlist({'id':0, 'nr':99}))
|
||||
call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
|
||||
call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
|
||||
call assert_equal({}, g:Xgetlist({'id':99, 'nr':0}))
|
||||
call assert_equal({}, g:Xgetlist({'id':"abc", 'nr':0}))
|
||||
call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
|
||||
call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
|
||||
|
||||
call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
|
||||
call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
|
||||
@ -2740,10 +2776,166 @@ func Xqfid_tests(cchar)
|
||||
|
||||
let qfid = g:Xgetlist({'id':0, 'nr':0})
|
||||
call g:Xsetlist([], 'f')
|
||||
call assert_equal({}, g:Xgetlist({'id':qfid, 'nr':0}))
|
||||
call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
|
||||
endfunc
|
||||
|
||||
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
|
||||
|
||||
" Tests for the getqflist() and getloclist() functions when the list is not
|
||||
" present or is empty
|
||||
func Xgetlist_empty_tests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
" Empty quickfix stack
|
||||
call g:Xsetlist([], 'f')
|
||||
call assert_equal('', g:Xgetlist({'context' : 0}).context)
|
||||
call assert_equal(0, g:Xgetlist({'id' : 0}).id)
|
||||
call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
|
||||
call assert_equal([], g:Xgetlist({'items' : 0}).items)
|
||||
call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
|
||||
call assert_equal(0, g:Xgetlist({'size' : 0}).size)
|
||||
call assert_equal('', g:Xgetlist({'title' : 0}).title)
|
||||
call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
|
||||
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0}, g:Xgetlist({'all' : 0}))
|
||||
|
||||
" Empty quickfix list
|
||||
Xexpr ""
|
||||
call assert_equal('', g:Xgetlist({'context' : 0}).context)
|
||||
call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
|
||||
call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
|
||||
call assert_equal([], g:Xgetlist({'items' : 0}).items)
|
||||
call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
|
||||
call assert_equal(0, g:Xgetlist({'size' : 0}).size)
|
||||
call assert_notequal('', g:Xgetlist({'title' : 0}).title)
|
||||
call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
|
||||
|
||||
let qfid = g:Xgetlist({'id' : 0}).id
|
||||
call g:Xsetlist([], 'f')
|
||||
|
||||
" Non-existing quickfix identifier
|
||||
call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
|
||||
call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
|
||||
call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
|
||||
call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
|
||||
call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
|
||||
call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
|
||||
call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
|
||||
call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
|
||||
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
|
||||
|
||||
" Non-existing quickfix list number
|
||||
call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
|
||||
call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
|
||||
call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
|
||||
call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
|
||||
call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
|
||||
call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
|
||||
call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
|
||||
call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
|
||||
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0}, g:Xgetlist({'nr' : 5, 'all' : 0}))
|
||||
endfunc
|
||||
|
||||
func Test_getqflist()
|
||||
call Xgetlist_empty_tests('c')
|
||||
call Xgetlist_empty_tests('l')
|
||||
endfunc
|
||||
|
@ -1,126 +0,0 @@
|
||||
Test for wordcount() function
|
||||
|
||||
STARTTEST
|
||||
:so small.vim
|
||||
:so mbyte.vim
|
||||
:set enc=utf8
|
||||
:set selection=inclusive fileformat=unix fileformats=unix
|
||||
:new
|
||||
:fu DoRecordWin(...)
|
||||
: wincmd k
|
||||
: if exists("a:1")
|
||||
: call cursor(a:1)
|
||||
: endif
|
||||
: let result=[]
|
||||
: call add(result, g:test)
|
||||
: call add(result, getline(1, '$'))
|
||||
: call add(result, wordcount())
|
||||
: wincmd j
|
||||
: return result
|
||||
:endfu
|
||||
:fu PutInWindow(args)
|
||||
: wincmd k
|
||||
: %d _
|
||||
: call append(1, a:args)
|
||||
: wincmd j
|
||||
:endfu
|
||||
:fu Log()
|
||||
: $put ='----'
|
||||
: $put =remove(g:log,0)
|
||||
: $put =string(g:log)
|
||||
:endfu
|
||||
:fu! STL()
|
||||
: if mode() =~? 'V'
|
||||
: let g:visual_stat=wordcount()
|
||||
: endif
|
||||
: return string(wordcount())
|
||||
:endfu
|
||||
:let g:test="Test 1: empty window"
|
||||
:let log=DoRecordWin()
|
||||
:call Log()
|
||||
:"
|
||||
:let g:test="Test 2: some words, cursor at start"
|
||||
:call PutInWindow('one two three')
|
||||
:let log=DoRecordWin([1,1,0])
|
||||
:call Log()
|
||||
:"
|
||||
:let g:test="Test 3: some words, cursor at end"
|
||||
:call PutInWindow('one two three')
|
||||
:let log=DoRecordWin([2,99,0])
|
||||
:call Log()
|
||||
:"
|
||||
:let g:test="Test 4: some words, cursor at end, ve=all"
|
||||
:set ve=all
|
||||
:call PutInWindow('one two three')
|
||||
:let log=DoRecordWin([2,99,0])
|
||||
:call Log()
|
||||
:set ve=
|
||||
:"
|
||||
:let g:test="Test 5: several lines with words"
|
||||
:call PutInWindow(['one two three', 'one two three', 'one two three'])
|
||||
:let log=DoRecordWin([4,99,0])
|
||||
:call Log()
|
||||
:"
|
||||
:let g:test="Test 6: one line with BOM set"
|
||||
:call PutInWindow('one two three')
|
||||
:wincmd k
|
||||
:set bomb
|
||||
:w! Xtest
|
||||
:wincmd j
|
||||
:let log=DoRecordWin([2,99,0])
|
||||
:call Log()
|
||||
:wincmd k
|
||||
:set nobomb
|
||||
:w!
|
||||
:wincmd j
|
||||
:"
|
||||
:let g:test="Test 7: one line with multibyte words"
|
||||
:call PutInWindow(['Äne M¤ne Müh'])
|
||||
:let log=DoRecordWin([2,99,0])
|
||||
:call Log()
|
||||
:"
|
||||
:let g:test="Test 8: several lines with multibyte words"
|
||||
:call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])
|
||||
:let log=DoRecordWin([3,99,0])
|
||||
:call Log()
|
||||
:"
|
||||
:let g:test="Test 9: visual mode, complete buffer"
|
||||
:call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])
|
||||
:wincmd k
|
||||
:set ls=2 stl=%{STL()}
|
||||
:" start visual mode quickly and select complete buffer
|
||||
:0
|
||||
V2jy
|
||||
:set stl= ls=1
|
||||
:let log=DoRecordWin([3,99,0])
|
||||
:let log[2]=g:visual_stat
|
||||
:call Log()
|
||||
:"
|
||||
:let g:test="Test 10: visual mode (empty)"
|
||||
:call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])
|
||||
:wincmd k
|
||||
:set ls=2 stl=%{STL()}
|
||||
:" start visual mode quickly and select complete buffer
|
||||
:0
|
||||
v$y
|
||||
:set stl= ls=1
|
||||
:let log=DoRecordWin([3,99,0])
|
||||
:let log[2]=g:visual_stat
|
||||
:call Log()
|
||||
:"
|
||||
:let g:test="Test 11: visual mode, single line"
|
||||
:call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])
|
||||
:wincmd k
|
||||
:set ls=2 stl=%{STL()}
|
||||
:" start visual mode quickly and select complete buffer
|
||||
:2
|
||||
0v$y
|
||||
:set stl= ls=1
|
||||
:let log=DoRecordWin([3,99,0])
|
||||
:let log[2]=g:visual_stat
|
||||
:call Log()
|
||||
:"
|
||||
:/^RESULT test/,$w! test.out
|
||||
:qa!
|
||||
ENDTEST
|
||||
RESULT test:
|
@ -1,34 +0,0 @@
|
||||
RESULT test:
|
||||
----
|
||||
Test 1: empty window
|
||||
[[''], {'chars': 0, 'cursor_chars': 0, 'words': 0, 'cursor_words': 0, 'bytes': 0, 'cursor_bytes': 0}]
|
||||
----
|
||||
Test 2: some words, cursor at start
|
||||
[['', 'one two three'], {'chars': 15, 'cursor_chars': 1, 'words': 3, 'cursor_words': 0, 'bytes': 15, 'cursor_bytes': 1}]
|
||||
----
|
||||
Test 3: some words, cursor at end
|
||||
[['', 'one two three'], {'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3, 'bytes': 15, 'cursor_bytes': 14}]
|
||||
----
|
||||
Test 4: some words, cursor at end, ve=all
|
||||
[['', 'one two three'], {'chars': 15, 'cursor_chars': 15, 'words': 3, 'cursor_words': 3, 'bytes': 15, 'cursor_bytes': 15}]
|
||||
----
|
||||
Test 5: several lines with words
|
||||
[['', 'one two three', 'one two three', 'one two three'], {'chars': 43, 'cursor_chars': 42, 'words': 9, 'cursor_words': 9, 'bytes': 43, 'cursor_bytes': 42}]
|
||||
----
|
||||
Test 6: one line with BOM set
|
||||
[['', 'one two three'], {'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3, 'bytes': 18, 'cursor_bytes': 14}]
|
||||
----
|
||||
Test 7: one line with multibyte words
|
||||
[['', 'Äne M¤ne Müh'], {'chars': 14, 'cursor_chars': 13, 'words': 3, 'cursor_words': 3, 'bytes': 17, 'cursor_bytes': 16}]
|
||||
----
|
||||
Test 8: several lines with multibyte words
|
||||
[['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'cursor_chars': 31, 'words': 7, 'cursor_words': 7, 'bytes': 36, 'cursor_bytes': 35}]
|
||||
----
|
||||
Test 9: visual mode, complete buffer
|
||||
[['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 32, 'visual_words': 7, 'visual_bytes': 36}]
|
||||
----
|
||||
Test 10: visual mode (empty)
|
||||
[['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 1, 'visual_words': 0, 'visual_bytes': 1}]
|
||||
----
|
||||
Test 11: visual mode, single line
|
||||
[['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 13, 'visual_words': 3, 'visual_bytes': 16}]
|
108
src/testdir/test_wordcount.vim
Normal file
108
src/testdir/test_wordcount.vim
Normal file
@ -0,0 +1,108 @@
|
||||
" Test for wordcount() function
|
||||
|
||||
if !has('multi_byte')
|
||||
finish
|
||||
endif
|
||||
|
||||
func Test_wordcount()
|
||||
let save_enc = &enc
|
||||
set encoding=utf-8
|
||||
set selection=inclusive fileformat=unix fileformats=unix
|
||||
|
||||
new
|
||||
|
||||
" Test 1: empty window
|
||||
call assert_equal({'chars': 0, 'cursor_chars': 0, 'words': 0, 'cursor_words': 0,
|
||||
\ 'bytes': 0, 'cursor_bytes': 0}, wordcount())
|
||||
|
||||
" Test 2: some words, cursor at start
|
||||
call append(1, 'one two three')
|
||||
call cursor([1, 1, 0])
|
||||
call assert_equal({'chars': 15, 'cursor_chars': 1, 'words': 3, 'cursor_words': 0,
|
||||
\ 'bytes': 15, 'cursor_bytes': 1}, wordcount())
|
||||
|
||||
" Test 3: some words, cursor at end
|
||||
%d _
|
||||
call append(1, 'one two three')
|
||||
call cursor([2, 99, 0])
|
||||
call assert_equal({'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3,
|
||||
\ 'bytes': 15, 'cursor_bytes': 14}, wordcount())
|
||||
|
||||
" Test 4: some words, cursor at end, ve=all
|
||||
set ve=all
|
||||
%d _
|
||||
call append(1, 'one two three')
|
||||
call cursor([2, 99, 0])
|
||||
call assert_equal({'chars': 15, 'cursor_chars': 15, 'words': 3, 'cursor_words': 3,
|
||||
\ 'bytes': 15, 'cursor_bytes': 15}, wordcount())
|
||||
set ve=
|
||||
|
||||
" Test 5: several lines with words
|
||||
%d _
|
||||
call append(1, ['one two three', 'one two three', 'one two three'])
|
||||
call cursor([4, 99, 0])
|
||||
call assert_equal({'chars': 43, 'cursor_chars': 42, 'words': 9, 'cursor_words': 9,
|
||||
\ 'bytes': 43, 'cursor_bytes': 42}, wordcount())
|
||||
|
||||
" Test 6: one line with BOM set
|
||||
%d _
|
||||
call append(1, 'one two three')
|
||||
set bomb
|
||||
w! Xtest
|
||||
call cursor([2, 99, 0])
|
||||
call assert_equal({'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3,
|
||||
\ 'bytes': 18, 'cursor_bytes': 14}, wordcount())
|
||||
set nobomb
|
||||
w!
|
||||
call delete('Xtest')
|
||||
|
||||
" Test 7: one line with multibyte words
|
||||
%d _
|
||||
call append(1, ['Äne M¤ne Müh'])
|
||||
call cursor([2, 99, 0])
|
||||
call assert_equal({'chars': 14, 'cursor_chars': 13, 'words': 3, 'cursor_words': 3,
|
||||
\ 'bytes': 17, 'cursor_bytes': 16}, wordcount())
|
||||
|
||||
" Test 8: several lines with multibyte words
|
||||
%d _
|
||||
call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
|
||||
call cursor([3, 99, 0])
|
||||
call assert_equal({'chars': 32, 'cursor_chars': 31, 'words': 7, 'cursor_words': 7,
|
||||
\ 'bytes': 36, 'cursor_bytes': 35}, wordcount())
|
||||
|
||||
" Visual map to capture wordcount() in visual mode
|
||||
vnoremap <expr> <F2> execute("let g:visual_stat = wordcount()")
|
||||
|
||||
" Test 9: visual mode, complete buffer
|
||||
let g:visual_stat = {}
|
||||
%d _
|
||||
call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
|
||||
" start visual mode and select the complete buffer
|
||||
0
|
||||
exe "normal V2j\<F2>y"
|
||||
call assert_equal({'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 32,
|
||||
\ 'visual_words': 7, 'visual_bytes': 36}, g:visual_stat)
|
||||
|
||||
" Test 10: visual mode (empty)
|
||||
%d _
|
||||
call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
|
||||
" start visual mode and select the complete buffer
|
||||
0
|
||||
exe "normal v$\<F2>y"
|
||||
call assert_equal({'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 1,
|
||||
\ 'visual_words': 0, 'visual_bytes': 1}, g:visual_stat)
|
||||
|
||||
" Test 11: visual mode, single line
|
||||
%d _
|
||||
call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
|
||||
" start visual mode and select the complete buffer
|
||||
2
|
||||
exe "normal 0v$\<F2>y"
|
||||
call assert_equal({'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 13,
|
||||
\ 'visual_words': 3, 'visual_bytes': 16}, g:visual_stat)
|
||||
|
||||
set selection& fileformat& fileformats&
|
||||
let &enc = save_enc
|
||||
enew!
|
||||
close
|
||||
endfunc
|
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));
|
||||
}
|
||||
|
@ -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,32 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1390,
|
||||
/**/
|
||||
1389,
|
||||
/**/
|
||||
1388,
|
||||
/**/
|
||||
1387,
|
||||
/**/
|
||||
1386,
|
||||
/**/
|
||||
1385,
|
||||
/**/
|
||||
1384,
|
||||
/**/
|
||||
1383,
|
||||
/**/
|
||||
1382,
|
||||
/**/
|
||||
1381,
|
||||
/**/
|
||||
1380,
|
||||
/**/
|
||||
1379,
|
||||
/**/
|
||||
1378,
|
||||
/**/
|
||||
1377,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user