summaryrefslogtreecommitdiffstats
path: root/src/evalfunc.c
AgeCommit message (Collapse)Author
2024-06-01patch 9.1.0456: Left shift is incorrect with vartabstop and shiftwidth=0v9.1.0456Gary Johnson
Problem: Left shift is incorrect with vartabstop and shiftwidth=0 Solution: make tabstop_at() function aware of shift direction (Gary Johnson) The problem was that with 'vartabstop' set and 'shiftwidth' equal 0, left shifts using << were shifting the line to the wrong column. The tabstop to the right of the first character in the line was being used as the shift amount instead of the tabstop to the left of that first character. The reason was that the tabstop_at() function always returned the value of the tabstop to the right of the given column and was not accounting for the direction of the shift. The solution was to make tabstop_at() aware of the direction of the shift and to choose the tabtop accordingly. A test was added to check this behavior and make sure it doesn't regress. While at it, also fix a few indentation/alignment issues. fixes: #14864 closes: #14887 Signed-off-by: Gary Johnson <garyjohn@spocom.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-05-30patch 9.1.0449: MS-Windows: Compiler warningsv9.1.0449Mike Williams
Problem: MS-Windows: Compiler warnings Solution: Resolve size_t to int warnings closes: #14874 A couple of warnings in ex_docmd.c have been resolved by modifying their function argument types, followed by some changes in various function call sites. This also allowed removal of some casts to cope with size_t/int conversion. Signed-off-by: Mike Williams <mrmrdubya@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-05-26patch 9.1.0446: getregionpos() inconsistent for partly-selected multibyte charv9.1.0446zeertzjq
Problem: getregionpos() behaves inconsistently for a partly-selected multibyte char. Solution: Always use column of the first byte for a partly-selected multibyte char (zeertzjq). closes: #14851 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-05-24patch 9.1.0443: Can't use blockwise selection with width for getregion()v9.1.0443zeertzjq
Problem: Can't use a blockwise selection with a width for getregion(). Solution: Add support for blockwise selection with width like the return value of getregtype() or the "regtype" value of TextYankPost (zeertzjq). closes: #14842 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-05-24patch 9.1.0441: getregionpos() can't properly indicate positions beyond eolv9.1.0441zeertzjq
Problem: getregionpos() can't properly indicate positions beyond eol. Solution: Add an "eol" flag that enables handling positions beyond end of line like getpos() does (zeertzjq). Also fix the problem that a position still has the coladd beyond the end of the line when its column has been clamped. In the last test case with TABs at the end of the line the old behavior is obviously wrong. I decided to gate this behind a flag because returning positions that don't correspond to actual characters in the line may lead to mistakes for callers that want to calculate the length of the selected text, so the behavior is only enabled if the caller wants it. closes: #14838 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-05-23patch 9.1.0433: Wrong yanking with exclusive selection and ve=allv9.1.0433zeertzjq
Problem: Wrong yanking with exclusive selection and virtualedit=all, and integer overflow when using getregion() on it. Solution: Set coladd when decreasing column and 'virtualedit' is active. Add more tests for getregion() with 'virtualedit' (zeertzjq). closes: #14830 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-05-22patch 9.1.0430: getregionpos() doesn't handle one char selectionv9.1.0430zeertzjq
Problem: getregionpos() doesn't handle one char selection. Solution: Handle startspaces differently when is_oneChar is set. Also add a test for an exclusive charwise selection with multibyte chars (zeertzjq) closes: #14825 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-05-20patch 9.1.0426: too many strlen() calls in search.cv9.1.0426John Marriott
Problem: too many strlen() calls in search.c Solution: refactor code and remove more strlen() calls, use explicit variable to remember strlen (John Marriott) closes: #14796 Signed-off-by: John Marriott <basilisk@internode.on.net> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-05-20patch 9.1.0423: getregionpos() wrong with blockwise mode and multibytev9.1.0423zeertzjq
Problem: getregionpos() wrong with blockwise mode and multibyte. Solution: Use textcol and textlen instead of start_vcol and end_vcol. Handle coladd properly (zeertzjq). Also remove unnecessary buflist_findnr() in add_regionpos_range(), as getregionpos() has already switched buffer. closes: #14805 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-05-17patch 9.1.0418: Cannot move to previous/next rare wordv9.1.0418Christ van Willegen - van Noort
Problem: Cannot move to previous/next rare word (Colin Kennedy) Solution: Add the ]r and [r motions (Christ van Willegen) fixes: #14773 closes: #14780 Signed-off-by: Christ van Willegen - van Noort <github.com@vanwillegen-vannoort.nl> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-05-17patch 9.1.0415: Some functions are not testedv9.1.0415Yegappan Lakshmanan
Problem: Some functions are not tested Solution: Add a few more tests, fix a few minor problems (Yegappan Lakshmanan) closes: #14789 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-05-08patch 9.1.0395: getregionpos() may leak memory on errorv9.1.0395Christian Brabandt
Problem: regionpos may leak memory on error, coverity complains about dereferencing Null pointer Solution: free all list pointers (after v9.1.394), return early if buflist_findnr() returns NULL closes: #14731 Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-05-07patch 9.1.0394: Cannot get a list of positions describing a regionv9.1.0394Shougo Matsushita
Problem: Cannot get a list of positions describing a region (Justin M. Keyes, after v9.1.0120) Solution: Add the getregionpos() function (Shougo Matsushita) fixes: #14609 closes: #14617 Co-authored-by: Justin M. Keyes <justinkz@gmail.com> Signed-off-by: Shougo Matsushita <Shougo.Matsu@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-05-02patch 9.1.0388: cursor() and getregion() don't handle v:maxcol wellv9.1.0388zeertzjq
Problem: cursor() and getregion() don't handle v:maxcol well. Solution: Add special handling for v:maxcol like setpos() does. (zeertzjq) closes: #14698 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-05-02patch 9.1.0387: Vim9: null value tests not sufficientv9.1.0387Yegappan Lakshmanan
Problem: Vim9: null value tests not sufficient Solution: Add a more comprehensive test for null values (Yegappan Lakshmanan) closes: #14701 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-05-01patch 9.1.0385: Vim9: crash with null_class and null_objectv9.1.0385Yegappan Lakshmanan
Problem: Vim9: crash with null_class and null_object (Aliaksei Budavei) Solution: Handle null_class and null_object correctly (Yegappan Lakshmanan) fixes: #14678 closes: #14681 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-04-04patch 9.1.0265: console dialog cannot save unnamed buffersv9.1.0265glepnir
Problem: console dialog cannot save unnamed buffers Solution: set bufname before save (glepnir). Define dialog_con_gui to test for GUI+Console dialog support, use it to skip the test when the GUI feature has been defined. Note: The dialog_changed() function will also try to call the browse_save_fname() function, when FEAT_BROWSE is defined (which is only defined in a GUI build of Vim). This will eventually lead to a call of do_browse(), which causes an error message if a GUI is not currently running (see the TODO: in do_browse()) and will then lead to a failure in Test_goto_buf_with_onfirm(). Therefore, we must disable the Test_goto_buf_with_onfirm(), when the dialog_con_gui feature is enabled (which basically means dialog feature for GUI and Console builds, in contrast to the dialog_con and dialog_gui feature). (Previously this wasn't a problem, because the test aborted in the YES case for the :confirm :b XgotoConf case and did therefore not run into the browse function call) closes: #14398 Signed-off-by: glepnir <glephunter@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-03-31patch 9.1.0231: Filetype may be undetected when SwapExists sets ft in other bufv9.1.0231zeertzjq
Problem: Filetype may be undetected when a SwapExists autocommand sets filetype in another buffer. Solution: Make filetype detection state buffer-specific. Also fix a similar problem for 'modified' (zeertzjq). closes: #14344 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-03-28patch 9.1.0219: Vim9: No enum supportv9.1.0219Yegappan Lakshmanan
Problem: No enum support Solution: Implement enums for Vim9 script (Yegappan Lakshmanan) closes: #14224 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-03-11patch 9.1.0168: too many STRLEN() callsv9.1.0168John Marriott
Problem: too many STRLEN() calls Solution: Make use of ml_get_len() calls instead (John Marriott) closes: #14123 Signed-off-by: John Marriott <basilisk@internode.on.net> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-03-11patch 9.1.0166: Internal error with blockwise getregion() in another bufferv9.1.0166zeertzjq
Problem: Internal error with blockwise getregion() in another buffer Solution: Also change curwin->w_buffer when changing curbuf (zeertzjq) closes: #14179 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-03-10patch 9.1.0164: Internal error when passing invalid position to getregion()v9.1.0164zeertzjq
Problem: Internal error or crash when passing invalid position to getregion(). Solution: Give an error for invalid position (zeertzjq). closes: #14172 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-03-07patch 9.1.0157: Duplicate assignment in f_getregion()v9.1.0157zeertzjq
Problem: Duplicate assignment in f_getregion(). Solution: Remove the duplicate assignment. Also improve getregion() docs wording and fix an unrelated typo (zeertzjq) closes: #14154 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-03-06patch 9.1.0155: can only get getregion() from current bufferv9.1.0155Shougo Matsushita
Problem: can only call getregion() for current buffer Solution: Allow to retrieve selections from different buffers (Shougo Matsushita) closes: #14131 Co-authored-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Shougo Matsushita <Shougo.Matsu@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-03-03patch 9.1.0148: Vim9: can't call internal methods with objectsv9.1.0148Yegappan Lakshmanan
Problem: Vim9: can't call internal methods with objects Solution: Add support for empty(), len() and string() function calls for objects (Yegappan Lakshmanan) closes: #14129 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-02-28patch 9.1.0142: getregion() can be improvedv9.1.0142Shougo Matsushita
Problem: getregion() can be improved (after v9.1.120) Solution: change getregion() implementation to use pos as lists and one optional {opt} dictionary (Shougo Matsushita) Note: The following is a breaking change! Currently, the getregion() function (included as of patch v9.1.120) takes 3 arguments: the first 2 arguments are strings, describing a position, arg3 is the type string. However, that is slightly inflexible, there is no way to specify additional arguments. So let's instead change the function signature to: getregion(pos1, pos2 [, {Dict}]) where both pos1 and pos2 are lists. This is slightly cleaner, and gives us the flexibility to specify additional arguments as key/value pairs to the optional Dict arg. Now it supports the "type" key to specify the selection type (characterwise, blockwise or linewise) and now in addition one can also define the selection type, independently of what the 'selection' option actually is. Technically, this is a breaking change, but since the getregion() Vimscript function is still quite new, this should be fine. closes: #14090 Co-authored-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Shougo Matsushita <Shougo.Matsu@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-02-22patch 9.1.0127: Naming a non-pointer variable "oap" is strangev9.1.0127zeertzjq
Problem: Naming a non-pointer variable "oap" is strange. Solution: Rename it to "oa". Also prevent using freed memory in case of memory allocation failure. (zeertzjq) closes: #14075 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-02-22patch 9.1.0126: Internal error when using upper-case mark in getregion()v9.1.0126zeertzjq
Problem: Internal error when passing mark in another buffer to getregion(). Solution: Don't allow marks in another buffer (zeertzjq) closes: #14076 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Internal error when passing mark in another buffer to getregion()
2024-02-21patch 9.1.0122: Some minor issues with the getregion() functionv9.1.0122Maxim Kim
Problem: Some minor issues with the getregion() function Solution: Fix examples in the help, use OP_NOP op_type and MBLOCK as motion_type in f_getreg(), update vim syntax to for getregion() (Maxim Kim) ``` :xnoremap <CR> \ <Cmd>echow getregion('v', '.', mode())<CR> ``` `echo` while in visual mode has no visible effect, thus people trying example might be frustrated as it looks like nothing happens. So the option is to change it to `echow` or `echom`. With `echom` it is again has no visible effect but one can at least inspect `:messages`. On the other hand `echow` showes selected text in a popup window. ``` Can also be used as a |method|: > '.'->getregion("'a', 'v') ``` Here is the typo, which makes example invalid, should be `("'a", ...` closes: #14064 Signed-off-by: Maxim Kim <habamax@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-02-21patch 9.1.0120: hard to get visual region using Vim scriptv9.1.0120Shougo Matsushita
Problem: hard to get visual region using Vim script Solution: Add getregion() Vim script function (Shougo Matsushita, Jakub Łuczyński) closes: #13998 closes: #11579 Co-authored-by: =?UTF-8?q?Jakub=20=C5=81uczy=C5=84ski?= <doubleloop@o2.pl> Co-authored-by: Shougo Matsushita <Shougo.Matsu@gmail.com> Signed-off-by: Shougo Matsushita <Shougo.Matsu@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-02-12patch 9.1.0099: Not able to use diff() with 'diffexpr'v9.1.0099Yegappan Lakshmanan
Problem: Not able to use diff() with 'diffexpr' (rickhowe, after v9.1.0096) Solution: Use a default context length of 0, update diff() help text, add a test for using diff() with 'diffexpr' (Yegappan Lakshmanan) closes: #14013 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-02-01patch 9.1.0071: Need a diff() Vim script functionv9.1.0071Yegappan Lakshmanan
Problem: Need a diff() Vim script function Solution: Add the diff() Vim script function using the xdiff internal diff library, add support for "unified" and "indices" mode. (Yegappan Lakshmanan) fixes: #4241 closes: #12321 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-01-13patch 9.1.0027: Vim is missing a foreach() funcv9.1.0027Ernie Rael
Problem: Vim is missing a foreach() func Solution: Implement foreach({expr1}, {expr2}) function, which applies {expr2} for each item in {expr1} without changing it (Ernie Rael) closes: #12166 Signed-off-by: Ernie Rael <errael@raelity.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-01-04patch 9.1.0009: Cannot easily get the list of matchesv9.1.0009Yegappan Lakshmanan
Problem: Cannot easily get the list of matches Solution: Add the matchstrlist() and matchbufline() Vim script functions (Yegappan Lakshmanan) closes: #13766 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-01-04patch 9.1.0006: is*() and to*() function may be unsafev9.1.0006Keith Thompson
Problem: is*() and to*() function may be unsafe Solution: Add SAFE_* macros and start using those instead (Keith Thompson) Use SAFE_() macros for is*() and to*() functions The standard is*() and to*() functions declared in <ctype.h> have undefined behavior for negative arguments other than EOF. If plain char is signed, passing an unchecked value from argv for from user input to one of these functions has undefined behavior. Solution: Add SAFE_*() macros that cast the argument to unsigned char. Most implementations behave sanely for negative arguments, and most character values in practice are non-negative, but it's still best to avoid undefined behavior. The change from #13347 has been omitted, as this has already been separately fixed in commit ac709e2fc0db6d31abb7da96f743c40956b60c3a (v9.0.2054) fixes: #13332 closes: #13347 Signed-off-by: Keith Thompson <Keith.S.Thompson@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2023-12-16patch 9.0.2169: Vim9: builtin funcs may accept a non-valuev9.0.2169Ernie Rael
Problem: Vim9: builtin funcs may accept a non-value Solution: Restrict builtin functions that accept `type` This PR finishes off detection and prevention of using a type as a value. It takes care of builtin functions. However there are some builtin functions, that need to be able to handle types as well as non-args: instanceof(), type(), typename(), string(). A "bit", FE_X, is added to funcentry_T; when set, the builtin function can handle a type (class or type-alias) in addition to a value. Noteworthy change: Discovered that in compile_call() the builtin add() is compiled inline instead of calling the builtin. Had to add a check there. closes: #13688 Signed-off-by: Ernie Rael <errael@raelity.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2023-12-14patch 9.0.2165: Vim9: can simplify arg type checking codev9.0.2165Ernie Rael
Problem: Vim9: can simplify arg type checking code Solution: In `f_argcheck` array use `arg_any`, instead of NULL closes: #13674 Signed-off-by: Ernie Rael <errael@raelity.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2023-12-12patch 9.0.2160: instanceof() should use varargs as second argv9.0.2160Ernie Rael
Problem: instanceof() should use varargs as second arg Solution: Modify `instanceof()` to use varargs instead of list Modify `instanceof()` to use varargs instead of list Valid `instanceof()` arguments are `type`s. A `type` is not a value; it cannot be added to a list. This change is non-compatible with the current usage of instanceof; but instanceof is relatively new and it's a trivial change. fixes: #13421 closes: #13644 Signed-off-by: Ernie Rael <errael@raelity.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2023-11-28patch 9.0.2135: No test for mode() when executing Ex commandsv9.0.2135zeertzjq
Problem: No test for mode() when executing Ex commands Solution: Add some test cases and simplify several other test cases. Also add a few more test cases for ModeChanged. closes: #13588 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2023-11-23patch 9.0.2123: Problem with initializing the length of range() listsv9.0.2123Christian Brabandt
Problem: Problem with initializing the length of range() lists Solution: Set length explicitly when it shouldn't contain any items range() may cause a wrong calculation of list length, which may later then cause a segfault in list_find(). This is usually not a problem, because range_list_materialize() calculates the length, when it materializes the list. In addition, in list_find() when the length of the range was wrongly initialized, it may seem to be valid, so the check for list index out-of-bounds will not be true, because it is called before the list is actually materialized. And so we may eventually try to access a null pointer, causing a segfault. So this patch does 3 things: - In f_range(), when we know that the list should be empty, explicitly set the list->lv_len value to zero. This should happen, when start is larger than end (in case the stride is positive) or end is larger than start when the stride is negative. This should fix the underlying issue properly. However, - as a safety measure, let's check that the requested index is not out of range one more time, after the list has been materialized and return NULL in case it suddenly is. - add a few more tests to verify the behaviour. fixes: #13557 closes: #13563 Co-authored-by: Tim Pope <tpope@github.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
2023-10-27patch 9.0.2076: Vim9: No support for type aliasesv9.0.2076Yegappan Lakshmanan
Problem: Vim9: No support for type aliases Solution: Implement :type command A type definition is giving a name to a type specification. This also known type alias. :type ListOfStrings = list<string> The type alias can be used wherever a built-in type can be used. The type alias name must start with an upper case character. closes: #13407 Signed-off-by: Christian Brabandt <cb@256bit.org> Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
2023-10-26patch 9.0.2070: [security] disallow setting env in restricted modev9.0.2070Christian Brabandt
Problem: [security] disallow setting env in restricted mode Solution: Setting environment variables in restricted mode could potentially be used to execute shell commands. Disallow this. restricted mode: disable allow setting of environment variables Setting environment variables in restricted mode, may have some unwanted consequences. So, for example by setting $GCONV_PATH in restricted mode and then calling the iconv() function, one may be able to execute some unwanted payload, because the `iconv_open()` function internally uses the `$GCONV_PATH` variable to find its conversion data. So let's disable setting environment variables, even so this is no complete protection, since we are not clearing the existing environment. I tried a few ways but wasn't successful :( One could also argue to disable the iconv() function completely in restricted mode, but who knows what other API functions can be influenced by setting some other unrelated environment variables. So let's leave it as it is currently. closes: #13394 See: https://huntr.com/bounties/b0a2eda1-459c-4e36-98e6-0cc7d7faccfe/ Signed-off-by: Christian Brabandt <cb@256bit.org>
2023-10-14patch 9.0.2020: Vim9: islocked() needs more workv9.0.2020Ernie Rael
Problem: Vim9: islocked() needs more work Solution: rework islocked() and remove sync_root from get_lval() closes: #13329 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Ernie Rael <errael@raelity.com>
2023-10-14patch 9.0.2019: Vim9: no support for funcrefsv9.0.2019Yegappan Lakshmanan
Problem: Vim9: no support for funcrefs Solution: Add support for object/class funcref members closes: #11981 #12417 #12960 #12324 #13333 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
2023-10-11patch 9.0.2015: Vim9: does not handle islocked() from a method correctlyv9.0.2015Ernie Rael
Problem: Vim9: does not handle islocked() from a method correctly Solution: Handle islocked() builtin from a method. - Setup `lval_root` from `f_islocked()`. - Add function `fill_exec_lval_root()` to get info about executing method. - `sync_root` added in get_lval to handle method member access. - Conservative approach to reference counting. closes: #13309 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Ernie Rael <errael@raelity.com>
2023-10-07patch 9.0.2001: Vim9: segfault with islocked()v9.0.2001Ernie Rael
Problem: Vim9: segfault with islocked() Solution: Check that the lval pointer is not null for objects and class variables closes: #13295 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Ernie Rael <errael@raelity.com>
2023-09-30patch 9.0.1962: No support for writing extended attributesv9.0.1962Christian Brabandt
Problem: No support for writing extended attributes Solution: Add extended attribute support for linux It's been a long standing issue, that if you write a file with extended attributes and backupcopy is set to no, the file will loose the extended attributes. So this patch adds support for retrieving the extended attributes and copying it to the new file. It currently only works on linux, mainly because I don't know the different APIs for other systems (BSD, MacOSX and Solaris). On linux, this should be supported since Kernel 2.4 or something, so this should be pretty safe to use now. Enable the extended attribute support with normal builds. I also added it explicitly to the :version output as well as make it able to check using `:echo has("xattr")`, to have users easily check that this is available. In contrast to the similar support for SELINUX and SMACK support (which also internally uses extended attributes), I have made this a FEAT_XATTR define, instead of the similar HAVE_XATTR. Add a test and change CI to include relevant packages so that CI can test that extended attributes are correctly written. closes: #306 closes: #13203 Signed-off-by: Christian Brabandt <cb@256bit.org>
2023-08-27patch 9.0.1801: Vim9 instanceof() fails in a def funcv9.0.1801Yegappan Lakshmanan
Problem: Vim9 instanceof() fails in a def func Solution: allow Objects in compile time check closes: #12907 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
2023-08-23patch 9.0.1786: Vim9: need instanceof() functionv9.0.1786LemonBoy
Problem: Vim9: need instanceof() function Solution: Implement instanceof() builtin Implemented in the same form as Python's isinstance because it allows for checking multiple class types at the same time. closes: #12867 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: LemonBoy <thatlemon@gmail.com>
2023-08-20patch 9.0.1776: No support for stable Python 3 ABIv9.0.1776Yee Cheng Chin
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>