0
0
mirror of https://github.com/vim/vim.git synced 2025-07-04 23:07:33 -04:00
vim/src/version.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

3053 lines
37 KiB
C
Raw Normal View History

/* vi:set ts=8 sts=4 sw=4 noet:
2004-06-13 20:20:40 +00:00
*
* VIM - Vi IMproved by Bram Moolenaar
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
* See README.txt for an overview of the Vim source code.
*/
#include "vim.h"
/*
* Vim originated from Stevie version 3.6 (Fish disk 217) by GRWalter (Fred)
* It has been changed beyond recognition since then.
*
* Differences between version 8.2 and 9.0 can be found with ":help version9".
* Differences between version 7.4 and 8.x can be found with ":help version8".
* Differences between version 6.4 and 7.x can be found with ":help version7".
* Differences between version 5.8 and 6.x can be found with ":help version6".
2004-06-13 20:20:40 +00:00
* Differences between version 4.x and 5.x can be found with ":help version5".
* Differences between version 3.0 and 4.x can be found with ":help version4".
* All the remarks about older versions have been removed, they are not very
* interesting.
*/
#include "version.h"
2005-06-30 22:04:15 +00:00
char *Version = VIM_VERSION_SHORT;
static char *mediumVersion = VIM_VERSION_MEDIUM;
2004-06-13 20:20:40 +00:00
#if defined(HAVE_DATE_TIME) || defined(PROTO)
# if (defined(VMS) && defined(VAXC)) || defined(PROTO)
char longVersion[sizeof(VIM_VERSION_LONG_DATE) + sizeof(__DATE__)
+ sizeof(__TIME__) + 3];
2004-06-13 20:20:40 +00:00
void
init_longVersion(void)
2004-06-13 20:20:40 +00:00
{
/*
* Construct the long version string. Necessary because
* VAX C can't concatenate strings in the preprocessor.
2004-06-13 20:20:40 +00:00
*/
strcpy(longVersion, VIM_VERSION_LONG_DATE);
#ifdef BUILD_DATE
strcat(longVersion, BUILD_DATE);
#else
2004-06-13 20:20:40 +00:00
strcat(longVersion, __DATE__);
strcat(longVersion, " ");
strcat(longVersion, __TIME__);
#endif
2004-06-13 20:20:40 +00:00
strcat(longVersion, ")");
}
2004-06-13 20:20:40 +00:00
# else
char *longVersion = NULL;
void
init_longVersion(void)
{
if (longVersion != NULL)
return;
#ifdef BUILD_DATE
char *date_time = BUILD_DATE;
#else
char *date_time = __DATE__ " " __TIME__;
#endif
char *msg = _("%s (%s, compiled %s)");
size_t len = strlen(msg)
+ strlen(VIM_VERSION_LONG_ONLY)
+ strlen(VIM_VERSION_DATE_ONLY)
+ strlen(date_time);
longVersion = alloc(len);
if (longVersion == NULL)
longVersion = VIM_VERSION_LONG;
else
vim_snprintf(longVersion, len, msg,
VIM_VERSION_LONG_ONLY, VIM_VERSION_DATE_ONLY, date_time);
}
2004-06-13 20:20:40 +00:00
# endif
#else
char *longVersion = VIM_VERSION_LONG;
void
init_longVersion(void)
{
// nothing to do
}
2004-06-13 20:20:40 +00:00
#endif
static char *(features[]) =
{
#ifdef HAVE_ACL
"+acl",
#else
"-acl",
#endif
#ifdef AMIGA // only for Amiga systems
2004-06-13 20:20:40 +00:00
# ifdef FEAT_ARP
"+ARP",
# else
"-ARP",
# endif
#endif
#ifdef FEAT_ARABIC
"+arabic",
#else
"-arabic",
#endif
"+autocmd",
#ifdef FEAT_AUTOCHDIR
"+autochdir",
#else
"-autochdir",
#endif
#ifdef FEAT_AUTOSERVERNAME
"+autoservername",
#else
"-autoservername",
#endif
#ifdef FEAT_BEVAL_GUI
2004-06-13 20:20:40 +00:00
"+balloon_eval",
#else
"-balloon_eval",
#endif
#ifdef FEAT_BEVAL_TERM
"+balloon_eval_term",
#else
"-balloon_eval_term",
#endif
2004-06-13 20:20:40 +00:00
#ifdef FEAT_BROWSE
"+browse",
#else
"-browse",
#endif
"++builtin_terms",
#ifdef FEAT_BYTEOFF
"+byte_offset",
#else
"-byte_offset",
#endif
#ifdef FEAT_JOB_CHANNEL
"+channel",
#else
"-channel",
#endif
2004-06-13 20:20:40 +00:00
"+cindent",
#ifdef FEAT_CLIENTSERVER
"+clientserver",
#else
"-clientserver",
#endif
#ifdef FEAT_CLIPBOARD
"+clipboard",
#else
"-clipboard",
#endif
"+cmdline_compl",
"+cmdline_hist",
"+cmdline_info",
"+comments",
#ifdef FEAT_CONCEAL
"+conceal",
#else
"-conceal",
#endif
2004-06-13 20:20:40 +00:00
#ifdef FEAT_CRYPT
"+cryptv",
#else
"-cryptv",
#endif
#ifdef FEAT_CSCOPE
"+cscope",
#else
"-cscope",
#endif
"+cursorbind",
2006-01-26 22:25:15 +00:00
#ifdef CURSOR_SHAPE
"+cursorshape",
#else
"-cursorshape",
#endif
2004-06-13 20:20:40 +00:00
#if defined(FEAT_CON_DIALOG) && defined(FEAT_GUI_DIALOG)
"+dialog_con_gui",
#else
# if defined(FEAT_CON_DIALOG)
"+dialog_con",
# else
# if defined(FEAT_GUI_DIALOG)
"+dialog_gui",
# else
"-dialog",
# endif
# endif
#endif
#ifdef FEAT_DIFF
"+diff",
#else
"-diff",
#endif
#ifdef FEAT_DIGRAPHS
"+digraphs",
#else
"-digraphs",
#endif
#ifdef FEAT_GUI_MSWIN
# ifdef FEAT_DIRECTX
"+directx",
# else
"-directx",
# endif
#endif
2004-06-13 20:20:40 +00:00
#ifdef FEAT_DND
"+dnd",
#else
"-dnd",
#endif
"-ebcdic",
#ifdef FEAT_EMACS_TAGS
"+emacs_tags",
#else
"-emacs_tags",
#endif
#ifdef FEAT_EVAL
"+eval",
#else
"-eval",
#endif
"+ex_extra",
#ifdef FEAT_SEARCH_EXTRA
"+extra_search",
#else
"-extra_search",
#endif
"-farsi",
"+file_in_path",
#ifdef FEAT_FIND_ID
"+find_in_path",
#else
"-find_in_path",
#endif
2008-06-24 21:56:24 +00:00
"+float",
2004-06-13 20:20:40 +00:00
#ifdef FEAT_FOLDING
"+folding",
#else
"-folding",
#endif
"-footer",
// only interesting on Unix systems
2004-06-13 20:20:40 +00:00
#if !defined(USE_SYSTEM) && defined(UNIX)
"+fork()",
#endif
#ifdef FEAT_GETTEXT
# ifdef DYNAMIC_GETTEXT
"+gettext/dyn",
# else
"+gettext",
# endif
#else
"-gettext",
#endif
"-hangul_input",
#if (defined(HAVE_ICONV_H) && defined(USE_ICONV)) || defined(DYNAMIC_ICONV)
# ifdef DYNAMIC_ICONV
"+iconv/dyn",
# else
"+iconv",
# endif
#else
"-iconv",
#endif
"+insert_expand",
#ifdef FEAT_IPV6
"+ipv6",
#else
"-ipv6",
#endif
#ifdef FEAT_JOB_CHANNEL
"+job",
#else
"-job",
#endif
2004-06-13 20:20:40 +00:00
"+jumplist",
#ifdef FEAT_KEYMAP
"+keymap",
#else
"-keymap",
#endif
#ifdef FEAT_EVAL
"+lambda",
#else
"-lambda",
#endif
2004-06-13 20:20:40 +00:00
#ifdef FEAT_LANGMAP
"+langmap",
#else
"-langmap",
#endif
#ifdef FEAT_LIBCALL
"+libcall",
#else
"-libcall",
#endif
#ifdef FEAT_LINEBREAK
"+linebreak",
#else
"-linebreak",
#endif
"+lispindent",
"+listcmds",
"+localmap",
2010-07-14 23:23:17 +02:00
#ifdef FEAT_LUA
# ifdef DYNAMIC_LUA
"+lua/dyn",
# else
"+lua",
# endif
#else
"-lua",
#endif
2004-06-13 20:20:40 +00:00
#ifdef FEAT_MENU
"+menu",
#else
"-menu",
#endif
#ifdef FEAT_SESSION
"+mksession",
#else
"-mksession",
#endif
"+modify_fname",
"+mouse",
#ifdef FEAT_MOUSESHAPE
2004-06-13 20:20:40 +00:00
"+mouseshape",
#else
2004-06-13 20:20:40 +00:00
"-mouseshape",
#endif
2004-06-13 20:20:40 +00:00
#if defined(UNIX) || defined(VMS)
# ifdef FEAT_MOUSE_DEC
"+mouse_dec",
# else
"-mouse_dec",
# endif
# ifdef FEAT_MOUSE_GPM
# ifdef DYNAMIC_GPM
"+mouse_gpm/dyn",
# else
2004-06-13 20:20:40 +00:00
"+mouse_gpm",
# endif
2004-06-13 20:20:40 +00:00
# else
"-mouse_gpm",
# endif
# ifdef FEAT_MOUSE_JSB
"+mouse_jsbterm",
# else
"-mouse_jsbterm",
# endif
# ifdef FEAT_MOUSE_NET
"+mouse_netterm",
# else
"-mouse_netterm",
# endif
#endif
#ifdef __QNX__
# ifdef FEAT_MOUSE_PTERM
"+mouse_pterm",
# else
"-mouse_pterm",
# endif
#endif
#if defined(UNIX) || defined(VMS)
"+mouse_sgr",
2008-06-24 21:56:24 +00:00
# ifdef FEAT_SYSMOUSE
"+mouse_sysmouse",
# else
"-mouse_sysmouse",
# endif
# ifdef FEAT_MOUSE_URXVT
"+mouse_urxvt",
# else
"-mouse_urxvt",
# endif
"+mouse_xterm",
2004-06-13 20:20:40 +00:00
#endif
2004-06-13 20:20:40 +00:00
#ifdef FEAT_MBYTE_IME
# ifdef DYNAMIC_IME
"+multi_byte_ime/dyn",
# else
"+multi_byte_ime",
# endif
#else
"+multi_byte",
#endif
#ifdef FEAT_MULTI_LANG
"+multi_lang",
#else
"-multi_lang",
#endif
2004-07-05 15:58:32 +00:00
#ifdef FEAT_MZSCHEME
2005-01-25 22:07:05 +00:00
# ifdef DYNAMIC_MZSCHEME
"+mzscheme/dyn",
# else
2004-07-05 15:58:32 +00:00
"+mzscheme",
2005-01-25 22:07:05 +00:00
# endif
2004-07-05 15:58:32 +00:00
#else
"-mzscheme",
#endif
2004-06-13 20:20:40 +00:00
#ifdef FEAT_NETBEANS_INTG
"+netbeans_intg",
#else
"-netbeans_intg",
#endif
"+num64",
#ifdef FEAT_GUI_MSWIN
2004-06-13 20:20:40 +00:00
# ifdef FEAT_OLE
"+ole",
# else
"-ole",
# endif
#endif
#ifdef FEAT_EVAL
"+packages",
#else
"-packages",
#endif
2004-06-13 20:20:40 +00:00
"+path_extra",
#ifdef FEAT_PERL
# ifdef DYNAMIC_PERL
"+perl/dyn",
# else
"+perl",
# endif
#else
"-perl",
#endif
#ifdef FEAT_PERSISTENT_UNDO
"+persistent_undo",
#else
"-persistent_undo",
#endif
#ifdef FEAT_PROP_POPUP
"+popupwin",
#else
"-popupwin",
#endif
2004-06-13 20:20:40 +00:00
#ifdef FEAT_PRINTER
# ifdef FEAT_POSTSCRIPT
"+postscript",
# else
"-postscript",
# endif
"+printer",
#else
"-printer",
#endif
2005-02-26 23:04:13 +00:00
#ifdef FEAT_PROFILE
"+profile",
#else
"-profile",
#endif
2004-06-13 20:20:40 +00:00
#ifdef FEAT_PYTHON
# ifdef DYNAMIC_PYTHON
"+python/dyn",
# else
"+python",
# endif
#else
"-python",
#endif
#ifdef FEAT_PYTHON3
# ifdef DYNAMIC_PYTHON3
patch 9.0.1776: No support for stable Python 3 ABI Problem: No support for stable Python 3 ABI Solution: Support Python 3 stable ABI Commits: 1) Support Python 3 stable ABI to allow mixed version interoperatbility Vim currently supports embedding Python for use with plugins, and the "dynamic" linking option allows the user to specify a locally installed version of Python by setting `pythonthreedll`. However, one caveat is that the Python 3 libs are not binary compatible across minor versions, and mixing versions can potentially be dangerous (e.g. let's say Vim was linked against the Python 3.10 SDK, but the user sets `pythonthreedll` to a 3.11 lib). Usually, nothing bad happens, but in theory this could lead to crashes, memory corruption, and other unpredictable behaviors. It's also difficult for the user to tell something is wrong because Vim has no way of reporting what Python 3 version Vim was linked with. For Vim installed via a package manager, this usually isn't an issue because all the dependencies would already be figured out. For prebuilt Vim binaries like MacVim (my motivation for working on this), AppImage, and Win32 installer this could potentially be an issue as usually a single binary is distributed. This is more tricky when a new Python version is released, as there's a chicken-and-egg issue with deciding what Python version to build against and hard to keep in sync when a new Python version just drops and we have a mix of users of different Python versions, and a user just blindly upgrading to a new Python could lead to bad interactions with Vim. Python 3 does have a solution for this problem: stable ABI / limited API (see https://docs.python.org/3/c-api/stable.html). The C SDK limits the API to a set of functions that are promised to be stable across versions. This pull request adds an ifdef config that allows us to turn it on when building Vim. Vim binaries built with this option should be safe to freely link with any Python 3 libraies without having the constraint of having to use the same minor version. Note: Python 2 has no such concept and this doesn't change how Python 2 integration works (not that there is going to be a new version of Python 2 that would cause compatibility issues in the future anyway). --- Technical details: ====== The stable ABI can be accessed when we compile with the Python 3 limited API (by defining `Py_LIMITED_API`). The Python 3 code (in `if_python3.c` and `if_py_both.h`) would now handle this and switch to limited API mode. Without it set, Vim will still use the full API as before so this is an opt-in change. The main difference is that `PyType_Object` is now an opaque struct that we can't directly create "static types" out of, and we have to create type objects as "heap types" instead. This is because the struct is not stable and changes from version to version (e.g. 3.8 added a `tp_vectorcall` field to it). I had to change all the types to be allocated on the heap instead with just a pointer to them. Other functions are also simply missing in limited API, or they are introduced too late (e.g. `PyUnicode_AsUTF8AndSize` in 3.10) to it that we need some other ways to do the same thing, so I had to abstract a few things into macros, and sometimes re-implement functions like `PyObject_NEW`. One caveat is that in limited API, `OutputType` (used for replacing `sys.stdout`) no longer inherits from `PyStdPrinter_Type` which I don't think has any real issue other than minor differences in how they convert to a string and missing a couple functions like `mode()` and `fileno()`. Also fixed an existing bug where `tp_basicsize` was set incorrectly for `BufferObject`, `TabListObject, `WinListObject`. Technically, there could be a small performance drop, there is a little more indirection with accessing type objects, and some APIs like `PyUnicode_AsUTF8AndSize` are missing, but in practice I didn't see any difference, and any well-written Python plugin should try to avoid excessing callbacks to the `vim` module in Python anyway. I only tested limited API mode down to Python 3.7, which seemes to compile and work fine. I haven't tried earlier Python versions. 2) Fix PyIter_Check on older Python vers / type##Ptr unused warning For PyIter_Check, older versions exposed them as either macros (used in full API), or a function (for use in limited API). A previous change exposed PyIter_Check to the dynamic build because Python just moved it to function-only in 3.10 anyway. Because of that, just make sure we always grab the function in dynamic builds in earlier versions since that's what Python eventually did anyway. 3) Move Py_LIMITED_API define to configure script Can now use --with-python-stable-abi flag to customize what stable ABI version to target. Can also use an env var to do so as well. 4) Show +python/dyn-stable in :version, and allow has() feature query Not sure if the "/dyn-stable" suffix would break things, or whether we should do it another way. Or just don't show it in version and rely on has() feature checking. 5) Documentation first draft. Still need to implement v:python3_version 6) Fix PyIter_Check build breaks when compiling against Python 3.8 7) Add CI coverage stable ABI on Linux/Windows / make configurable on Windows This adds configurable options for Windows make files (both MinGW and MSVC). CI will also now exercise both traditional full API and stable ABI for Linux and Windows in the matrix for coverage. Also added a "dynamic" option to Linux matrix as a drive-by change to make other scripting languages like Ruby / Perl testable under both static and dynamic builds. 8) Fix inaccuracy in Windows docs Python's own docs are confusing but you don't actually want to use `python3.dll` for the dynamic linkage. 9) Add generated autoconf file 10) Add v:python3_version support This variable indicates the version of Python3 that Vim was built against (PY_VERSION_HEX), and will be useful to check whether the Python library you are loading in dynamically actually fits it. When built with stable ABI, it will be the limited ABI version instead (`Py_LIMITED_API`), which indicates the minimum version of Python 3 the user should have, rather than the exact match. When stable ABI is used, we won't be exposing PY_VERSION_HEX in this var because it just doesn't seem necessary to do so (the whole point of stable ABI is the promise that it will work across versions), and I don't want to confuse the user with too many variables. Also, cleaned up some documentation, and added help tags. 11) Fix Python 3.7 compat issues Fix a couple issues when using limited API < 3.8 - Crash on exit: In Python 3.7, if a heap-allocated type is destroyed before all instances are, it would cause a crash later. This happens when we destroyed `OptionsType` before calling `Py_Finalize` when using the limited API. To make it worse, later versions changed the semantics and now each instance has a strong reference to its own type and the recommendation has changed to have each instance de-ref its own type and have its type in GC traversal. To avoid dealing with these cross-version variations, we just don't free the heap type. They are static types in non-limited-API anyway and are designed to last through the entirety of the app, and we also don't restart the Python runtime and therefore do not need it to have absolutely 0 leaks. See: - https://docs.python.org/3/whatsnew/3.8.html#changes-in-the-c-api - https://docs.python.org/3/whatsnew/3.9.html#changes-in-the-c-api - PyIter_Check: This function is not provided in limited APIs older than 3.8. Previously I was trying to mock it out using manual PyType_GetSlot() but it was brittle and also does not actually work properly for static types (it will generate a Python error). Just return false. It does mean using limited API < 3.8 is not recommended as you lose the functionality to handle iterators, but from playing with plugins I couldn't find it to be an issue. - Fix loading of PyIter_Check so it will be done when limited API < 3.8. Otherwise loading a 3.7 Python lib will fail even if limited API was specified to use it. 12) Make sure to only load `PyUnicode_AsUTF8AndSize` in needed in limited API We don't use this function unless limited API >= 3.10, but we were loading it regardless. Usually it's ok in Unix-like systems where Python just has a single lib that we load from, but in Windows where there is a separate python3.dll this would not work as the symbol would not have been exposed in this more limited DLL file. This makes it much clearer under what condition is this function needed. closes: #12032 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>
2023-08-20 21:18:38 +02:00
# ifdef DYNAMIC_PYTHON3_STABLE_ABI
"+python3/dyn-stable",
# else
"+python3/dyn",
patch 9.0.1776: No support for stable Python 3 ABI Problem: No support for stable Python 3 ABI Solution: Support Python 3 stable ABI Commits: 1) Support Python 3 stable ABI to allow mixed version interoperatbility Vim currently supports embedding Python for use with plugins, and the "dynamic" linking option allows the user to specify a locally installed version of Python by setting `pythonthreedll`. However, one caveat is that the Python 3 libs are not binary compatible across minor versions, and mixing versions can potentially be dangerous (e.g. let's say Vim was linked against the Python 3.10 SDK, but the user sets `pythonthreedll` to a 3.11 lib). Usually, nothing bad happens, but in theory this could lead to crashes, memory corruption, and other unpredictable behaviors. It's also difficult for the user to tell something is wrong because Vim has no way of reporting what Python 3 version Vim was linked with. For Vim installed via a package manager, this usually isn't an issue because all the dependencies would already be figured out. For prebuilt Vim binaries like MacVim (my motivation for working on this), AppImage, and Win32 installer this could potentially be an issue as usually a single binary is distributed. This is more tricky when a new Python version is released, as there's a chicken-and-egg issue with deciding what Python version to build against and hard to keep in sync when a new Python version just drops and we have a mix of users of different Python versions, and a user just blindly upgrading to a new Python could lead to bad interactions with Vim. Python 3 does have a solution for this problem: stable ABI / limited API (see https://docs.python.org/3/c-api/stable.html). The C SDK limits the API to a set of functions that are promised to be stable across versions. This pull request adds an ifdef config that allows us to turn it on when building Vim. Vim binaries built with this option should be safe to freely link with any Python 3 libraies without having the constraint of having to use the same minor version. Note: Python 2 has no such concept and this doesn't change how Python 2 integration works (not that there is going to be a new version of Python 2 that would cause compatibility issues in the future anyway). --- Technical details: ====== The stable ABI can be accessed when we compile with the Python 3 limited API (by defining `Py_LIMITED_API`). The Python 3 code (in `if_python3.c` and `if_py_both.h`) would now handle this and switch to limited API mode. Without it set, Vim will still use the full API as before so this is an opt-in change. The main difference is that `PyType_Object` is now an opaque struct that we can't directly create "static types" out of, and we have to create type objects as "heap types" instead. This is because the struct is not stable and changes from version to version (e.g. 3.8 added a `tp_vectorcall` field to it). I had to change all the types to be allocated on the heap instead with just a pointer to them. Other functions are also simply missing in limited API, or they are introduced too late (e.g. `PyUnicode_AsUTF8AndSize` in 3.10) to it that we need some other ways to do the same thing, so I had to abstract a few things into macros, and sometimes re-implement functions like `PyObject_NEW`. One caveat is that in limited API, `OutputType` (used for replacing `sys.stdout`) no longer inherits from `PyStdPrinter_Type` which I don't think has any real issue other than minor differences in how they convert to a string and missing a couple functions like `mode()` and `fileno()`. Also fixed an existing bug where `tp_basicsize` was set incorrectly for `BufferObject`, `TabListObject, `WinListObject`. Technically, there could be a small performance drop, there is a little more indirection with accessing type objects, and some APIs like `PyUnicode_AsUTF8AndSize` are missing, but in practice I didn't see any difference, and any well-written Python plugin should try to avoid excessing callbacks to the `vim` module in Python anyway. I only tested limited API mode down to Python 3.7, which seemes to compile and work fine. I haven't tried earlier Python versions. 2) Fix PyIter_Check on older Python vers / type##Ptr unused warning For PyIter_Check, older versions exposed them as either macros (used in full API), or a function (for use in limited API). A previous change exposed PyIter_Check to the dynamic build because Python just moved it to function-only in 3.10 anyway. Because of that, just make sure we always grab the function in dynamic builds in earlier versions since that's what Python eventually did anyway. 3) Move Py_LIMITED_API define to configure script Can now use --with-python-stable-abi flag to customize what stable ABI version to target. Can also use an env var to do so as well. 4) Show +python/dyn-stable in :version, and allow has() feature query Not sure if the "/dyn-stable" suffix would break things, or whether we should do it another way. Or just don't show it in version and rely on has() feature checking. 5) Documentation first draft. Still need to implement v:python3_version 6) Fix PyIter_Check build breaks when compiling against Python 3.8 7) Add CI coverage stable ABI on Linux/Windows / make configurable on Windows This adds configurable options for Windows make files (both MinGW and MSVC). CI will also now exercise both traditional full API and stable ABI for Linux and Windows in the matrix for coverage. Also added a "dynamic" option to Linux matrix as a drive-by change to make other scripting languages like Ruby / Perl testable under both static and dynamic builds. 8) Fix inaccuracy in Windows docs Python's own docs are confusing but you don't actually want to use `python3.dll` for the dynamic linkage. 9) Add generated autoconf file 10) Add v:python3_version support This variable indicates the version of Python3 that Vim was built against (PY_VERSION_HEX), and will be useful to check whether the Python library you are loading in dynamically actually fits it. When built with stable ABI, it will be the limited ABI version instead (`Py_LIMITED_API`), which indicates the minimum version of Python 3 the user should have, rather than the exact match. When stable ABI is used, we won't be exposing PY_VERSION_HEX in this var because it just doesn't seem necessary to do so (the whole point of stable ABI is the promise that it will work across versions), and I don't want to confuse the user with too many variables. Also, cleaned up some documentation, and added help tags. 11) Fix Python 3.7 compat issues Fix a couple issues when using limited API < 3.8 - Crash on exit: In Python 3.7, if a heap-allocated type is destroyed before all instances are, it would cause a crash later. This happens when we destroyed `OptionsType` before calling `Py_Finalize` when using the limited API. To make it worse, later versions changed the semantics and now each instance has a strong reference to its own type and the recommendation has changed to have each instance de-ref its own type and have its type in GC traversal. To avoid dealing with these cross-version variations, we just don't free the heap type. They are static types in non-limited-API anyway and are designed to last through the entirety of the app, and we also don't restart the Python runtime and therefore do not need it to have absolutely 0 leaks. See: - https://docs.python.org/3/whatsnew/3.8.html#changes-in-the-c-api - https://docs.python.org/3/whatsnew/3.9.html#changes-in-the-c-api - PyIter_Check: This function is not provided in limited APIs older than 3.8. Previously I was trying to mock it out using manual PyType_GetSlot() but it was brittle and also does not actually work properly for static types (it will generate a Python error). Just return false. It does mean using limited API < 3.8 is not recommended as you lose the functionality to handle iterators, but from playing with plugins I couldn't find it to be an issue. - Fix loading of PyIter_Check so it will be done when limited API < 3.8. Otherwise loading a 3.7 Python lib will fail even if limited API was specified to use it. 12) Make sure to only load `PyUnicode_AsUTF8AndSize` in needed in limited API We don't use this function unless limited API >= 3.10, but we were loading it regardless. Usually it's ok in Unix-like systems where Python just has a single lib that we load from, but in Windows where there is a separate python3.dll this would not work as the symbol would not have been exposed in this more limited DLL file. This makes it much clearer under what condition is this function needed. closes: #12032 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>
2023-08-20 21:18:38 +02:00
# endif
# else
"+python3",
# endif
#else
"-python3",
#endif
2004-06-13 20:20:40 +00:00
#ifdef FEAT_QUICKFIX
"+quickfix",
#else
"-quickfix",
#endif
2006-05-02 22:08:30 +00:00
#ifdef FEAT_RELTIME
"+reltime",
#else
"-reltime",
#endif
2004-06-13 20:20:40 +00:00
#ifdef FEAT_RIGHTLEFT
"+rightleft",
#else
"-rightleft",
#endif
#ifdef FEAT_RUBY
# ifdef DYNAMIC_RUBY
"+ruby/dyn",
# else
"+ruby",
# endif
#else
"-ruby",
#endif
"+scrollbind",
#ifdef FEAT_SIGNS
"+signs",
#else
"-signs",
#endif
"+smartindent",
#ifdef FEAT_SODIUM
# ifdef DYNAMIC_SODIUM
"+sodium/dyn",
# else
"+sodium",
# endif
#else
"-sodium",
#endif
#ifdef FEAT_SOUND
"+sound",
#else
"-sound",
#endif
#ifdef FEAT_SPELL
"+spell",
#else
"-spell",
#endif
2009-11-11 13:22:11 +00:00
#ifdef STARTUPTIME
"+startuptime",
#else
"-startuptime",
#endif
2004-06-13 20:20:40 +00:00
#ifdef FEAT_STL_OPT
"+statusline",
#else
"-statusline",
#endif
"-sun_workshop",
#ifdef FEAT_SYN_HL
"+syntax",
#else
"-syntax",
#endif
// only interesting on Unix systems
#if defined(USE_SYSTEM) && defined(UNIX)
2004-06-13 20:20:40 +00:00
"+system()",
#endif
"+tag_binary",
"-tag_old_static",
"-tag_any_white",
#ifdef FEAT_TCL
# ifdef DYNAMIC_TCL
"+tcl/dyn",
# else
"+tcl",
# endif
#else
"-tcl",
#endif
#ifdef FEAT_TERMGUICOLORS
"+termguicolors",
#else
"-termguicolors",
#endif
#ifdef FEAT_TERMINAL
"+terminal",
#else
"-terminal",
#endif
#if defined(UNIX)
// only Unix can have terminfo instead of termcap
2004-06-13 20:20:40 +00:00
# ifdef TERMINFO
"+terminfo",
# else
"-terminfo",
# endif
#endif
#ifdef FEAT_TERMRESPONSE
"+termresponse",
#else
"-termresponse",
#endif
"+textobjects",
#ifdef FEAT_PROP_POPUP
"+textprop",
#else
"-textprop",
#endif
#if !defined(UNIX)
// unix always includes termcap support
# ifdef HAVE_TGETENT
"+tgetent",
# else
"-tgetent",
# endif
#endif
#ifdef FEAT_TIMERS
"+timers",
#else
"-timers",
#endif
2004-06-13 20:20:40 +00:00
"+title",
#ifdef FEAT_TOOLBAR
"+toolbar",
#else
"-toolbar",
#endif
"+user_commands",
#ifdef FEAT_VARTABS
"+vartabs",
#else
"-vartabs",
2004-06-13 20:20:40 +00:00
#endif
"+vertsplit",
"+vim9script",
2004-06-13 20:20:40 +00:00
#ifdef FEAT_VIMINFO
"+viminfo",
#else
"-viminfo",
#endif
"+virtualedit",
"+visual",
"+visualextra",
2004-06-13 20:20:40 +00:00
"+vreplace",
#ifdef MSWIN
# ifdef FEAT_VTP
"+vtp",
# else
"-vtp",
# endif
#endif
2004-06-13 20:20:40 +00:00
"+wildignore",
"+wildmenu",
"+windows",
#ifdef FEAT_WRITEBACKUP
"+writebackup",
#else
"-writebackup",
#endif
#if defined(UNIX) || defined(VMS)
# ifdef FEAT_X11
"+X11",
# else
"-X11",
# endif
#endif
# ifdef FEAT_XATTR
"+xattr",
# else
"-xattr",
# endif
2004-06-13 20:20:40 +00:00
#ifdef FEAT_XFONTSET
"+xfontset",
#else
"-xfontset",
#endif
#ifdef FEAT_XIM
"+xim",
#else
"-xim",
#endif
#if defined(MSWIN)
# ifdef FEAT_XPM_W32
"+xpm_w32",
# else
"-xpm_w32",
# endif
#elif defined(HAVE_XPM)
"+xpm",
#else
"-xpm",
#endif
2004-06-13 20:20:40 +00:00
#if defined(UNIX) || defined(VMS)
# if defined(USE_XSMP_INTERACT)
2004-06-13 20:20:40 +00:00
"+xsmp_interact",
# elif defined(USE_XSMP)
2004-06-13 20:20:40 +00:00
"+xsmp",
# else
2004-06-13 20:20:40 +00:00
"-xsmp",
# endif
# ifdef FEAT_XCLIPBOARD
"+xterm_clipboard",
# else
"-xterm_clipboard",
# endif
#endif
#ifdef FEAT_XTERM_SAVE
"+xterm_save",
#else
"-xterm_save",
#endif
NULL
};
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
836,
/**/
835,
/**/
834,
/**/
833,
/**/
832,
/**/
831,
/**/
830,
/**/
829,
/**/
828,
/**/
827,
/**/
826,
/**/
825,
/**/
824,
/**/
823,
/**/
822,
/**/
821,
/**/
820,
/**/
819,
/**/
818,
/**/
817,
/**/
816,
/**/
815,
/**/
814,
/**/
813,
/**/
812,
/**/
811,
/**/
810,
/**/
809,
/**/
808,
/**/
807,
/**/
806,
/**/
805,
/**/
804,
/**/
803,
/**/
802,
/**/
801,
/**/
800,
/**/
799,
/**/
798,
/**/
797,
/**/
796,
/**/
795,
/**/
794,
/**/
793,
/**/
792,
/**/
791,
/**/
790,
/**/
789,
/**/
788,
/**/
787,
/**/
786,
/**/
785,
/**/
784,
/**/
783,
/**/
782,
/**/
781,
/**/
780,
/**/
779,
/**/
778,
/**/
777,
/**/
776,
/**/
775,
/**/
774,
/**/
773,
/**/
772,
/**/
771,
/**/
770,
/**/
769,
/**/
768,
/**/
767,
/**/
766,
/**/
765,
/**/
764,
/**/
763,
/**/
762,
/**/
761,
/**/
760,
/**/
759,
/**/
758,
/**/
757,
/**/
756,
/**/
755,
/**/
754,
/**/
753,
/**/
752,
/**/
751,
/**/
750,
/**/
749,
/**/
748,
/**/
747,
/**/
746,
/**/
745,
/**/
744,
/**/
743,
/**/
742,
/**/
741,
/**/
740,
/**/
739,
/**/
738,
/**/
737,
/**/
736,
/**/
735,
/**/
734,
/**/
733,
/**/
732,
/**/
731,
/**/
730,
/**/
729,
/**/
728,
/**/
727,
/**/
726,
/**/
725,
/**/
724,
/**/
723,
/**/
722,
/**/
721,
/**/
720,
/**/
719,
/**/
718,
/**/
717,
/**/
716,
/**/
715,
/**/
714,
/**/
713,
/**/
712,
/**/
711,
/**/
710,
/**/
709,
/**/
708,
/**/
707,
/**/
706,
/**/
705,
/**/
704,
/**/
703,
/**/
702,
/**/
701,
/**/
700,
/**/
699,
/**/
698,
/**/
697,
/**/
696,
/**/
695,
/**/
694,
/**/
693,
/**/
692,
/**/
691,
/**/
690,
/**/
689,
/**/
688,
/**/
687,
/**/
686,
/**/
685,
/**/
684,
/**/
683,
/**/
682,
patch 9.1.0681: tests: Analyzing failed screendumps is hard Problem: tests: Analyzing failed screendumps is hard Solution: Facilitate the viewing of rendered screendumps under src/ add some documentation on how to use the viewdumps.vim script (Aliaksei Budavei) With the submitted "viewdumps.vim" script, a few manual steps in typical workflows (see below) can be automated. The updated "README.txt" contains additional information. ============================================================ Reviewing LOCAL failed screendump tests can be arranged as follows: 1) Run tests and generate screendumps: ------------------------------------------------------------ cd /path/to/fork/src/testdir make ------------------------------------------------------------ 2) Examine the screendumps from the "failed" directory: ------------------------------------------------------------ ../vim -u NONE -S viewdumps.vim ------------------------------------------------------------ ============================================================ Reviewing UPLOADED failed screendump tests can be arranged as follows (it can be further locally scripted): 1) Fetch an artifact with failed screendumps from "github.com/vim/vim/actions/runs/A_ID/artifacts/B_ID". 2) Extract the archived files: ------------------------------------------------------------ unzip /tmp/failed-tests.zip -d /tmp ------------------------------------------------------------ 3) Set up the "dumps" directory. Create a symlink to "/path/to/fork/dirs/dumps" in the extracted directories so that term_dumpdiff() can be used. (The lookup algorithm resolves "dumps" for every loaded filename. So, with "/tmp/src/testdir/failed/*.dump" files passed as script arguments, the algorithm will make the files in "/tmp/src/testdir/dumps" queried.) ------------------------------------------------------------ cd /path/to/fork ln -s $(pwd)/src/testdir/dumps /tmp/src/testdir/dumps ------------------------------------------------------------ 4) Examine the extracted screendumps: ------------------------------------------------------------ ./src/vim -u NONE -S src/testdir/viewdumps.vim \ /tmp/src/testdir/failed/*.dump ------------------------------------------------------------ 5) Clean up: ------------------------------------------------------------ unlink /tmp/src/testdir/dumps rm -rf /tmp/src ------------------------------------------------------------ ============================================================ Reviewing SUBMITTED FOR PULL REQUEST screendump tests can be arranged as follows (it can be further locally scripted): 1) List the fetched changeset and write the changed "dumps" filenames to "/tmp/filelist": ------------------------------------------------------------ cd /path/to/fork git switch prs/1234 git diff-index --relative=src/testdir/dumps/ \ --name-only prs/1234~1 > /tmp/filelist ------------------------------------------------------------ 2) Reconcile relative filepaths, and copy next-to-be-updated "dumps" files in the "failed" directory (note the missing new screendumps, if any): ------------------------------------------------------------ git switch master cd src/testdir/dumps test -d ../failed || mkdir ../failed cp -t ../failed $(cat /tmp/filelist) ------------------------------------------------------------ 3) Remember about the introduced INVERTED relation between "dumps" and "failed", i.e. the files to be committed are in "dumps" already and their previous versions are in "failed"; therefore, copy the missing new screendumps from "dumps" to "failed" (otherwise these won't be shown): ------------------------------------------------------------ git switch prs/1234 cp -t ../failed foo_10.dump foo_11.dump foo_12.dump ------------------------------------------------------------ 4) Examine the screendumps from the "failed" directory (new screendumps will be shown with no difference between their versions): ------------------------------------------------------------ cd .. ../vim -u NONE -S viewdumps.vim ------------------------------------------------------------ closes: #15515 Signed-off-by: Aliaksei Budavei <0x000c70@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-08-19 21:33:26 +02:00
/**/
681,
/**/
680,
/**/
679,
/**/
678,
/**/
677,
/**/
676,
/**/
675,
/**/
674,
/**/
673,
/**/
672,
/**/
671,
/**/
670,
/**/
669,
/**/
668,
/**/
667,
/**/
666,
/**/
665,
/**/
664,
/**/
663,
/**/
662,
/**/
661,
/**/
660,
/**/
659,
/**/
658,
/**/
657,
/**/
656,
/**/
655,
/**/
654,
/**/
653,
/**/
652,
/**/
651,
/**/
650,
/**/
649,
/**/
648,
/**/
647,
/**/
646,
patch 9.1.0645: regex: wrong match when searching multi-byte char case-insensitive Problem: regex: wrong match when searching multi-byte char case-insensitive (diffsetter) Solution: Apply proper case-folding for characters and search-string This patch does the following 4 things: 1) When the regexp engine compares two utf-8 codepoints case insensitive it may match an adjacent character, because it assumes it can step over as many bytes as the pattern contains. This however is not necessarily true because of case-folding, a multi-byte UTF-8 character can be considered equal to some single-byte value. Let's consider the pattern 'ſ' and the string 's'. When comparing and ignoring case, the single character 's' matches, and since it matches Vim will try to step over the match (by the amount of bytes of the pattern), assuming that since it matches, the length of both strings is the same. However in that case, it should only step over the single byte value 's' by 1 byte and try to start matching after it again. So for the backtracking engine we need to ensure: * we try to match the correct length for the pattern and the text * in case of a match, we step over it correctly There is one tricky thing for the backtracing engine. We also need to calculate correctly the number of bytes to compare the 2 different utf-8 strings s1 and s2. So we will count the number of characters in s1 that the byte len specified. Then we count the number of bytes to step over the same number of characters in string s2 and then we can correctly compare the 2 utf-8 strings. 2) A similar thing can happen for the NFA engine, when skipping to the next character to test for a match. We are skipping over the regstart pointer, however we do not consider the case that because of case-folding we may need to adjust the number of bytes to skip over. So this needs to be adjusted in find_match_text() as well. 3) A related issue turned out, when prog->match_text is actually empty. In that case we should try to find the next match and skip this condition. 4) When comparing characters using collections, we must also apply case folding to each character in the collection and not just to the current character from the search string. This doesn't apply to the NFA engine, because internally it converts collections to branches [abc] -> a\|b\|c fixes: #14294 closes: #14756 Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-07-30 20:39:18 +02:00
/**/
645,
/**/
644,
/**/
643,
/**/
642,
/**/
641,
/**/
640,
/**/
639,
/**/
638,
/**/
637,
/**/
636,
/**/
635,
/**/
634,
/**/
633,
/**/
632,
/**/
631,
/**/
630,
/**/
629,
/**/
628,
/**/
627,
/**/
626,
/**/
625,
/**/
624,
/**/
623,
/**/
622,
/**/
621,
/**/
620,
/**/
619,
/**/
618,
/**/
617,
/**/
616,
/**/
615,
/**/
614,
/**/
613,
/**/
612,
/**/
611,
/**/
610,
patch 9.1.0609: outdated comments in Makefile Problem: outdated comments in Makefile Solution: update outdated comments, update rule for vimtags (Shane Harper) related: commit b81109192f Here are the changes and the reasons for them: - Delete the comment preceding the assignment to VIMPROG. Since b81109192f there's no need for VIMPROG to be set to something else when this is executed from src/Makefile. (The comment was wrong anyway; VIMPROG was being set to "$$BUILD_DIR/$(VIMTARGET)".) ``` # Set to $(VIMTARGET) when executed from src/Makefile. VIMPROG = ../../src/vim ``` - Delete "`and installed`" in the following comment; The vimtags rule doesn't require that Vim has been installed. ``` # Use Vim to generate the tags file. Can only be used when Vim has been # compiled and installed. Supports multiple languages. vimtags: $(DOCS) ``` - With commit b81109192f there is no longer a need to set VIMPROG here: ``` -@BUILD_DIR="`pwd`"; cd $(HELPSOURCE); if test -z "$(CROSS_COMPILING)"; then \ $(MAKE) VIMPROG="$$BUILD_DIR/$(VIMTARGET)" vimtags; fi ``` The new code below will use the same vim executable as the old code: ``` -@cd $(HELPSOURCE); if test -z "$(CROSS_COMPILING)"; then \ $(MAKE) vimtags; fi ``` - Delete the following comment which was related to setting VIMPROG as it no longer has any value: ``` # We can assume Vim was build, but it may not have been installed, # thus use the executable in the current directory. ``` Note: this comment used to be (unnecessarily) echoed to the terminal (because it was indented) when making installrtbase. closes: #15320 Signed-off-by: Shane Harper <shane@shaneharper.net> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-07-22 20:09:26 +02:00
/**/
609,
/**/
608,
/**/
607,
patch 9.1.0606: tests: generated files may cause failure in test_codestyle Problem: tests: generated files may cause failure in test_codestyle Solution: Exclude OLE-related generated files from style checks. (Ken Takata) Some OLE-related auto-generated files may contain space errors: https://ci.appveyor.com/project/chrisbra/vim-win32-installer/builds/50248542/job/w45ve9yd6qmmws8t#L11475 ``` From test_codestyle.vim: Found errors in Test_source_files(): command line..script C:/projects/vim-win32-installer/vim/src/testdir/runtest.vim[607]..function RunTheTest[57]..Test_source_files[8]..<SNR>8_PerformCheck[11]..<SNR>8_ReportError line 2: ../dlldata.c line 2: trailing white space command line..script C:/projects/vim-win32-installer/vim/src/testdir/runtest.vim[607]..function RunTheTest[57]..Test_source_files[8]..<SNR>8_PerformCheck[11]..<SNR>8_ReportError line 2: ../iid_ole.c line 12: trailing white space command line..script C:/projects/vim-win32-installer/vim/src/testdir/runtest.vim[607]..function RunTheTest[57]..Test_source_files[6]..<SNR>8_PerformCheck[11]..<SNR>8_ReportError line 2: ../if_ole.h line 60: space before Tab command line..script C:/projects/vim-win32-installer/vim/src/testdir/runtest.vim[607]..function RunTheTest[57]..Test_source_files[8]..<SNR>8_PerformCheck[11]..<SNR>8_ReportError line 2: ../if_ole.h line 10: trailing white space ``` Exclude them from style checking. closes: #15309 Signed-off-by: Ken Takata <kentkt@csc.jp> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-07-20 11:55:13 +02:00
/**/
606,
/**/
605,
/**/
604,
/**/
603,
/**/
602,
/**/
601,
/**/
600,
/**/
599,
/**/
598,
/**/
597,
/**/
596,
/**/
595,
/**/
594,
/**/
593,
/**/
592,
/**/
591,
/**/
590,
patch 9.1.0589: vi: d{motion} and cw work differently than expected Problem: vi: d{motion} and cw command work differently than expected Solution: add new cpo-z flag to make the behaviour configurable There are two special vi compatible behaviours (or should I say bugs?): 1): cw behaves differently than dw. That is, because cw is special cased by Vim and is effectively aliased to ce. POSIX behaviour is documented here: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/vi.html#tag_20_152_13_81 2): d{motion} may make the whole delete operation linewise, if the start and end of the motion are on different lines and there are only blanks before the start and after the end of the motion. Did not find a related POSIX link that requires this behaviour. Both behaviours can be considered inconsistent, but we cannot easily change it, because it would be a backward incompatible change and also incompatible to how classic vi behaved. So let's add the new cpo flag "z", which when not included fixes both behaviours and make them more consistent to what users would expect. This has been requested several times: https://groups.google.com/d/msg/vim_use/aaBqT6ECkA4/ALf4odKzEDgJ https://groups.google.com/d/msg/vim_dev/Dpn3xtUF16I/T6JcOPKN6usJ http://www.reddit.com/r/vim/comments/26nut8/why_does_cw_work_like_ce/ https://groups.google.com/d/msg/vim_use/vunNWLFWfQg/MmJh_ZGaAgAJ https://github.com/vim/vim/issues/4390 So in summary, if you want to have the w motion work more consistent, remove the 'z' from the cpo settings. related: #4390 closes: #15263 Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-07-15 20:51:11 +02:00
/**/
589,
/**/
588,
/**/
587,
/**/
586,
/**/
585,
/**/
584,
/**/
583,
/**/
582,
/**/
581,
/**/
580,
/**/
579,
/**/
578,
/**/
577,
/**/
576,
/**/
575,
/**/
574,
/**/
573,
/**/
572,
/**/
571,
/**/
570,
/**/
569,
/**/
568,
/**/
567,
/**/
566,
/**/
565,
/**/
564,
/**/
563,
/**/
562,
/**/
561,
/**/
560,
/**/
559,
/**/
558,
/**/
557,
/**/
556,
/**/
555,
/**/
554,
/**/
553,
/**/
552,
/**/
551,
/**/
550,
/**/
549,
/**/
548,
/**/
547,
/**/
546,
/**/
545,
/**/
544,
/**/
543,
/**/
542,
/**/
541,
/**/
540,
/**/
539,
/**/
538,
/**/
537,
/**/
536,
/**/
535,
/**/
534,
/**/
533,
/**/
532,
/**/
531,
/**/
530,
/**/
529,
/**/
528,
/**/
527,
/**/
526,
/**/
525,
/**/
524,
/**/
523,
/**/
522,
/**/
521,
/**/
520,
/**/
519,
/**/
518,
/**/
517,
/**/
516,
/**/
515,
/**/
514,
/**/
513,
/**/
512,
/**/
511,
/**/
510,
/**/
509,
/**/
508,
/**/
507,
/**/
506,
/**/
505,
/**/
504,
/**/
503,
/**/
502,
/**/
501,
/**/
500,
/**/
499,
/**/
498,
/**/
497,
/**/
496,
/**/
495,
/**/
494,
/**/
493,
/**/
492,
/**/
491,
/**/
490,
/**/
489,
/**/
488,
/**/
487,
/**/
486,
/**/
485,
/**/
484,
/**/
483,
patch 9.1.0482: termdebug plugin needs more love Problem: termdebug plugin needs more love Solution: start with some more Vim9 refactoring to improve maintenance and readability (Ubaldo Tiberi) List of Changes and the Reasoning Behind Them: 1) Introduction of InitScriptVariables() Function: Reasoning: This function has been introduced to ensure that when you open and close Termdebug, and then open it again, there are no leftover script variable values from the previous session. Leftover values could potentially cause issues. The goal is for each Termdebug session to be independent of previous sessions. At startup, all script variables are initialized. The only exception is g:termdebug_loaded located at the very beginning of the script to prevent sourcing the script twice. The variables are declared at script level and defined in InitScriptVariables(). 2) More Descriptive Variable Names: Reasoning: The names of variables have been made more comprehensive. Almost every Termdebug buffer now has a variable to indicate its name and another variable to indicate its number, improving code readability and maintainability. Due to the latest discussion around the &mousemodel option save/restore mechanism, perhaps some other variables shall be prepended with saved_. 3) Consistent Naming for GDB Terminal Buffers: Reasoning: The name of the GDB terminal buffer now matches the name of the GDB program being used, e.g., 'gdb', 'mygdb', 'arm-eabi-none-gdb', etc. This ensures clarity and consistency in identifying buffers. 4) Other minor improvements: Moved EchoErr() on top, added another test, some refactoring, mainly changed several 0 and 1 to true and false closes: #14980 Signed-off-by: Ubaldo Tiberi <ubaldo.tiberi@volvo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-06-13 19:23:07 +02:00
/**/
482,
/**/
481,
/**/
480,
/**/
479,
/**/
478,
/**/
477,
/**/
476,
/**/
475,
/**/
474,
/**/
473,
/**/
472,
/**/
471,
/**/
470,
/**/
469,
/**/
468,
/**/
467,
/**/
466,
/**/
465,
/**/
464,
/**/
463,
/**/
462,
/**/
461,
/**/
460,
/**/
459,
/**/
458,
/**/
457,
/**/
456,
/**/
455,
/**/
454,
/**/
453,
/**/
452,
/**/
451,
/**/
450,
/**/
449,
/**/
448,
/**/
447,
/**/
446,
/**/
445,
/**/
444,
/**/
443,
/**/
442,
/**/
441,
/**/
440,
/**/
439,
/**/
438,
/**/
437,
/**/
436,
/**/
435,
/**/
434,
/**/
433,
/**/
432,
/**/
431,
/**/
430,
/**/
429,
/**/
428,
/**/
427,
/**/
426,
/**/
425,
/**/
424,
/**/
423,
/**/
422,
/**/
421,
/**/
420,
/**/
419,
/**/
418,
/**/
417,
/**/
416,
/**/
415,
/**/
414,
/**/
413,
/**/
412,
/**/
411,
/**/
410,
/**/
409,
/**/
408,
/**/
407,
/**/
406,
/**/
405,
/**/
404,
/**/
403,
/**/
402,
/**/
401,
/**/
400,
/**/
399,
/**/
398,
/**/
397,
/**/
396,
/**/
395,
/**/
394,
/**/
393,
/**/
392,
/**/
391,
/**/
390,
/**/
389,
/**/
388,
/**/
387,
/**/
386,
/**/
385,
/**/
384,
/**/
383,
/**/
382,
/**/
381,
/**/
380,
/**/
379,
/**/
378,
/**/
377,
/**/
376,
/**/
375,
/**/
374,
/**/
373,
/**/
372,
/**/
371,
/**/
370,
/**/
369,
/**/
368,
/**/
367,
/**/
366,
/**/
365,
/**/
364,
/**/
363,
/**/
362,
/**/
361,
/**/
360,
/**/
359,
/**/
358,
/**/
357,
/**/
356,
/**/
355,
/**/
354,
/**/
353,
/**/
352,
/**/
351,
/**/
350,
/**/
349,
/**/
348,
/**/
347,
/**/
346,
/**/
345,
/**/
344,
/**/
343,
/**/
342,
/**/
341,
/**/
340,
/**/
339,
/**/
338,
/**/
337,
/**/
336,
/**/
335,
/**/
334,
/**/
333,
/**/
332,
/**/
331,
/**/
330,
/**/
329,
/**/
328,
/**/
327,
/**/
326,
/**/
325,
/**/
324,
/**/
323,
/**/
322,
/**/
321,
/**/
320,
/**/
319,
/**/
318,
/**/
317,
/**/
316,
/**/
315,
/**/
314,
/**/
313,
/**/
312,
/**/
311,
/**/
310,
/**/
309,
/**/
308,
/**/
307,
/**/
306,
/**/
305,
/**/
304,
/**/
303,
/**/
302,
/**/
301,
/**/
300,
/**/
299,
/**/
298,
/**/
297,
patch 9.1.0296: regexp: engines do not handle case-folding well Problem: Regex engines do not handle case-folding well Solution: Correctly calculate byte length of characters to skip When the regexp engine compares two utf-8 codepoints case insensitively it may match an adjacent character, because it assumes it can step over as many bytes as the pattern contains. This however is not necessarily true because of case-folding, a multi-byte UTF-8 character can be considered equal to some single-byte value. Let's consider the pattern 'ſ' and the string 's'. When comparing and ignoring case, the single character 's' matches, and since it matches Vim will try to step over the match (by the amount of bytes of the pattern), assuming that since it matches, the length of both strings is the same. However in that case, it should only step over the single byte value 's' so by 1 byte and try to start matching after it again. So for the backtracking engine we need to ensure: - we try to match the correct length for the pattern and the text - in case of a match, we step over it correctly The same thing can happen for the NFA engine, when skipping to the next character to test for a match. We are skipping over the regstart pointer, however we do not consider the case that because of case-folding we may need to adjust the number of bytes to skip over. So this needs to be adjusted in find_match_text() as well. A related issue turned out, when prog->match_text is actually empty. In that case we should try to find the next match and skip this condition. fixes: #14294 closes: #14433 Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-04-09 22:53:19 +02:00
/**/
296,
/**/
295,
/**/
294,
/**/
293,
/**/
292,
/**/
291,
/**/
290,
/**/
289,
/**/
288,
/**/
287,
/**/
286,
/**/
285,
/**/
284,
/**/
283,
/**/
282,
/**/
281,
/**/
280,
/**/
279,
/**/
278,
/**/
277,
/**/
276,
/**/
275,
/**/
274,
/**/
273,
/**/
272,
/**/
271,
/**/
270,
/**/
269,
/**/
268,
/**/
267,
/**/
266,
/**/
265,
/**/
264,
/**/
263,
/**/
262,
/**/
261,
/**/
260,
/**/
259,
/**/
258,
/**/
257,
/**/
256,
/**/
255,
/**/
254,
/**/
253,
/**/
252,
/**/
251,
/**/
250,
/**/
249,
/**/
248,
/**/
247,
/**/
246,
/**/
245,
/**/
244,
/**/
243,
/**/
242,
/**/
241,
/**/
240,
/**/
239,
/**/
238,
/**/
237,
/**/
236,
/**/
235,
/**/
234,
/**/
233,
/**/
232,
/**/
231,
/**/
230,
/**/
229,
/**/
228,
/**/
227,
/**/
226,
/**/
225,
/**/
224,
/**/
223,
/**/
222,
/**/
221,
/**/
220,
/**/
219,
/**/
218,
/**/
217,
/**/
216,
/**/
215,
/**/
214,
/**/
213,
/**/
212,
/**/
211,
/**/
210,
/**/
209,
/**/
208,
/**/
207,
/**/
206,
/**/
205,
/**/
204,
/**/
203,
/**/
202,
/**/
201,
/**/
200,
/**/
199,
/**/
198,
/**/
197,
/**/
196,
/**/
195,
/**/
194,
/**/
193,
/**/
192,
/**/
191,
/**/
190,
/**/
189,
/**/
188,
/**/
187,
/**/
186,
/**/
185,
/**/
184,
/**/
183,
/**/
182,
/**/
181,
/**/
180,
/**/
179,
/**/
178,
/**/
177,
/**/
176,
/**/
175,
/**/
174,
/**/
173,
/**/
172,
/**/
171,
patch 9.1.0170: Re-allow curwin == prevwin, but document it instead Problem: more places exist where curwin == prevwin, and it may even be expected in some cases. Solution: revert v9.1.0001, but document that it's possible instead. (Sean Dewar) I've had a change of heart for the following reasons: - A quick 'n dirty [GitHub code search](https://github.com/search?q=%2F%28winnr%5C%28%5C%29%5Cs*%3D%3D%5Cs*winnr%5C%28%5B%27%22%5D%23%5B%27%22%5D%5C%29%7Cwinnr%5C%28%5B%27%22%5D%23%5B%27%22%5D%5C%29%5Cs*%3D%3D%5Cs*winnr%5C%28%5C%29%29%2F&type=code) reveals some cases where it's expected in the wild. Particularly, it made me aware `winnr() == winnr('#')` is possible when curwin is changed temporarily during the evaluation of a &statusline expression item (`%{...}`), and is used to show something different on the statusline belonging to the previous window; that behaviour wasn't changed in v9.1.0001, but it means curwin == prevwin makes sense in some cases. - The definition and call sites of back_to_prevwin imply some expectation that prevwin == wp (== curwin) is possible, as it's used to skip entering the prevwin in that case. - Prior to v9.1.0001, `:wincmd p` would not beep in the case that was patched in v9.1.0001, but now does. That resulted in #14047 being opened, as it affected the CtrlP plugin. I find it odd that `:wincmd p` had cases where it wouldn't beep despite doing nothing, but it may be preferable to keep things that way (or instead also beep if curwin == prevwin, if that's preferred). - After more digging, I found cases in win_free_mem, enter_tabpage, aucmd_restbuf and qf_open_new_cwindow where curwin == prevwin is possible (many of them from autocommands). Others probably exist too, especially in places where curwin is changed temporarily. fixes: #14047 closes: #14186 Signed-off-by: Sean Dewar <6256228+seandewar@users.noreply.github.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-03-12 20:46:12 +01:00
/**/
170,
/**/
169,
/**/
168,
/**/
167,
/**/
166,
/**/
165,
/**/
164,
/**/
163,
patch 9.1.0162: problem with writing extended attributes on failure Problem: problem with writing extended attributes on failure Solution: Change return type to ssize_t and check listxattr's return value correctly on failure (Paul Tagliamonte) The existing logic will return when the listxattr call returns with the errno set to ENOTSUP (or a size of 0 bytes), without checking to see if listxattr actually failed. listxattr can fail with at least E2BIG, ENOTSUP, ERANGE, or anything that `stat(2)` can fail with (in my case; ENOENT from stat). The returned size is stored to a size_t, but the return type is a ssize_t. On failure, listxattr returns -1, which will get translated to size_t's MAX. If the listxattr call failed with anything other than ENOTSUP, this triggers a request for size_t MAX bytes. This means that, if the listxattr call fails with anything other than ENOTSUP on save, vim will error with `E342: Out of memory! (allocating 18446744073709551615 bytes)` (keen observers will note 18446744073709551615 is 0xffffffffffffffff) In reality, this is likely masking a different (usually filesystem?) error -- but at least it's an error being pushed to the user now, and we don't try to allocate size_t MAX bytes. I've opted to change the type that we store listxattr to from size_t to ssize_t, to match listxattr(2)'s signature, and to check for the -1 return value. Additionally, I've removed the errno check -- if we get a listxattr failure for any reason, we may as well bail without trying; it's not like we can even recover. closes: #14169 Signed-off-by: Paul Tagliamonte <paultag@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-03-10 08:35:10 +01:00
/**/
162,
/**/
161,
/**/
160,
/**/
159,
/**/
158,
/**/
157,
/**/
156,
/**/
155,
/**/
154,
/**/
153,
/**/
152,
/**/
151,
patch 9.1.0150: Several minor 'winfixbuf' issues Problem: several minor 'winfixbuf' issues exist, mostly relating to the quickfix list Solution: address them and adjust tests. Retab and reflow a few things too. (Sean Dewar) Things touched include: - Replace the semsgs with gettext'd emsgs. - Handle window switching in ex_listdo properly, so curbuf and curwin are kept in-sync and trigger autocommands; handle those properly. - Don't change the list entry index in qf_jump_edit_buffer if we fail due to 'wfb' (achieved by returning FAIL; QF_ABORT should only be used if the list was changed). - Make qf_jump_edit_buffer actually switch to prevwin when using `:cXX` commands **outside** of the list window if 'wfb' is set in curwin. Handle autocommands properly in case they mess with the list. NOTE: previously, it seemed to split if 'wfb' was set, but do nothing and fail if prevwin is *valid*. This behaviour seemed strange, and maybe unintentional? Now it aligns more with what's described for the `:cXX` commands in the original PR description when used outside a list window, I think. - In both functions, only consider prevwin if 'wfb' isn't set for it; fallback to splitting otherwise. - Use win_split to split. Not sure if there was a specific reason for using ex_splitview. win_split is simpler and respects modifiers like :vertical that may have been used. Plus, its return value can be checked for setting opened_window in qf code (technically win_split_ins autocmds could immediately close it or change windows, in which the qf code might close some other window on failure; it's already the case elsewhere, though). closes: #14142 Signed-off-by: Sean Dewar <6256228+seandewar@users.noreply.github.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-03-05 20:39:07 +01:00
/**/
150,
/**/
149,
/**/
148,
/**/
147,
/**/
146,
/**/
145,
/**/
144,
patch 9.1.0143: [security]: autocmd causes use-after-free in set_curbuf() Problem: [security]: autocmd cause use-after-free in set_curbuf() (kawarimidoll) Solution: check side-effect of BufLeave autocommand, when the number of windows changed, close windows containing buffers that will be wiped, if curbuf changed unexpectedly make sure b_nwindows is decremented otherwise it cannot be wiped set_curbuf() already makes some efforts to ensure the BufLeave autocommands do not cause issues. However there are still 2 issues that are not taken care of: 1) If a BufLeave autocommand opens a new window containing the same buffer as that is going got be closed in close_buffer() a bit later, we suddenly have another window open, containing a free'd buffer. So we must check if the number of windows changed and if it does (and the current buffer is going to be wiped (according to the 'bufhidden' setting), let's immediately close all windows containing the current buffer using close_windows() 2) If a BufLeave autocommand changes our current buffer (displays it in the current window), buf->b_nwindow will be incremented. As part of set_curbuf() we will however enter another buffer soon, which means, the newly created curbuf will have b_nwindows still have set, even so the buffer is no longer displayed in a window. This causes later problems, because it will no longer be possible to wipe such a buffer. So just before entering the final buffer, check if the curbuf changed when calling the BufLeave autocommand and if it does (and curbuf is still valid), decrement curbuf->b_nwindows. Both issues can be verified using the provided test (however the second issue only because such an impacted buffer won't be wiped, causing futher issues in later tests). fixes: #13839 closes: #14104 Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-02-28 23:32:00 +01:00
/**/
143,
/**/
142,
/**/
141,
/**/
140,
/**/
139,
/**/
138,
/**/
137,
/**/
136,
/**/
135,
/**/
134,
/**/
133,
/**/
132,
patch 9.1.0131: buffer-completion may not always find all matches Problem: buffer-completion code too complicated and does not always find all matches (irisjae) Solution: do not try to anchor pattern to beginning of line or directory-separator, always return all matches Note: we are considering the non-fuzzy buffer-matching here. Currently, the buffer-completion code makes 2 attempts to match a pattern against the list of available patterns. First try is to match the pattern and anchor it to either the beginning of the file name or at a directory-separator (// or \\). When a match is found, Vim returns the matching buffers and does not try to find a match anywhere within a buffer name. So if you have opened two buffers like /tmp/Foobar.c and /tmp/MyFoobar.c using `:b Foo` will only complete to the first filename, but not the second (the same happens with `getcompletion('Foo', 'buffer')`). It may make sense, that completion priorities buffer names at directory boundaries, but it inconsistent, may cause confusion why a certain buffer name is not completed when typing `:b Foo<C-D>` which returns only a single file name and then pressing Enter (to switch to that buffer), Vim will error with 'E93: More than one match for Foo'). Similar things may happen when wiping the /tmp/Foobar.c pattern and afterwards the completion starts completing other buffers. So let's simplify the code and always match the pattern anywhere in the buffer name, do not try to favor matches at directory boundaries. This is also simplifies the code a bit, we do not need to run over the list of buffers several times, but only twice. fixes #13894 closes: #14082 Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-02-24 14:12:13 +01:00
/**/
131,
/**/
130,
/**/
129,
/**/
128,
/**/
127,
/**/
126,
/**/
125,
/**/
124,
patch 9.1.0123: MS-Windows: system() may deadlock Problem: MS-Windows: system() may deadlock when calling binaries that expect stdin Solution: Ignore the SHELL_EXPAND flag (GuyBrush) This happens on binaries that expect stdin. For example: :echo system("xxd") will cause a deadlock. SHELL_EXPAND is a flag devoted to support the linux implementation of the backtick-expansion mechanism. On linux backtic-expansion relies in the function mch_expand_wildchars() (os_unix.c) that delegates on each specific shell (bash, sh, csh, zsh) the expansion. Basically it composes a shell command that does the expansion and redirects the output to a file and call_shell() it. On windows backtick-expansion is performed by Vim itself. On linux SHELL_EXPAND modifies how mch_call_shell_fork() (os_unix.c) works. This function: - relies on posix fork() to spawn a child process to execute a external command. - Child and parent process communicate using pipes (or pseudoterminal if available). User input (type ahead content) is processed in a loop only if !(SHELL_EXPAND || SHELL_COOKED). Though signals are used to detect Ctrl-C in all cases (the input loop is not necessary to interrupt the function). In the backtick-expansion the external command is the shell command that provides the expansion. For the child redirection: - SHELL_EXPAND replaces stdin, stdout & stderr to /dev/null. This is why the shell command composed includes redirection (otherwise output would be lost). - !SHELL_EXPAND replaces stdin, stdout & stderr with the parent created pipes (or pseudoterminal). Note that the use of SIGINT signal prevents mch_call_shell_fork() from hanging vim. On Windows mch_system_piped() (os_win32.c) (which is only used when the GUI is running) mimics mch_call_shell_fork() (os_unix.c). Win32 lacks fork() and relies on CreateProcessW() and only has pipe support (not pseudoterminal) which makes the implementation much different. But, the key idea is that windows lacks signals, the OS provides support for console apps but gvim is not one. The only way of detecting a Ctrl-C is actually processing user input (type ahead content). By ignoring the user input under SHELL_EXPAND the function can hang gvim. Ignoring SHELL_EXPAND flag has no consequence in Windows because as mentioned above it is only meaningful in linux. closes: #13988 Signed-off-by: GuyBrush <miguel.barro@live.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-02-21 20:16:38 +01:00
/**/
123,
/**/
122,
/**/
121,
/**/
120,
/**/
119,
/**/
118,
patch 9.1.0117: Stop split-moving from firing WinNew and WinNewPre autocommands Problem: win_splitmove fires WinNewPre and possibly WinNew when moving windows, even though no new windows are created. Solution: don't fire WinNew and WinNewPre when inserting an existing window, even if it isn't the current window. Improve the accuracy of related documentation. (Sean Dewar) Likewise, before this patch, WinClosed was not fired anyway (even for :wincmd H/J/K/L, which also didn't fire WinNew, but did still fire WinNewPre), despite documentation saying windows are "closed". Note that :wincmd T actually indeed works by creating a new window (and closing the old one), unlike the others. This also fixes issues where WinNewPre is fired when split-moving while curwin doesn't yet have a frame or entry in the window list, causing many things to not work (it's not considered valid at that point). This was guaranteed when using :wincmd H/J/K/L. Because WinNewPre is no longer fired when split-moving, this makes restoring the previous window layout on failure easier, as we can be sure that frames are not resized from WinNewPre autocommands if win_split_ins fails. This allows us to use a different strategy in the following commit. -- In my opinion, this leaves questions about the current usefulness of WinNewPre. A motivation described in #10635 states how creating a new window can steal room from other windows, and how WinNewPre will be useful for detecting that, but this is also true when inserting an existing window, which now doesn't fire it. Maybe the autocommand should be changed to have a better name? There are also other issues I found with the current implementation of WinNewPre that need addressing: - it allows switching windows and tabpages, which can cause incorrect windows to be split/moved, and big problems when switching tabpages. - it fires before win_split_ins checks for room, before it makes any changes to window sizes or before it considers allocating a new window. This should be changed or documented. I hope to address some of this stuff in a different PR, if possible. related: #14038 Signed-off-by: Sean Dewar <6256228+seandewar@users.noreply.github.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-02-20 21:52:31 +01:00
/**/
117,
patch 9.1.0116: win_split_ins may not check available room Problem: win_split_ins has no check for E36 when moving an existing window Solution: check for room and fix the issues in f_win_splitmove() (Sean Dewar) win_split_ins has no check for E36 when moving an existing window, allowing for layouts with many overlapping zero-sized windows to be created (which may also cause drawing issues with tablines and such). f_win_splitmove also has some bugs. So check for room and fix the issues in f_win_splitmove. Handle failure in the two relevant win_split_ins callers by restoring the original layout, and factor the common logic into win_splitmove. Don't check for room when opening an autocommand window, as it's a temporary window that's rarely interacted with or drawn anyhow, and is rather important for some autocommands. Issues fixed in f_win_splitmove: - Error if splitting is disallowed. - Fix heap-use-after-frees if autocommands fired from switching to "targetwin" close "wp" or "oldwin". - Fix splitting the wrong window if autocommands fired from switching to "targetwin" switch to a different window. - Ensure -1 is returned for all errors. Also handle allocation failure a bit earlier in make_snapshot (callers, except win_splitmove, don't really care if a snapshot can't be made, so just ignore the return value). Note: Test_smoothscroll_in_zero_width_window failed after these changes with E36, as it was using the previous behaviour to create a zero-width window. I've fixed the test such that it fails with UBSAN as expected when v9.0.1367 is reverted (and simplified it too). related: #14042 Signed-off-by: Sean Dewar <6256228+seandewar@users.noreply.github.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-02-20 20:28:15 +01:00
/**/
116,
/**/
115,
/**/
114,
/**/
113,
/**/
112,
/**/
111,
/**/
110,
/**/
109,
/**/
108,
patch 9.1.0107: CI: Fix MacOS-14 tests Problem: CI: Fix MacOS-14 tests (after 9.1.0070) Solution: Re-enable sound tests by granting Mic access, disable Test_diff_screen because of buggy MacOS diff (non GNU version), re-enable Test_term_gettitle() (Yee Cheng Chin) macos-14 runner was turned on in #13943, but it had to turn off a few tests in order for CI to run. Re-enable them and fix the underlying issues. * `Test_diff_screen`: The test failure is due to a bug in Apple's diff utility. Apple introduced a new diff tool based on FreeBSD in macOS 13 and it has buggy behaviors when using unified diff (`-U0`) and the diff is on the first line of the file. Simply disable this test for now if we detect Apple diff (instead of the old GNU diff). Can re-enable this in the future if Apple fixes the issue. * `Test_play_event` / `Test_play_silent`: GitHub Actions currently has an issue with playing sound in CI in macos-14 runners. It for some reason triggers a microphone permission dialog popup which blocks the CI action (see https://github.com/actions/runner-images/issues/9330). To fix this, add a temporary step in macos-14 to manually allow microphone permissions in the runner. * `Test_term_gettitle`: I could not reproduce the failure, so I just turned it on and it seems to run just fine. Maybe it's a timing issue and whatnot but either way that should be fixed when we can reproduce the issue. closes: #14032 Signed-off-by: Yee Cheng Chin <ychin.git@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-02-14 20:34:58 +01:00
/**/
107,
/**/
106,
/**/
105,
/**/
104,
/**/
103,
/**/
102,
/**/
101,
/**/
100,
/**/
99,
/**/
98,
/**/
97,
/**/
96,
/**/
95,
/**/
94,
/**/
93,
/**/
92,
/**/
91,
/**/
90,
/**/
89,
/**/
88,
/**/
87,
/**/
86,
/**/
85,
/**/
84,
/**/
83,
/**/
82,
/**/
81,
/**/
80,
/**/
79,
/**/
78,
/**/
77,
/**/
76,
/**/
75,
/**/
74,
/**/
73,
/**/
72,
/**/
71,
/**/
70,
/**/
69,
/**/
68,
/**/
67,
/**/
66,
/**/
65,
/**/
64,
/**/
63,
/**/
62,
/**/
61,
/**/
60,
/**/
59,
/**/
58,
/**/
57,
/**/
56,
/**/
55,
/**/
54,
/**/
53,
/**/
52,
/**/
51,
/**/
50,
/**/
49,
/**/
48,
/**/
47,
/**/
46,
/**/
45,
/**/
44,
/**/
43,
/**/
42,
/**/
41,
/**/
40,
/**/
39,
/**/
38,
/**/
37,
/**/
36,
/**/
35,
/**/
34,
/**/
33,
/**/
32,
/**/
31,
/**/
30,
/**/
29,
/**/
28,
/**/
27,
/**/
26,
/**/
25,
/**/
24,
/**/
23,
/**/
22,
/**/
21,
/**/
20,
/**/
19,
/**/
18,
/**/
17,
/**/
16,
/**/
15,
patch 9.1.0014: incorrect use of W_WINROW in edit.c Problem: incorrect use of W_WINROW in edit.c Solution: compare against curwin->w_height instead Remove incorrect use of W_WINROW In structs.h it is mentioned that w_wrow is relative to w_winrow, so using W_WINROW doesn't make sense when comparing with window height. This change won't lead to any observable behavior change: The condition intends to check if there are 'scrolloff' lines between the current cursor when the bottom of the window. When W_WINROW(curwin) is added to curwin->w_height - 1 - get_scrolloff_value(), the condition is instead satisfied when the cursor is on some screen line below that position. However, - If 'scrolloff' is smaller than half the window height, this condition can only be satisfied when W_WINROW(curwin) == 0. And if it is not satisfied, update_topline() does the actual scrolling. - If 'scrolloff' is larger than half the window height, update_topline() will put the cursor at the center of the window soon afterwards anyway, because set_topline() now unsets VALID_TOPLINE flag starting from https://github.com/vim/vim-history/commit/7db7bb45b0f919ff0615d463ebd4fde881c69d1f. To put it in another way, https://github.com/vim/vim-history/commit/7db7bb45b0f919ff0615d463ebd4fde881c69d1f makes the update_topline() just below correct the mistakes made in this block, so this incorrect use of W_WINROW() no longer affects observable behavior. closes: #12331 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-01-05 18:11:43 +01:00
/**/
14,
/**/
13,
/**/
12,
/**/
11,
/**/
10,
/**/
9,
/**/
8,
/**/
7,
/**/
6,
/**/
5,
/**/
4,
/**/
3,
/**/
2,
/**/
1,
2004-06-13 20:20:40 +00:00
/**/
0
};
2008-11-30 11:15:09 +00:00
/*
* Place to put a short description when adding a feature with a patch.
* Keep it short, e.g.,: "relative numbers", "persistent undo".
* Also add a comment marker to separate the lines.
* See the official Vim patches for the diff format: It must use a context of
2008-12-24 13:25:14 +00:00
* one line only. Create it by hand or use "diff -C2" and edit the patch.
2008-11-30 11:15:09 +00:00
*/
static char *(extra_patches[]) =
{ /* Add your patch description below this line */
/**/
NULL
};
2004-06-13 20:20:40 +00:00
int
highest_patch(void)
2004-06-13 20:20:40 +00:00
{
// this relies on the highest patch number to be the first entry
return included_patches[0];
2004-06-13 20:20:40 +00:00
}
#if defined(FEAT_EVAL) || defined(PROTO)
/*
* Return TRUE if patch "n" has been included.
*/
int
has_patch(int n)
2004-06-13 20:20:40 +00:00
{
int h, m, l;
2004-06-13 20:20:40 +00:00
// Perform a binary search.
l = 0;
h = (int)ARRAY_LENGTH(included_patches) - 1;
for (;;)
{
m = (l + h) / 2;
if (included_patches[m] == n)
2004-06-13 20:20:40 +00:00
return TRUE;
if (l == h)
break;
if (included_patches[m] < n)
h = m;
else
l = m + 1;
}
2004-06-13 20:20:40 +00:00
return FALSE;
}
#endif
void
ex_version(exarg_T *eap)
2004-06-13 20:20:40 +00:00
{
/*
* Ignore a ":version 9.99" command.
*/
if (*eap->arg == NUL)
{
msg_putchar('\n');
list_version();
}
}
/*
* Output a string for the version message. If it's going to wrap, output a
* newline, unless the message is too long to fit on the screen anyway.
* When "wrap" is TRUE wrap the string in [].
*/
static void
version_msg_wrap(char_u *s, int wrap)
{
int len = vim_strsize(s) + (wrap ? 2 : 0);
if (!got_int && len < (int)Columns && msg_col + len >= (int)Columns
&& *s != '\n')
msg_putchar('\n');
if (!got_int)
{
if (wrap)
msg_puts("[");
msg_puts((char *)s);
if (wrap)
msg_puts("]");
}
}
static void
version_msg(char *s)
{
version_msg_wrap((char_u *)s, FALSE);
}
/*
* List all features aligned in columns, dictionary style.
*/
static void
list_features(void)
{
list_in_columns((char_u **)features, -1, -1);
}
/*
* List string items nicely aligned in columns.
* When "size" is < 0 then the last entry is marked with NULL.
* The entry with index "current" is inclosed in [].
*/
void
list_in_columns(char_u **items, int size, int current)
{
int i;
int ncol;
int nrow;
int cur_row = 1;
int item_count = 0;
int width = 0;
#ifdef FEAT_SYN_HL
int use_highlight = (items == (char_u **)features);
#endif
// Find the length of the longest item, use that + 1 as the column
// width.
for (i = 0; size < 0 ? items[i] != NULL : i < size; ++i)
{
int l = vim_strsize(items[i]) + (i == current ? 2 : 0);
if (l > width)
width = l;
++item_count;
}
width += 1;
if (Columns < width)
{
// Not enough screen columns - show one per line
for (i = 0; i < item_count; ++i)
{
version_msg_wrap(items[i], i == current);
if (msg_col > 0 && i < item_count - 1)
msg_putchar('\n');
}
return;
}
// The rightmost column doesn't need a separator.
// Sacrifice it to fit in one more column if possible.
ncol = (int) (Columns + 1) / width;
nrow = item_count / ncol + ((item_count % ncol) ? 1 : 0);
// "i" counts columns then rows. "idx" counts rows then columns.
for (i = 0; !got_int && i < nrow * ncol; ++i)
{
int idx = (i / ncol) + (i % ncol) * nrow;
if (idx < item_count)
{
int last_col = (i + 1) % ncol == 0;
if (idx == current)
msg_putchar('[');
#ifdef FEAT_SYN_HL
if (use_highlight && items[idx][0] == '-')
msg_puts_attr((char *)items[idx], HL_ATTR(HLF_W));
else
#endif
msg_puts((char *)items[idx]);
if (idx == current)
msg_putchar(']');
if (last_col)
{
if (msg_col > 0 && cur_row < nrow)
msg_putchar('\n');
++cur_row;
}
else
{
while (msg_col % width)
msg_putchar(' ');
}
}
else
{
// this row is out of items, thus at the end of the row
if (msg_col > 0)
{
if (cur_row < nrow)
msg_putchar('\n');
++cur_row;
}
}
}
}
2004-06-13 20:20:40 +00:00
void
list_version(void)
2004-06-13 20:20:40 +00:00
{
int i;
int first;
char *s = "";
/*
* When adding features here, don't forget to update the list of
* internal variables in eval.c!
*/
init_longVersion();
msg(longVersion);
#ifdef MSWIN
# ifdef FEAT_GUI_MSWIN
# ifdef VIMDLL
# ifdef _WIN64
msg_puts(_("\nMS-Windows 64-bit GUI/console version"));
# else
msg_puts(_("\nMS-Windows 32-bit GUI/console version"));
# endif
# else
# ifdef _WIN64
msg_puts(_("\nMS-Windows 64-bit GUI version"));
# else
msg_puts(_("\nMS-Windows 32-bit GUI version"));
# endif
2004-06-13 20:20:40 +00:00
# endif
# ifdef FEAT_OLE
msg_puts(_(" with OLE support"));
# endif
2004-06-13 20:20:40 +00:00
# else
2008-06-20 14:32:41 +00:00
# ifdef _WIN64
msg_puts(_("\nMS-Windows 64-bit console version"));
2008-06-20 14:32:41 +00:00
# else
msg_puts(_("\nMS-Windows 32-bit console version"));
2008-06-20 14:32:41 +00:00
# endif
2004-06-13 20:20:40 +00:00
# endif
#endif
#if defined(MACOS_X)
# if defined(MACOS_X_DARWIN)
msg_puts(_("\nmacOS version"));
# else
msg_puts(_("\nmacOS version w/o darwin feat."));
2004-06-13 20:20:40 +00:00
# endif
# if defined(__arm64__)
msg_puts(" - arm64");
# elif defined(__x86_64__)
msg_puts(" - x86_64");
# endif
2004-06-13 20:20:40 +00:00
#endif
#ifdef VMS
msg_puts(_("\nOpenVMS version"));
2006-11-28 16:43:58 +00:00
# ifdef HAVE_PATHDEF
if (*compiled_arch != NUL)
{
msg_puts(" - ");
msg_puts((char *)compiled_arch);
2006-11-28 16:43:58 +00:00
}
# endif
2004-06-13 20:20:40 +00:00
#endif
// Print the list of patch numbers if there is at least one.
// Print a range when patches are consecutive: "1-10, 12, 15-40, 42-45"
2004-06-13 20:20:40 +00:00
if (included_patches[0] != 0)
{
msg_puts(_("\nIncluded patches: "));
2004-06-13 20:20:40 +00:00
first = -1;
i = (int)ARRAY_LENGTH(included_patches) - 1;
2004-06-13 20:20:40 +00:00
while (--i >= 0)
{
if (first < 0)
first = included_patches[i];
if (i == 0 || included_patches[i - 1] != included_patches[i] + 1)
{
msg_puts(s);
2004-06-13 20:20:40 +00:00
s = ", ";
msg_outnum((long)first);
if (first != included_patches[i])
{
msg_puts("-");
2004-06-13 20:20:40 +00:00
msg_outnum((long)included_patches[i]);
}
first = -1;
}
}
}
// Print the list of extra patch descriptions if there is at least one.
2008-11-30 11:15:09 +00:00
if (extra_patches[0] != NULL)
{
msg_puts(_("\nExtra patches: "));
2008-11-30 11:15:09 +00:00
s = "";
for (i = 0; extra_patches[i] != NULL; ++i)
{
msg_puts(s);
2008-11-30 11:15:09 +00:00
s = ", ";
msg_puts(extra_patches[i]);
2008-11-30 11:15:09 +00:00
}
}
2004-06-13 20:20:40 +00:00
#ifdef MODIFIED_BY
msg_puts("\n");
msg_puts(_("Modified by "));
msg_puts(MODIFIED_BY);
2004-06-13 20:20:40 +00:00
#endif
#ifdef HAVE_PATHDEF
if (*compiled_user != NUL || *compiled_sys != NUL)
{
msg_puts(_("\nCompiled "));
2004-06-13 20:20:40 +00:00
if (*compiled_user != NUL)
{
msg_puts(_("by "));
msg_puts((char *)compiled_user);
2004-06-13 20:20:40 +00:00
}
if (*compiled_sys != NUL)
{
msg_puts("@");
msg_puts((char *)compiled_sys);
2004-06-13 20:20:40 +00:00
}
}
#endif
#if defined(FEAT_HUGE)
msg_puts(_("\nHuge version "));
#elif defined(FEAT_NORMAL)
msg_puts(_("\nNormal version "));
#else
msg_puts(_("\nTiny version "));
2004-06-13 20:20:40 +00:00
#endif
#if !defined(FEAT_GUI)
msg_puts(_("without GUI."));
#elif defined(FEAT_GUI_GTK)
# if defined(USE_GTK3)
msg_puts(_("with GTK3 GUI."));
# elif defined(FEAT_GUI_GNOME)
msg_puts(_("with GTK2-GNOME GUI."));
# else
msg_puts(_("with GTK2 GUI."));
# endif
#elif defined(FEAT_GUI_MOTIF)
msg_puts(_("with X11-Motif GUI."));
#elif defined(FEAT_GUI_HAIKU)
msg_puts(_("with Haiku GUI."));
#elif defined(FEAT_GUI_PHOTON)
msg_puts(_("with Photon GUI."));
#elif defined(MSWIN)
msg_puts(_("with GUI."));
2004-06-13 20:20:40 +00:00
#endif
version_msg(_(" Features included (+) or not (-):\n"));
list_features();
if (msg_col > 0)
msg_putchar('\n');
2004-06-13 20:20:40 +00:00
#ifdef SYS_VIMRC_FILE
version_msg(_(" system vimrc file: \""));
version_msg(SYS_VIMRC_FILE);
version_msg("\"\n");
#endif
#ifdef USR_VIMRC_FILE
version_msg(_(" user vimrc file: \""));
version_msg(USR_VIMRC_FILE);
version_msg("\"\n");
#endif
#ifdef USR_VIMRC_FILE2
version_msg(_(" 2nd user vimrc file: \""));
version_msg(USR_VIMRC_FILE2);
version_msg("\"\n");
#endif
#if defined(USR_VIMRC_FILE3) && defined(XDG_VIMRC_FILE)
2004-06-13 20:20:40 +00:00
version_msg(_(" 3rd user vimrc file: \""));
version_msg(USR_VIMRC_FILE3);
version_msg("\"\n");
version_msg(_(" 4th user vimrc file: \""));
version_msg((char *)(XDG_VIMRC_FILE));
version_msg("\"\n");
#elif defined(USR_VIMRC_FILE3)
version_msg(_(" 3rd user vimrc file: \""));
version_msg(USR_VIMRC_FILE3);
version_msg("\"\n");
#elif defined(XDG_VIMRC_FILE)
version_msg(_(" 3rd user vimrc file: \""));
version_msg((char *)(XDG_VIMRC_FILE));
version_msg("\"\n");
2004-06-13 20:20:40 +00:00
#endif
#ifdef USR_EXRC_FILE
version_msg(_(" user exrc file: \""));
version_msg(USR_EXRC_FILE);
version_msg("\"\n");
#endif
#ifdef USR_EXRC_FILE2
version_msg(_(" 2nd user exrc file: \""));
version_msg(USR_EXRC_FILE2);
version_msg("\"\n");
#endif
#ifdef FEAT_GUI
# ifdef SYS_GVIMRC_FILE
version_msg(_(" system gvimrc file: \""));
version_msg(SYS_GVIMRC_FILE);
version_msg("\"\n");
# endif
version_msg(_(" user gvimrc file: \""));
version_msg(USR_GVIMRC_FILE);
version_msg("\"\n");
# ifdef USR_GVIMRC_FILE2
version_msg(_("2nd user gvimrc file: \""));
version_msg(USR_GVIMRC_FILE2);
version_msg("\"\n");
# endif
# ifdef USR_GVIMRC_FILE3
version_msg(_("3rd user gvimrc file: \""));
version_msg(USR_GVIMRC_FILE3);
version_msg("\"\n");
# endif
#endif
version_msg(_(" defaults file: \""));
version_msg(VIM_DEFAULTS_FILE);
version_msg("\"\n");
2004-06-13 20:20:40 +00:00
#ifdef FEAT_GUI
# ifdef SYS_MENU_FILE
version_msg(_(" system menu file: \""));
version_msg(SYS_MENU_FILE);
version_msg("\"\n");
# endif
#endif
#ifdef HAVE_PATHDEF
if (*default_vim_dir != NUL)
{
version_msg(_(" fall-back for $VIM: \""));
version_msg((char *)default_vim_dir);
version_msg("\"\n");
}
if (*default_vimruntime_dir != NUL)
{
version_msg(_(" f-b for $VIMRUNTIME: \""));
version_msg((char *)default_vimruntime_dir);
version_msg("\"\n");
}
version_msg(_("Compilation: "));
version_msg((char *)all_cflags);
version_msg("\n");
#ifdef VMS
if (*compiler_version != NUL)
{
version_msg(_("Compiler: "));
version_msg((char *)compiler_version);
version_msg("\n");
}
#endif
version_msg(_("Linking: "));
version_msg((char *)all_lflags);
#endif
#ifdef DEBUG
version_msg("\n");
version_msg(_(" DEBUG BUILD"));
#endif
}
static void do_intro_line(int row, char_u *mesg, int add_version, int attr);
static void intro_message(int colon);
2004-06-13 20:20:40 +00:00
/*
* Show the intro message when not editing a file.
*/
void
maybe_intro_message(void)
{
if (BUFEMPTY()
&& curbuf->b_fname == NULL
&& firstwin->w_next == NULL
&& vim_strchr(p_shm, SHM_INTRO) == NULL)
intro_message(FALSE);
}
2004-06-13 20:20:40 +00:00
/*
* Give an introductory message about Vim.
* Only used when starting Vim on an empty file, without a file name.
* Or with the ":intro" command (for Sven :-).
*/
static void
intro_message(
int colon) // TRUE for ":intro"
2004-06-13 20:20:40 +00:00
{
int i;
int row;
int blanklines;
int sponsor;
char *p;
static char *(lines[]) =
{
N_("VIM - Vi IMproved"),
"",
N_("version "),
N_("by Bram Moolenaar et al."),
#ifdef MODIFIED_BY
" ",
#endif
N_("Vim is open source and freely distributable"),
"",
N_("Help poor children in Uganda!"),
N_("type :help iccf<Enter> for information "),
"",
N_("type :q<Enter> to exit "),
N_("type :help<Enter> or <F1> for on-line help"),
N_("type :help version9<Enter> for version info"),
2004-06-13 20:20:40 +00:00
NULL,
"",
N_("Running in Vi compatible mode"),
N_("type :set nocp<Enter> for Vim defaults"),
N_("type :help cp-default<Enter> for info on this"),
};
#ifdef FEAT_GUI
static char *(gui_lines[]) =
{
NULL,
NULL,
NULL,
NULL,
#ifdef MODIFIED_BY
NULL,
#endif
NULL,
NULL,
NULL,
N_("menu Help->Orphans for information "),
NULL,
N_("Running modeless, typed text is inserted"),
N_("menu Edit->Global Settings->Toggle Insert Mode "),
N_(" for two modes "),
NULL,
NULL,
NULL,
N_("menu Edit->Global Settings->Toggle Vi Compatible"),
N_(" for Vim defaults "),
};
#endif
// blanklines = screen height - # message lines
blanklines = (int)Rows - (ARRAY_LENGTH(lines) - 1);
2004-06-13 20:20:40 +00:00
if (!p_cp)
blanklines += 4; // add 4 for not showing "Vi compatible" message
2004-06-13 20:20:40 +00:00
// Don't overwrite a statusline. Depends on 'cmdheight'.
2004-06-13 20:20:40 +00:00
if (p_ls > 1)
blanklines -= Rows - topframe->fr_height;
if (blanklines < 0)
blanklines = 0;
// Show the sponsor and register message one out of four times, the Uganda
// message two out of four times.
2005-12-22 22:47:02 +00:00
sponsor = (int)time(NULL);
2004-06-13 20:20:40 +00:00
sponsor = ((sponsor & 2) == 0) - ((sponsor & 4) == 0);
// start displaying the message lines after half of the blank lines
2004-06-13 20:20:40 +00:00
row = blanklines / 2;
if ((row >= 2 && Columns >= 50) || colon)
{
for (i = 0; i < (int)ARRAY_LENGTH(lines); ++i)
2004-06-13 20:20:40 +00:00
{
p = lines[i];
#ifdef FEAT_GUI
if (p_im && gui.in_use && gui_lines[i] != NULL)
p = gui_lines[i];
#endif
if (p == NULL)
{
if (!p_cp)
break;
continue;
}
if (sponsor != 0)
{
if (strstr(p, "children") != NULL)
p = sponsor < 0
? N_("Sponsor Vim development!")
: N_("Become a registered Vim user!");
else if (strstr(p, "iccf") != NULL)
p = sponsor < 0
? N_("type :help sponsor<Enter> for information ")
: N_("type :help register<Enter> for information ");
else if (strstr(p, "Orphans") != NULL)
p = N_("menu Help->Sponsor/Register for information ");
}
if (*p != NUL)
do_intro_line(row, (char_u *)_(p), i == 2, 0);
++row;
}
}
// Make the wait-return message appear just below the text.
2004-06-13 20:20:40 +00:00
if (colon)
msg_row = row;
}
static void
do_intro_line(
int row,
char_u *mesg,
int add_version,
int attr)
2004-06-13 20:20:40 +00:00
{
char_u vers[20];
int col;
char_u *p;
int l;
int clen;
#ifdef MODIFIED_BY
# define MODBY_LEN 150
char_u modby[MODBY_LEN];
if (*mesg == ' ')
{
2008-01-05 12:59:22 +00:00
vim_strncpy(modby, (char_u *)_("Modified by "), MODBY_LEN - 1);
l = (int)STRLEN(modby);
2008-01-05 12:59:22 +00:00
vim_strncpy(modby + l, (char_u *)MODIFIED_BY, MODBY_LEN - l - 1);
2004-06-13 20:20:40 +00:00
mesg = modby;
}
#endif
// Center the message horizontally.
2004-06-13 20:20:40 +00:00
col = vim_strsize(mesg);
if (add_version)
{
STRCPY(vers, mediumVersion);
if (highest_patch())
{
// Check for 9.9x or 9.9xx, alpha/beta version
if (SAFE_isalpha((int)vers[3]))
2004-06-13 20:20:40 +00:00
{
int len = (SAFE_isalpha((int)vers[4])) ? 5 : 4;
sprintf((char *)vers + len, ".%d%s", highest_patch(),
mediumVersion + len);
2004-06-13 20:20:40 +00:00
}
else
sprintf((char *)vers + 3, ".%d", highest_patch());
}
col += (int)STRLEN(vers);
}
col = (Columns - col) / 2;
if (col < 0)
col = 0;
// Split up in parts to highlight <> items differently.
2004-06-13 20:20:40 +00:00
for (p = mesg; *p != NUL; p += l)
{
clen = 0;
for (l = 0; p[l] != NUL
&& (l == 0 || (p[l] != '<' && p[l - 1] != '>')); ++l)
{
if (has_mbyte)
{
clen += ptr2cells(p + l);
2005-08-10 21:07:57 +00:00
l += (*mb_ptr2len)(p + l) - 1;
2004-06-13 20:20:40 +00:00
}
else
clen += byte2cells(p[l]);
}
screen_puts_len(p, l, row, col, *p == '<' ? HL_ATTR(HLF_8) : attr);
2004-06-13 20:20:40 +00:00
col += clen;
}
// Add the version number to the version line.
2004-06-13 20:20:40 +00:00
if (add_version)
screen_puts(vers, row, col, 0);
}
/*
* ":intro": clear screen, display intro screen and wait for return.
*/
void
ex_intro(exarg_T *eap UNUSED)
2004-06-13 20:20:40 +00:00
{
screenclear();
intro_message(TRUE);
wait_return(TRUE);
}