diff -Nru vim-7.4.1830/debian/changelog vim-7.4.1907/debian/changelog --- vim-7.4.1830/debian/changelog 2016-05-14 04:06:23.000000000 +0000 +++ vim-7.4.1907/debian/changelog 2016-06-08 04:23:43.000000000 +0000 @@ -1,4 +1,11 @@ -vim (2:7.4.1830-1~ppa1~w) wily; urgency=medium +vim (2:7.4.1907-1~ppa1~w) wily; urgency=medium + + * Applied patches 1831-1907 + * Updated runtime files + + -- pi-rho Tue, 07 Jun 2016 22:19:22 -0600 + +vim (2:7.4.1830-1~ppa1~uuu) UNRELEASED; urgency=medium * Applied patches 1820-1830 * Updated runtime files diff -Nru vim-7.4.1830/debian/changelog.old vim-7.4.1907/debian/changelog.old --- vim-7.4.1830/debian/changelog.old 2016-05-14 04:06:18.000000000 +0000 +++ vim-7.4.1907/debian/changelog.old 2016-06-08 04:23:39.000000000 +0000 @@ -1,3 +1,10 @@ +vim (2:7.4.1907-1~ppa1~uuu) UNRELEASED; urgency=medium + + * Applied patches 1831-1907 + * Updated runtime files + + -- pi-rho Tue, 07 Jun 2016 22:19:22 -0600 + vim (2:7.4.1830-1~ppa1~uuu) UNRELEASED; urgency=medium * Applied patches 1820-1830 diff -Nru vim-7.4.1830/debian/changelog.upstream vim-7.4.1907/debian/changelog.upstream --- vim-7.4.1830/debian/changelog.upstream 2016-05-14 04:06:18.000000000 +0000 +++ vim-7.4.1907/debian/changelog.upstream 2016-06-08 04:23:39.000000000 +0000 @@ -1847,3 +1847,80 @@ 6598 7.4.1828 may try to access buffer that's already freed 1821 7.4.1829 (after 7.4.1828) no channel log message when buffer was freed 2725 7.4.1830 non-antialiased misnamed + 1719 7.4.1831 no proper error message for wrong argument to timer_stop() + 1730 7.4.1832 memory leak in debug commands + 4769 7.4.1833 cannot use an Ex command for 'keywordprg' + 1425 7.4.1834 possible crash when conceal is active + 4692 7.4.1835 when splitting and closing a window the status height changes + 8955 7.4.1836 when using partial on dict it's always bound to that dict + 4561 7.4.1837 the BufUnload event may be triggered twice + 14247 7.4.1838 functions specifically for testing do not sort together + 3633 7.4.1839 cannot get the items stored in a partial + 4897 7.4.1840 when using packages an "after" directory cannot be used + 6145 7.4.1841 code to reallocate the buffer used for quickfix is repeated + 5036 7.4.1842 (after 7.4.1839) get() works for Partial but not for Funcref + 28265 7.4.1843 tests involving Python are flaky + 15744 7.4.1844 more functions should start with test_ + 4674 7.4.1845 mentioning NetBeans when reading from channel + 2529 7.4.1846 ubsan detects a multiplication overflow + 3475 7.4.1847 using NULL dict or list crashes Vim + 4210 7.4.1848 can't build with Strawberry Perl 5.24 + 1908 7.4.1849 still trying to read from channel that is going to be closed + 1980 7.4.1850 GUI freezes when using a job + 2533 7.4.1851 test_syn_attr fails when using the GUI + 5752 7.4.1852 Unix: Cannot run all tests with the GUI + 1752 7.4.1853 crash when job and channel in same dict while using partials + 2861 7.4.1854 when setting 'termguicolors' Ignore highlighting doesn't work + 4209 7.4.1855 valgrind reports memory leak for job that is not freed + 1940 7.4.1856 failing job test fails on MS-Windows + 12921 7.4.1857 channel can append to a buffer that is 'nomodifiable' + 3993 7.4.1858 channel writing to buffer doesn't find it by the short name + 2989 7.4.1859 cannot use a function reference for "exit_cb" + 3759 7.4.1860 using a partial for timer_start() may cause a crash + 2556 7.4.1861 compiler warnings with 64 bit compiler + 22001 7.4.1862 eval() can't handle result from string() with repeated item + 5216 7.4.1863 compiler warnings on Win64 + 1582 7.4.1864 Python: encoding error with Python 2 + 1600 7.4.1865 memory leaks in test49 + 2279 7.4.1866 invalid memory access when exiting with EXITFREE defined + 1567 7.4.1867 memory leak in test_matchstrpos + 3598 7.4.1868 setting really_exiting causes memory leaks to be reported + 1748 7.4.1869 can't build with old version of Perl + 1950 7.4.1870 (after 7.4.1863) one more Win64 compiler warning + 13569 7.4.1871 appending to quickfix list is slow if quickfix window is open + 1458 7.4.1872 still build problem with old version of Perl + 7495 7.4.1873 GUI: when a callback adds a timer it is not used until later + 1309 7.4.1874 unused variable in Win32 code + 8249 7.4.1875 comparing functions and partials doesn't work well + 1786 7.4.1876 typing "k" at the hit-enter prompt has no effect + 2872 7.4.1877 no test for invoking "close_cb" when writing to a buffer + 4193 7.4.1878 exited job isn't detected until a character is typed + 1889 7.4.1879 (after 7.4.1877) channel test is flaky + 1807 7.4.1880 MS-Windows console build defaults to not having +channel + 15175 7.4.1881 appending to a long quickfix list is slow + 1629 7.4.1882 check for line break at end of line wrong + 2126 7.4.1883 cppcheck found 2 incorrect printf formats + 6332 7.4.1884 updating marks in long quickfix list is very slow + 1516 7.4.1885 MinGW console build defaults to not having +channel + 13782 7.4.1886 mapping times out when interrupted by receiving data + 7052 7.4.1887 when receiving channel data 'updatetime' is not respected + 2512 7.4.1888 wrong computation of remaining wait time in RealWaitForChar() + 2182 7.4.1889 when umask is set to 0177 Vim can't create temp files + 6161 7.4.1890 GUI: cursor blinking interrupted when channel data received + 8326 7.4.1891 channel reading very long lines is slow + 4055 7.4.1892 balloon eval only gets the window number, not the ID + 4736 7.4.1893 cannot easily get the window ID for a buffer + 5057 7.4.1894 cannot get the window ID for a mouse click + 11328 7.4.1895 cannot use a window ID where a window number is expected + 3440 7.4.1896 invoking mark_adjust() when it is pointless + 8595 7.4.1897 various typos, long lines and style mistakes + 8285 7.4.1898 user commands don't support modifiers + 2191 7.4.1899 GTK 3: cursor blinking doesn't work well + 2149 7.4.1900 using CTRL-] in the help on "{address}." doesn't work + 1860 7.4.1901 Win32: the "Disabled" menu items would appear enabled + 3076 7.4.1902 no test for collapsing channel buffers; some text is lost + 31848 7.4.1903 recent history items may be dropped when writing viminfo + 2219 7.4.1904 (after 7.4.1903) build fails + 1558 7.4.1905 (after 7.4.1903) some compilers can't handle double semicolon + 14566 7.4.1906 collapsing channel buffers does not work properly + 1925 7.4.1907 warnings from 64 bit compiler diff -Nru vim-7.4.1830/debian/patches/debian/disabled-modelines.patch vim-7.4.1907/debian/patches/debian/disabled-modelines.patch --- vim-7.4.1830/debian/patches/debian/disabled-modelines.patch 2016-05-14 04:06:18.000000000 +0000 +++ vim-7.4.1907/debian/patches/debian/disabled-modelines.patch 2016-06-08 04:23:39.000000000 +0000 @@ -11,7 +11,7 @@ --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt -@@ -5086,7 +5086,7 @@ A jump table for the options with a shor +@@ -5089,7 +5089,7 @@ A jump table for the options with a shor *'modeline'* *'ml'* *'nomodeline'* *'noml'* 'modeline' 'ml' boolean (Vim default: on (off for root), diff -Nru vim-7.4.1830/debian/patches/debian/yakkety.patch vim-7.4.1907/debian/patches/debian/yakkety.patch --- vim-7.4.1830/debian/patches/debian/yakkety.patch 2016-05-14 04:06:18.000000000 +0000 +++ vim-7.4.1907/debian/patches/debian/yakkety.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -commit 11dedcf8888d3fbcb2f7c89c23b16d5405c21382 -Author: James McCoy -Date: Sun Apr 24 00:09:39 2016 -0400 - - {debsources,debchangelog}.vim: Add yakkety as a known release. - - Restore trusty as a supported release, moving vivid to unsupported - instead. - - Signed-off-by: James McCoy - ---- a/runtime/syntax/debchangelog.vim -+++ b/runtime/syntax/debchangelog.vim -@@ -3,7 +3,7 @@ - " Maintainer: Debian Vim Maintainers - " Former Maintainers: Gerfried Fuchs - " Wichert Akkerman --" Last Change: 2015 Oct 24 -+" Last Change: 2016 Apr 24 - " URL: https://anonscm.debian.org/cgit/pkg-vim/vim.git/plain/runtime/syntax/debchangelog.vim - - " Standard syntax initialization -@@ -23,7 +23,7 @@ let binNMU='binary-only=yes' - syn match debchangelogName contained "^[[:alnum:]][[:alnum:].+-]\+ " - exe 'syn match debchangelogFirstKV contained "; \('.urgency.'\|'.binNMU.'\)"' - exe 'syn match debchangelogOtherKV contained ", \('.urgency.'\|'.binNMU.'\)"' --syn match debchangelogTarget contained "\v %(frozen|unstable|sid|%(testing|%(old)=stable)%(-proposed-updates|-security)=|experimental|squeeze-%(backports%(-sloppy)=|volatile|lts|security)|wheezy-%(backports%(-sloppy)=|security)|jessie%(-backports|-security)=|stretch|%(devel|precise|trusty|vivid|wily|xenial)%(-%(security|proposed|updates|backports|commercial|partner))=)+" -+syn match debchangelogTarget contained "\v %(frozen|unstable|sid|%(testing|%(old)=stable)%(-proposed-updates|-security)=|experimental|squeeze-%(backports%(-sloppy)=|volatile|lts|security)|wheezy-%(backports%(-sloppy)=|security)|jessie%(-backports|-security)=|stretch|%(devel|precise|trusty|vivid|wily|xenial|yakkety)%(-%(security|proposed|updates|backports|commercial|partner))=)+" - syn match debchangelogVersion contained "(.\{-})" - syn match debchangelogCloses contained "closes:\_s*\(bug\)\=#\=\_s\=\d\+\(,\_s*\(bug\)\=#\=\_s\=\d\+\)*" - syn match debchangelogLP contained "\clp:\s\+#\d\+\(,\s*#\d\+\)*" ---- a/runtime/syntax/debsources.vim -+++ b/runtime/syntax/debsources.vim -@@ -2,7 +2,7 @@ - " Language: Debian sources.list - " Maintainer: Debian Vim Maintainers - " Former Maintainer: Matthijs Mohlmann --" Last Change: 2015 Oct 24 -+" Last Change: 2016 Apr 24 - " URL: https://anonscm.debian.org/cgit/pkg-vim/vim.git/plain/runtime/syntax/debsources.vim - - " Standard syntax initialization -@@ -27,7 +27,7 @@ let s:supported = [ - \ 'oldstable', 'stable', 'testing', 'unstable', 'experimental', - \ 'squeeze', 'wheezy', 'jessie', 'stretch', 'sid', 'rc-buggy', - \ -- \ 'precise', 'trusty', 'vivid', 'wily', 'xenial', 'devel' -+ \ 'precise', 'trusty', 'wily', 'xenial', 'yakkety', 'devel' - \ ] - let s:unsupported = [ - \ 'buzz', 'rex', 'bo', 'hamm', 'slink', 'potato', -@@ -36,7 +36,7 @@ let s:unsupported = [ - \ 'warty', 'hoary', 'breezy', 'dapper', 'edgy', 'feisty', - \ 'gutsy', 'hardy', 'intrepid', 'jaunty', 'karmic', 'lucid', - \ 'maverick', 'natty', 'oneiric', 'quantal', 'raring', 'saucy', -- \ 'utopic' -+ \ 'utopic', 'vivid' - \ ] - let &cpo=s:cpo - diff -Nru vim-7.4.1830/debian/patches/series vim-7.4.1907/debian/patches/series --- vim-7.4.1830/debian/patches/series 2016-05-14 04:06:18.000000000 +0000 +++ vim-7.4.1907/debian/patches/series 2016-06-08 04:23:39.000000000 +0000 @@ -3,5 +3,4 @@ debian/disabled-modelines.patch debian/extra-tex-detection.patch debian/build-date.patch -debian/yakkety.patch debian-runtime-fixes.patch diff -Nru vim-7.4.1830/debian/patches/upstream/extra-rst-detection.patch vim-7.4.1907/debian/patches/upstream/extra-rst-detection.patch --- vim-7.4.1830/debian/patches/upstream/extra-rst-detection.patch 2016-05-14 04:06:18.000000000 +0000 +++ vim-7.4.1907/debian/patches/upstream/extra-rst-detection.patch 2016-06-08 04:23:39.000000000 +0000 @@ -8,7 +8,7 @@ --- a/runtime/scripts.vim +++ b/runtime/scripts.vim -@@ -331,6 +331,14 @@ else +@@ -332,6 +332,14 @@ else elseif s:line1 =~ 'exec\s\+\S*scheme' || s:line2 =~ 'exec\s\+\S*scheme' set ft=scheme diff -Nru vim-7.4.1830/runtime/doc/channel.txt vim-7.4.1907/runtime/doc/channel.txt --- vim-7.4.1830/runtime/doc/channel.txt 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/doc/channel.txt 2016-06-07 20:50:01.000000000 +0000 @@ -1,4 +1,4 @@ -*channel.txt* For Vim version 7.4. Last change: 2016 Apr 30 +*channel.txt* For Vim version 7.4. Last change: 2016 Jun 02 VIM REFERENCE MANUAL by Bram Moolenaar @@ -61,7 +61,7 @@ crosss-refrences in a database. ============================================================================== -2. Channel demo *channel-demo* +2. Channel demo *channel-demo* *demoserver.py* This requires Python. The demo program can be found in $VIMRUNTIME/tools/demoserver.py @@ -146,11 +146,19 @@ For all callbacks: Use |function()| to bind it to arguments and/or a Dictionary. Or use the form "dict.function" to bind the Dictionary. + + Callbacks are only called at a "safe" moment, usually when Vim + is waiting for the user to type a character. Vim does not use + multi-threading. + *close_cb* "close_cb" A function that is called when the channel gets closed, other than by calling ch_close(). It should be defined like this: > func MyCloseHandler(channel) -< *waittime* +< Vim will invoke callbacks that handle data before invoking + close_cb, thus when this function is called no more data will + be received. + *waittime* "waittime" The time to wait for the connection to be made in milliseconds. A negative number waits forever. @@ -565,13 +573,15 @@ "err_cb" wasn't set the channel callback is used. *job-close_cb* "close_cb": handler Callback for when the channel is closed. Same as - "close_cb" on ch_open(). + "close_cb" on |ch_open()|, see |close_cb|. *job-exit_cb* "exit_cb": handler Callback for when the job ends. The arguments are the job and the exit status. Vim checks about every 10 seconds for jobs that ended. - The callback can also be triggered by calling - |job_status()|. + The check also be triggered by calling |job_status()|, + which may then invoke the exit_cb handler. + Note that data can be buffered, callbacks may still be + called after the process ends. *job-timeout* "timeout" The time to wait for a request when blocking, E.g. when using ch_evalexpr(). In milliseconds. The @@ -615,18 +625,22 @@ "out_io": "null" disconnect stdout (goes to /dev/null) "out_io": "pipe" stdout is connected to the channel (default) "out_io": "file" stdout writes to a file -"out_io": "buffer" stdout appends to a buffer +"out_io": "buffer" stdout appends to a buffer (see below) "out_name": "/path/file" the name of the file or buffer to write to "out_buf": number the number of the buffer to write to +"out_modifiable": 0 when writing to a buffer, 'modifiable' will be off + (see below) *job-err_io* *err_name* *err_buf* "err_io": "out" stderr messages to go to stdout "err_io": "null" disconnect stderr (goes to /dev/null) "err_io": "pipe" stderr is connected to the channel (default) "err_io": "file" stderr writes to a file -"err_io": "buffer" stderr appends to a buffer +"err_io": "buffer" stderr appends to a buffer (see below) "err_name": "/path/file" the name of the file or buffer to write to "err_buf": number the number of the buffer to write to +"err_modifiable": 0 when writing to a buffer, 'modifiable' will be off + (see below) "block_write": number only for testing: pretend every other write to stdin will block @@ -645,14 +659,27 @@ ID will be added to the buffer, after decoding + encoding. Messages with a positive number will be handled by a callback, commands are handled as usual. -The name of the buffer is compared the full name of existing buffers. If -there is a match that buffer is used. Otherwise a new buffer is created. -Use an empty name to always create a new buffer. |ch_getbufnr()| can then be -used to get the buffer number. +The name of the buffer from "out_name" or "err_name" is compared the full name +of existing buffers, also after expanding the name for the current directory. +E.g., when a buffer was created with ":edit somename" and the buffer name is +"somename" it will use that buffer. + +If there is no matching buffer a new buffer is created. Use an empty name to +always create a new buffer. |ch_getbufnr()| can then be used to get the +buffer number. For a new buffer 'buftype' is set to "nofile" and 'bufhidden' to "hide". If you prefer other settings, create the buffer first and pass the buffer number. +The "out_modifiable" and "err_modifiable" options can be used to set the +'modifiable' option off, or write to a buffer that has 'modifiable' off. That +means that lines will be appended to the buffer, but the user can't easily +change the buffer. + +When an existing buffer is to be written where 'modifiable' is off and the +"out_modifiable" or "err_modifiable" options is not zero, an error is given +and the buffer will not be written to. + When the buffer written to is displayed in a window and the cursor is in the first column of the last line, the cursor will be moved to the newly added line and the window is scrolled up to show the cursor if needed. diff -Nru vim-7.4.1830/runtime/doc/eval.txt vim-7.4.1907/runtime/doc/eval.txt --- vim-7.4.1830/runtime/doc/eval.txt 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/doc/eval.txt 2016-06-07 20:50:01.000000000 +0000 @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 7.4. Last change: 2016 May 05 +*eval.txt* For Vim version 7.4. Last change: 2016 Jun 04 VIM REFERENCE MANUAL by Bram Moolenaar @@ -59,6 +59,9 @@ Funcref A reference to a function |Funcref|. Example: function("strlen") + It can be bound to a dictionary and arguments, it then works + like a Partial. + Example: function("Callback", [arg], myDict) Special |v:false|, |v:true|, |v:none| and |v:null|. *Special* @@ -150,6 +153,43 @@ You can use |call()| to invoke a Funcref and use a list variable for the arguments: > :let r = call(Fn, mylist) +< + *Partial* +A Funcref optionally binds a Dictionary and/or arguments. This is also called +a Partial. This is created by passing the Dictionary and/or arguments to +function(). When calling the function the Dictionary and/or arguments will be +passed to the function. Example: > + + let Cb = function('Callback', ['foo'], myDict) + call Cb() + +This will invoke the function as if using: > + call myDict.Callback('foo') + +This is very useful when passing a function around, e.g. in the arguments of +|ch_open()|. + +Note that binding a function to a Dictionary also happens when the function is +a member of the Dictionary: > + + let myDict.myFunction = MyFunction + call myDict.myFunction() + +Here MyFunction() will get myDict passed as "self". This happens when the +"myFunction" member is accessed. When making assigning "myFunction" to +otherDict and calling it, it will be bound to otherDict: > + + let otherDict.myFunction = myDict.myFunction + call otherDict.myFunction() + +Now "self" will be "otherDict". But when the dictionary was bound explicitly +this won't happen: > + + let myDict.myFunction = function(MyFunction, myDict) + let otherDict.myFunction = myDict.myFunction + call otherDict.myFunction() + +Here "self" will be "myDict", because it was bound explitly. 1.3 Lists ~ @@ -1318,6 +1358,10 @@ window has number zero (unlike most other places where a window gets a number). + *v:beval_winid* *beval_winid-variable* +v:beval_winid The window ID of the window, over which the mouse pointer is. + Otherwise like v:beval_winnr. + *v:char* *char-variable* v:char Argument for evaluating 'formatexpr' and used for the typed character when using in an abbreviation |:map-|. @@ -1551,6 +1595,10 @@ First window has number 1, like with |winnr()|. The value is zero when there was no mouse button click. + *v:mouse_winid* *mouse_winid-variable* +v:mouse_winid Window ID for a mouse click obtained with |getchar()|. + The value is zero when there was no mouse button click. + *v:mouse_lnum* *mouse_lnum-variable* v:mouse_lnum Line number for a mouse click obtained with |getchar()|. This is the text line number, not the screen line number. The @@ -1725,7 +1773,7 @@ {only when compiled with |+termresponse| feature} *v:testing* *testing-variable* -v:testing Must be set before using `garbagecollect_for_testing()`. +v:testing Must be set before using `test_garbagecollect_now()`. *v:this_session* *this_session-variable* v:this_session Full filename of the last loaded or saved session file. See @@ -1781,7 +1829,7 @@ When an MS-Windows GUI is running this will be set to the window handle. Otherwise the value is zero. - Note: for windows inside Vim use |winnr()|. + Note: for windows inside Vim use |winnr()| or |win_getid()|. ============================================================================== 4. Builtin Functions *functions* @@ -1795,8 +1843,6 @@ abs({expr}) Float or Number absolute value of {expr} acos({expr}) Float arc cosine of {expr} add({list}, {item}) List append {item} to |List| {list} -alloc_fail({id}, {countdown}, {repeat}) - none make memory allocation fail and({expr}, {expr}) Number bitwise AND append({lnum}, {string}) Number append {string} below line {lnum} append({lnum}, {list}) Number append lines {list} below line {lnum} @@ -1824,6 +1870,7 @@ bufloaded({expr}) Number TRUE if buffer {expr} is loaded bufname({expr}) String Name of the buffer {expr} bufnr({expr} [, {create}]) Number Number of the buffer {expr} +bufwinid({expr}) Number window ID of buffer {expr} bufwinnr({expr}) Number window number of buffer {expr} byte2line({byte}) Number line number at byte count {byte} byteidx({expr}, {nr}) Number byte index of {nr}'th char in {expr} @@ -1878,8 +1925,6 @@ did_filetype() Number TRUE if FileType autocommand event used diff_filler({lnum}) Number diff filler lines about {lnum} diff_hlID({lnum}, {col}) Number diff highlighting at {lnum}/{col} -disable_char_avail_for_testing({expr}) - none test without typeahead empty({expr}) Number TRUE if {expr} is empty escape({string}, {chars}) String escape {chars} in {string} with '\' eval({string}) any evaluate {string} into its value @@ -1915,9 +1960,9 @@ function({name} [, {arglist}] [, {dict}]) Funcref reference to function {name} garbagecollect([{atexit}]) none free memory, breaking cyclic references -garbagecollect_for_testing() none free memory right now get({list}, {idx} [, {def}]) any get item {idx} from {list} or {def} get({dict}, {key} [, {def}]) any get item {key} from {dict} or {def} +get({func}, {what}) any get property of funcref/partial {func} getbufline({expr}, {lnum} [, {end}]) List lines {lnum} to {end} of buffer {expr} getbufvar({expr}, {varname} [, {def}]) @@ -2163,6 +2208,16 @@ tan({expr}) Float tangent of {expr} tanh({expr}) Float hyperbolic tangent of {expr} tempname() String name for a temporary file +test_alloc_fail({id}, {countdown}, {repeat}) + none make memory allocation fail +test_disable_char_avail({expr}) none test without typeahead +test_garbagecollect_now() none free memory right now for testing +test_null_channel() Channel null value for testing +test_null_dict() Dict null value for testing +test_null_job() Job null value for testing +test_null_list() List null value for testing +test_null_partial() Funcref null value for testing +test_null_string() String null value for testing timer_start({time}, {callback} [, {options}]) Number create a timer timer_stop({timer}) none stop a timer @@ -2238,13 +2293,6 @@ Use |insert()| to add an item at another position. -alloc_fail({id}, {countdown}, {repeat}) *alloc_fail()* - This is for testing: If the memory allocation with {id} is - called, then decrement {countdown}, and when it reaches zero - let memory allocation fail {repeat} times. When {repeat} is - smaller than one it fails one time. - - and({expr}, {expr}) *and()* Bitwise AND on the two arguments. The arguments are converted to a number. A List, Dict or Float argument causes an error. @@ -2282,6 +2330,7 @@ With {winnr} only use this window in the current tab page. With {winnr} and {tabnr} use the window in the specified tab page. + {winnr} can be the window number or the window ID. *argv()* argv([{nr}]) The result is the {nr}th file in the argument list of the @@ -2518,6 +2567,16 @@ *last_buffer_nr()* Obsolete name for bufnr("$"): last_buffer_nr(). +bufwinid({expr}) *bufwinid()* + The result is a Number, which is the window ID of the first + window associated with buffer {expr}. For the use of {expr}, + see |bufname()| above. If buffer {expr} doesn't exist or + there is no such window, -1 is returned. Example: > + + echo "A window containing buffer 1 is " . (bufwinid(1)) +< + Only deals with the current tab page. + bufwinnr({expr}) *bufwinnr()* The result is a Number, which is the number of the first window associated with buffer {expr}. For the use of {expr}, @@ -3111,14 +3170,6 @@ The highlight ID can be used with |synIDattr()| to obtain syntax information about the highlighting. - *disable_char_avail_for_testing()* -disable_char_avail_for_testing({expr}) - When {expr} is 1 the internal char_avail() function will - return FALSE. When {expr} is 0 the char_avail() function will - function normally. - Only use this for a test where typeahead causes the test not - to work. E.g., to trigger the CursorMovedI autocommand event. - empty({expr}) *empty()* Return the Number 1 if {expr} is empty, zero otherwise. - A |List| or |Dictionary| is empty when it does not have any @@ -3645,7 +3696,7 @@ let Broken = function(dict.Func, [arg], dict) < When {arglist} or {dict} is present this creates a partial. - That mans the argument list and/or the dictionary is stored in + That means the argument list and/or the dictionary is stored in the Funcref and will be used when the Funcref is called. The arguments are passed to the function in front of other @@ -3712,11 +3763,10 @@ collection will also be done when exiting Vim, if it wasn't done before. This is useful when checking for memory leaks. -garbagecollect_for_testing() *garbagecollect_for_testing()* - Like garbagecollect(), but executed right away. This must - only be called directly to avoid any structure to exist - internally, and |v:testing| must have been set before calling - any function. + The garbage collection is not done immediately but only when + it's safe to perform. This is when waiting for the user to + type a character. To force garbage collection immediately use + |test_garbagecollect_now()|. get({list}, {idx} [, {default}]) *get()* Get item {idx} from |List| {list}. When this item is not @@ -3726,6 +3776,13 @@ Get item with key {key} from |Dictionary| {dict}. When this item is not available return {default}. Return zero when {default} is omitted. +get({func}, {what}) + Get an item with from Funcref {func}. Possible values for + {what} are: + 'name' The function name + 'func' The function + 'dict' The dictionary + 'args' The list with arguments *getbufline()* getbufline({expr}, {lnum} [, {end}]) @@ -3798,8 +3855,8 @@ When the user clicks a mouse button, the mouse event will be returned. The position can then be found in |v:mouse_col|, - |v:mouse_lnum| and |v:mouse_win|. This example positions the - mouse as it would normally happen: > + |v:mouse_lnum|, |v:mouse_winid| and |v:mouse_win|. This + example positions the mouse as it would normally happen: > let c = getchar() if c == "\" && v:mouse_win > 0 exe v:mouse_win . "wincmd w" @@ -3931,6 +3988,7 @@ in the current tab page. With {winnr} and {tabnr} return the local current directory of the window in the specified tab page. + {winnr} can be the window number or the window ID. Return an empty string if the arguments are invalid. getfsize({fname}) *getfsize()* @@ -4027,7 +4085,9 @@ getloclist({nr}) *getloclist()* Returns a list with all the entries in the location list for - window {nr}. When {nr} is zero the current window is used. + window {nr}. {nr} can be the window number or the window ID. + When {nr} is zero the current window is used. + For a location list window, the displayed location list is returned. For an invalid window number {nr}, an empty list is returned. Otherwise, same as |getqflist()|. @@ -4161,6 +4221,7 @@ Note that {varname} must be the name without "w:". Tabs are numbered starting with one. For the current tabpage use |getwinvar()|. + {winnr} can be the window number or the window ID. When {winnr} is zero the current window is used. This also works for a global option, buffer-local option and window-local option, but it doesn't work for a global variable @@ -4285,6 +4346,7 @@ With {winnr} use this window in the current tab page. With {winnr} and {tabnr} use the window in the specified tab page. + {winnr} can be the window number or the window ID. Return 0 if the arguments are invalid. hasmapto({what} [, {mode} [, {abbr}]]) *hasmapto()* @@ -4676,6 +4738,10 @@ "fail" job failed to start "dead" job died or was stopped after running + On Unix a non-existing command results in "dead" instead of + "fail", because a fork happens before the failure can be + detected. + If an exit callback was set with the "exit_cb" option and the job is now detected to be "dead" the callback will be invoked. @@ -6227,9 +6293,11 @@ setloclist({nr}, {list} [, {action}]) *setloclist()* Create or replace or add to the location list for window {nr}. - When {nr} is zero the current window is used. For a location - list window, the displayed location list is modified. For an - invalid window number {nr}, -1 is returned. + {nr} can be the window number or the window ID. + When {nr} is zero the current window is used. + + For a location list window, the displayed location list is + modified. For an invalid window number {nr}, -1 is returned. Otherwise, same as |setqflist()|. Also see |location-list|. @@ -6321,10 +6389,15 @@ *E927* If {action} is set to 'a', then the items from {list} are added to the existing quickfix list. If there is no existing - list, then a new list is created. If {action} is set to 'r', - then the items from the current quickfix list are replaced - with the items from {list}. If {action} is not present or is - set to ' ', then a new list is created. + list, then a new list is created. + + If {action} is set to 'r', then the items from the current + quickfix list are replaced with the items from {list}. This + can also be used to clear the list: > + :call setqflist([], 'r') +< + If {action} is not present or is set to ' ', then a new list + is created. Returns zero for success, -1 for failure. @@ -6391,6 +6464,7 @@ {val}. Tabs are numbered starting with one. For the current tabpage use |setwinvar()|. + {winnr} can be the window number or the window ID. When {winnr} is zero the current window is used. This also works for a global or local buffer option, but it doesn't work for a global or local buffer variable. @@ -7125,17 +7199,6 @@ located by Vim. Refer to |tags-file-format| for the format of the tags file generated by the different ctags tools. -tempname() *tempname()* *temp-file-name* - The result is a String, which is the name of a file that - doesn't exist. It can be used for a temporary file. The name - is different for at least 26 consecutive calls. Example: > - :let tmpfile = tempname() - :exe "redir > " . tmpfile -< For Unix, the file will be in a private directory |tempfile|. - For MS-Windows forward slashes are used when the 'shellslash' - option is set or when 'shellcmdflag' starts with '-'. - - tan({expr}) *tan()* Return the tangent of {expr}, measured in radians, as a |Float| in the range [-inf, inf]. @@ -7160,6 +7223,59 @@ {only available when compiled with the |+float| feature} +tempname() *tempname()* *temp-file-name* + The result is a String, which is the name of a file that + doesn't exist. It can be used for a temporary file. The name + is different for at least 26 consecutive calls. Example: > + :let tmpfile = tempname() + :exe "redir > " . tmpfile +< For Unix, the file will be in a private directory |tempfile|. + For MS-Windows forward slashes are used when the 'shellslash' + option is set or when 'shellcmdflag' starts with '-'. + + +test_alloc_fail({id}, {countdown}, {repeat}) *test_alloc_fail()* + This is for testing: If the memory allocation with {id} is + called, then decrement {countdown}, and when it reaches zero + let memory allocation fail {repeat} times. When {repeat} is + smaller than one it fails one time. + + + *test_disable_char_avail()* +test_disable_char_avail({expr}) + When {expr} is 1 the internal char_avail() function will + return FALSE. When {expr} is 0 the char_avail() function will + function normally. + Only use this for a test where typeahead causes the test not + to work. E.g., to trigger the CursorMovedI autocommand event. + +test_garbagecollect_now() *test_garbagecollect_now()* + Like garbagecollect(), but executed right away. This must + only be called directly to avoid any structure to exist + internally, and |v:testing| must have been set before calling + any function. + +test_null_channel() *test_null_channel()* + Return a Channel that is null. Only useful for testing. + {only available when compiled with the +channel feature} + +test_null_dict() *test_null_dict()* + Return a Dict that is null. Only useful for testing. + +test_null_job() *test_null_job()* + Return a Job that is null. Only useful for testing. + {only available when compiled with the +job feature} + +test_null_list() *test_null_list()* + Return a List that is null. Only useful for testing. + +test_null_partial() *test_null_partial()* + Return a Partial that is null. Only useful for testing. + +test_null_string() *test_null_string()* + Return a String that is null. Only useful for testing. + + *timer_start()* timer_start({time}, {callback} [, {options}]) Create a timer and return the timer ID. @@ -7188,8 +7304,9 @@ {only available when compiled with the |+timers| feature} timer_stop({timer}) *timer_stop()* - Stop a timer. {timer} is an ID returned by timer_start(). - The timer callback will no longer be invoked. + Stop a timer. The timer callback will no longer be invoked. + {timer} is an ID returned by timer_start(), thus it must be a + Number. tolower({expr}) *tolower()* The result is a copy of the String given, with all uppercase @@ -7420,9 +7537,11 @@ *winbufnr()* winbufnr({nr}) The result is a Number, which is the number of the buffer - associated with window {nr}. When {nr} is zero, the number of - the buffer in the current window is returned. When window - {nr} doesn't exist, -1 is returned. + associated with window {nr}. {nr} can be the window number or + the window ID. + When {nr} is zero, the number of the buffer in the current + window is returned. + When window {nr} doesn't exist, -1 is returned. Example: > :echo "The file in the current window is " . bufname(winbufnr(0)) < @@ -7433,6 +7552,7 @@ winheight({nr}) *winheight()* The result is a Number, which is the height of window {nr}. + {nr} can be the window number or the window ID. When {nr} is zero, the height of the current window is returned. When window {nr} doesn't exist, -1 is returned. An existing window always has a height of zero or more. @@ -7512,6 +7632,7 @@ winwidth({nr}) *winwidth()* The result is a Number, which is the width of window {nr}. + {nr} can be the window number or the window ID. When {nr} is zero, the width of the current window is returned. When window {nr} doesn't exist, -1 is returned. An existing window always has a width of zero or more. diff -Nru vim-7.4.1830/runtime/doc/filetype.txt vim-7.4.1907/runtime/doc/filetype.txt --- vim-7.4.1830/runtime/doc/filetype.txt 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/doc/filetype.txt 2016-06-07 20:50:01.000000000 +0000 @@ -1,4 +1,4 @@ -*filetype.txt* For Vim version 7.4. Last change: 2016 Apr 30 +*filetype.txt* For Vim version 7.4. Last change: 2016 May 24 VIM REFERENCE MANUAL by Bram Moolenaar @@ -585,6 +585,10 @@ folding style instead. For example: > autocmd FileType man setlocal foldmethod=indent foldenable +You may also want to set 'keywordprg' to make the |K| command open a manual +page in a Vim window: > + set keywordprg=:Man + MANPAGER *manpager.vim* diff -Nru vim-7.4.1830/runtime/doc/if_pyth.txt vim-7.4.1907/runtime/doc/if_pyth.txt --- vim-7.4.1830/runtime/doc/if_pyth.txt 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/doc/if_pyth.txt 2016-06-07 20:50:01.000000000 +0000 @@ -659,19 +659,31 @@ `vim.bindeval('function(%s)'%json.dumps(name))`. Attributes (read-only): - Attribute Description ~ - name Function name. - args `None` or a |python-List| object with arguments. Note that - this is a copy of the arguments list, constructed each time - you request this attribute. Modifications made to the list - will be ignored (but not to the containers inside argument - list: this is like |copy()| and not |deepcopy()|). - self `None` or a |python-Dictionary| object with self - dictionary. Note that explicit `self` keyword used when - calling resulting object overrides this attribute. + Attribute Description ~ + name Function name. + args `None` or a |python-List| object with arguments. Note + that this is a copy of the arguments list, constructed + each time you request this attribute. Modifications made + to the list will be ignored (but not to the containers + inside argument list: this is like |copy()| and not + |deepcopy()|). + self `None` or a |python-Dictionary| object with self + dictionary. Note that explicit `self` keyword used when + calling resulting object overrides this attribute. + auto_rebind Boolean. True if partial created from this Python object + and stored in the VimL dictionary should be automatically + rebound to the dictionary it is stored in when this + dictionary is indexed. Exposes Vim internal difference + between `dict.func` (auto_rebind=True) and + `function(dict.func,dict)` (auto_rebind=False). This + attribute makes no sense if `self` attribute is `None`. - Constructor additionally accepts `args` and `self` keywords. If any of - them is given then it constructs a partial, see |function()|. + Constructor additionally accepts `args`, `self` and `auto_rebind` + keywords. If `args` and/or `self` argument is given then it constructs + a partial, see |function()|. `auto_rebind` is only used when `self` + argument is given, otherwise it is assumed to be `True` regardless of + whether it was given or not. If `self` is given then it defaults to + `False`. Examples: > f = vim.Function('tr') # Constructor diff -Nru vim-7.4.1830/runtime/doc/map.txt vim-7.4.1907/runtime/doc/map.txt --- vim-7.4.1830/runtime/doc/map.txt 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/doc/map.txt 2016-06-07 20:50:01.000000000 +0000 @@ -1411,6 +1411,27 @@ (See the '-bang' attribute) Expands to a ! if the command was executed with a ! modifier, otherwise expands to nothing. + ** + The command modifiers, if specified. Otherwise, expands to + nothing. Supported modifiers are |aboveleft|, |belowright|, + |botright|, |browse|, |confirm|, |hide|, |keepalt|, + |keepjumps|, |keepmarks|, |keeppatterns|, |lockmarks|, + |noswapfile|, |silent|, |tab|, |topleft|, |verbose|, and + |vertical|. + Examples: > + command! -nargs=+ -complete=file MyEdit + \ for f in expand(, 0, 1) | + \ exe ' split ' . f | + \ endfor + + function! SpecialEdit(files, mods) + for f in expand(a:files, 0, 1) + exe a:mods . ' split ' . f + endfor + endfunction + command! -nargs=+ -complete=file Sedit + \ call SpecialEdit(, ) +< ** ** (See the '-register' attribute) The optional register, if specified. Otherwise, expands to nothing. diff -Nru vim-7.4.1830/runtime/doc/options.txt vim-7.4.1907/runtime/doc/options.txt --- vim-7.4.1830/runtime/doc/options.txt 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/doc/options.txt 2016-06-07 20:50:01.000000000 +0000 @@ -1,4 +1,4 @@ -*options.txt* For Vim version 7.4. Last change: 2016 Apr 21 +*options.txt* For Vim version 7.4. Last change: 2016 Jun 04 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1103,6 +1103,7 @@ v:beval_bufnr number of the buffer in which balloon is going to show v:beval_winnr number of the window + v:beval_winid ID of the window v:beval_lnum line number v:beval_col column number (byte index) v:beval_text word under or after the mouse pointer @@ -3635,7 +3636,7 @@ SYMBOL, THAI, TURKISH, VIETNAMESE ANSI and BALTIC. Normally you would use "cDEFAULT". qXX - quality XX. Valid quality names are: PROOF, DRAFT, - ANTIALIASED, UNANTIALIASED, CLEARTYPE, DEFAULT. + ANTIALIASED, NONANTIALIASED, CLEARTYPE, DEFAULT. Normally you would use "qDEFAULT". Some quality values isn't supported in legacy OSs. @@ -4587,16 +4588,18 @@ *'keywordprg'* *'kp'* 'keywordprg' 'kp' string (default "man" or "man -s", DOS: ":help", - OS/2: "view /", VMS: "help") + VMS: "help") global or local to buffer |global-local| {not in Vi} Program to use for the |K| command. Environment variables are expanded |:set_env|. ":help" may be used to access the Vim internal help. (Note that previously setting the global option to the empty value did this, which is now deprecated.) - When "man" is used, Vim will automatically translate a count for the - "K" command to a section number. Also for "man -s", in which case the - "-s" is removed when there is no count. + When the first character is ":", the command is invoked as a Vim + Ex command prefixed with [count]. + When "man", "man -s" or an Ex command is used, Vim will automatically + translate a count for the "K" command and pass it as the first + argument. For "man -s" the "-s" is removed when there is no count. See |option-backslash| about including spaces and backslashes. Example: > :set keywordprg=man\ -s @@ -6063,6 +6066,7 @@ keymap/ key mapping files |mbyte-keymap| lang/ menu translations |:menutrans| menu.vim GUI menus |menu.vim| + pack/ packages |:packadd| plugin/ plugin scripts |write-plugin| print/ files for printing |postscript-print-encoding| spell/ spell checking files |spell| @@ -6084,6 +6088,8 @@ personal preferences to overrule or add to the distributed defaults or system-wide settings (rarely needed). + More entries are added when using |packages|. + Note that, unlike 'path', no wildcards like "**" are allowed. Normal wildcards are allowed, but can significantly slow down searching for runtime files. For speed, use as few items as possible and avoid diff -Nru vim-7.4.1830/runtime/doc/quickfix.txt vim-7.4.1907/runtime/doc/quickfix.txt --- vim-7.4.1830/runtime/doc/quickfix.txt 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/doc/quickfix.txt 2016-06-07 20:50:01.000000000 +0000 @@ -1,4 +1,4 @@ -*quickfix.txt* For Vim version 7.4. Last change: 2016 Mar 23 +*quickfix.txt* For Vim version 7.4. Last change: 2016 Jun 02 VIM REFERENCE MANUAL by Bram Moolenaar @@ -457,6 +457,9 @@ The BufWinEnter event is also triggered, again using "quickfix" for the buffer name. +Note: When adding to an existing quickfix list the autocommand are not +triggered. + Note: Making changes in the quickfix window has no effect on the list of errors. 'modifiable' is off to avoid making changes. If you delete or insert lines anyway, the relation between the text and the error number is messed up. diff -Nru vim-7.4.1830/runtime/doc/repeat.txt vim-7.4.1907/runtime/doc/repeat.txt --- vim-7.4.1830/runtime/doc/repeat.txt 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/doc/repeat.txt 2016-06-07 20:50:01.000000000 +0000 @@ -1,4 +1,4 @@ -*repeat.txt* For Vim version 7.4. Last change: 2016 Apr 05 +*repeat.txt* For Vim version 7.4. Last change: 2016 May 24 VIM REFERENCE MANUAL by Bram Moolenaar @@ -232,6 +232,8 @@ pack/*/opt/{name} ~ The directory is added to 'runtimepath' if it wasn't there yet. + If the directory pack/*/opt/{name}/after exists it is + added at the end of 'runtimepath'. Note that {name} is the directory name, not the name of the .vim file. All the files matching the pattern @@ -507,6 +509,9 @@ This also works when loading plugins is disabled. The automatic loading will only happen once. +If the package has an "after" directory, that directory is added to the end of +'runtimepath', so that anything there will be loaded later. + Using a single plugin and loading it automatically ~ diff -Nru vim-7.4.1830/runtime/doc/syntax.txt vim-7.4.1907/runtime/doc/syntax.txt --- vim-7.4.1830/runtime/doc/syntax.txt 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/doc/syntax.txt 2016-06-07 20:50:01.000000000 +0000 @@ -1,4 +1,4 @@ -*syntax.txt* For Vim version 7.4. Last change: 2016 Apr 10 +*syntax.txt* For Vim version 7.4. Last change: 2016 May 28 VIM REFERENCE MANUAL by Bram Moolenaar @@ -4779,6 +4779,10 @@ All fonts used, except for Menu and Tooltip, should be of the same character size as the default font! Otherwise redrawing problems will occur. + To use a font name with an embedded space or other special character, + put it in single quotes. The single quote cannot be used then. + Example: > + :hi comment font='Monospace 10' guifg={color-name} *highlight-guifg* guibg={color-name} *highlight-guibg* diff -Nru vim-7.4.1830/runtime/doc/tags vim-7.4.1907/runtime/doc/tags --- vim-7.4.1830/runtime/doc/tags 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/doc/tags 2016-06-07 20:50:01.000000000 +0000 @@ -1261,6 +1261,7 @@ +mzscheme/dyn various.txt /*+mzscheme\/dyn* +netbeans_intg various.txt /*+netbeans_intg* +ole various.txt /*+ole* ++packages various.txt /*+packages* +path_extra various.txt /*+path_extra* +perl various.txt /*+perl* +perl/dyn various.txt /*+perl\/dyn* @@ -4588,6 +4589,7 @@ PHP_outdentphpescape indent.txt /*PHP_outdentphpescape* PHP_removeCRwhenUnix indent.txt /*PHP_removeCRwhenUnix* PHP_vintage_case_default_indent indent.txt /*PHP_vintage_case_default_indent* +Partial eval.txt /*Partial* Pattern pattern.txt /*Pattern* Perl if_perl.txt /*Perl* Posix intro.txt /*Posix* @@ -4914,7 +4916,6 @@ aff-dic-format spell.txt /*aff-dic-format* after-directory options.txt /*after-directory* aleph options.txt /*aleph* -alloc_fail() eval.txt /*alloc_fail()* alt intro.txt /*alt* alt-input debugger.txt /*alt-input* alternate-file editing.txt /*alternate-file* @@ -5035,6 +5036,7 @@ beval_col-variable eval.txt /*beval_col-variable* beval_lnum-variable eval.txt /*beval_lnum-variable* beval_text-variable eval.txt /*beval_text-variable* +beval_winid-variable eval.txt /*beval_winid-variable* beval_winnr-variable eval.txt /*beval_winnr-variable* bitwise-function usr_41.txt /*bitwise-function* blockwise-examples visual.txt /*blockwise-examples* @@ -5067,6 +5069,7 @@ bufloaded() eval.txt /*bufloaded()* bufname() eval.txt /*bufname()* bufnr() eval.txt /*bufnr()* +bufwinid() eval.txt /*bufwinid()* bufwinnr() eval.txt /*bufwinnr()* bug-fixes-5 version5.txt /*bug-fixes-5* bug-fixes-6 version6.txt /*bug-fixes-6* @@ -5561,6 +5564,7 @@ delete-insert change.txt /*delete-insert* delete-menus gui.txt /*delete-menus* deleting change.txt /*deleting* +demoserver.py channel.txt /*demoserver.py* design-assumptions develop.txt /*design-assumptions* design-compatible develop.txt /*design-compatible* design-decisions develop.txt /*design-decisions* @@ -5616,7 +5620,6 @@ dircolors.vim syntax.txt /*dircolors.vim* dis motion.txt /*dis* disable-menus gui.txt /*disable-menus* -disable_char_avail_for_testing() eval.txt /*disable_char_avail_for_testing()* discard editing.txt /*discard* distribute-script usr_41.txt /*distribute-script* distribution intro.txt /*distribution* @@ -6350,7 +6353,6 @@ g`a motion.txt /*g`a* ga various.txt /*ga* garbagecollect() eval.txt /*garbagecollect()* -garbagecollect_for_testing() eval.txt /*garbagecollect_for_testing()* gd pattern.txt /*gd* gdb debug.txt /*gdb* ge motion.txt /*ge* @@ -7185,6 +7187,7 @@ mouse_col-variable eval.txt /*mouse_col-variable* mouse_lnum-variable eval.txt /*mouse_lnum-variable* mouse_win-variable eval.txt /*mouse_win-variable* +mouse_winid-variable eval.txt /*mouse_winid-variable* movement intro.txt /*movement* ms-dos os_msdos.txt /*ms-dos* msdos os_msdos.txt /*msdos* @@ -8610,6 +8613,15 @@ terminfo term.txt /*terminfo* termresponse-variable eval.txt /*termresponse-variable* test-functions usr_41.txt /*test-functions* +test_alloc_fail() eval.txt /*test_alloc_fail()* +test_disable_char_avail() eval.txt /*test_disable_char_avail()* +test_garbagecollect_now() eval.txt /*test_garbagecollect_now()* +test_null_channel() eval.txt /*test_null_channel()* +test_null_dict() eval.txt /*test_null_dict()* +test_null_job() eval.txt /*test_null_job()* +test_null_list() eval.txt /*test_null_list()* +test_null_partial() eval.txt /*test_null_partial()* +test_null_string() eval.txt /*test_null_string()* testing-variable eval.txt /*testing-variable* tex-cchar syntax.txt /*tex-cchar* tex-cole syntax.txt /*tex-cole* @@ -8752,6 +8764,7 @@ v:beval_col eval.txt /*v:beval_col* v:beval_lnum eval.txt /*v:beval_lnum* v:beval_text eval.txt /*v:beval_text* +v:beval_winid eval.txt /*v:beval_winid* v:beval_winnr eval.txt /*v:beval_winnr* v:char eval.txt /*v:char* v:charconvert_from eval.txt /*v:charconvert_from* @@ -8786,6 +8799,7 @@ v:mouse_col eval.txt /*v:mouse_col* v:mouse_lnum eval.txt /*v:mouse_lnum* v:mouse_win eval.txt /*v:mouse_win* +v:mouse_winid eval.txt /*v:mouse_winid* v:none eval.txt /*v:none* v:null eval.txt /*v:null* v:oldfiles eval.txt /*v:oldfiles* diff -Nru vim-7.4.1830/runtime/doc/todo.txt vim-7.4.1907/runtime/doc/todo.txt --- vim-7.4.1830/runtime/doc/todo.txt 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/doc/todo.txt 2016-06-07 20:50:01.000000000 +0000 @@ -1,4 +1,4 @@ -*todo.txt* For Vim version 7.4. Last change: 2016 May 08 +*todo.txt* For Vim version 7.4. Last change: 2016 Jun 04 VIM REFERENCE MANUAL by Bram Moolenaar @@ -34,35 +34,11 @@ *known-bugs* -------------------- Known bugs and current work ----------------------- -Crash when running a job a second time. (stewart, May 4) - -problem with "Ignore" after adding 'guicolors'. (Charles Campbell, 2016 Apr -27) - -In test_partial when start_job() has a non-existing command memory leaks. - -Rename garbagecollect_for_testing() to test_garbagecollect_now(). -Add test_get_null_list(), use in test_expr. - -Memory leak in test49 -Memory leak in test_alot, with matchstrpos() - -Packages: -- Add the "after" directory to 'runtimepath' only if it exists. - (Greg Hurrell, May 1) -- Also keep a list of loaded plugins, skip when encountered again? - -Vim.org: when a user already has a homepage, do show the field so that it can -be deleted. - +channel: -- When running "echo hello" the job remains defunc. (Nicola, May 7) -- Feedback from Ramel Eshed, May 7. Occasional crashes. -- GUI:cursor blinking is irregular when invoking callbacks. (Ramel Eshed, 2016 - Apr 16) somehow remember the previous state? - When a message in the queue but there is no callback, drop it after a while? Add timestamp to queued messages and callbacks with ID, remove after a minute. Option to set the droptime. +- Add an option to drop text of very long lines? Default to 1 Mbyte. - Add remark about undo sync, is there a way to force it? - When starting a job, have an option to open the server socket, so we know the port, and pass it to the command with --socket-fd {nr}. (Olaf Dabrunz, @@ -73,8 +49,6 @@ - job_start(): run job in a newly opened terminal. With xterm could use -S{pty}. -Make it so that the window ID can be used where currently a window nr is used - Regexp problems: - Since 7.4.704 the old regex engine fails to match [[:print:]] in 0xf6. (Manuel Ortega, 2016 Apr 24) @@ -122,7 +96,11 @@ matches the empty string. (Dominique Pelle, 2015 Oct 2, Nov 24) - Search for \\~ causes error E874. -Using freed memory in quickfix code. (Dominique, 2016 Mar 21) +Patch to reduce number of memory allocations for quickfix lines. +(Yegappan Lakshmanan, 2016 May 22, #831) + +User commands: add a <> item to pass on command modifiers, such as ":tab". +Patch by Yegappan Lakshmanan, 2016 May 22, #829. jsonencode(): should convert to utf-8. (Nikolai Pavlov, 2016 Jan 23) What if there is an invalid character? @@ -130,8 +108,12 @@ Once .exe with updated installer is available: Add remark to download page about /S and /D options (Ken Takata, 2016 Apr 13) -Patch to avoid reallocating buffer for quickfix lines three times. -(Yegappan Lakshmanan, 2016 May 7) +Cursor positioned in the wrong place when editing src/testdir/test_viml.vim. + +When using "k" at the hit-enter prompt only get the hit-enter prompt, not +scrolling up. (Ramel Eshed, 2016 May 25) +Related patches: Patch 7.4.1603, Patch 7.4.1594 +Patch by Hirohito Higashi, 2016 May 26. Patch to make cursor blinking work better with GTK3. (Kazunobu Kuriyama, 2016 Apr 19) Need to check this works on Linux. @@ -148,11 +130,34 @@ Invalid behavior with NULL list. (Nikolai Pavlov, #768) -After patch 7.4.1818 the language is removed too often. (Ken Takata, 2016 May +Patch to fix using CTRL-] on "{address}." in help. (Hirohito Higashi, 2016 May +18, #814) + +Can we add a function to parse one line for 'errorformat'? Like ":caddexpr" +for one line. + +Patch to fix greying popup menu items. (Shane Harper, 2016 May 23, #834) + +&t_ut not used with 'termguicolors' is set. (Jacob Niehus, 2016 May 14, #804) +Patch to fix this, Jacob Niehus, 2016 May 14, #805) + +For current Windows build .pdb file is missing. (Gabriele Fava, 2016 May 11) 5) +Patch to support expression argument to sort() instead of a function name. +Yasuhiro Matsumoto, 2013 May 31. +Or should we add a more general mechanism, like a lambda() function? +Patch by Yasuhiro Matsumoto, 2014 Sep 16, update 2016 Apr 17. +Correction for test, Ken Takata, 2016 May 27. + +Problem with whitespace in errorformat. (Gerd Wachsmuth, 2016 May 15, #807) + +Patch to add filtering of the quickfix list. (Yegappan Lakshmanan, 2016 Mar +13, last version) Update May 22, #830. + When 'autochdir' is set, writing new file does not change the current dir. (Dan Church, issue #777) +Patch to fix this. (mister fish (Allen Haim), 2016 May 14, #803) ml_get errors when reloading file. (Chris Desjardins, 2016 Apr 19) Also with latest version. @@ -181,6 +186,10 @@ Patch to make matchit work better, respect 'matchpairs'. (Ken Takata, 2016 Mar 25) +Possibly wrong value for seq_cur. (Florent Fayolle, 2016 May 15, #806) + +Patch to improve map documentation. Issue #799. + We can use '. to go to the last change in the current buffer, but how about the last change in any buffer? Can we use ', (, is next to .)? @@ -206,6 +215,14 @@ Patch to support 64 bit ints for Number. (Ken Takata, 2016 Jan 21) Update 2016 Apr 24. +Patch to improve cscope. (Adrian Kocis, #843) + +Patch for groovy multi-line comment highlighting. (Justin M. Keyes, 2016 May +20 #644) + +When doing "vi buf.md" a BufNew autocommand for *.md is not triggered. +Because of using the initial buffer? (Dun Peal, 2016 May 12) + Patch to add the :bvimgrep command. (Christian Brabandt, 2014 Nov 12) Updated 2016 Feb 10 @@ -247,11 +264,6 @@ When repeating the 'confirm' dialog one needs to press Enter. (ds26gte, 2016 Apr 17) #762 -Patch to support expression argument to sort() instead of a function name. -Yasuhiro Matsumoto, 2013 May 31. -Or should we add a more general mechanism, like a lambda() function? -Patch by Yasuhiro Matsumoto, 2014 Sep 16, update 2016 Apr 17. - Should jsonencode()/jsondecode() restrict recursiveness? Or avoid recursiveness. @@ -374,9 +386,6 @@ Value returned by virtcol() changes depending on how lines wrap. This is inconsistent with the documentation. -Patch to add filtering of the quickfix list. (Yegappan Lakshmanan, 2016 Mar -13, last version) Update Mar 21., Apr 2. - Can we cache the syntax attributes, so that updates for 'relativenumber' and 'cursorline'/'cursorcolumn' are a lot faster? @@ -422,8 +431,6 @@ Proposal to make options.txt easier to read. (Arnaud Decara, 2015 Aug 5) Update Aug 14. -Crash in :cnext on MS-Windows. (Ben Fritz, 2015 Oct 27) - When using --remote-tab on MS-Windows 'encoding' hasn't been initialized yet, the file name ends up encoded wrong. (Raul Coronado, 2015 Dec 21) diff -Nru vim-7.4.1830/runtime/doc/usr_41.txt vim-7.4.1907/runtime/doc/usr_41.txt --- vim-7.4.1830/runtime/doc/usr_41.txt 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/doc/usr_41.txt 2016-06-07 20:50:01.000000000 +0000 @@ -1,4 +1,4 @@ -*usr_41.txt* For Vim version 7.4. Last change: 2016 Apr 12 +*usr_41.txt* For Vim version 7.4. Last change: 2016 Jun 04 VIM USER MANUAL - by Bram Moolenaar @@ -786,6 +786,7 @@ tabpagenr() get the number of a tab page tabpagewinnr() like winnr() for a specified tab page winnr() get the window number for the current window + bufwinid() get the window ID of a specific buffer bufwinnr() get the window number of a specific buffer winbufnr() get the buffer number of a specific window getbufline() get a list of lines from the specified buffer diff -Nru vim-7.4.1830/runtime/doc/various.txt vim-7.4.1907/runtime/doc/various.txt --- vim-7.4.1830/runtime/doc/various.txt 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/doc/various.txt 2016-06-07 20:50:01.000000000 +0000 @@ -1,4 +1,4 @@ -*various.txt* For Vim version 7.4. Last change: 2016 May 05 +*various.txt* For Vim version 7.4. Last change: 2016 May 24 VIM REFERENCE MANUAL by Bram Moolenaar @@ -607,13 +607,16 @@ directory of Vim. It is called 'ref' and does a simple spelling check. Special cases: + - If 'keywordprg' begins with ":" it is invoked as + a Vim Ex command with [count]. - If 'keywordprg' is empty, the ":help" command is used. It's a good idea to include more characters in 'iskeyword' then, to be able to find more help. - - When 'keywordprg' is equal to "man", a count before - "K" is inserted after the "man" command and before - the keyword. For example, using "2K" while the - cursor is on "mkdir", results in: > + - When 'keywordprg' is equal to "man" or starts with + ":", a [count] before "K" is inserted after + keywordprg and before the keyword. For example, + using "2K" while the cursor is on "mkdir", results + in: > !man 2 mkdir < - When 'keywordprg' is equal to "man -s", a count before "K" is inserted after the "-s". If there is diff -Nru vim-7.4.1830/runtime/doc/version7.txt vim-7.4.1907/runtime/doc/version7.txt --- vim-7.4.1830/runtime/doc/version7.txt 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/doc/version7.txt 2016-06-07 20:50:01.000000000 +0000 @@ -1,4 +1,4 @@ -*version7.txt* For Vim version 7.4. Last change: 2016 Apr 03 +*version7.txt* For Vim version 7.4. Last change: 2016 Jun 04 VIM REFERENCE MANUAL by Bram Moolenaar diff -Nru vim-7.4.1830/runtime/doc/version8.txt vim-7.4.1907/runtime/doc/version8.txt --- vim-7.4.1830/runtime/doc/version8.txt 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/doc/version8.txt 2016-06-07 20:50:01.000000000 +0000 @@ -1,4 +1,4 @@ -*version8.txt* For Vim version 8.0. Last change: 2016 Apr 14 +*version8.txt* For Vim version 8.0. Last change: 2016 Jun 04 VIM REFERENCE MANUAL by Bram Moolenaar @@ -13,10 +13,8 @@ :version See |vi_diff.txt| for an overview of differences between Vi and Vim 7.0. -See |version4.txt| for differences between Vim 3.x and Vim 4.x. -See |version5.txt| for differences between Vim 4.x and Vim 5.x. -See |version6.txt| for differences between Vim 5.x and Vim 6.x. -See |version7.txt| for differences between Vim 6.x and Vim 7.x. +See |version4.txt|, |version5.txt|, |version6.txt| and |version7.txt| for +differences between other versions. INCOMPATIBLE CHANGES |incompatible-8| @@ -104,7 +102,8 @@ This is for Vim developers. So far writing tests for Vim has not been easy. Vim 8 adds assert functions and a framework to run tests. This makes it a lot -simpler to write tests and keep them updated. +simpler to write tests and keep them updated. Also new are several functions +that are added specifically for testing. These functions have been added: |assert_equal()| @@ -115,15 +114,22 @@ |assert_match()| |assert_notmatch()| |assert_true()| - |alloc_fail()| - |disable_char_avail_for_testing()| + |test_alloc_fail()| + |test_disable_char_avail()| + |test_garbagecollect_now()| + |test_null_channel()| + |test_null_dict()| + |test_null_job()| + |test_null_list()| + |test_null_partial()| + |test_null_string()| Window IDs ~ Previously windows could only be accessed by their number. And every time a window would open, close or move that number changes. Each window now has a -unique ID, so that they are easy to find. +unique ID, so that they are easy to find. See |win_getid()| and |win_id2win()|. Wrapping lines with indent ~ diff -Nru vim-7.4.1830/runtime/ftplugin/groovy.vim vim-7.4.1907/runtime/ftplugin/groovy.vim --- vim-7.4.1830/runtime/ftplugin/groovy.vim 1970-01-01 00:00:00.000000000 +0000 +++ vim-7.4.1907/runtime/ftplugin/groovy.vim 2016-06-07 20:50:01.000000000 +0000 @@ -0,0 +1,19 @@ +" Vim filetype plugin file +" Language: groovy +" Maintainer: Justin M. Keyes +" Last Change: 2016 May 22 + +if exists('b:did_ftplugin') + finish +endif +let b:did_ftplugin = 1 + +let s:cpo_save = &cpo +set cpo-=C + +let b:undo_ftplugin = 'setlocal commentstring<' + +setlocal commentstring=//%s + +let &cpo = s:cpo_save +unlet s:cpo_save diff -Nru vim-7.4.1830/runtime/ftplugin/spec.vim vim-7.4.1907/runtime/ftplugin/spec.vim --- vim-7.4.1830/runtime/ftplugin/spec.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/ftplugin/spec.vim 2016-06-07 20:50:01.000000000 +0000 @@ -36,10 +36,11 @@ else: specfile = vim.current.buffer.name if specfile: + rpm.delMacro("dist") spec = rpm.spec(specfile) - headers = spec.packages[0].header - version = headers['Version'] - release = ".".join(headers['Release'].split(".")[:-1]) + headers = spec.sourceHeader + version = headers["Version"] + release = headers["Release"] vim.command("let ver = " + version) vim.command("let rel = " + release) PYEND @@ -113,7 +114,10 @@ endif endif if (chgline != -1) + let tmptime = v:lc_time + language time C let parsed_format = "* ".strftime(format)." - ".ver."-".rel + execute "language time" tmptime let release_info = "+ ".name."-".ver."-".rel let wrong_format = 0 let wrong_release = 0 @@ -179,12 +183,8 @@ endif let varname = strpart(a:str, start+2, end-(start+2)) execute a:strline - let definestr = "^[ \t]*%define[ \t]\\+" . varname . "[ \t]\\+\\(.*\\)$" + let definestr = "^[ \t]*%(?:global|define)[ \t]\\+" . varname . "[ \t]\\+\\(.*\\)$" let linenum = search(definestr, "bW") - if (linenum == 0) - let definestr = substitute(definestr, "%define", "%global", "") - let linenum = search(definestr, "bW") - endif if (linenum != -1) let ret = ret . substitute(getline(linenum), definestr, "\\1", "") else @@ -201,7 +201,7 @@ let b:match_ignorecase = 0 let b:match_words = - \ '^Name:^%description:^%clean:^%setup:^%build:^%install:^%files:' . + \ '^Name:^%description:^%clean:^%(?:auto)?setup:^%build:^%install:^%files:' . \ '^%package:^%preun:^%postun:^%changelog' let &cpo = s:cpo_save diff -Nru vim-7.4.1830/runtime/indent/vhdl.vim vim-7.4.1907/runtime/indent/vhdl.vim --- vim-7.4.1830/runtime/indent/vhdl.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/indent/vhdl.vim 2016-06-07 20:50:01.000000000 +0000 @@ -1,8 +1,8 @@ " VHDL indent ('93 syntax) " Language: VHDL " Maintainer: Gerald Lai -" Version: 1.58 -" Last Change: 2011 Sep 27 +" Version: 1.60 +" Last Change: 2016 Feb 26 " URL: http://www.vim.org/scripts/script.php?script_id=1450 " only load this indent file when no other was loaded @@ -104,7 +104,7 @@ let pn = prevnonblank(pn - 1) let ps = getline(pn) endwhile - if (curs =~ '^\s*)' || curs =~? '^\s*\%(\<\%(procedure\|generic\|map\|port\)\>.*\)\@\s*\S\+\|:[^=]\@=\s*\%(\%(in\|out\|inout\|buffer\|linkage\)\>\|\w\+\s\+:=\)\)') && (prevs =~? s:NC.'\<\%(procedure\s\+\S\+\|generic\|map\|port\)\s*(\%(\s*\w\)\=' || (ps =~? s:NC.'\<\%(procedure\|generic\|map\|port\)'.s:ES && prevs =~ '^\s*(')) + if (curs =~ '^\s*)' || curs =~? '^\s*\%(\<\%(procedure\|generic\|map\|port\)\>.*\)\@\s*\S\+\|:[^=]\@=\s*\%(\%(in\|out\|inout\|buffer\|linkage\)\>\|\s\+\)\)') && (prevs =~? s:NC.'\<\%(procedure\s\+\S\+\|generic\|map\|port\)\s*(\%(\s*\w\)\=' || (ps =~? s:NC.'\<\%(procedure\|generic\|map\|port\)'.s:ES && prevs =~ '^\s*(')) " align closing ")" with opening "(" if curs =~ '^\s*)' return ind2 + stridx(prevs_noi, '(') @@ -412,11 +412,22 @@ " **************************************************************************************** " indent: maintain indent of previous opening statement - " keywords: without "procedure", "generic", "map", "port" + ":" but not ":=" + "in", "out", "inout", "buffer", "linkage", variable & ":=" + " keywords: without "procedure", "generic", "map", "port" + ":" but not ":=" + eventually ;$ " where: start of current line - if curs =~? '^\s*\%(\<\%(procedure\|generic\|map\|port\)\>.*\)\@\|\w\+\s\+:=\)' + if curs =~? '^\s*\%(\<\%(procedure\|generic\|map\|port\)\>.*\)\@.*\)\@.*\)\@ " Version: 1.13.2, for Vim 6.3+ +" Fix from Fernando Torres included. " URL: http://www.vim.org/script.php?script_id=39 " Documentation: @@ -122,7 +123,6 @@ " Thanks to Preben "Peppe" Guldberg and Bram Moolenaar for this suggestion! if (match_words != s:last_words) || (&mps != s:last_mps) || \ exists("b:match_debug") - let s:last_words = match_words let s:last_mps = &mps " The next several lines were here before " BF started messing with this script. @@ -134,6 +134,7 @@ \ '\/\*:\*\/,#\s*if\%(def\)\=:#\s*else\>:#\s*elif\>:#\s*endif\>' " s:all = pattern with all the keywords let match_words = match_words . (strlen(match_words) ? "," : "") . default + let s:last_words = match_words if match_words !~ s:notslash . '\\\d' let s:do_BR = 0 let s:pat = match_words diff -Nru vim-7.4.1830/runtime/plugin/manpager.vim vim-7.4.1907/runtime/plugin/manpager.vim --- vim-7.4.1830/runtime/plugin/manpager.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/plugin/manpager.vim 2016-06-07 20:50:01.000000000 +0000 @@ -1,6 +1,6 @@ " Vim plugin for using Vim as manpager. " Maintainer: Enno Nagel -" Last Change: 2016 May 07 +" Last Change: 2016 May 20 " $MAN_PN is supposed to be set by MANPAGER, see ":help manpager.vim". if empty($MAN_PN) @@ -25,5 +25,5 @@ bwipe! setlocal filetype=man - exe 'Man' page_sec[1] page_sec[0] + exe 'Man' page_sec[2] page_sec[1] endfunction diff -Nru vim-7.4.1830/runtime/scripts.vim vim-7.4.1907/runtime/scripts.vim --- vim-7.4.1830/runtime/scripts.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/scripts.vim 2016-06-07 20:50:01.000000000 +0000 @@ -1,7 +1,7 @@ " Vim support file to detect file types in scripts " " Maintainer: Bram Moolenaar -" Last change: 2014 Aug 24 +" Last change: 2016 May 21 " This file is called by an autocommand for every file that has just been " loaded into a buffer. It checks if the type of file can be recognized by @@ -245,7 +245,8 @@ set ft=xhtml " HTML (e.g.: ' + " Avoid "doctype html", used by slim. + elseif s:line1 =~? '' set ft=html " PDF diff -Nru vim-7.4.1830/runtime/syntax/bib.vim vim-7.4.1907/runtime/syntax/bib.vim --- vim-7.4.1830/runtime/syntax/bib.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/syntax/bib.vim 2016-06-07 20:50:01.000000000 +0000 @@ -2,7 +2,7 @@ " Language: BibTeX (bibliographic database format for (La)TeX) " Maintainer: Bernd Feige " Filenames: *.bib -" Last Change: 2014 Mar 26 +" Last Change: 2016 May 31 " Thanks to those who pointed out problems with this file or supplied fixes! @@ -35,8 +35,40 @@ syn keyword bibEntryKw contained institution journal key month note syn keyword bibEntryKw contained number organization pages publisher syn keyword bibEntryKw contained school series title type volume year + +" biblatex keywords, cf. http://mirrors.ctan.org/macros/latex/contrib/biblatex/doc/biblatex.pdf +syn keyword bibType contained mvbook bookinbook suppbook collection mvcollection suppcollection +syn keyword bibType contained online patent periodical suppperiodical mvproceedings reference +syn keyword bibType contained mvreference inreference report set thesis xdata customa customb +syn keyword bibType contained customc customd custome customf electronic www artwork audio bibnote +syn keyword bibType contained commentary image jurisdiction legislation legal letter movie music +syn keyword bibType contained performance review software standard video + +syn keyword bibEntryKw contained abstract isbn issn keywords url +syn keyword bibEntryKw contained addendum afterwordannotation annotation annotator authortype +syn keyword bibEntryKw contained bookauthor bookpagination booksubtitle booktitleaddon +syn keyword bibEntryKw contained commentator date doi editora editorb editorc editortype +syn keyword bibEntryKw contained editoratype editorbtype editorctype eid entrysubtype +syn keyword bibEntryKw contained eprint eprintclass eprinttype eventdate eventtitle +syn keyword bibEntryKw contained eventtitleaddon file foreword holder indextitle +syn keyword bibEntryKw contained introduction isan ismn isrn issue issuesubtitle +syn keyword bibEntryKw contained issuetitle iswc journalsubtitle journaltitle label +syn keyword bibEntryKw contained language library location mainsubtitle maintitle +syn keyword bibEntryKw contained maintitleaddon nameaddon origdate origlanguage +syn keyword bibEntryKw contained origlocation origpublisher origtitle pagetotal +syn keyword bibEntryKw contained pagination part pubstate reprinttitle shortauthor +syn keyword bibEntryKw contained shorteditor shorthand shorthandintro shortjournal +syn keyword bibEntryKw contained shortseries shorttitle subtitle titleaddon translator +syn keyword bibEntryKw contained urldate venue version volumes entryset execute gender +syn keyword bibEntryKw contained langid langidopts ids indexsorttitle options presort +syn keyword bibEntryKw contained related relatedoptions relatedtype relatedstring +syn keyword bibEntryKw contained sortkey sortname sortshorthand sorttitle sortyear xdata +syn keyword bibEntryKw contained xref namea nameb namec nameatype namebtype namectype +syn keyword bibEntryKw contained lista listb listc listd liste listf usera userb userc +syn keyword bibEntryKw contained userd usere userf verba verbb verbc archiveprefix pdf +syn keyword bibEntryKw contained primaryclass + " Non-standard: -syn keyword bibNSEntryKw contained abstract isbn issn keywords url " AMS mref http://www.ams.org/mref syn keyword bibNSEntryKw contained mrclass mrnumber mrreviewer fjournal coden diff -Nru vim-7.4.1830/runtime/syntax/debchangelog.vim vim-7.4.1907/runtime/syntax/debchangelog.vim --- vim-7.4.1830/runtime/syntax/debchangelog.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/syntax/debchangelog.vim 2016-06-07 20:50:01.000000000 +0000 @@ -3,7 +3,7 @@ " Maintainer: Debian Vim Maintainers " Former Maintainers: Gerfried Fuchs " Wichert Akkerman -" Last Change: 2015 Oct 24 +" Last Change: 2016 Apr 24 " URL: https://anonscm.debian.org/cgit/pkg-vim/vim.git/plain/runtime/syntax/debchangelog.vim " Standard syntax initialization @@ -23,7 +23,7 @@ syn match debchangelogName contained "^[[:alnum:]][[:alnum:].+-]\+ " exe 'syn match debchangelogFirstKV contained "; \('.urgency.'\|'.binNMU.'\)"' exe 'syn match debchangelogOtherKV contained ", \('.urgency.'\|'.binNMU.'\)"' -syn match debchangelogTarget contained "\v %(frozen|unstable|sid|%(testing|%(old)=stable)%(-proposed-updates|-security)=|experimental|squeeze-%(backports%(-sloppy)=|volatile|lts|security)|wheezy-%(backports%(-sloppy)=|security)|jessie%(-backports|-security)=|stretch|%(devel|precise|trusty|vivid|wily|xenial)%(-%(security|proposed|updates|backports|commercial|partner))=)+" +syn match debchangelogTarget contained "\v %(frozen|unstable|sid|%(testing|%(old)=stable)%(-proposed-updates|-security)=|experimental|squeeze-%(backports%(-sloppy)=|volatile|lts|security)|wheezy-%(backports%(-sloppy)=|security)|jessie%(-backports|-security)=|stretch|%(devel|precise|trusty|vivid|wily|xenial|yakkety)%(-%(security|proposed|updates|backports|commercial|partner))=)+" syn match debchangelogVersion contained "(.\{-})" syn match debchangelogCloses contained "closes:\_s*\(bug\)\=#\=\_s\=\d\+\(,\_s*\(bug\)\=#\=\_s\=\d\+\)*" syn match debchangelogLP contained "\clp:\s\+#\d\+\(,\s*#\d\+\)*" diff -Nru vim-7.4.1830/runtime/syntax/debsources.vim vim-7.4.1907/runtime/syntax/debsources.vim --- vim-7.4.1830/runtime/syntax/debsources.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/syntax/debsources.vim 2016-06-07 20:50:01.000000000 +0000 @@ -2,7 +2,7 @@ " Language: Debian sources.list " Maintainer: Debian Vim Maintainers " Former Maintainer: Matthijs Mohlmann -" Last Change: 2015 Oct 24 +" Last Change: 2016 Apr 24 " URL: https://anonscm.debian.org/cgit/pkg-vim/vim.git/plain/runtime/syntax/debsources.vim " Standard syntax initialization @@ -27,7 +27,7 @@ \ 'oldstable', 'stable', 'testing', 'unstable', 'experimental', \ 'squeeze', 'wheezy', 'jessie', 'stretch', 'sid', 'rc-buggy', \ - \ 'precise', 'trusty', 'vivid', 'wily', 'xenial', 'devel' + \ 'precise', 'trusty', 'wily', 'xenial', 'yakkety', 'devel' \ ] let s:unsupported = [ \ 'buzz', 'rex', 'bo', 'hamm', 'slink', 'potato', @@ -36,7 +36,7 @@ \ 'warty', 'hoary', 'breezy', 'dapper', 'edgy', 'feisty', \ 'gutsy', 'hardy', 'intrepid', 'jaunty', 'karmic', 'lucid', \ 'maverick', 'natty', 'oneiric', 'quantal', 'raring', 'saucy', - \ 'utopic' + \ 'utopic', 'vivid' \ ] let &cpo=s:cpo diff -Nru vim-7.4.1830/runtime/syntax/groovy.vim vim-7.4.1907/runtime/syntax/groovy.vim --- vim-7.4.1830/runtime/syntax/groovy.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/syntax/groovy.vim 2016-06-07 20:50:01.000000000 +0000 @@ -2,9 +2,9 @@ " Language: Groovy " Original Author: Alessio Pace " Maintainer: Tobias Rapp -" Version: 0.1.14 +" Version: 0.1.16 " URL: http://www.vim.org/scripts/script.php?script_id=945 -" Last Change: 2015 Apr 21 +" Last Change: 2016 May 23 " THE ORIGINAL AUTHOR'S NOTES: " @@ -255,8 +255,11 @@ syn region groovyString start=+'+ end=+'+ end=+$+ contains=groovySpecialChar,groovySpecialError,@Spell syn region groovyString start=+"""+ end=+"""+ contains=groovySpecialChar,groovySpecialError,@Spell,groovyELExpr syn region groovyString start=+'''+ end=+'''+ contains=groovySpecialChar,groovySpecialError,@Spell -" regex string -syn region groovyString start='/[^/]' end='/' contains=groovySpecialChar,groovyRegexChar,groovyELExpr +if exists("groovy_regex_strings") + " regex strings interfere with the division operator and thus are disabled + " by default + syn region groovyString start='/[^/*]' end='/' contains=groovySpecialChar,groovyRegexChar,groovyELExpr +endif " syn region groovyELExpr start=+${+ end=+}+ keepend contained syn match groovyELExpr /\${.\{-}}/ contained syn match groovyELExpr /\$[a-zA-Z_][a-zA-Z0-9_.]*/ contained diff -Nru vim-7.4.1830/runtime/syntax/scheme.vim vim-7.4.1907/runtime/syntax/scheme.vim --- vim-7.4.1830/runtime/syntax/scheme.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/syntax/scheme.vim 2016-06-07 20:50:01.000000000 +0000 @@ -1,6 +1,6 @@ " Vim syntax file " Language: Scheme (R5RS + some R6RS extras) -" Last Change: 2012 May 13 +" Last Change: 2016 May 23 " Maintainer: Sergey Khorev " Original author: Dirk van Deun @@ -245,6 +245,18 @@ syn region schemeUnquote matchgroup=Delimiter start="#,@\[" end="\]" contains=ALL syn region schemeQuoted matchgroup=Delimiter start="#['`]" end=![ \t()\[\]";]!me=e-1 contains=ALL syn region schemeQuoted matchgroup=Delimiter start="#['`](" matchgroup=Delimiter end=")" contains=ALL + + " Identifiers are very liberal in MzScheme/Racket + syn match schemeOther ![^()[\]{}",'`;#|\\ ]\+! + + " Language setting + syn match schemeLang "#lang [-+_/A-Za-z0-9]\+\>" + + " Various number forms + syn match schemeNumber "[-+]\=[0-9]\+\(\.[0-9]*\)\=\(e[-+]\=[0-9]\+\)\=\>" + syn match schemeNumber "[-+]\=\.[0-9]\+\(e[-+]\=[0-9]\+\)\=\>" + syn match schemeNumber "[-+]\=[0-9]\+/[0-9]\+\>" + syn match schemeNumber "\([-+]\=\([0-9]\+\(\.[0-9]*\)\=\(e[-+]\=[0-9]\+\)\=\|\.[0-9]\+\(e[-+]\=[0-9]\+\)\=\|[0-9]\+/[0-9]\+\)\)\=[-+]\([0-9]\+\(\.[0-9]*\)\=\(e[-+]\=[0-9]\+\)\=\|\.[0-9]\+\(e[-+]\=[0-9]\+\)\=\|[0-9]\+/[0-9]\+\)\=i\>" endif @@ -321,6 +333,9 @@ HiLink schemeExtSyntax Type HiLink schemeExtFunc PreProc + + HiLink schemeLang PreProc + delcommand HiLink endif diff -Nru vim-7.4.1830/runtime/syntax/spec.vim vim-7.4.1907/runtime/syntax/spec.vim --- vim-7.4.1830/runtime/syntax/spec.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/syntax/spec.vim 2016-06-07 20:50:01.000000000 +0000 @@ -3,7 +3,7 @@ " Language: SPEC: Build/install scripts for Linux RPM packages " Maintainer: Igor Gnatenko i.gnatenko.brain@gmail.com " Former Maintainer: Donovan Rebbechi elflord@panix.com (until March 2014) -" Last Change: Sun Mar 2 10:33 MSK 2014 Igor Gnatenko +" Last Change: Sat Apr 9 15:30 2016 Filip Szymański " For version 5.x: Clear all syntax items " For version 6.x: Quit when a syntax file was already loaded @@ -83,8 +83,8 @@ "One line macros - valid in all ScriptAreas "tip: remember do include new items on specScriptArea's skip section -syn region specSectionMacroArea oneline matchgroup=specSectionMacro start='^%\(define\|global\|patch\d*\|setup\|configure\|GNUconfigure\|find_lang\|makeinstall\|make_install\|include\)\>' end='$' contains=specCommandOpts,specMacroIdentifier -syn region specSectionMacroBracketArea oneline matchgroup=specSectionMacro start='^%{\(configure\|GNUconfigure\|find_lang\|makeinstall\|make_install\)}' end='$' contains=specCommandOpts,specMacroIdentifier +syn region specSectionMacroArea oneline matchgroup=specSectionMacro start='^%\(define\|global\|patch\d*\|setup\|autosetup\|autopatch\|configure\|GNUconfigure\|find_lang\|make_build\|makeinstall\|make_install\|include\)\>' end='$' contains=specCommandOpts,specMacroIdentifier +syn region specSectionMacroBracketArea oneline matchgroup=specSectionMacro start='^%{\(configure\|GNUconfigure\|find_lang\|make_build\|makeinstall\|make_install\)}' end='$' contains=specCommandOpts,specMacroIdentifier "%% Files Section %% "TODO %config valid parameters: missingok\|noreplace @@ -105,7 +105,7 @@ "%% PreAmble Section %% "Copyright and Serial were deprecated by License and Epoch syn region specPreAmbleDeprecated oneline matchgroup=specError start='^\(Copyright\|Serial\)' end='$' contains=specEmail,specURL,specURLMacro,specLicense,specColon,specVariables,specSpecialChar,specMacroIdentifier -syn region specPreAmble oneline matchgroup=specCommand start='^\(Prereq\|Summary\|Name\|Version\|Packager\|Requires\|Icon\|URL\|Source\d*\|Patch\d*\|Prefix\|Packager\|Group\|License\|Release\|BuildRoot\|Distribution\|Vendor\|Provides\|ExclusiveArch\|ExcludeArch\|ExclusiveOS\|Obsoletes\|BuildArch\|BuildArchitectures\|BuildRequires\|BuildConflicts\|BuildPreReq\|Conflicts\|AutoRequires\|AutoReq\|AutoReqProv\|AutoProv\|Epoch\)' end='$' contains=specEmail,specURL,specURLMacro,specLicense,specColon,specVariables,specSpecialChar,specMacroIdentifier +syn region specPreAmble oneline matchgroup=specCommand start='^\(Prereq\|Summary\|Name\|Version\|Packager\|Requires\|Recommends\|Suggests\|Supplements\|Enhances\|Icon\|URL\|Source\d*\|Patch\d*\|Prefix\|Packager\|Group\|License\|Release\|BuildRoot\|Distribution\|Vendor\|Provides\|ExclusiveArch\|ExcludeArch\|ExclusiveOS\|Obsoletes\|BuildArch\|BuildArchitectures\|BuildRequires\|BuildConflicts\|BuildPreReq\|Conflicts\|AutoRequires\|AutoReq\|AutoReqProv\|AutoProv\|Epoch\)' end='$' contains=specEmail,specURL,specURLMacro,specLicense,specColon,specVariables,specSpecialChar,specMacroIdentifier "%% Description Section %% syn region specDescriptionArea matchgroup=specSection start='^%description' end='^%'me=e-1 contains=specDescriptionOpts,specEmail,specURL,specNumber,specMacroIdentifier,specComment @@ -114,7 +114,7 @@ syn region specPackageArea matchgroup=specSection start='^%package' end='^%'me=e-1 contains=specPackageOpts,specPreAmble,specComment "%% Scripts Section %% -syn region specScriptArea matchgroup=specSection start='^%\(prep\|build\|install\|clean\|pre\|postun\|preun\|post\|posttrans\)\>' skip='^%{\|^%\(define\|patch\d*\|configure\|GNUconfigure\|setup\|find_lang\|makeinstall\|make_install\)\>' end='^%'me=e-1 contains=specSpecialVariables,specVariables,@specCommands,specVariables,shDo,shFor,shCaseEsac,specNoNumberHilite,specCommandOpts,shComment,shIf,specSpecialChar,specMacroIdentifier,specSectionMacroArea,specSectionMacroBracketArea,shOperator,shQuote1,shQuote2 +syn region specScriptArea matchgroup=specSection start='^%\(prep\|build\|install\|clean\|pre\|postun\|preun\|post\|posttrans\)\>' skip='^%{\|^%\(define\|patch\d*\|configure\|GNUconfigure\|setup\|autosetup\|autopatch\|find_lang\|make_build\|makeinstall\|make_install\)\>' end='^%'me=e-1 contains=specSpecialVariables,specVariables,@specCommands,specVariables,shDo,shFor,shCaseEsac,specNoNumberHilite,specCommandOpts,shComment,shIf,specSpecialChar,specMacroIdentifier,specSectionMacroArea,specSectionMacroBracketArea,shOperator,shQuote1,shQuote2 "%% Changelog Section %% syn region specChangelogArea matchgroup=specSection start='^%changelog' end='^%'me=e-1 contains=specEmail,specURL,specWeekday,specMonth,specNumber,specComment,specLicense diff -Nru vim-7.4.1830/runtime/tools/ccfilter.c vim-7.4.1907/runtime/tools/ccfilter.c --- vim-7.4.1830/runtime/tools/ccfilter.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/runtime/tools/ccfilter.c 2016-06-07 20:50:01.000000000 +0000 @@ -309,7 +309,7 @@ ok = sscanf( p, "make[%*d]: Entering directory `%[^']", BasePath ); if (verbose) - printf( "[%u]?%s\n", ok, Line ); + printf( "[%u]?%s\n", (unsigned)ok, Line ); } else { diff -Nru vim-7.4.1830/src/buffer.c vim-7.4.1907/src/buffer.c --- vim-7.4.1830/src/buffer.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/buffer.c 2016-06-07 20:50:01.000000000 +0000 @@ -574,9 +574,12 @@ int is_curbuf = (buf == curbuf); buf->b_closing = TRUE; - apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf); - if (!buf_valid(buf)) /* autocommands may delete the buffer */ - return; + if (buf->b_ml.ml_mfp != NULL) + { + apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf); + if (!buf_valid(buf)) /* autocommands may delete the buffer */ + return; + } if ((flags & BFA_DEL) && buf->b_p_bl) { apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, FALSE, buf); @@ -1646,6 +1649,7 @@ * If (flags & BLN_CURBUF) is TRUE, may use current buffer. * If (flags & BLN_LISTED) is TRUE, add new buffer to buffer list. * If (flags & BLN_DUMMY) is TRUE, don't count it as a real buffer. + * If (flags & BLN_NEW) is TRUE, don't use an existing buffer. * This is the ONLY way to create a new buffer. */ static int top_file_num = 1; /* highest file number */ @@ -1673,7 +1677,7 @@ if (sfname == NULL || mch_stat((char *)sfname, &st) < 0) st.st_dev = (dev_T)-1; #endif - if (ffname != NULL && !(flags & BLN_DUMMY) && (buf = + if (ffname != NULL && !(flags & (BLN_DUMMY | BLN_NEW)) && (buf = #ifdef UNIX buflist_findname_stat(ffname, &st) #else @@ -2512,7 +2516,7 @@ nr = curwin->w_alt_fnum; for (buf = firstbuf; buf != NULL; buf = buf->b_next) if (buf->b_fnum == nr) - return (buf); + return buf; return NULL; } diff -Nru vim-7.4.1830/src/channel.c vim-7.4.1907/src/channel.c --- vim-7.4.1830/src/channel.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/channel.c 2016-06-07 20:50:01.000000000 +0000 @@ -505,7 +505,7 @@ if (channel == NULL) ch_errorn(NULL, "Channel for fd %d not found", fd); else - channel_read(channel, part, "messageFromNetbeans"); + channel_read(channel, part, "channel_read_fd"); } #endif @@ -514,9 +514,9 @@ */ #ifdef FEAT_GUI_X11 static void -messageFromNetbeans(XtPointer clientData, - int *unused1 UNUSED, - XtInputId *unused2 UNUSED) +messageFromServer(XtPointer clientData, + int *unused1 UNUSED, + XtInputId *unused2 UNUSED) { channel_read_fd((int)(long)clientData); } @@ -525,9 +525,9 @@ #ifdef FEAT_GUI_GTK # if GTK_CHECK_VERSION(3,0,0) static gboolean -messageFromNetbeans(GIOChannel *unused1 UNUSED, - GIOCondition unused2 UNUSED, - gpointer clientData) +messageFromServer(GIOChannel *unused1 UNUSED, + GIOCondition unused2 UNUSED, + gpointer clientData) { channel_read_fd(GPOINTER_TO_INT(clientData)); return TRUE; /* Return FALSE instead in case the event source is to @@ -535,9 +535,9 @@ } # else static void -messageFromNetbeans(gpointer clientData, - gint unused1 UNUSED, - GdkInputCondition unused2 UNUSED) +messageFromServer(gpointer clientData, + gint unused1 UNUSED, + GdkInputCondition unused2 UNUSED) { channel_read_fd((int)(long)clientData); } @@ -558,7 +558,7 @@ (XtAppContext)app_context, channel->ch_part[part].ch_fd, (XtPointer)(XtInputReadMask + XtInputExceptMask), - messageFromNetbeans, + messageFromServer, (XtPointer)(long)channel->ch_part[part].ch_fd); # else # ifdef FEAT_GUI_GTK @@ -573,7 +573,7 @@ channel->ch_part[part].ch_inputHandler = g_io_add_watch( chnnl, G_IO_IN|G_IO_HUP|G_IO_ERR|G_IO_PRI, - messageFromNetbeans, + messageFromServer, GINT_TO_POINTER(channel->ch_part[part].ch_fd)); g_io_channel_unref(chnnl); @@ -583,7 +583,7 @@ (gint)channel->ch_part[part].ch_fd, (GdkInputCondition) ((int)GDK_INPUT_READ + (int)GDK_INPUT_EXCEPTION), - messageFromNetbeans, + messageFromServer, (gpointer)(long)channel->ch_part[part].ch_fd); # endif # endif @@ -1079,11 +1079,15 @@ buf_T *save_curbuf = curbuf; if (name != NULL && *name != NUL) + { buf = buflist_findname(name); + if (buf == NULL) + buf = buflist_findname_exp(name); + } if (buf == NULL) { buf = buflist_new(name == NULL || *name == NUL ? NULL : name, - NULL, (linenr_T)0, BLN_LISTED); + NULL, (linenr_T)0, BLN_LISTED | BLN_NEW); if (buf == NULL) return NULL; buf_copy_options(buf, BCO_ENTER); @@ -1209,9 +1213,20 @@ } if (buf != NULL) { - ch_logs(channel, "writing out to buffer '%s'", + if (opt->jo_set & JO_OUT_MODIFIABLE) + channel->ch_part[PART_OUT].ch_nomodifiable = + !opt->jo_modifiable[PART_OUT]; + + if (!buf->b_p_ma && !channel->ch_part[PART_OUT].ch_nomodifiable) + { + EMSG(_(e_modifiable)); + } + else + { + ch_logs(channel, "writing out to buffer '%s'", (char *)buf->b_ffname); - channel->ch_part[PART_OUT].ch_buffer = buf; + channel->ch_part[PART_OUT].ch_buffer = buf; + } } } @@ -1236,9 +1251,19 @@ buf = find_buffer(opt->jo_io_name[PART_ERR], TRUE); if (buf != NULL) { - ch_logs(channel, "writing err to buffer '%s'", + if (opt->jo_set & JO_ERR_MODIFIABLE) + channel->ch_part[PART_ERR].ch_nomodifiable = + !opt->jo_modifiable[PART_ERR]; + if (!buf->b_p_ma && !channel->ch_part[PART_ERR].ch_nomodifiable) + { + EMSG(_(e_modifiable)); + } + else + { + ch_logs(channel, "writing err to buffer '%s'", (char *)buf->b_ffname); - channel->ch_part[PART_ERR].ch_buffer = buf; + channel->ch_part[PART_ERR].ch_buffer = buf; + } } } @@ -1285,6 +1310,7 @@ int len = (int)STRLEN(line); char_u *p; + /* Need to make a copy to be able to append a NL. */ if ((p = alloc(len + 2)) == NULL) return; STRCPY(p, line); @@ -1524,6 +1550,35 @@ } /* + * Return the first node from "channel"/"part" without removing it. + * Returns NULL if there is nothing. + */ + readq_T * +channel_peek(channel_T *channel, int part) +{ + readq_T *head = &channel->ch_part[part].ch_head; + + return head->rq_next; +} + +/* + * Return a pointer to the first NL in "node". + * Skips over NUL characters. + * Returns NULL if there is no NL. + */ + char_u * +channel_first_nl(readq_T *node) +{ + char_u *buffer = node->rq_buffer; + long_u i; + + for (i = 0; i < node->rq_buflen; ++i) + if (buffer[i] == NL) + return buffer + i; + return NULL; +} + +/* * Return the first buffer from channel "channel"/"part" and remove it. * The caller must free it. * Returns NULL if there is nothing. @@ -1550,6 +1605,7 @@ /* * Returns the whole buffer contents concatenated for "channel"/"part". + * Replaces NUL bytes with NL. */ static char_u * channel_get_all(channel_T *channel, int part) @@ -1566,13 +1622,17 @@ /* Concatenate everything into one buffer. */ for (node = head->rq_next; node != NULL; node = node->rq_next) - len += (long_u)STRLEN(node->rq_buffer); + len += node->rq_buflen; res = lalloc(len, TRUE); if (res == NULL) return NULL; - *res = NUL; + p = res; for (node = head->rq_next; node != NULL; node = node->rq_next) - STRCAT(res, node->rq_buffer); + { + mch_memmove(p, node->rq_buffer, node->rq_buflen); + p += node->rq_buflen; + } + *p = NUL; /* Free all buffers */ do @@ -1581,37 +1641,89 @@ vim_free(p); } while (p != NULL); + /* turn all NUL into NL */ + while (len > 0) + { + --len; + if (res[len] == NUL) + res[len] = NL; + } + return res; } /* + * Consume "len" bytes from the head of "channel"/"part". + * Caller must check these bytes are available. + */ + void +channel_consume(channel_T *channel, int part, int len) +{ + readq_T *head = &channel->ch_part[part].ch_head; + readq_T *node = head->rq_next; + char_u *buf = node->rq_buffer; + + mch_memmove(buf, buf + len, node->rq_buflen - len); + node->rq_buflen -= len; +} + +/* * Collapses the first and second buffer for "channel"/"part". * Returns FAIL if that is not possible. + * When "want_nl" is TRUE collapse more buffers until a NL is found. */ int -channel_collapse(channel_T *channel, int part) +channel_collapse(channel_T *channel, int part, int want_nl) { readq_T *head = &channel->ch_part[part].ch_head; readq_T *node = head->rq_next; + readq_T *last_node; + readq_T *n; + char_u *newbuf; char_u *p; + long_u len; if (node == NULL || node->rq_next == NULL) return FAIL; - p = alloc((unsigned)(STRLEN(node->rq_buffer) - + STRLEN(node->rq_next->rq_buffer) + 1)); - if (p == NULL) - return FAIL; /* out of memory */ - STRCPY(p, node->rq_buffer); - STRCAT(p, node->rq_next->rq_buffer); - vim_free(node->rq_next->rq_buffer); - node->rq_next->rq_buffer = p; + last_node = node->rq_next; + len = node->rq_buflen + last_node->rq_buflen + 1; + if (want_nl) + while (last_node->rq_next != NULL + && channel_first_nl(last_node) == NULL) + { + last_node = last_node->rq_next; + len += last_node->rq_buflen; + } - /* dispose of the node and its buffer */ - head->rq_next = node->rq_next; - head->rq_next->rq_prev = NULL; + p = newbuf = alloc(len); + if (newbuf == NULL) + return FAIL; /* out of memory */ + mch_memmove(p, node->rq_buffer, node->rq_buflen); + p += node->rq_buflen; vim_free(node->rq_buffer); - vim_free(node); + node->rq_buffer = newbuf; + for (n = node; n != last_node; ) + { + n = n->rq_next; + mch_memmove(p, n->rq_buffer, n->rq_buflen); + p += n->rq_buflen; + vim_free(n->rq_buffer); + } + node->rq_buflen = (long_u)(p - newbuf); + + /* dispose of the collapsed nodes and their buffers */ + for (n = node->rq_next; n != last_node; ) + { + n = n->rq_next; + vim_free(n->rq_prev); + } + node->rq_next = last_node->rq_next; + if (last_node->rq_next == NULL) + head->rq_prev = node; + else + last_node->rq_next->rq_prev = node; + vim_free(last_node); return OK; } @@ -1632,6 +1744,8 @@ node = (readq_T *)alloc(sizeof(readq_T)); if (node == NULL) return FAIL; /* out of memory */ + /* A NUL is added at the end, because netbeans code expects that. + * Otherwise a NUL may appear inside the text. */ node->rq_buffer = alloc(len + 1); if (node->rq_buffer == NULL) { @@ -1647,11 +1761,13 @@ if (buf[i] != CAR || i + 1 >= len || buf[i + 1] != NL) *p++ = buf[i]; *p = NUL; + node->rq_buflen = (long_u)(p - node->rq_buffer); } else { mch_memmove(node->rq_buffer, buf, len); node->rq_buffer[len] = NUL; + node->rq_buflen = (long_u)len; } if (prepend) @@ -1998,7 +2114,7 @@ #ifdef FEAT_GUI if (gui.in_use) { - gui_update_cursor(FALSE, FALSE); + gui_update_cursor(TRUE, FALSE); gui_mch_flush(); } #endif @@ -2106,11 +2222,23 @@ } static void -append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel) +append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel, int part) { buf_T *save_curbuf = curbuf; linenr_T lnum = buffer->b_ml.ml_line_count; int save_write_to = buffer->b_write_to_channel; + chanpart_T *ch_part = &channel->ch_part[part]; + int save_p_ma = buffer->b_p_ma; + + if (!buffer->b_p_ma && !ch_part->ch_nomodifiable) + { + if (!ch_part->ch_nomod_error) + { + ch_error(channel, "Buffer is not modifiable, cannot append"); + ch_part->ch_nomod_error = TRUE; + } + return; + } /* If the buffer is also used as input insert above the last * line. Don't write these lines. */ @@ -2123,6 +2251,7 @@ /* Append to the buffer */ ch_logn(channel, "appending line %d to buffer", (int)lnum + 1); + buffer->b_p_ma = TRUE; curbuf = buffer; u_sync(TRUE); /* ignore undo failure, undo is not very useful here */ @@ -2131,6 +2260,10 @@ ml_append(lnum, msg, 0, FALSE); appended_lines_mark(lnum, 1L); curbuf = save_curbuf; + if (ch_part->ch_nomodifiable) + buffer->b_p_ma = FALSE; + else + buffer->b_p_ma = save_p_ma; if (buffer->b_nwindows > 0) { @@ -2205,6 +2338,7 @@ char_u *callback = NULL; partial_T *partial = NULL; buf_T *buffer = NULL; + char_u *p; if (channel->ch_nb_close_cb != NULL) /* this channel is handled elsewhere (netbeans) */ @@ -2297,19 +2431,27 @@ { char_u *nl; char_u *buf; + readq_T *node; /* See if we have a message ending in NL in the first buffer. If * not try to concatenate the first and the second buffer. */ while (TRUE) { - buf = channel_peek(channel, part); - nl = vim_strchr(buf, NL); + node = channel_peek(channel, part); + nl = channel_first_nl(node); if (nl != NULL) break; - if (channel_collapse(channel, part) == FAIL) + if (channel_collapse(channel, part, TRUE) == FAIL) return FALSE; /* incomplete message */ } - if (nl[1] == NUL) + buf = node->rq_buffer; + + /* Convert NUL to NL, the internal representation. */ + for (p = buf; p < nl && p < buf + node->rq_buflen; ++p) + if (*p == NUL) + *p = NL; + + if (nl + 1 == buf + node->rq_buflen) { /* get the whole buffer, drop the NL */ msg = channel_get(channel, part); @@ -2317,16 +2459,19 @@ } else { - /* Copy the message into allocated memory and remove it from - * the buffer. */ + /* Copy the message into allocated memory (excluding the NL) + * and remove it from the buffer (including the NL). */ msg = vim_strnsave(buf, (int)(nl - buf)); - mch_memmove(buf, nl + 1, STRLEN(nl + 1) + 1); + channel_consume(channel, part, (int)(nl - buf) + 1); } } else + { /* For a raw channel we don't know where the message ends, just - * get everything we have. */ + * get everything we have. + * Convert NUL to NL, the internal representation. */ msg = channel_get_all(channel, part); + } if (msg == NULL) return FALSE; /* out of memory (and avoids Coverity warning) */ @@ -2358,7 +2503,7 @@ /* JSON or JS mode: re-encode the message. */ msg = json_encode(listtv, ch_mode); if (msg != NULL) - append_to_buffer(buffer, msg, channel); + append_to_buffer(buffer, msg, channel, part); } if (callback != NULL) @@ -2566,7 +2711,6 @@ clear_tv(&rettv); channel_need_redraw = TRUE; } - --channel->ch_refcount; /* the callback is only called once */ vim_free(channel->ch_close_cb); @@ -2574,6 +2718,8 @@ partial_unref(channel->ch_close_partial); channel->ch_close_partial = NULL; + --channel->ch_refcount; + if (channel_need_redraw) { channel_need_redraw = FALSE; @@ -2589,20 +2735,6 @@ } /* - * Return the first buffer from "channel"/"part" without removing it. - * Returns NULL if there is nothing. - */ - char_u * -channel_peek(channel_T *channel, int part) -{ - readq_T *head = &channel->ch_part[part].ch_head; - - if (head->rq_next == NULL) - return NULL; - return head->rq_next->rq_buffer; -} - -/* * Clear the read buffer on "channel"/"part". */ static void @@ -2868,6 +3000,11 @@ * died. Don't close the channel right away, it may be the wrong moment * to invoke callbacks. */ channel->ch_to_be_closed = TRUE; + +#ifdef FEAT_GUI + /* Stop listening to GUI events right away. */ + channel_gui_unregister(channel); +#endif } static void @@ -2882,7 +3019,7 @@ /* * Read from channel "channel" for as long as there is something to read. * "part" is PART_SOCK, PART_OUT or PART_ERR. - * The data is put in the read queue. + * The data is put in the read queue. No callbacks are invoked here. */ static void channel_read(channel_T *channel, int part, char *func) @@ -2893,6 +3030,10 @@ sock_T fd; int use_socket = FALSE; + /* If we detected a read error don't try reading again. */ + if (channel->ch_to_be_closed) + return; + fd = channel->ch_part[part].ch_fd; if (fd == INVALID_FD) { @@ -2955,18 +3096,23 @@ ch_mode_T mode = channel->ch_part[part].ch_mode; sock_T fd = channel->ch_part[part].ch_fd; char_u *nl; + readq_T *node; ch_logsn(channel, "Blocking %s read, timeout: %d msec", mode == MODE_RAW ? "RAW" : "NL", timeout); while (TRUE) { - buf = channel_peek(channel, part); - if (buf != NULL && (mode == MODE_RAW - || (mode == MODE_NL && vim_strchr(buf, NL) != NULL))) - break; - if (buf != NULL && channel_collapse(channel, part) == OK) - continue; + node = channel_peek(channel, part); + if (node != NULL) + { + if (mode == MODE_RAW || (mode == MODE_NL + && channel_first_nl(node) != NULL)) + /* got a complete message */ + break; + if (channel_collapse(channel, part, mode == MODE_NL) == OK) + continue; + } /* Wait for up to the channel timeout. */ if (fd == INVALID_FD) @@ -2985,8 +3131,17 @@ } else { - nl = vim_strchr(buf, NL); - if (nl[1] == NUL) + char_u *p; + + buf = node->rq_buffer; + nl = channel_first_nl(node); + + /* Convert NUL to NL, the internal representation. */ + for (p = buf; p < nl && p < buf + node->rq_buflen; ++p) + if (*p == NUL) + *p = NL; + + if (nl + 1 == buf + node->rq_buflen) { /* get the whole buffer */ msg = channel_get(channel, part); @@ -2997,7 +3152,7 @@ /* Copy the message into allocated memory and remove it from the * buffer. */ msg = vim_strnsave(buf, (int)(nl - buf)); - mch_memmove(buf, nl + 1, STRLEN(nl + 1) + 1); + channel_consume(channel, part, (int)(nl - buf) + 1); } } if (log_fd != NULL) @@ -3193,6 +3348,10 @@ for (channel = first_channel; channel != NULL; channel = channel->ch_next) { + /* If we detected a read error don't try reading again. */ + if (channel->ch_to_be_closed) + continue; + /* check the socket and pipes */ for (part = PART_SOCK; part <= PART_ERR; ++part) { @@ -3782,6 +3941,8 @@ partial_unref(opt->jo_err_partial); if (opt->jo_close_partial != NULL) partial_unref(opt->jo_close_partial); + if (opt->jo_exit_partial != NULL) + partial_unref(opt->jo_exit_partial); } /* @@ -3900,6 +4061,16 @@ return FAIL; } } + else if (STRCMP(hi->hi_key, "out_modifiable") == 0 + || STRCMP(hi->hi_key, "err_modifiable") == 0) + { + part = part_from_char(*hi->hi_key); + + if (!(supported & JO_OUT_IO)) + break; + opt->jo_set |= JO_OUT_MODIFIABLE << (part - PART_OUT); + opt->jo_modifiable[part] = get_tv_number(item); + } else if (STRCMP(hi->hi_key, "in_top") == 0 || STRCMP(hi->hi_key, "in_bot") == 0) { @@ -3984,6 +4155,18 @@ return FAIL; } } + else if (STRCMP(hi->hi_key, "exit_cb") == 0) + { + if (!(supported & JO_EXIT_CB)) + break; + opt->jo_set |= JO_EXIT_CB; + opt->jo_exit_cb = get_callback(item, &opt->jo_exit_partial); + if (opt->jo_exit_cb == NULL) + { + EMSG2(_(e_invarg2), "exit_cb"); + return FAIL; + } + } else if (STRCMP(hi->hi_key, "waittime") == 0) { if (!(supported & JO_WAITTIME)) @@ -4046,25 +4229,6 @@ return FAIL; } } - else if (STRCMP(hi->hi_key, "exit_cb") == 0) - { - if (!(supported & JO_EXIT_CB)) - break; - opt->jo_set |= JO_EXIT_CB; - if (item->v_type == VAR_PARTIAL && item->vval.v_partial != NULL) - { - opt->jo_exit_partial = item->vval.v_partial; - opt->jo_exit_cb = item->vval.v_partial->pt_name; - } - else - opt->jo_exit_cb = get_tv_string_buf_chk( - item, opt->jo_ecb_buf); - if (opt->jo_exit_cb == NULL) - { - EMSG2(_(e_invarg2), "exit_cb"); - return FAIL; - } - } else if (STRCMP(hi->hi_key, "block_write") == 0) { if (!(supported & JO_BLOCK_WRITE)) @@ -4170,6 +4334,15 @@ } } +#if defined(EXITFREE) || defined(PROTO) + void +job_free_all(void) +{ + while (first_job != NULL) + job_free(first_job); +} +#endif + /* * Return TRUE if the job should not be freed yet. Do not free the job when * it has not ended yet and there is a "stoponexit" flag, an exit callback @@ -4332,6 +4505,21 @@ } /* + * Return TRUE when there is any job that might exit, which means + * job_check_ended() should be called once in a while. + */ + int +has_pending_job() +{ + job_T *job; + + for (job = first_job; job != NULL; job = job->jv_next) + if (job->jv_status == JOB_STARTED && job_still_useful(job)) + return TRUE; + return FALSE; +} + +/* * Called once in a while: check if any jobs that seem useful have ended. */ void @@ -4354,6 +4542,11 @@ job_status(job); /* may free "job" */ } } + if (channel_need_redraw) + { + channel_need_redraw = FALSE; + redraw_after_callback(); + } } /* @@ -4587,6 +4780,7 @@ job->jv_exit_partial, NULL); clear_tv(&rettv); --job->jv_refcount; + channel_need_redraw = TRUE; } if (job->jv_status == JOB_ENDED && job->jv_refcount == 0) { diff -Nru vim-7.4.1830/src/config.aap.in vim-7.4.1907/src/config.aap.in --- vim-7.4.1830/src/config.aap.in 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/config.aap.in 2016-06-07 20:50:01.000000000 +0000 @@ -75,9 +75,6 @@ RUBY_CFLAGS = @RUBY_CFLAGS@ RUBY_LIBS = @RUBY_LIBS@ -SNIFF_SRC = @SNIFF_SRC@ -SNIFF_OBJ = @SNIFF_OBJ@ - AWK = @AWK@ STRIP = @STRIP@ diff -Nru vim-7.4.1830/src/eval.c vim-7.4.1907/src/eval.c --- vim-7.4.1830/src/eval.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/eval.c 2016-06-07 20:50:01.000000000 +0000 @@ -349,6 +349,7 @@ {VV_NAME("fcs_choice", VAR_STRING), 0}, {VV_NAME("beval_bufnr", VAR_NUMBER), VV_RO}, {VV_NAME("beval_winnr", VAR_NUMBER), VV_RO}, + {VV_NAME("beval_winid", VAR_NUMBER), VV_RO}, {VV_NAME("beval_lnum", VAR_NUMBER), VV_RO}, {VV_NAME("beval_col", VAR_NUMBER), VV_RO}, {VV_NAME("beval_text", VAR_STRING), VV_RO}, @@ -358,6 +359,7 @@ {VV_NAME("swapcommand", VAR_STRING), VV_RO}, {VV_NAME("char", VAR_STRING), 0}, {VV_NAME("mouse_win", VAR_NUMBER), 0}, + {VV_NAME("mouse_winid", VAR_NUMBER), 0}, {VV_NAME("mouse_lnum", VAR_NUMBER), 0}, {VV_NAME("mouse_col", VAR_NUMBER), 0}, {VV_NAME("operator", VAR_STRING), VV_RO}, @@ -445,16 +447,17 @@ static int list_extend(list_T *l1, list_T *l2, listitem_T *bef); static int list_concat(list_T *l1, list_T *l2, typval_T *tv); static list_T *list_copy(list_T *orig, int deep, int copyID); -static char_u *list2string(typval_T *tv, int copyID); -static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int echo_style, int copyID, garray_T *join_gap); -static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo, int copyID); +static char_u *list2string(typval_T *tv, int copyID, int restore_copyID); +static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID, garray_T *join_gap); +static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID); static int free_unref_items(int copyID); static dictitem_T *dictitem_copy(dictitem_T *org); static void dictitem_remove(dict_T *dict, dictitem_T *item); static dict_T *dict_copy(dict_T *orig, int deep, int copyID); static long dict_len(dict_T *d); -static char_u *dict2string(typval_T *tv, int copyID); +static char_u *dict2string(typval_T *tv, int copyID, int restore_copyID); static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate); +static char_u *echo_string_core(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID, int echo_style, int restore_copyID, int dict_val); static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); static char_u *string_quote(char_u *str, int function); static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); @@ -472,7 +475,6 @@ static void f_acos(typval_T *argvars, typval_T *rettv); #endif static void f_add(typval_T *argvars, typval_T *rettv); -static void f_alloc_fail(typval_T *argvars, typval_T *rettv); static void f_and(typval_T *argvars, typval_T *rettv); static void f_append(typval_T *argvars, typval_T *rettv); static void f_argc(typval_T *argvars, typval_T *rettv); @@ -499,6 +501,7 @@ static void f_bufloaded(typval_T *argvars, typval_T *rettv); static void f_bufname(typval_T *argvars, typval_T *rettv); static void f_bufnr(typval_T *argvars, typval_T *rettv); +static void f_bufwinid(typval_T *argvars, typval_T *rettv); static void f_bufwinnr(typval_T *argvars, typval_T *rettv); static void f_byte2line(typval_T *argvars, typval_T *rettv); static void byteidx(typval_T *argvars, typval_T *rettv, int comp); @@ -549,7 +552,6 @@ static void f_did_filetype(typval_T *argvars, typval_T *rettv); static void f_diff_filler(typval_T *argvars, typval_T *rettv); static void f_diff_hlID(typval_T *argvars, typval_T *rettv); -static void f_disable_char_avail_for_testing(typval_T *argvars, typval_T *rettv); static void f_empty(typval_T *argvars, typval_T *rettv); static void f_escape(typval_T *argvars, typval_T *rettv); static void f_eval(typval_T *argvars, typval_T *rettv); @@ -583,7 +585,6 @@ static void f_foreground(typval_T *argvars, typval_T *rettv); static void f_function(typval_T *argvars, typval_T *rettv); static void f_garbagecollect(typval_T *argvars, typval_T *rettv); -static void f_garbagecollect_for_testing(typval_T *argvars, typval_T *rettv); static void f_get(typval_T *argvars, typval_T *rettv); static void f_getbufline(typval_T *argvars, typval_T *rettv); static void f_getbufvar(typval_T *argvars, typval_T *rettv); @@ -806,7 +807,20 @@ static void f_taglist(typval_T *argvars, typval_T *rettv); static void f_tagfiles(typval_T *argvars, typval_T *rettv); static void f_tempname(typval_T *argvars, typval_T *rettv); -static void f_test(typval_T *argvars, typval_T *rettv); +static void f_test_alloc_fail(typval_T *argvars, typval_T *rettv); +static void f_test_disable_char_avail(typval_T *argvars, typval_T *rettv); +static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv); +#ifdef FEAT_JOB_CHANNEL +static void f_test_null_channel(typval_T *argvars, typval_T *rettv); +#endif +static void f_test_null_dict(typval_T *argvars, typval_T *rettv); +#ifdef FEAT_JOB_CHANNEL +static void f_test_null_job(typval_T *argvars, typval_T *rettv); +#endif +static void f_test_null_list(typval_T *argvars, typval_T *rettv); +static void f_test_null_partial(typval_T *argvars, typval_T *rettv); +static void f_test_null_string(typval_T *argvars, typval_T *rettv); +static void f_test_settime(typval_T *argvars, typval_T *rettv); #ifdef FEAT_FLOAT static void f_tan(typval_T *argvars, typval_T *rettv); static void f_tanh(typval_T *argvars, typval_T *rettv); @@ -1453,7 +1467,7 @@ ga_init2(&ga, (int)sizeof(char), 80); if (tv.vval.v_list != NULL) { - list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0); + list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, FALSE, 0); if (tv.vval.v_list->lv_len > 0) ga_append(&ga, NL); } @@ -4617,7 +4631,26 @@ clear_tv(&var2); return FAIL; } - n1 = tv_equal(rettv, &var2, FALSE, FALSE); + if ((rettv->v_type == VAR_PARTIAL + && rettv->vval.v_partial == NULL) + || (var2.v_type == VAR_PARTIAL + && var2.vval.v_partial == NULL)) + /* when a partial is NULL assume not equal */ + n1 = FALSE; + else if (type_is) + { + if (rettv->v_type == VAR_FUNC && var2.v_type == VAR_FUNC) + /* strings are considered the same if their value is + * the same */ + n1 = tv_equal(rettv, &var2, ic, FALSE); + else if (rettv->v_type == VAR_PARTIAL + && var2.v_type == VAR_PARTIAL) + n1 = (rettv->vval.v_partial == var2.vval.v_partial); + else + n1 = FALSE; + } + else + n1 = tv_equal(rettv, &var2, ic, FALSE); if (type == TYPE_NEQUAL) n1 = !n1; } @@ -5288,7 +5321,7 @@ * what follows. So set it here. */ if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(') { - rettv->vval.v_string = vim_strsave((char_u *)""); + rettv->vval.v_string = NULL; rettv->v_type = VAR_FUNC; } @@ -6221,6 +6254,8 @@ dictitem_T *item2; int todo; + if (d1 == NULL && d2 == NULL) + return TRUE; if (d1 == NULL || d2 == NULL) return FALSE; if (d1 == d2) @@ -6246,6 +6281,58 @@ static int tv_equal_recurse_limit; + static int +func_equal( + typval_T *tv1, + typval_T *tv2, + int ic) /* ignore case */ +{ + char_u *s1, *s2; + dict_T *d1, *d2; + int a1, a2; + int i; + + /* empty and NULL function name considered the same */ + s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string + : tv1->vval.v_partial->pt_name; + if (s1 != NULL && *s1 == NUL) + s1 = NULL; + s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string + : tv2->vval.v_partial->pt_name; + if (s2 != NULL && *s2 == NUL) + s2 = NULL; + if (s1 == NULL || s2 == NULL) + { + if (s1 != s2) + return FALSE; + } + else if (STRCMP(s1, s2) != 0) + return FALSE; + + /* empty dict and NULL dict is different */ + d1 = tv1->v_type == VAR_FUNC ? NULL : tv1->vval.v_partial->pt_dict; + d2 = tv2->v_type == VAR_FUNC ? NULL : tv2->vval.v_partial->pt_dict; + if (d1 == NULL || d2 == NULL) + { + if (d1 != d2) + return FALSE; + } + else if (!dict_equal(d1, d2, ic, TRUE)) + return FALSE; + + /* empty list and no list considered the same */ + a1 = tv1->v_type == VAR_FUNC ? 0 : tv1->vval.v_partial->pt_argc; + a2 = tv2->v_type == VAR_FUNC ? 0 : tv2->vval.v_partial->pt_argc; + if (a1 != a2) + return FALSE; + for (i = 0; i < a1; ++i) + if (!tv_equal(tv1->vval.v_partial->pt_argv + i, + tv2->vval.v_partial->pt_argv + i, ic, TRUE)) + return FALSE; + + return TRUE; +} + /* * Return TRUE if "tv1" and "tv2" have the same value. * Compares the items just like "==" would compare them, but strings and @@ -6263,22 +6350,6 @@ static int recursive_cnt = 0; /* catch recursive loops */ int r; - /* For VAR_FUNC and VAR_PARTIAL only compare the function name. */ - if ((tv1->v_type == VAR_FUNC - || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL)) - && (tv2->v_type == VAR_FUNC - || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL))) - { - s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string - : tv1->vval.v_partial->pt_name; - s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string - : tv2->vval.v_partial->pt_name; - return (s1 != NULL && s2 != NULL && STRCMP(s1, s2) == 0); - } - - if (tv1->v_type != tv2->v_type) - return FALSE; - /* Catch lists and dicts that have an endless loop by limiting * recursiveness to a limit. We guess they are equal then. * A fixed limit has the problem of still taking an awful long time. @@ -6293,6 +6364,21 @@ return TRUE; } + /* For VAR_FUNC and VAR_PARTIAL only compare the function name. */ + if ((tv1->v_type == VAR_FUNC + || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL)) + && (tv2->v_type == VAR_FUNC + || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL))) + { + ++recursive_cnt; + r = func_equal(tv1, tv2, ic); + --recursive_cnt; + return r; + } + + if (tv1->v_type != tv2->v_type) + return FALSE; + switch (tv1->v_type) { case VAR_LIST: @@ -6755,7 +6841,7 @@ * May return NULL. */ static char_u * -list2string(typval_T *tv, int copyID) +list2string(typval_T *tv, int copyID, int restore_copyID) { garray_T ga; @@ -6763,7 +6849,8 @@ return NULL; ga_init2(&ga, (int)sizeof(char), 80); ga_append(&ga, '['); - if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL) + if (list_join(&ga, tv->vval.v_list, (char_u *)", ", + FALSE, restore_copyID, copyID) == FAIL) { vim_free(ga.ga_data); return NULL; @@ -6784,6 +6871,7 @@ list_T *l, char_u *sep, int echo_style, + int restore_copyID, int copyID, garray_T *join_gap) /* to keep each list item string */ { @@ -6800,10 +6888,8 @@ /* Stringify each item in the list. */ for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) { - if (echo_style) - s = echo_string(&item->li_tv, &tofree, numbuf, copyID); - else - s = tv2string(&item->li_tv, &tofree, numbuf, copyID); + s = echo_string_core(&item->li_tv, &tofree, numbuf, copyID, + echo_style, restore_copyID, FALSE); if (s == NULL) return FAIL; @@ -6862,6 +6948,7 @@ list_T *l, char_u *sep, int echo_style, + int restore_copyID, int copyID) { garray_T join_ga; @@ -6872,7 +6959,8 @@ if (l->lv_len < 1) return OK; /* nothing to do */ ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len); - retval = list_join_inner(gap, l, sep, echo_style, copyID, &join_ga); + retval = list_join_inner(gap, l, sep, echo_style, restore_copyID, + copyID, &join_ga); /* Dispose each item in join_ga. */ if (join_ga.ga_data != NULL) @@ -6925,7 +7013,7 @@ /* * Do garbage collection for lists and dicts. - * When "testing" is TRUE this is called from garbagecollect_for_testing(). + * When "testing" is TRUE this is called from test_garbagecollect_now(). * Return TRUE if some memory was freed. */ int @@ -7035,6 +7123,10 @@ abort = abort || set_ref_in_nb_channel(copyID); #endif +#ifdef FEAT_TIMERS + abort = abort || set_ref_in_timer(copyID); +#endif + if (!abort) { /* @@ -7754,6 +7846,8 @@ char_u *tofree = NULL; hashitem_T *hi; + if (d == NULL) + return NULL; if (len < 0) akey = key; else if (len >= AKEYLEN) @@ -7816,7 +7910,7 @@ * May return NULL. */ static char_u * -dict2string(typval_T *tv, int copyID) +dict2string(typval_T *tv, int copyID, int restore_copyID) { garray_T ga; int first = TRUE; @@ -7851,7 +7945,8 @@ vim_free(tofree); } ga_concat(&ga, (char_u *)": "); - s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID); + s = echo_string_core(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID, + FALSE, restore_copyID, TRUE); if (s != NULL) ga_concat(&ga, s); vim_free(tofree); @@ -8009,16 +8104,23 @@ * Return a string with the string representation of a variable. * If the memory is allocated "tofree" is set to it, otherwise NULL. * "numbuf" is used for a number. - * Does not put quotes around strings, as ":echo" displays values. * When "copyID" is not NULL replace recursive lists and dicts with "...". + * When both "echo_style" and "dict_val" are FALSE, put quotes around stings as + * "string()", otherwise does not put quotes around strings, as ":echo" + * displays values. + * When "restore_copyID" is FALSE, repeated items in dictionaries and lists + * are replaced with "...". * May return NULL. */ static char_u * -echo_string( +echo_string_core( typval_T *tv, char_u **tofree, char_u *numbuf, - int copyID) + int copyID, + int echo_style, + int restore_copyID, + int dict_val) { static int recurse = 0; char_u *r = NULL; @@ -8040,9 +8142,30 @@ switch (tv->v_type) { + case VAR_STRING: + if (echo_style && !dict_val) + { + *tofree = NULL; + r = get_tv_string_buf(tv, numbuf); + } + else + { + *tofree = string_quote(tv->vval.v_string, FALSE); + r = *tofree; + } + break; + case VAR_FUNC: - *tofree = NULL; - r = tv->vval.v_string; + if (echo_style) + { + *tofree = NULL; + r = tv->vval.v_string; + } + else + { + *tofree = string_quote(tv->vval.v_string, TRUE); + r = *tofree; + } break; case VAR_PARTIAL: @@ -8097,15 +8220,20 @@ *tofree = NULL; r = NULL; } - else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID) + else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID + && tv->vval.v_list->lv_len > 0) { *tofree = NULL; r = (char_u *)"[...]"; } else { + int old_copyID = tv->vval.v_list->lv_copyID; + tv->vval.v_list->lv_copyID = copyID; - *tofree = list2string(tv, copyID); + *tofree = list2string(tv, copyID, restore_copyID); + if (restore_copyID) + tv->vval.v_list->lv_copyID = old_copyID; r = *tofree; } break; @@ -8116,20 +8244,23 @@ *tofree = NULL; r = NULL; } - else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID) + else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID + && tv->vval.v_dict->dv_hashtab.ht_used != 0) { *tofree = NULL; r = (char_u *)"{...}"; } else { + int old_copyID = tv->vval.v_dict->dv_copyID; tv->vval.v_dict->dv_copyID = copyID; - *tofree = dict2string(tv, copyID); + *tofree = dict2string(tv, copyID, restore_copyID); + if (restore_copyID) + tv->vval.v_dict->dv_copyID = old_copyID; r = *tofree; } break; - case VAR_STRING: case VAR_NUMBER: case VAR_UNKNOWN: case VAR_JOB: @@ -8161,6 +8292,24 @@ * Return a string with the string representation of a variable. * If the memory is allocated "tofree" is set to it, otherwise NULL. * "numbuf" is used for a number. + * Does not put quotes around strings, as ":echo" displays values. + * When "copyID" is not NULL replace recursive lists and dicts with "...". + * May return NULL. + */ + static char_u * +echo_string( + typval_T *tv, + char_u **tofree, + char_u *numbuf, + int copyID) +{ + return echo_string_core(tv, tofree, numbuf, copyID, TRUE, FALSE, FALSE); +} + +/* + * Return a string with the string representation of a variable. + * If the memory is allocated "tofree" is set to it, otherwise NULL. + * "numbuf" is used for a number. * Puts quotes around strings, so that they can be parsed back by eval(). * May return NULL. */ @@ -8171,31 +8320,7 @@ char_u *numbuf, int copyID) { - switch (tv->v_type) - { - case VAR_FUNC: - *tofree = string_quote(tv->vval.v_string, TRUE); - return *tofree; - case VAR_STRING: - *tofree = string_quote(tv->vval.v_string, FALSE); - return *tofree; - case VAR_FLOAT: -#ifdef FEAT_FLOAT - *tofree = NULL; - vim_snprintf((char *)numbuf, NUMBUFLEN - 1, "%g", tv->vval.v_float); - return numbuf; -#endif - case VAR_NUMBER: - case VAR_LIST: - case VAR_DICT: - case VAR_PARTIAL: - case VAR_SPECIAL: - case VAR_JOB: - case VAR_CHANNEL: - case VAR_UNKNOWN: - break; - } - return echo_string(tv, tofree, numbuf, copyID); + return echo_string_core(tv, tofree, numbuf, copyID, FALSE, TRUE, FALSE); } /* @@ -8335,7 +8460,6 @@ {"acos", 1, 1, f_acos}, /* WJMc */ #endif {"add", 2, 2, f_add}, - {"alloc_fail", 3, 3, f_alloc_fail}, {"and", 2, 2, f_and}, {"append", 2, 2, f_append}, {"argc", 0, 0, f_argc}, @@ -8367,6 +8491,7 @@ {"bufloaded", 1, 1, f_bufloaded}, {"bufname", 1, 1, f_bufname}, {"bufnr", 1, 2, f_bufnr}, + {"bufwinid", 1, 1, f_bufwinid}, {"bufwinnr", 1, 1, f_bufwinnr}, {"byte2line", 1, 1, f_byte2line}, {"byteidx", 2, 2, f_byteidx}, @@ -8416,7 +8541,6 @@ {"did_filetype", 0, 0, f_did_filetype}, {"diff_filler", 1, 1, f_diff_filler}, {"diff_hlID", 2, 2, f_diff_hlID}, - {"disable_char_avail_for_testing", 1, 1, f_disable_char_avail_for_testing}, {"empty", 1, 1, f_empty}, {"escape", 2, 2, f_escape}, {"eval", 1, 1, f_eval}, @@ -8451,7 +8575,6 @@ {"foreground", 0, 0, f_foreground}, {"function", 1, 3, f_function}, {"garbagecollect", 0, 1, f_garbagecollect}, - {"garbagecollect_for_testing", 0, 0, f_garbagecollect_for_testing}, {"get", 2, 3, f_get}, {"getbufline", 2, 3, f_getbufline}, {"getbufvar", 2, 3, f_getbufvar}, @@ -8681,7 +8804,20 @@ {"tanh", 1, 1, f_tanh}, #endif {"tempname", 0, 0, f_tempname}, - {"test", 1, 1, f_test}, + {"test_alloc_fail", 3, 3, f_test_alloc_fail}, + {"test_disable_char_avail", 1, 1, f_test_disable_char_avail}, + {"test_garbagecollect_now", 0, 0, f_test_garbagecollect_now}, +#ifdef FEAT_JOB_CHANNEL + {"test_null_channel", 0, 0, f_test_null_channel}, +#endif + {"test_null_dict", 0, 0, f_test_null_dict}, +#ifdef FEAT_JOB_CHANNEL + {"test_null_job", 0, 0, f_test_null_job}, +#endif + {"test_null_list", 0, 0, f_test_null_list}, + {"test_null_partial", 0, 0, f_test_null_partial}, + {"test_null_string", 0, 0, f_test_null_string}, + {"test_settime", 1, 1, f_test_settime}, #ifdef FEAT_TIMERS {"timer_start", 2, 3, f_timer_start}, {"timer_stop", 1, 1, f_timer_stop}, @@ -8931,7 +9067,7 @@ if (get_vim_var_nr(VV_TESTING)) { - /* Prepare for calling garbagecollect_for_testing(), need to know + /* Prepare for calling test_garbagecollect_now(), need to know * what variables are used on the call stack. */ if (funcargs.ga_itemsize == 0) ga_init2(&funcargs, (int)sizeof(typval_T *), 50); @@ -9069,14 +9205,12 @@ if (partial != NULL) { - if (partial->pt_dict != NULL) - { - /* When the function has a partial with a dict and there is a dict - * argument, use the dict argument. That is backwards compatible. - */ - if (selfdict_in == NULL) - selfdict = partial->pt_dict; - } + /* When the function has a partial with a dict and there is a dict + * argument, use the dict argument. That is backwards compatible. + * When the dict was bound explicitly use the one from the partial. */ + if (partial->pt_dict != NULL + && (selfdict_in == NULL || !partial->pt_auto)) + selfdict = partial->pt_dict; if (error == ERROR_NONE && partial->pt_argc > 0) { for (argv_clear = 0; argv_clear < partial->pt_argc; ++argv_clear) @@ -9365,29 +9499,6 @@ } /* - * "alloc_fail(id, countdown, repeat)" function - */ - static void -f_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED) -{ - if (argvars[0].v_type != VAR_NUMBER - || argvars[0].vval.v_number <= 0 - || argvars[1].v_type != VAR_NUMBER - || argvars[1].vval.v_number < 0 - || argvars[2].v_type != VAR_NUMBER) - EMSG(_(e_invarg)); - else - { - alloc_fail_id = argvars[0].vval.v_number; - if (alloc_fail_id >= aid_last) - EMSG(_(e_invarg)); - alloc_fail_countdown = argvars[1].vval.v_number; - alloc_fail_repeat = argvars[2].vval.v_number; - did_outofmem_msg = FALSE; - } -} - -/* * "and(expr, expr)" function */ static void @@ -10107,11 +10218,8 @@ rettv->vval.v_number = -1; } -/* - * "bufwinnr(nr)" function - */ static void -f_bufwinnr(typval_T *argvars, typval_T *rettv) +buf_win_common(typval_T *argvars, typval_T *rettv, int get_nr) { #ifdef FEAT_WINDOWS win_T *wp; @@ -10129,14 +10237,33 @@ if (wp->w_buffer == buf) break; } - rettv->vval.v_number = (wp != NULL ? winnr : -1); + rettv->vval.v_number = (wp != NULL ? (get_nr ? winnr : wp->w_id) : -1); #else - rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); + rettv->vval.v_number = (curwin->w_buffer == buf + ? (get_nr ? 1 : curwin->w_id) : -1); #endif --emsg_off; } /* + * "bufwinid(nr)" function + */ + static void +f_bufwinid(typval_T *argvars, typval_T *rettv) +{ + buf_win_common(argvars, rettv, FALSE); +} + +/* + * "bufwinnr(nr)" function + */ + static void +f_bufwinnr(typval_T *argvars, typval_T *rettv) +{ + buf_win_common(argvars, rettv, TRUE); +} + +/* * "byte2line(byte)" function */ static void @@ -11099,15 +11226,6 @@ } /* - * "disable_char_avail_for_testing({expr})" function - */ - static void -f_disable_char_avail_for_testing(typval_T *argvars, typval_T *rettv UNUSED) -{ - disable_char_avail_for_testing = get_tv_number(&argvars[0]); -} - -/* * "empty({expr})" function */ static void @@ -12330,12 +12448,16 @@ * use "dict". That is backwards compatible. */ if (dict_idx > 0) { + /* The dict is bound explicitly, pt_auto is FALSE. */ pt->pt_dict = argvars[dict_idx].vval.v_dict; ++pt->pt_dict->dv_refcount; } else if (arg_pt != NULL) { + /* If the dict was bound automatically the result is also + * bound automatically. */ pt->pt_dict = arg_pt->pt_dict; + pt->pt_auto = arg_pt->pt_auto; if (pt->pt_dict != NULL) ++pt->pt_dict->dv_refcount; } @@ -12372,17 +12494,6 @@ } /* - * "garbagecollect_for_testing()" function - */ - static void -f_garbagecollect_for_testing(typval_T *argvars UNUSED, typval_T *rettv UNUSED) -{ - /* This is dangerous, any Lists and Dicts used internally may be freed - * while still in use. */ - garbage_collect(TRUE); -} - -/* * "get()" function */ static void @@ -12414,6 +12525,55 @@ tv = &di->di_tv; } } + else if (argvars[0].v_type == VAR_PARTIAL || argvars[0].v_type == VAR_FUNC) + { + partial_T *pt; + partial_T fref_pt; + + if (argvars[0].v_type == VAR_PARTIAL) + pt = argvars[0].vval.v_partial; + else + { + vim_memset(&fref_pt, 0, sizeof(fref_pt)); + fref_pt.pt_name = argvars[0].vval.v_string; + pt = &fref_pt; + } + + if (pt != NULL) + { + char_u *what = get_tv_string(&argvars[1]); + + if (STRCMP(what, "func") == 0 || STRCMP(what, "name") == 0) + { + rettv->v_type = (*what == 'f' ? VAR_FUNC : VAR_STRING); + if (pt->pt_name == NULL) + rettv->vval.v_string = NULL; + else + rettv->vval.v_string = vim_strsave(pt->pt_name); + } + else if (STRCMP(what, "dict") == 0) + { + rettv->v_type = VAR_DICT; + rettv->vval.v_dict = pt->pt_dict; + if (pt->pt_dict != NULL) + ++pt->pt_dict->dv_refcount; + } + else if (STRCMP(what, "args") == 0) + { + rettv->v_type = VAR_LIST; + if (rettv_list_alloc(rettv) == OK) + { + int i; + + for (i = 0; i < pt->pt_argc; ++i) + list_append_tv(rettv->vval.v_list, &pt->pt_argv[i]); + } + } + else + EMSG2(_(e_invarg2), what); + return; + } + } else EMSG2(_(e_listdictarg), "get()"); @@ -12598,6 +12758,7 @@ --allow_keys; vimvars[VV_MOUSE_WIN].vv_nr = 0; + vimvars[VV_MOUSE_WINID].vv_nr = 0; vimvars[VV_MOUSE_LNUM].vv_nr = 0; vimvars[VV_MOUSE_COL].vv_nr = 0; @@ -12653,6 +12814,7 @@ ++winnr; # endif vimvars[VV_MOUSE_WIN].vv_nr = winnr; + vimvars[VV_MOUSE_WINID].vv_nr = win->w_id; vimvars[VV_MOUSE_LNUM].vv_nr = lnum; vimvars[VV_MOUSE_COL].vv_nr = col + 1; } @@ -13406,11 +13568,18 @@ for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin; wp != NULL; wp = wp->w_next) - if (--nr <= 0) + if (nr >= LOWEST_WIN_ID) + { + if (wp->w_id == nr) + return wp; + } + else if (--nr <= 0) break; + if (nr >= LOWEST_WIN_ID) + return NULL; return wp; #else - if (nr == 0 || nr == 1) + if (nr == 0 || nr == 1 || nr == curwin->w_id) return curwin; return NULL; #endif @@ -15148,7 +15317,7 @@ if (sep != NULL) { ga_init2(&ga, (int)sizeof(char), 80); - list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0); + list_join(&ga, argvars[0].vval.v_list, sep, TRUE, FALSE, 0); ga_append(&ga, NUL); rettv->vval.v_string = (char_u *)ga.ga_data; } @@ -15705,6 +15874,7 @@ listitem_T *li3 = li2->li_next; listitem_T *li4 = li3->li_next; + vim_free(li1->li_tv.vval.v_string); li1->li_tv.vval.v_string = vim_strnsave(regmatch.startp[0], (int)(regmatch.endp[0] - regmatch.startp[0])); li3->li_tv.vval.v_number = @@ -18577,8 +18747,12 @@ char_u buf[NUMBUFLEN]; char_u **curval; char_u **curallocval; - int len = argvars[1].vval.v_list->lv_len; + list_T *ll = argvars[1].vval.v_list; listitem_T *li; + int len; + + /* If the list is NULL handle like an empty list. */ + len = ll == NULL ? 0 : ll->lv_len; /* First half: use for pointers to result lines; second half: use for * pointers to allocated copies. */ @@ -18589,7 +18763,7 @@ allocval = lstval + len + 2; curallocval = allocval; - for (li = argvars[1].vval.v_list->lv_first; li != NULL; + for (li = ll == NULL ? NULL : ll->lv_first; li != NULL; li = li->li_next) { strval = get_tv_string_buf_chk(&li->li_tv, buf); @@ -20600,35 +20774,6 @@ } while (x == 'I' || x == 'O'); } -/* - * "test(list)" function: Just checking the walls... - */ - static void -f_test(typval_T *argvars UNUSED, typval_T *rettv UNUSED) -{ - /* Used for unit testing. Change the code below to your liking. */ -#if 0 - listitem_T *li; - list_T *l; - char_u *bad, *good; - - if (argvars[0].v_type != VAR_LIST) - return; - l = argvars[0].vval.v_list; - if (l == NULL) - return; - li = l->lv_first; - if (li == NULL) - return; - bad = get_tv_string(&li->li_tv); - li = li->li_next; - if (li == NULL) - return; - good = get_tv_string(&li->li_tv); - rettv->vval.v_number = test_edit_score(bad, good); -#endif -} - #ifdef FEAT_FLOAT /* * "tan()" function @@ -20661,6 +20806,101 @@ } #endif +/* + * "test_alloc_fail(id, countdown, repeat)" function + */ + static void +f_test_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED) +{ + if (argvars[0].v_type != VAR_NUMBER + || argvars[0].vval.v_number <= 0 + || argvars[1].v_type != VAR_NUMBER + || argvars[1].vval.v_number < 0 + || argvars[2].v_type != VAR_NUMBER) + EMSG(_(e_invarg)); + else + { + alloc_fail_id = argvars[0].vval.v_number; + if (alloc_fail_id >= aid_last) + EMSG(_(e_invarg)); + alloc_fail_countdown = argvars[1].vval.v_number; + alloc_fail_repeat = argvars[2].vval.v_number; + did_outofmem_msg = FALSE; + } +} + +/* + * "test_disable_char_avail({expr})" function + */ + static void +f_test_disable_char_avail(typval_T *argvars, typval_T *rettv UNUSED) +{ + disable_char_avail_for_testing = get_tv_number(&argvars[0]); +} + +/* + * "test_garbagecollect_now()" function + */ + static void +f_test_garbagecollect_now(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ + /* This is dangerous, any Lists and Dicts used internally may be freed + * while still in use. */ + garbage_collect(TRUE); +} + +#ifdef FEAT_JOB_CHANNEL + static void +f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv) +{ + rettv->v_type = VAR_CHANNEL; + rettv->vval.v_channel = NULL; +} +#endif + + static void +f_test_null_dict(typval_T *argvars UNUSED, typval_T *rettv) +{ + rettv->v_type = VAR_DICT; + rettv->vval.v_dict = NULL; +} + +#ifdef FEAT_JOB_CHANNEL + static void +f_test_null_job(typval_T *argvars UNUSED, typval_T *rettv) +{ + rettv->v_type = VAR_JOB; + rettv->vval.v_job = NULL; +} +#endif + + static void +f_test_null_list(typval_T *argvars UNUSED, typval_T *rettv) +{ + rettv->v_type = VAR_LIST; + rettv->vval.v_list = NULL; +} + + static void +f_test_null_partial(typval_T *argvars UNUSED, typval_T *rettv) +{ + rettv->v_type = VAR_PARTIAL; + rettv->vval.v_partial = NULL; +} + + static void +f_test_null_string(typval_T *argvars UNUSED, typval_T *rettv) +{ + rettv->v_type = VAR_STRING; + rettv->vval.v_string = NULL; +} + + static void +f_test_settime(typval_T *argvars, typval_T *rettv UNUSED) +{ + time_for_testing = (time_t)get_tv_number(&argvars[0]); +} + #if defined(FEAT_JOB_CHANNEL) || defined(FEAT_TIMERS) || defined(PROTO) /* * Get a callback from "arg". It can be a Funcref or a function name. @@ -20733,8 +20973,14 @@ static void f_timer_stop(typval_T *argvars, typval_T *rettv UNUSED) { - timer_T *timer = find_timer(get_tv_number(&argvars[0])); + timer_T *timer; + if (argvars[0].v_type != VAR_NUMBER) + { + EMSG(_(e_number_exp)); + return; + } + timer = find_timer(get_tv_number(&argvars[0])); if (timer != NULL) stop_timer(timer); } @@ -22273,8 +22519,14 @@ } } - if ((rettv->v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL) - && selfdict != NULL) + /* Turn "dict.Func" into a partial for "Func" bound to "dict". + * Don't do this when "Func" is already a partial that was bound + * explicitly (pt_auto is FALSE). */ + if (selfdict != NULL + && (rettv->v_type == VAR_FUNC + || (rettv->v_type == VAR_PARTIAL + && (rettv->vval.v_partial->pt_auto + || rettv->vval.v_partial->pt_dict == NULL)))) { char_u *fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string : rettv->vval.v_partial->pt_name; @@ -22288,7 +22540,6 @@ fp = find_func(fname); vim_free(tofree); - /* Turn "dict.Func" into a partial for "Func" with "dict". */ if (fp != NULL && (fp->uf_flags & FC_DICT)) { partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T)); @@ -22297,6 +22548,7 @@ { pt->pt_refcount = 1; pt->pt_dict = selfdict; + pt->pt_auto = TRUE; selfdict = NULL; if (rettv->v_type == VAR_FUNC) { @@ -25204,7 +25456,12 @@ { fp = find_func(name); if (fp == NULL) - EMSG2(_(e_intern2), "func_unref()"); + { +#ifdef EXITFREE + if (!entered_free_all_mem) +#endif + EMSG2(_(e_intern2), "func_unref()"); + } else if (--fp->uf_refcount <= 0) { /* Only delete it when it's not being used. Otherwise it's done diff -Nru vim-7.4.1830/src/ex_cmds2.c vim-7.4.1907/src/ex_cmds2.c --- vim-7.4.1830/src/ex_cmds2.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/ex_cmds2.c 2016-06-07 20:50:01.000000000 +0000 @@ -164,6 +164,7 @@ ignore_script = TRUE; } + vim_free(cmdline); cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL); if (typeahead_saved) @@ -306,8 +307,6 @@ (void)do_cmdline(cmdline, getexline, NULL, DOCMD_VERBOSE|DOCMD_EXCRESET); debug_break_level = n; - - vim_free(cmdline); } lines_left = Rows - 1; } @@ -1102,6 +1101,7 @@ if (first_timer != NULL) first_timer->tr_prev = timer; first_timer = timer; + did_add_timer = TRUE; } /* @@ -1253,6 +1253,25 @@ remove_timer(timer); free_timer(timer); } + +/* + * Mark references in partials of timers. + */ + int +set_ref_in_timer(int copyID) +{ + int abort = FALSE; + timer_T *timer; + typval_T tv; + + for (timer = first_timer; timer != NULL; timer = timer->tr_next) + { + tv.v_type = VAR_PARTIAL; + tv.vval.v_partial = timer->tr_partial; + abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL); + } + return abort; +} # endif #if defined(FEAT_SYN_HL) && defined(FEAT_RELTIME) && defined(FEAT_FLOAT) @@ -3325,15 +3344,17 @@ int c; char_u *new_rtp; int keep; - int oldlen; - int addlen; + size_t oldlen; + size_t addlen; + char_u *afterdir; + size_t afterlen = 0; char_u *ffname = fix_fname(fname); if (ffname == NULL) return; if (cookie != &APP_LOAD && strstr((char *)p_rtp, (char *)ffname) == NULL) { - /* directory not in 'runtimepath', add it */ + /* directory is not yet in 'runtimepath', add it */ p4 = p3 = p2 = p1 = get_past_head(ffname); for (p = p1; *p; mb_ptr_adv(p)) if (vim_ispathsep_nocolon(*p)) @@ -3361,20 +3382,31 @@ } *p4 = c; - oldlen = (int)STRLEN(p_rtp); - addlen = (int)STRLEN(ffname); - new_rtp = alloc(oldlen + addlen + 2); + /* check if rtp/pack/name/start/name/after exists */ + afterdir = concat_fnames(ffname, (char_u *)"after", TRUE); + if (afterdir != NULL && mch_isdir(afterdir)) + afterlen = STRLEN(afterdir) + 1; /* add one for comma */ + + oldlen = STRLEN(p_rtp); + addlen = STRLEN(ffname) + 1; /* add one for comma */ + new_rtp = alloc((int)(oldlen + addlen + afterlen + 1)); /* add one for NUL */ if (new_rtp == NULL) goto theend; keep = (int)(insp - p_rtp); mch_memmove(new_rtp, p_rtp, keep); new_rtp[keep] = ','; - mch_memmove(new_rtp + keep + 1, ffname, addlen + 1); + mch_memmove(new_rtp + keep + 1, ffname, addlen); if (p_rtp[keep] != NUL) - mch_memmove(new_rtp + keep + 1 + addlen, p_rtp + keep, + mch_memmove(new_rtp + keep + addlen, p_rtp + keep, oldlen - keep + 1); + if (afterlen > 0) + { + STRCAT(new_rtp, ","); + STRCAT(new_rtp, afterdir); + } set_option_value((char_u *)"rtp", 0L, new_rtp, 0); vim_free(new_rtp); + vim_free(afterdir); } if (cookie != &APP_ADD_DIR) diff -Nru vim-7.4.1830/src/ex_cmds.c vim-7.4.1907/src/ex_cmds.c --- vim-7.4.1830/src/ex_cmds.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/ex_cmds.c 2016-06-07 20:50:01.000000000 +0000 @@ -1750,9 +1750,14 @@ #if defined(FEAT_VIMINFO) || defined(PROTO) static int no_viminfo(void); +static int read_viminfo_barline(vir_T *virp, int got_encoding, int writing); +static void write_viminfo_version(FILE *fp_out); static void write_viminfo_barlines(vir_T *virp, FILE *fp_out); static int viminfo_errcnt; +#define VIMINFO_VERSION 2 +#define VIMINFO_VERSION_WITH_HISTORY 2 + static int no_viminfo(void) { @@ -2156,6 +2161,7 @@ vir.vir_conv.vc_type = CONV_NONE; #endif ga_init2(&vir.vir_barlines, (int)sizeof(char_u *), 100); + vir.vir_version = -1; if (fp_in != NULL) { @@ -2177,6 +2183,7 @@ fprintf(fp_out, _("# This viminfo file was generated by Vim %s.\n"), VIM_VERSION_MEDIUM); fputs(_("# You may edit it if you're careful!\n\n"), fp_out); + write_viminfo_version(fp_out); #ifdef FEAT_MBYTE fputs(_("# Value of 'encoding' when this file was written\n"), fp_out); fprintf(fp_out, "*encoding=%s\n\n", p_enc); @@ -2220,6 +2227,7 @@ { int eof; buf_T *buf; + int got_encoding = FALSE; #ifdef FEAT_CMDHIST prepare_viminfo_history(forceit ? 9999 : 0, writing); @@ -2240,12 +2248,11 @@ case '#': eof = viminfo_readline(virp); break; - case '|': /* copy line (for future use) */ - if (writing) - ga_add_string(&virp->vir_barlines, virp->vir_line); - eof = viminfo_readline(virp); + case '|': + eof = read_viminfo_barline(virp, got_encoding, writing); break; case '*': /* "*encoding=value" */ + got_encoding = TRUE; eof = viminfo_encoding(virp); break; case '!': /* global variable */ @@ -2274,10 +2281,13 @@ case '=': case '@': #ifdef FEAT_CMDHIST - eof = read_viminfo_history(virp, writing); -#else - eof = viminfo_readline(virp); + /* When history is in bar lines skip the old style history + * lines. */ + if (virp->vir_version < VIMINFO_VERSION_WITH_HISTORY) + eof = read_viminfo_history(virp, writing); + else #endif + eof = viminfo_readline(virp); break; case '-': case '\'': @@ -2347,8 +2357,8 @@ } /* - * check string read from viminfo file - * remove '\n' at the end of the line + * Check string read from viminfo file. + * Remove '\n' at the end of the line. * - replace CTRL-V CTRL-V with CTRL-V * - replace CTRL-V 'n' with '\n' * @@ -2463,6 +2473,283 @@ putc('\n', fd); } +/* + * Write a string in quotes that barline_parse() can read back. + * Breaks the line in less than LSIZE pieces when needed. + * Returns remaining characters in the line. + */ + int +barline_writestring(FILE *fd, char_u *s, int remaining_start) +{ + char_u *p; + int remaining = remaining_start; + int len = 2; + + /* Count the number of characters produced, including quotes. */ + for (p = s; *p != NUL; ++p) + { + if (*p == NL) + len += 2; + else if (*p == '"' || *p == '\\') + len += 2; + else + ++len; + } + if (len > remaining) + { + fprintf(fd, ">%d\n|<", len); + remaining = LSIZE - 20; + } + + putc('"', fd); + for (p = s; *p != NUL; ++p) + { + if (*p == NL) + { + putc('\\', fd); + putc('n', fd); + --remaining; + } + else if (*p == '"' || *p == '\\') + { + putc('\\', fd); + putc(*p, fd); + --remaining; + } + else + putc(*p, fd); + --remaining; + + if (remaining < 3) + { + putc('\n', fd); + putc('|', fd); + putc('<', fd); + /* Leave enough space for another continuation. */ + remaining = LSIZE - 20; + } + } + putc('"', fd); + return remaining; +} + +/* + * Parse a viminfo line starting with '|'. + * Put each decoded value in "values" and return the number of values found. + */ + static int +barline_parse(vir_T *virp, char_u *text, bval_T *values) +{ + char_u *p = text; + char_u *nextp = NULL; + char_u *buf = NULL; + int count = 0; + int i; + int allocated = FALSE; + + while (*p == ',') + { + if (count == BVAL_MAX) + { + EMSG2(e_intern2, "barline_parse()"); + break; + } + ++p; + + if (*p == '>') + { + /* Need to read a continuation line. Need to put strings in + * allocated memory, because virp->vir_line is overwritten. */ + if (!allocated) + { + for (i = 0; i < count; ++i) + if (values[i].bv_type == BVAL_STRING) + { + values[i].bv_string = vim_strnsave( + values[i].bv_string, values[i].bv_len); + values[i].bv_allocated = TRUE; + } + allocated = TRUE; + } + + if (vim_isdigit(p[1])) + { + size_t len; + size_t todo; + size_t n; + + /* String value was split into lines that are each shorter + * than LSIZE: + * |{bartype},>{length of "{text}{text2}"} + * |<"{text1} + * |<{text2}",{value} + */ + ++p; + len = getdigits(&p); + buf = alloc((int)(len + 1)); + p = buf; + for (todo = len; todo > 0; todo -= n) + { + if (viminfo_readline(virp) || virp->vir_line[0] != '|' + || virp->vir_line[1] != '<') + /* file was truncated or garbled */ + return 0; + /* Get length of text, excluding |< and NL chars. */ + n = STRLEN(virp->vir_line); + while (n > 0 && (virp->vir_line[n - 1] == NL + || virp->vir_line[n - 1] == CAR)) + --n; + n -= 2; + if (n > todo) + { + /* more values follow after the string */ + nextp = virp->vir_line + 2 + todo; + n = todo; + } + mch_memmove(p, virp->vir_line + 2, n); + p += n; + } + *p = NUL; + p = buf; + } + else + { + /* Line ending in ">" continues in the next line: + * |{bartype},{lots of values},> + * |<{value},{value} + */ + if (viminfo_readline(virp) || virp->vir_line[0] != '|' + || virp->vir_line[1] != '<') + /* file was truncated or garbled */ + return 0; + p = virp->vir_line + 2; + } + } + + if (isdigit(*p)) + { + values[count].bv_type = BVAL_NR; + values[count].bv_nr = getdigits(&p); + ++count; + } + else if (*p == '"') + { + int len = 0; + char_u *s = p; + + /* Unescape special characters in-place. */ + ++p; + while (*p != '"') + { + if (*p == NL || *p == NUL) + return count; /* syntax error, drop the value */ + if (*p == '\\') + { + ++p; + if (*p == 'n') + s[len++] = '\n'; + else + s[len++] = *p; + ++p; + } + else + s[len++] = *p++; + } + s[len] = NUL; + + if (s != buf && allocated) + s = vim_strsave(s); + values[count].bv_string = s; + values[count].bv_type = BVAL_STRING; + values[count].bv_len = len; + values[count].bv_allocated = allocated; + ++count; + if (nextp != NULL) + { + /* values following a long string */ + p = nextp; + nextp = NULL; + } + } + else if (*p == ',') + { + values[count].bv_type = BVAL_EMPTY; + ++count; + } + else + break; + } + + return count; +} + + static int +read_viminfo_barline(vir_T *virp, int got_encoding, int writing) +{ + char_u *p = virp->vir_line + 1; + int bartype; + bval_T values[BVAL_MAX]; + int count = 0; + int i; + + /* The format is: |{bartype},{value},... + * For a very long string: + * |{bartype},>{length of "{text}{text2}"} + * |<{text1} + * |<{text2},{value} + * For a long line not using a string + * |{bartype},{lots of values},> + * |<{value},{value} + */ + if (*p == '<') + { + /* Continuation line of an unrecognized item. */ + if (writing) + ga_add_string(&virp->vir_barlines, virp->vir_line); + } + else + { + bartype = getdigits(&p); + switch (bartype) + { + case BARTYPE_VERSION: + /* Only use the version when it comes before the encoding. + * If it comes later it was copied by a Vim version that + * doesn't understand the version. */ + if (!got_encoding) + { + count = barline_parse(virp, p, values); + if (count > 0 && values[0].bv_type == BVAL_NR) + virp->vir_version = values[0].bv_nr; + } + break; + + case BARTYPE_HISTORY: + count = barline_parse(virp, p, values); + handle_viminfo_history(values, count, writing); + break; + + default: + /* copy unrecognized line (for future use) */ + if (writing) + ga_add_string(&virp->vir_barlines, virp->vir_line); + } + } + + for (i = 0; i < count; ++i) + if (values[i].bv_type == BVAL_STRING && values[i].bv_allocated) + vim_free(values[i].bv_string); + + return viminfo_readline(virp); +} + + static void +write_viminfo_version(FILE *fp_out) +{ + fprintf(fp_out, "# Viminfo version\n|%d,%d\n\n", + BARTYPE_VERSION, VIMINFO_VERSION); +} + static void write_viminfo_barlines(vir_T *virp, FILE *fp_out) { @@ -6216,6 +6503,9 @@ */ if (*s == '\'' && s > arg && *arg == '\'') break; + /* Also '{' and '}'. */ + if (*s == '}' && s > arg && *arg == '{') + break; } *d = NUL; diff -Nru vim-7.4.1830/src/ex_docmd.c vim-7.4.1907/src/ex_docmd.c --- vim-7.4.1830/src/ex_docmd.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/ex_docmd.c 2016-06-07 20:50:01.000000000 +0000 @@ -2139,7 +2139,8 @@ #endif } ea.cmd = skipwhite(ea.cmd); - lnum = get_address(&ea, &ea.cmd, ea.addr_type, ea.skip, ea.addr_count == 0); + lnum = get_address(&ea, &ea.cmd, ea.addr_type, ea.skip, + ea.addr_count == 0); if (ea.cmd == NULL) /* error detected */ goto doend; if (lnum == MAXLNUM) @@ -6412,6 +6413,26 @@ return buf; } + static size_t +add_cmd_modifier(char_u *buf, char *mod_str, int *multi_mods) +{ + size_t result; + + result = STRLEN(mod_str); + if (*multi_mods) + result += 1; + if (buf != NULL) + { + if (*multi_mods) + STRCAT(buf, " "); + STRCAT(buf, mod_str); + } + + *multi_mods = 1; + + return result; +} + /* * Check for a <> code in a user command. * "code" points to the '<'. "len" the length of the <> (inclusive). @@ -6435,8 +6456,8 @@ char_u *p = code + 1; size_t l = len - 2; int quote = 0; - enum { ct_ARGS, ct_BANG, ct_COUNT, ct_LINE1, ct_LINE2, ct_REGISTER, - ct_LT, ct_NONE } type = ct_NONE; + enum { ct_ARGS, ct_BANG, ct_COUNT, ct_LINE1, ct_LINE2, ct_MODS, + ct_REGISTER, ct_LT, ct_NONE } type = ct_NONE; if ((vim_strchr((char_u *)"qQfF", *p) != NULL) && p[1] == '-') { @@ -6462,6 +6483,8 @@ type = ct_LT; else if (STRNICMP(p, "reg>", l) == 0 || STRNICMP(p, "register>", l) == 0) type = ct_REGISTER; + else if (STRNICMP(p, "mods>", l) == 0) + type = ct_MODS; switch (type) { @@ -6585,6 +6608,90 @@ break; } + case ct_MODS: + { + int multi_mods = 0; + typedef struct { + int *varp; + char *name; + } mod_entry_T; + static mod_entry_T mod_entries[] = { +#ifdef FEAT_BROWSE_CMD + {&cmdmod.browse, "browse"}, +#endif +#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) + {&cmdmod.confirm, "confirm"}, +#endif + {&cmdmod.hide, "hide"}, + {&cmdmod.keepalt, "keepalt"}, + {&cmdmod.keepjumps, "keepjumps"}, + {&cmdmod.keepmarks, "keepmarks"}, + {&cmdmod.keeppatterns, "keeppatterns"}, + {&cmdmod.lockmarks, "lockmarks"}, + {&cmdmod.noswapfile, "noswapfile"}, + {NULL, NULL} + }; + int i; + + result = quote ? 2 : 0; + if (buf != NULL) + { + if (quote) + *buf++ = '"'; + *buf = '\0'; + } + +#ifdef FEAT_WINDOWS + /* :aboveleft and :leftabove */ + if (cmdmod.split & WSP_ABOVE) + result += add_cmd_modifier(buf, "aboveleft", &multi_mods); + /* :belowright and :rightbelow */ + if (cmdmod.split & WSP_BELOW) + result += add_cmd_modifier(buf, "belowright", &multi_mods); + /* :botright */ + if (cmdmod.split & WSP_BOT) + result += add_cmd_modifier(buf, "botright", &multi_mods); +#endif + + /* the modifiers that are simple flags */ + for (i = 0; mod_entries[i].varp != NULL; ++i) + if (*mod_entries[i].varp) + result += add_cmd_modifier(buf, mod_entries[i].name, + &multi_mods); + + /* TODO: How to support :noautocmd? */ +#ifdef HAVE_SANDBOX + /* TODO: How to support :sandbox?*/ +#endif + /* :silent */ + if (msg_silent > 0) + result += add_cmd_modifier(buf, + emsg_silent > 0 ? "silent!" : "silent", &multi_mods); +#ifdef FEAT_WINDOWS + /* :tab */ + if (cmdmod.tab > 0) + result += add_cmd_modifier(buf, "tab", &multi_mods); + /* :topleft */ + if (cmdmod.split & WSP_TOP) + result += add_cmd_modifier(buf, "topleft", &multi_mods); +#endif + /* TODO: How to support :unsilent?*/ + /* :verbose */ + if (p_verbose > 0) + result += add_cmd_modifier(buf, "verbose", &multi_mods); +#ifdef FEAT_WINDOWS + /* :vertical */ + if (cmdmod.split & WSP_VERT) + result += add_cmd_modifier(buf, "vertical", &multi_mods); +#endif + if (quote && buf != NULL) + { + buf += result - 2; + *buf = '"'; + } + break; + } + case ct_REGISTER: result = eap->regname ? 1 : 0; if (quote) diff -Nru vim-7.4.1830/src/ex_getln.c vim-7.4.1907/src/ex_getln.c --- vim-7.4.1830/src/ex_getln.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/ex_getln.c 2016-06-07 20:50:01.000000000 +0000 @@ -58,6 +58,7 @@ int hisnum; /* identifying number */ int viminfo; /* when TRUE hisstr comes from viminfo */ char_u *hisstr; /* actual entry, separator char after the NUL */ + time_t time_set; /* when it was typed, zero if unknown */ } histentry_T; static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL}; @@ -5407,6 +5408,20 @@ NULL }; +/* + * Return the current time in seconds. Calls time(), unless test_settime() + * was used. + */ + static time_t +vim_time(void) +{ +#ifdef FEAT_EVAL + return time_for_testing == 0 ? time(NULL) : time_for_testing; +#else + return time(NULL); +#endif +} + #if defined(FEAT_CMDL_COMPL) || defined(PROTO) /* * Function given to ExpandGeneric() to obtain the possible first @@ -5576,6 +5591,7 @@ history[type][i].hisnum = ++hisnum[type]; history[type][i].viminfo = FALSE; history[type][i].hisstr = str; + history[type][i].time_set = vim_time(); return TRUE; } return FALSE; @@ -5663,6 +5679,7 @@ hisptr->hisnum = ++hisnum[histype]; hisptr->viminfo = FALSE; + hisptr->time_set = vim_time(); if (histype == HIST_SEARCH && in_map) last_maptick = maptick; } @@ -6131,9 +6148,10 @@ /* * Buffers for history read from a viminfo file. Only valid while reading. */ -static char_u **viminfo_history[HIST_COUNT] = {NULL, NULL, NULL, NULL}; -static int viminfo_hisidx[HIST_COUNT] = {0, 0, 0, 0}; -static int viminfo_hislen[HIST_COUNT] = {0, 0, 0, 0}; +static histentry_T *viminfo_history[HIST_COUNT] = + {NULL, NULL, NULL, NULL, NULL}; +static int viminfo_hisidx[HIST_COUNT] = {0, 0, 0, 0, 0}; +static int viminfo_hislen[HIST_COUNT] = {0, 0, 0, 0, 0}; static int viminfo_add_at_front = FALSE; static int hist_type2char(int type, int use_question); @@ -6191,8 +6209,8 @@ if (len <= 0) viminfo_history[type] = NULL; else - viminfo_history[type] = - (char_u **)lalloc((long_u)(len * sizeof(char_u *)), FALSE); + viminfo_history[type] = (histentry_T *)lalloc( + (long_u)(len * sizeof(histentry_T)), FALSE); if (viminfo_history[type] == NULL) len = 0; viminfo_hislen[type] = len; @@ -6242,7 +6260,9 @@ mch_memmove(p, val, (size_t)len + 1); p[len + 1] = NUL; } - viminfo_history[type][viminfo_hisidx[type]++] = p; + viminfo_history[type][viminfo_hisidx[type]].hisstr = p; + viminfo_history[type][viminfo_hisidx[type]].time_set = 0; + viminfo_hisidx[type]++; } } } @@ -6252,6 +6272,81 @@ } /* + * Accept a new style history line from the viminfo, store it in the history + * array when it's new. + */ + void +handle_viminfo_history( + bval_T *values, + int count, + int writing) +{ + int type; + long_u len; + char_u *val; + char_u *p; + + /* Check the format: + * |{bartype},{histtype},{timestamp},{separator},"text" */ + if (count < 4 + || values[0].bv_type != BVAL_NR + || values[1].bv_type != BVAL_NR + || (values[2].bv_type != BVAL_NR && values[2].bv_type != BVAL_EMPTY) + || values[3].bv_type != BVAL_STRING) + return; + + type = values[0].bv_nr; + if (type >= HIST_COUNT) + return; + if (viminfo_hisidx[type] < viminfo_hislen[type]) + { + val = values[3].bv_string; + if (val != NULL && *val != NUL) + { + int sep = type == HIST_SEARCH && values[2].bv_type == BVAL_NR + ? values[2].bv_nr : NUL; + int idx; + int overwrite = FALSE; + + if (!in_history(type, val, viminfo_add_at_front, sep, writing)) + { + /* If lines were written by an older Vim we need to avoid + * getting duplicates. See if the entry already exists. */ + for (idx = 0; idx < viminfo_hisidx[type]; ++idx) + { + p = viminfo_history[type][idx].hisstr; + if (STRCMP(val, p) == 0 + && (type != HIST_SEARCH || sep == p[STRLEN(p) + 1])) + { + overwrite = TRUE; + break; + } + } + + if (!overwrite) + { + /* Need to re-allocate to append the separator byte. */ + len = values[3].bv_len; + p = lalloc(len + 2, TRUE); + } + if (p != NULL) + { + viminfo_history[type][idx].time_set = values[1].bv_nr; + if (!overwrite) + { + mch_memmove(p, val, (size_t)len + 1); + /* Put the separator after the NUL. */ + p[len + 1] = sep; + viminfo_history[type][idx].hisstr = p; + viminfo_hisidx[type]++; + } + } + } + } + } +} + +/* * Finish reading history lines from viminfo. Not used when writing viminfo. */ void @@ -6290,8 +6385,9 @@ for (i = 0; i < viminfo_hisidx[type]; i++) { vim_free(history[type][idx].hisstr); - history[type][idx].hisstr = viminfo_history[type][i]; + history[type][idx].hisstr = viminfo_history[type][i].hisstr; history[type][idx].viminfo = TRUE; + history[type][idx].time_set = viminfo_history[type][i].time_set; if (--idx < 0) idx = hislen - 1; } @@ -6315,15 +6411,11 @@ * When "merge" is FALSE just write all history lines. Used for ":wviminfo!". */ void -write_viminfo_history( - FILE *fp, - int merge) +write_viminfo_history(FILE *fp, int merge) { int i; int type; int num_saved; - char_u *p; - int c; int round; init_history(); @@ -6339,8 +6431,9 @@ fprintf(fp, _("\n# %s History (newest to oldest):\n"), type == HIST_CMD ? _("Command Line") : type == HIST_SEARCH ? _("Search String") : - type == HIST_EXPR ? _("Expression") : - _("Input Line")); + type == HIST_EXPR ? _("Expression") : + type == HIST_INPUT ? _("Input Line") : + _("Debug Line")); if (num_saved > hislen) num_saved = hislen; @@ -6364,9 +6457,23 @@ while (num_saved > 0 && !(round == 2 && i >= viminfo_hisidx[type])) { - p = round == 1 ? history[type][i].hisstr - : viminfo_history[type] == NULL ? NULL - : viminfo_history[type][i]; + char_u *p; + time_t timestamp; + int c = NUL; + + if (round == 1) + { + p = history[type][i].hisstr; + timestamp = history[type][i].time_set; + } + else + { + p = viminfo_history[type] == NULL ? NULL + : viminfo_history[type][i].hisstr; + timestamp = viminfo_history[type] == NULL ? 0 + : viminfo_history[type][i].time_set; + } + if (p != NULL && (round == 2 || !merge || !history[type][i].viminfo)) @@ -6381,6 +6488,21 @@ putc(c == NUL ? ' ' : c, fp); } viminfo_writestring(fp, p); + + { + char cbuf[NUMBUFLEN]; + + /* New style history with a bar line. Format: + * |{bartype},{histtype},{timestamp},{separator},"text" */ + if (c == NUL) + cbuf[0] = NUL; + else + sprintf(cbuf, "%d", c); + fprintf(fp, "|%d,%d,%ld,%s,", BARTYPE_HISTORY, + type, (long)timestamp, cbuf); + barline_writestring(fp, p, LSIZE - 20); + putc('\n', fp); + } } if (round == 1) { @@ -6400,7 +6522,7 @@ } for (i = 0; i < viminfo_hisidx[type]; ++i) if (viminfo_history[type] != NULL) - vim_free(viminfo_history[type][i]); + vim_free(viminfo_history[type][i].hisstr); vim_free(viminfo_history[type]); viminfo_history[type] = NULL; viminfo_hisidx[type] = 0; diff -Nru vim-7.4.1830/src/fileio.c vim-7.4.1907/src/fileio.c --- vim-7.4.1830/src/fileio.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/fileio.c 2016-06-07 20:50:01.000000000 +0000 @@ -7389,10 +7389,20 @@ add_pathsep(itmp); # ifdef HAVE_MKDTEMP - /* Leave room for filename */ - STRCAT(itmp, "vXXXXXX"); - if (mkdtemp((char *)itmp) != NULL) - vim_settempdir(itmp); + { +# if defined(UNIX) || defined(VMS) + /* Make sure the umask doesn't remove the executable bit. + * "repl" has been reported to use "177". */ + mode_t umask_save = umask(077); +# endif + /* Leave room for filename */ + STRCAT(itmp, "vXXXXXX"); + if (mkdtemp((char *)itmp) != NULL) + vim_settempdir(itmp); +# if defined(UNIX) || defined(VMS) + (void)umask(umask_save); +# endif + } # else /* Get an arbitrary number of up to 6 digits. When it's * unlikely that it already exists it will be faster, diff -Nru vim-7.4.1830/src/getchar.c vim-7.4.1907/src/getchar.c --- vim-7.4.1830/src/getchar.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/getchar.c 2016-06-07 20:50:01.000000000 +0000 @@ -79,7 +79,7 @@ static int KeyNoremap = 0; /* remapping flags */ /* - * variables used by vgetorpeek() and flush_buffers() + * Variables used by vgetorpeek() and flush_buffers(). * * typebuf.tb_buf[] contains all characters that are not consumed yet. * typebuf.tb_buf[typebuf.tb_off] is the first valid character. @@ -129,6 +129,7 @@ static void map_free(mapblock_T **); static void validate_maphash(void); static void showmap(mapblock_T *mp, int local); +static int inchar(char_u *buf, int maxlen, long wait_time, int tb_change_cnt); #ifdef FEAT_EVAL static char_u *eval_map_expr(char_u *str, int c); #endif @@ -1880,7 +1881,7 @@ int retval; #ifdef FEAT_EVAL - /* When disable_char_avail_for_testing(1) was called pretend there is no + /* When test_disable_char_avail(1) was called pretend there is no * typeahead. */ if (disable_char_avail_for_testing) return FALSE; @@ -2941,7 +2942,7 @@ * Return the number of obtained characters. * Return -1 when end of input script reached. */ - int + static int inchar( char_u *buf, int maxlen, diff -Nru vim-7.4.1830/src/globals.h vim-7.4.1907/src/globals.h --- vim-7.4.1830/src/globals.h 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/globals.h 2016-06-07 20:50:01.000000000 +0000 @@ -635,6 +635,10 @@ EXTERN int really_exiting INIT(= FALSE); /* TRUE when we are sure to exit, e.g., after * a deadly signal */ +#if defined(EXITFREE) +EXTERN int entered_free_all_mem INIT(= FALSE); + /* TRUE when in or after free_all_mem() */ +#endif /* volatile because it is used in signal handler deathtrap(). */ EXTERN volatile int full_screen INIT(= FALSE); /* TRUE when doing full-screen output @@ -1631,6 +1635,14 @@ EXTERN int in_free_unref_items INIT(= FALSE); #endif +#ifdef FEAT_TIMERS +EXTERN int did_add_timer INIT(= FALSE); +#endif + +#ifdef FEAT_EVAL +EXTERN time_t time_for_testing INIT(= 0); +#endif + /* * Optional Farsi support. Include it here, so EXTERN and INIT are defined. */ diff -Nru vim-7.4.1830/src/gui_beval.c vim-7.4.1907/src/gui_beval.c --- vim-7.4.1830/src/gui_beval.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/gui_beval.c 2016-06-07 20:50:01.000000000 +0000 @@ -61,6 +61,7 @@ set_vim_var_nr(VV_BEVAL_BUFNR, (long)wp->w_buffer->b_fnum); set_vim_var_nr(VV_BEVAL_WINNR, winnr); + set_vim_var_nr(VV_BEVAL_WINID, wp->w_id); set_vim_var_nr(VV_BEVAL_LNUM, (long)lnum); set_vim_var_nr(VV_BEVAL_COL, (long)(col + 1)); set_vim_var_string(VV_BEVAL_TEXT, text, -1); diff -Nru vim-7.4.1830/src/gui_gtk_x11.c vim-7.4.1907/src/gui_gtk_x11.c --- vim-7.4.1830/src/gui_gtk_x11.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/gui_gtk_x11.c 2016-06-07 20:50:01.000000000 +0000 @@ -657,7 +657,7 @@ } static gboolean -draw_event(GtkWidget *widget, +draw_event(GtkWidget *widget UNUSED, cairo_t *cr, gpointer user_data UNUSED) { @@ -675,8 +675,6 @@ { cairo_rectangle_list_t *list = NULL; - gui_gtk_window_clear(gtk_widget_get_window(widget)); - list = cairo_copy_clip_rectangle_list(cr); if (list->status != CAIRO_STATUS_CLIP_NOT_REPRESENTABLE) { @@ -684,6 +682,10 @@ for (i = 0; i < list->num_rectangles; i++) { const cairo_rectangle_t rect = list->rectangles[i]; + + gui_mch_clear_block(Y_2_ROW(rect.y), 1, + Y_2_ROW(rect.y + rect.height - 1), Columns); + if (blink_mode) gui_gtk3_redraw(rect.x, rect.y, rect.width, rect.height); else @@ -810,6 +812,12 @@ } #endif + int +gui_mch_is_blinking(void) +{ + return blink_state != BLINK_NONE; +} + void gui_mch_set_blinking(long waittime, long on, long off) { @@ -6535,15 +6543,15 @@ int gui_mch_wait_for_chars(long wtime) { - int focus; - guint timer; - static int timed_out; + int focus; + guint timer; + static int timed_out; + int retval = FAIL; timed_out = FALSE; /* this timeout makes sure that we will return if no characters arrived in * time */ - if (wtime > 0) #if GTK_CHECK_VERSION(3,0,0) timer = g_timeout_add((guint)wtime, input_timer_cb, &timed_out); @@ -6568,7 +6576,15 @@ } #ifdef MESSAGE_QUEUE +# ifdef FEAT_TIMERS + did_add_timer = FALSE; +# endif parse_queued_messages(); +# ifdef FEAT_TIMERS + if (did_add_timer) + /* Need to recompute the waiting time. */ + goto theend; +# endif #endif /* @@ -6582,13 +6598,8 @@ /* Got char, return immediately */ if (input_available()) { - if (timer != 0 && !timed_out) -#if GTK_CHECK_VERSION(3,0,0) - g_source_remove(timer); -#else - gtk_timeout_remove(timer); -#endif - return OK; + retval = OK; + goto theend; } } while (wtime < 0 || !timed_out); @@ -6597,7 +6608,15 @@ */ gui_mch_update(); - return FAIL; +theend: + if (timer != 0 && !timed_out) +#if GTK_CHECK_VERSION(3,0,0) + g_source_remove(timer); +#else + gtk_timeout_remove(timer); +#endif + + return retval; } diff -Nru vim-7.4.1830/src/gui_mac.c vim-7.4.1907/src/gui_mac.c --- vim-7.4.1830/src/gui_mac.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/gui_mac.c 2016-06-07 20:50:01.000000000 +0000 @@ -5040,7 +5040,7 @@ SetControl32BitValue (sb->id, val); SetControlViewSize (sb->id, size); #ifdef DEBUG_MAC_SB - printf("thumb_sb (%x) %x, %x,%x\n",sb->id, val, size, max); + printf("thumb_sb (%x) %lx, %lx,%lx\n",sb->id, val, size, max); #endif } @@ -5114,6 +5114,11 @@ #endif } + int +gui_mch_is_blinking(void) +{ + return FALSE; +} /* * Cursor blink functions. diff -Nru vim-7.4.1830/src/gui_photon.c vim-7.4.1907/src/gui_photon.c --- vim-7.4.1830/src/gui_photon.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/gui_photon.c 2016-06-07 20:50:01.000000000 +0000 @@ -2232,6 +2232,12 @@ DRAW_END; } + int +gui_mch_is_blinking(void) +{ + return blink_state != BLINK_NONE; +} + void gui_mch_set_blinking(long wait, long on, long off) { diff -Nru vim-7.4.1830/src/gui_w32.c vim-7.4.1907/src/gui_w32.c --- vim-7.4.1830/src/gui_w32.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/gui_w32.c 2016-06-07 20:50:01.000000000 +0000 @@ -540,6 +540,12 @@ static long_u blink_offtime = 250; static UINT blink_timer = 0; + int +gui_mch_is_blinking(void) +{ + return blink_state != BLINK_NONE; +} + void gui_mch_set_blinking(long wait, long on, long off) { @@ -2022,6 +2028,22 @@ process_message(); } + static void +remove_any_timer(void) +{ + MSG msg; + + if (s_wait_timer != 0 && !s_timed_out) + { + KillTimer(NULL, s_wait_timer); + + /* Eat spurious WM_TIMER messages */ + while (pPeekMessage(&msg, s_hwnd, WM_TIMER, WM_TIMER, PM_REMOVE)) + ; + s_wait_timer = 0; + } +} + /* * GUI input routine called by gui_wait_for_chars(). Waits for a character * from the keyboard. @@ -2034,7 +2056,6 @@ int gui_mch_wait_for_chars(int wtime) { - MSG msg; int focus; s_timed_out = FALSE; @@ -2073,6 +2094,9 @@ s_need_activate = FALSE; } +#ifdef FEAT_TIMERS + did_add_timer = FALSE; +#endif #ifdef MESSAGE_QUEUE /* Check channel while waiting message. */ for (;;) @@ -2098,15 +2122,7 @@ if (input_available()) { - if (s_wait_timer != 0 && !s_timed_out) - { - KillTimer(NULL, s_wait_timer); - - /* Eat spurious WM_TIMER messages */ - while (pPeekMessage(&msg, s_hwnd, WM_TIMER, WM_TIMER, PM_REMOVE)) - ; - s_wait_timer = 0; - } + remove_any_timer(); allow_scrollbar = FALSE; /* Clear pending mouse button, the release event may have been @@ -2117,6 +2133,15 @@ return OK; } + +#ifdef FEAT_TIMERS + if (did_add_timer) + { + /* Need to recompute the waiting time. */ + remove_any_timer(); + break; + } +#endif } allow_scrollbar = FALSE; return FAIL; @@ -7001,10 +7026,8 @@ } else #endif - if (grey) - EnableMenuItem(s_menuBar, menu->id, MF_BYCOMMAND | MF_GRAYED); - else - EnableMenuItem(s_menuBar, menu->id, MF_BYCOMMAND | MF_ENABLED); + (void)EnableMenuItem(menu->parent ? menu->parent->submenu_id : s_menuBar, + menu->id, MF_BYCOMMAND | (grey ? MF_GRAYED : MF_ENABLED)); #ifdef FEAT_TEAROFF if ((menu->parent != NULL) && (IsWindow(menu->parent->tearoff_handle))) diff -Nru vim-7.4.1830/src/gui_x11.c vim-7.4.1907/src/gui_x11.c --- vim-7.4.1830/src/gui_x11.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/gui_x11.c 2016-06-07 20:50:01.000000000 +0000 @@ -2368,7 +2368,7 @@ for (i = 0; i < cmap_size; i++) colortable[i].pixel = (unsigned long)i; - XQueryColors (gui.dpy, colormap, colortable, cmap_size); + XQueryColors(gui.dpy, colormap, colortable, cmap_size); /* * Find the color that best approximates the desired one, then @@ -2792,7 +2792,8 @@ int gui_mch_wait_for_chars(long wtime) { - int focus; + int focus; + int retval = FAIL; /* * Make this static, in case gui_x11_timer_cb is called after leaving @@ -2828,7 +2829,15 @@ } #ifdef MESSAGE_QUEUE +# ifdef FEAT_TIMERS + did_add_timer = FALSE; +# endif parse_queued_messages(); +# ifdef FEAT_TIMERS + if (did_add_timer) + /* Need to recompute the waiting time. */ + break; +# endif #endif /* @@ -2843,12 +2852,15 @@ if (input_available()) { - if (timer != (XtIntervalId)0 && !timed_out) - XtRemoveTimeOut(timer); - return OK; + retval = OK; + break; } } - return FAIL; + + if (timer != (XtIntervalId)0 && !timed_out) + XtRemoveTimeOut(timer); + + return retval; } /* @@ -3143,6 +3155,12 @@ static long_u blink_offtime = 250; static XtIntervalId blink_timer = (XtIntervalId)0; + int +gui_mch_is_blinking(void) +{ + return blink_state != BLINK_NONE; +} + void gui_mch_set_blinking(long waittime, long on, long off) { diff -Nru vim-7.4.1830/src/if_mzsch.c vim-7.4.1907/src/if_mzsch.c --- vim-7.4.1830/src/if_mzsch.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/if_mzsch.c 2016-06-07 20:50:01.000000000 +0000 @@ -545,7 +545,7 @@ # if MZSCHEME_VERSION_MAJOR >= 500 # if defined(IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS) || defined(IMPLEMENT_THREAD_LOCAL_EXTERNALLY_VIA_PROC) -/* define as function for macro in schshread.h */ +/* define as function for macro in schthread.h */ Thread_Local_Variables * scheme_external_get_thread_local_variables(void) { @@ -849,7 +849,7 @@ static int mz_threads_allow = 0; #if defined(FEAT_GUI_W32) -static void CALLBACK timer_proc(HWND, UINT, UINT, DWORD); +static void CALLBACK timer_proc(HWND, UINT, UINT_PTR, DWORD); static UINT timer_id = 0; #elif defined(FEAT_GUI_GTK) # if GTK_CHECK_VERSION(3,0,0) @@ -894,7 +894,7 @@ /* timers are presented in GUI only */ # if defined(FEAT_GUI_W32) static void CALLBACK -timer_proc(HWND hwnd UNUSED, UINT uMsg UNUSED, UINT idEvent UNUSED, DWORD dwTime UNUSED) +timer_proc(HWND hwnd UNUSED, UINT uMsg UNUSED, UINT_PTR idEvent UNUSED, DWORD dwTime UNUSED) # elif defined(FEAT_GUI_GTK) # if GTK_CHECK_VERSION(3,0,0) static gboolean @@ -2725,7 +2725,8 @@ * Adjust marks. Invalidate any which lie in the * changed range, and move any in the remainder of the buffer. */ - mark_adjust((linenr_T)lo, (linenr_T)(hi - 1), (long)MAXLNUM, (long)extra); + mark_adjust((linenr_T)lo, (linenr_T)(hi - 1), + (long)MAXLNUM, (long)extra); changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra); if (buf->buf == curwin->w_buffer) @@ -3571,7 +3572,7 @@ info = scheme_make_byte_string(add_info); MZ_GC_CHECK(); - c_string = scheme_format_utf8(fmt, STRLEN(fmt), 1, &info, NULL); + c_string = scheme_format_utf8(fmt, (int)STRLEN(fmt), 1, &info, NULL); MZ_GC_CHECK(); byte_string = scheme_make_byte_string(c_string); MZ_GC_CHECK(); diff -Nru vim-7.4.1830/src/if_perl.xs vim-7.4.1907/src/if_perl.xs --- vim-7.4.1830/src/if_perl.xs 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/if_perl.xs 2016-06-07 20:50:01.000000000 +0000 @@ -61,6 +61,20 @@ # include #endif +/* Workaround for perl < 5.8.7 */ +#ifndef PERLIO_FUNCS_DECL +# ifdef PERLIO_FUNCS_CONST +# define PERLIO_FUNCS_DECL(funcs) const PerlIO_funcs funcs +# define PERLIO_FUNCS_CAST(funcs) (PerlIO_funcs*)(funcs) +# else +# define PERLIO_FUNCS_DECL(funcs) PerlIO_funcs funcs +# define PERLIO_FUNCS_CAST(funcs) (funcs) +# endif +#endif +#ifndef SvREFCNT_inc_void_NN +# define SvREFCNT_inc_void_NN SvREFCNT_inc +#endif + /* * Work around clashes between Perl and Vim namespace. proto.h doesn't * include if_perl.pro and perlsfio.pro when IN_PERL_FILE is defined, because @@ -299,6 +313,9 @@ # define PerlIOBase_pushed dll_PerlIOBase_pushed # define PerlIO_define_layer dll_PerlIO_define_layer # endif +# if (PERL_REVISION == 5) && (PERL_VERSION >= 24) +# define Perl_savetmps dll_Perl_savetmps +# endif /* * Declare HANDLE for perl.dll and function pointers. @@ -455,6 +472,9 @@ static IV (*PerlIOBase_pushed)(pTHX_ PerlIO *, const char *, SV *, PerlIO_funcs *); static void (*PerlIO_define_layer)(pTHX_ PerlIO_funcs *); #endif +#if (PERL_REVISION == 5) && (PERL_VERSION >= 24) +static void (*Perl_savetmps)(pTHX); +#endif /* * Table of name to function pointer of perl. @@ -598,17 +618,27 @@ {"PerlIOBase_pushed", (PERL_PROC*)&PerlIOBase_pushed}, {"PerlIO_define_layer", (PERL_PROC*)&PerlIO_define_layer}, #endif +#if (PERL_REVISION == 5) && (PERL_VERSION >= 24) + {"Perl_savetmps", (PERL_PROC*)&Perl_savetmps}, +#endif {"", NULL}, }; /* Work around for perl-5.18. - * The definitions of S_SvREFCNT_inc and S_SvREFCNT_dec are needed, so include - * "perl\lib\CORE\inline.h", after Perl_sv_free2 is defined. - * The linker won't complain about undefined __impl_Perl_sv_free2. */ + * For now, only the definitions of S_SvREFCNT_dec are needed in + * "perl\lib\CORE\inline.h". */ #if (PERL_REVISION == 5) && (PERL_VERSION >= 18) -# define PL_memory_wrap "panic: memory wrap" /* Dummy */ -# include -# undef PL_memory_wrap +static void +S_SvREFCNT_dec(pTHX_ SV *sv) +{ + if (LIKELY(sv != NULL)) { + U32 rc = SvREFCNT(sv); + if (LIKELY(rc > 1)) + SvREFCNT(sv) = rc - 1; + else + Perl_sv_free2(aTHX_ sv, rc); + } +} #endif /* @@ -777,7 +807,7 @@ sv_setiv(ptr->w_perl_private, PTR2IV(ptr)); } else - SvREFCNT_inc(ptr->w_perl_private); + SvREFCNT_inc_void_NN(ptr->w_perl_private); SvRV(rv) = ptr->w_perl_private; SvROK_on(rv); return sv_bless(rv, gv_stashpv("VIWIN", TRUE)); @@ -793,7 +823,7 @@ sv_setiv(ptr->b_perl_private, PTR2IV(ptr)); } else - SvREFCNT_inc(ptr->b_perl_private); + SvREFCNT_inc_void_NN(ptr->b_perl_private); SvRV(rv) = ptr->b_perl_private; SvROK_on(rv); return sv_bless(rv, gv_stashpv("VIBUF", TRUE)); @@ -1059,7 +1089,8 @@ { size_t len = 0; char * str_from = SvPV(sv, len); - char_u *str_to = (char_u*)alloc(sizeof(char_u) * (len + 1)); + char_u *str_to = (char_u*)alloc( + (unsigned)(sizeof(char_u) * (len + 1))); if (str_to) { str_to[len] = '\0'; @@ -1354,13 +1385,13 @@ char_u *str; PerlIOVim * s = PerlIOSelf(f, PerlIOVim); - str = vim_strnsave((char_u *)vbuf, count); + str = vim_strnsave((char_u *)vbuf, (int)count); if (str == NULL) return 0; msg_split((char_u *)str, s->attr); vim_free(str); - return count; + return (SSize_t)count; } static PERLIO_FUNCS_DECL(PerlIO_Vim) = { diff -Nru vim-7.4.1830/src/if_py_both.h vim-7.4.1907/src/if_py_both.h --- vim-7.4.1830/src/if_py_both.h 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/if_py_both.h 2016-06-07 20:50:01.000000000 +0000 @@ -2835,16 +2835,17 @@ typval_T *argv; dict_T *self; pylinkedlist_T ref; + int auto_rebind; } FunctionObject; static PyTypeObject FunctionType; -#define NEW_FUNCTION(name, argc, argv, self) \ - FunctionNew(&FunctionType, name, argc, argv, self) +#define NEW_FUNCTION(name, argc, argv, self, pt_auto) \ + FunctionNew(&FunctionType, (name), (argc), (argv), (self), (pt_auto)) static PyObject * FunctionNew(PyTypeObject *subtype, char_u *name, int argc, typval_T *argv, - dict_T *selfdict) + dict_T *selfdict, int auto_rebind) { FunctionObject *self; @@ -2877,6 +2878,7 @@ self->argc = argc; self->argv = argv; self->self = selfdict; + self->auto_rebind = selfdict == NULL ? TRUE : auto_rebind; if (self->argv || self->self) pyll_add((PyObject *)(self), &self->ref, &lastfunc); @@ -2889,6 +2891,7 @@ { PyObject *self; PyObject *selfdictObject; + PyObject *autoRebindObject; PyObject *argsObject = NULL; char_u *name; typval_T selfdicttv; @@ -2896,6 +2899,7 @@ list_T *argslist = NULL; dict_T *selfdict = NULL; int argc = 0; + int auto_rebind = TRUE; typval_T *argv = NULL; typval_T *curtv; listitem_T *li; @@ -2936,6 +2940,21 @@ } list_unref(argslist); } + if (selfdict != NULL) + { + auto_rebind = FALSE; + autoRebindObject = PyDict_GetItemString(kwargs, "auto_rebind"); + if (autoRebindObject != NULL) + { + auto_rebind = PyObject_IsTrue(autoRebindObject); + if (auto_rebind == -1) + { + dict_unref(selfdict); + list_unref(argslist); + return NULL; + } + } + } } if (!PyArg_ParseTuple(args, "et", "ascii", &name)) @@ -2947,7 +2966,7 @@ return NULL; } - self = FunctionNew(subtype, name, argc, argv, selfdict); + self = FunctionNew(subtype, name, argc, argv, selfdict, auto_rebind); PyMem_Free(name); @@ -2971,7 +2990,7 @@ } static char *FunctionAttrs[] = { - "softspace", "args", "self", + "softspace", "args", "self", "auto_rebind", NULL }; @@ -3001,6 +3020,10 @@ return self->self == NULL ? AlwaysNone(NULL) : NEW_DICTIONARY(self->self); + else if (strcmp(name, "auto_rebind") == 0) + return self->auto_rebind + ? AlwaysTrue(NULL) + : AlwaysFalse(NULL); else if (strcmp(name, "__members__") == 0) return ObjectDir(NULL, FunctionAttrs); return NULL; @@ -3035,6 +3058,7 @@ pt->pt_argc = 0; pt->pt_argv = NULL; } + pt->pt_auto = self->auto_rebind || !exported; pt->pt_dict = self->self; if (exported && self->self) ++pt->pt_dict->dv_refcount; @@ -3076,6 +3100,7 @@ if (self->argv || self->self) { + vim_memset(&pt, 0, sizeof(partial_T)); set_partial(self, &pt, FALSE); pt_ptr = &pt; } @@ -3148,6 +3173,8 @@ ga_concat(&repr_ga, tv2string(&tv, &tofree, numbuf, get_copyID())); --emsg_silent; vim_free(tofree); + if (self->auto_rebind) + ga_concat(&repr_ga, (char_u *)", auto_rebind=True"); } ga_append(&repr_ga, '>'); ret = PyString_FromString((char *)repr_ga.ga_data); @@ -6269,7 +6296,7 @@ case VAR_FUNC: return NEW_FUNCTION(tv->vval.v_string == NULL ? (char_u *)"" : tv->vval.v_string, - 0, NULL, NULL); + 0, NULL, NULL, TRUE); case VAR_PARTIAL: if (tv->vval.v_partial->pt_argc) { @@ -6284,7 +6311,8 @@ return NEW_FUNCTION(tv->vval.v_partial == NULL ? (char_u *)"" : tv->vval.v_partial->pt_name, tv->vval.v_partial->pt_argc, argv, - tv->vval.v_partial->pt_dict); + tv->vval.v_partial->pt_dict, + tv->vval.v_partial->pt_auto); case VAR_UNKNOWN: case VAR_CHANNEL: case VAR_JOB: @@ -6742,8 +6770,13 @@ return -1; ADD_OBJECT(m, "os", other_module); +#if PY_MAJOR_VERSION >= 3 if (!(py_getcwd = PyObject_GetAttrString(other_module, "getcwd"))) return -1; +#else + if (!(py_getcwd = PyObject_GetAttrString(other_module, "getcwdu"))) + return -1; +#endif ADD_OBJECT(m, "_getcwd", py_getcwd) if (!(py_chdir = PyObject_GetAttrString(other_module, "chdir"))) diff -Nru vim-7.4.1830/src/if_ruby.c vim-7.4.1907/src/if_ruby.c --- vim-7.4.1830/src/if_ruby.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/if_ruby.c 2016-06-07 20:50:01.000000000 +0000 @@ -733,7 +733,7 @@ vim_free(sval); if (enc) { - return rb_enc_str_new(s, strlen(s), enc); + return rb_enc_str_new(s, (long)strlen(s), enc); } } #endif diff -Nru vim-7.4.1830/src/INSTALL vim-7.4.1907/src/INSTALL --- vim-7.4.1830/src/INSTALL 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/INSTALL 2016-06-07 20:50:01.000000000 +0000 @@ -11,7 +11,7 @@ See INSTALLami.txt for Amiga See INSTALLmac.txt for Macintosh -See INSTALLpc.txt for PC (MS-DOS, Windows 95/98/NT/XP) +See INSTALLpc.txt for PC (Windows 95/98/NT/XP/Vista/7/8/10) See INSTALLvms.txt for VMS See INSTALLx.txt for cross-compiling on Unix See ../README_390.txt for OS/390 Unix diff -Nru vim-7.4.1830/src/main.aap vim-7.4.1907/src/main.aap --- vim-7.4.1830/src/main.aap 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/main.aap 2016-06-07 20:50:01.000000000 +0000 @@ -347,7 +347,6 @@ $PYTHON_SRC $TCL_SRC $RUBY_SRC - $SNIFF_SRC $WORKSHOP_SRC Objects = diff -Nru vim-7.4.1830/src/Make_cyg_ming.mak vim-7.4.1907/src/Make_cyg_ming.mak --- vim-7.4.1830/src/Make_cyg_ming.mak 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/Make_cyg_ming.mak 2016-06-07 20:50:01.000000000 +0000 @@ -67,7 +67,11 @@ # Set to yes to enable Netbeans support (requires CHANNEL). NETBEANS=$(GUI) # Set to yes to enable inter process communication. +ifeq (HUGE, $(FEATURES)) +CHANNEL=yes +else CHANNEL=$(GUI) +endif # Link against the shared version of libstdc++ by default. Set diff -Nru vim-7.4.1830/src/Makefile vim-7.4.1907/src/Makefile --- vim-7.4.1830/src/Makefile 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/Makefile 2016-06-07 20:50:01.000000000 +0000 @@ -582,7 +582,7 @@ #CFLAGS = -g -O2 '-DSTARTUPTIME="vimstartup"' -fno-strength-reduce -Wall -Wmissing-prototypes # Use this with GCC to check for mistakes, unused arguments, etc. -#CFLAGS = -g -Wall -Wextra -Wmissing-prototypes -Wunreachable-code -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 +#CFLAGS = -g -Wall -Wextra -Wshadow -Wmissing-prototypes -Wunreachable-code -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 #CFLAGS = -g -O2 -Wall -Wextra -Wmissing-prototypes -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -DU_DEBUG #PYTHON_CFLAGS_EXTRA = -Wno-missing-field-initializers #MZSCHEME_CFLAGS_EXTRA = -Wno-unreachable-code -Wno-unused-parameter @@ -1943,6 +1943,10 @@ cd testdir; $(MAKE) -f Makefile $(GUI_TESTTARGET) VIMPROG=../$(VIMTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE) $(MAKE) -f Makefile unittest +# Run the tests with the GUI. Assumes vim/gvim was already built +testgui: + cd testdir; $(MAKE) -f Makefile $(GUI_TESTTARGET) VIMPROG=../$(VIMTARGET) GUI_FLAG=-g $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE) + benchmark: cd testdir; $(MAKE) -f Makefile benchmark VIMPROG=../$(VIMTARGET) SCRIPTSOURCE=../$(SCRIPTSOURCE) @@ -2057,6 +2061,7 @@ test_viminfo \ test_viml \ test_visual \ + test_window_cmd \ test_window_id \ test_alot_latin \ test_alot_utf8 \ diff -Nru vim-7.4.1830/src/Make_mvc.mak vim-7.4.1907/src/Make_mvc.mak --- vim-7.4.1830/src/Make_mvc.mak 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/Make_mvc.mak 2016-06-07 20:50:01.000000000 +0000 @@ -263,6 +263,10 @@ # INCLUDE = c:\msvc20\include # LIB = c:\msvc20\lib +!if "$(FEATURES)"=="" +FEATURES = HUGE +!endif + !ifndef CTAGS CTAGS = ctags !endif @@ -283,8 +287,12 @@ !endif !ifndef CHANNEL +!if "$(FEATURES)"=="HUGE" +CHANNEL = yes +!else CHANNEL = $(GUI) !endif +!endif # Only allow NETBEANS and XPM for a GUI build and CHANNEL. !if "$(GUI)" == "yes" @@ -953,9 +961,6 @@ # # FEATURES: TINY, SMALL, NORMAL, BIG or HUGE # -!if "$(FEATURES)"=="" -FEATURES = HUGE -!endif CFLAGS = $(CFLAGS) -DFEAT_$(FEATURES) # diff -Nru vim-7.4.1830/src/message.c vim-7.4.1907/src/message.c --- vim-7.4.1830/src/message.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/message.c 2016-06-07 20:50:01.000000000 +0000 @@ -2475,9 +2475,9 @@ int i; /* We get called recursively when a timer callback outputs a message. In - * that case don't show another prompt. Also when at the hit-Enter prompt. - */ - if (entered || State == HITRETURN) + * that case don't show another prompt. Also when at the hit-Enter prompt + * and nothing was typed. */ + if (entered || (State == HITRETURN && typed_char == 0)) return FALSE; entered = TRUE; diff -Nru vim-7.4.1830/src/misc1.c vim-7.4.1907/src/misc1.c --- vim-7.4.1830/src/misc1.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/misc1.c 2016-06-07 20:50:01.000000000 +0000 @@ -1425,8 +1425,11 @@ == FAIL) goto theend; /* Postpone calling changed_lines(), because it would mess up folding - * with markers. */ - mark_adjust(curwin->w_cursor.lnum + 1, (linenr_T)MAXLNUM, 1L, 0L); + * with markers. + * Skip mark_adjust when adding a line after the last one, there can't + * be marks there. */ + if (curwin->w_cursor.lnum + 1 < curbuf->b_ml.ml_line_count) + mark_adjust(curwin->w_cursor.lnum + 1, (linenr_T)MAXLNUM, 1L, 0L); did_append = TRUE; } #ifdef FEAT_VREPLACE @@ -2861,7 +2864,10 @@ void appended_lines_mark(linenr_T lnum, long count) { - mark_adjust(lnum + 1, (linenr_T)MAXLNUM, count, 0L); + /* Skip mark_adjust when adding a line after the last one, there can't + * be marks there. */ + if (lnum + count < curbuf->b_ml.ml_line_count) + mark_adjust(lnum + 1, (linenr_T)MAXLNUM, count, 0L); changed_lines(lnum + 1, 0, lnum + 1, count); } diff -Nru vim-7.4.1830/src/misc2.c vim-7.4.1907/src/misc2.c --- vim-7.4.1830/src/misc2.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/misc2.c 2016-06-07 20:50:01.000000000 +0000 @@ -1036,13 +1036,12 @@ free_all_mem(void) { buf_T *buf, *nextbuf; - static int entered = FALSE; /* When we cause a crash here it is caught and Vim tries to exit cleanly. * Don't try freeing everything again. */ - if (entered) + if (entered_free_all_mem) return; - entered = TRUE; + entered_free_all_mem = TRUE; # ifdef FEAT_AUTOCMD /* Don't want to trigger autocommands from here on. */ @@ -1127,9 +1126,6 @@ # ifdef FEAT_DIFF diff_clear(curtab); # endif -# ifdef FEAT_JOB_CHANNEL - channel_free_all(); -# endif clear_sb_text(); /* free any scrollback text */ /* Free some global vars. */ @@ -1221,6 +1217,10 @@ # ifdef FEAT_EVAL eval_clear(); # endif +# ifdef FEAT_JOB_CHANNEL + channel_free_all(); + job_free_all(); +# endif free_termoptions(); diff -Nru vim-7.4.1830/src/netbeans.c vim-7.4.1907/src/netbeans.c --- vim-7.4.1830/src/netbeans.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/netbeans.c 2016-06-07 20:50:01.000000000 +0000 @@ -382,24 +382,25 @@ void netbeans_parse_messages(void) { + readq_T *node; char_u *buffer; char_u *p; int own_node; while (nb_channel != NULL) { - buffer = channel_peek(nb_channel, PART_SOCK); - if (buffer == NULL) + node = channel_peek(nb_channel, PART_SOCK); + if (node == NULL) break; /* nothing to read */ /* Locate the first line in the first buffer. */ - p = vim_strchr(buffer, '\n'); + p = channel_first_nl(node); if (p == NULL) { /* Command isn't complete. If there is no following buffer, * return (wait for more). If there is another buffer following, * prepend the text to that buffer and delete this one. */ - if (channel_collapse(nb_channel, PART_SOCK) == FAIL) + if (channel_collapse(nb_channel, PART_SOCK, TRUE) == FAIL) return; } else @@ -418,14 +419,14 @@ own_node = FALSE; /* now, parse and execute the commands */ - nb_parse_cmd(buffer); + nb_parse_cmd(node->rq_buffer); if (own_node) /* buffer finished, dispose of it */ - vim_free(buffer); + vim_free(node->rq_buffer); else /* more follows, move it to the start */ - STRMOVE(buffer, p); + channel_consume(nb_channel, PART_SOCK, (int)(p - buffer)); } } } diff -Nru vim-7.4.1830/src/normal.c vim-7.4.1907/src/normal.c --- vim-7.4.1830/src/normal.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/normal.c 2016-06-07 20:50:01.000000000 +0000 @@ -5485,10 +5485,12 @@ { char_u *ptr = NULL; char_u *buf; + unsigned buflen; char_u *newbuf; char_u *p; char_u *kp; /* value of 'keywordprg' */ - int kp_help; /* 'keywordprg' is ":help" */ + int kp_help; /* 'keywordprg' is ":he" */ + int kp_ex; /* 'keywordprg' starts with ":" */ int n = 0; /* init for GCC */ int cmdchar; int g_cmd; /* "g" command */ @@ -5536,7 +5538,9 @@ kp = (*curbuf->b_p_kp == NUL ? p_kp : curbuf->b_p_kp); kp_help = (*kp == NUL || STRCMP(kp, ":he") == 0 || STRCMP(kp, ":help") == 0); - buf = alloc((unsigned)(n * 2 + 30 + STRLEN(kp))); + kp_ex = (*kp == ':'); + buflen = (unsigned)(n * 2 + 30 + STRLEN(kp)); + buf = alloc(buflen); if (buf == NULL) return; buf[0] = NUL; @@ -5562,6 +5566,15 @@ case 'K': if (kp_help) STRCPY(buf, "he! "); + else if (kp_ex) + { + if (cap->count0 != 0) + vim_snprintf((char *)buf, buflen, "%s %ld", + kp, cap->count0); + else + STRCPY(buf, kp); + STRCAT(buf, " "); + } else { /* An external command will probably use an argument starting diff -Nru vim-7.4.1830/src/ops.c vim-7.4.1907/src/ops.c --- vim-7.4.1830/src/ops.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/ops.c 2016-06-07 20:50:01.000000000 +0000 @@ -3885,7 +3885,11 @@ if (dir == FORWARD) curbuf->b_op_start.lnum++; } - mark_adjust(curbuf->b_op_start.lnum + (y_type == MCHAR), + /* Skip mark_adjust when adding lines after the last one, there + * can't be marks there. */ + if (curbuf->b_op_start.lnum + (y_type == MCHAR) - 1 + nr_lines + < curbuf->b_ml.ml_line_count) + mark_adjust(curbuf->b_op_start.lnum + (y_type == MCHAR), (linenr_T)MAXLNUM, nr_lines, 0L); /* note changed text for displaying and folding */ diff -Nru vim-7.4.1830/src/option.c vim-7.4.1907/src/option.c --- vim-7.4.1830/src/option.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/option.c 2016-06-07 20:50:01.000000000 +0000 @@ -1665,7 +1665,7 @@ {"keywordprg", "kp", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, (char_u *)&p_kp, PV_KP, { -#if defined(MSWIN) +#ifdef MSWIN (char_u *)":help", #else # ifdef VMS diff -Nru vim-7.4.1830/src/os_unix.c vim-7.4.1907/src/os_unix.c --- vim-7.4.1830/src/os_unix.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/os_unix.c 2016-06-07 20:50:01.000000000 +0000 @@ -175,12 +175,12 @@ #endif static pid_t wait4pid(pid_t, waitstatus *); -static int WaitForChar(long); -static int WaitForCharOrMouse(long, int *break_loop); +static int WaitForChar(long msec, int *interrupted); +static int WaitForCharOrMouse(long msec, int *interrupted); #if defined(__BEOS__) || defined(VMS) -int RealWaitForChar(int, long, int *, int *break_loop); +int RealWaitForChar(int, long, int *, int *interrupted); #else -static int RealWaitForChar(int, long, int *, int *break_loop); +static int RealWaitForChar(int, long, int *, int *interrupted); #endif #ifdef FEAT_XCLIPBOARD @@ -369,6 +369,21 @@ RealWaitForChar(read_cmd_fd, p_wd, NULL, NULL); } +#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) +/* + * Return time in msec since "start_tv". + */ + static long +elapsed(struct timeval *start_tv) +{ + struct timeval now_tv; + + gettimeofday(&now_tv, NULL); + return (now_tv.tv_sec - start_tv->tv_sec) * 1000L + + (now_tv.tv_usec - start_tv->tv_usec) / 1000L; +} +#endif + /* * mch_inchar(): low level input function. * Get a characters from the keyboard. @@ -385,6 +400,13 @@ int tb_change_cnt) { int len; + int interrupted = FALSE; + long wait_time; +#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) + struct timeval start_tv; + + gettimeofday(&start_tv, NULL); +#endif #ifdef MESSAGE_QUEUE parse_queued_messages(); @@ -395,63 +417,105 @@ while (do_resize) handle_resize(); - if (wtime >= 0) + for (;;) { - while (!WaitForChar(wtime)) /* no character available */ + if (wtime >= 0) + wait_time = wtime; + else + wait_time = p_ut; +#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) + wait_time -= elapsed(&start_tv); + if (wait_time >= 0) { +#endif + if (WaitForChar(wait_time, &interrupted)) + break; + + /* no character available */ if (do_resize) + { handle_resize(); + continue; + } #ifdef FEAT_CLIENTSERVER - else if (!server_waiting()) -#else - else + if (server_waiting()) + { + parse_queued_messages(); + continue; + } #endif - /* return if not interrupted by resize or server */ - return 0; #ifdef MESSAGE_QUEUE - parse_queued_messages(); + if (interrupted) + { + parse_queued_messages(); + continue; + } +#endif +#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) + } #endif + if (wtime >= 0) + /* no character available within "wtime" */ + return 0; + + /* wtime == -1: no character available within 'updatetime' */ +#ifdef FEAT_AUTOCMD + if (trigger_cursorhold() && maxlen >= 3 + && !typebuf_changed(tb_change_cnt)) + { + buf[0] = K_SPECIAL; + buf[1] = KS_EXTRA; + buf[2] = (int)KE_CURSORHOLD; + return 3; } - } - else /* wtime == -1 */ - { +#endif /* * If there is no character available within 'updatetime' seconds * flush all the swap files to disk. * Also done when interrupted by SIGWINCH. */ - if (!WaitForChar(p_ut)) - { -#ifdef FEAT_AUTOCMD - if (trigger_cursorhold() && maxlen >= 3 - && !typebuf_changed(tb_change_cnt)) - { - buf[0] = K_SPECIAL; - buf[1] = KS_EXTRA; - buf[2] = (int)KE_CURSORHOLD; - return 3; - } -#endif - before_blocking(); - } + before_blocking(); + break; } - for (;;) /* repeat until we got a character */ + /* repeat until we got a character */ + for (;;) { + long wtime_now = -1L; + while (do_resize) /* window changed size */ handle_resize(); #ifdef MESSAGE_QUEUE parse_queued_messages(); + +# ifdef FEAT_JOB_CHANNEL + if (has_pending_job()) + { + /* Don't wait longer than a few seconds, checking for a finished + * job requires polling. */ + if (p_ut > 9000L) + wtime_now = 1000L; + else + wtime_now = 10000L - p_ut; + } +# endif #endif /* * We want to be interrupted by the winch signal * or by an event on the monitored file descriptors. */ - if (!WaitForChar(-1L)) + if (!WaitForChar(wtime_now, &interrupted)) { if (do_resize) /* interrupted by SIGWINCH signal */ - handle_resize(); + continue; +#ifdef MESSAGE_QUEUE + if (interrupted || wtime_now > 0) + { + parse_queued_messages(); + continue; + } +#endif return 0; } @@ -468,9 +532,7 @@ */ len = read_from_input_buf(buf, (long)maxlen); if (len > 0) - { return len; - } } } @@ -487,7 +549,7 @@ int mch_char_avail(void) { - return WaitForChar(0L); + return WaitForChar(0L, NULL); } #if defined(HAVE_TOTAL_MEM) || defined(PROTO) @@ -677,7 +739,7 @@ in_mch_delay = FALSE; } else - WaitForChar(msec); + WaitForChar(msec, NULL); } #if defined(HAVE_STACK_LIMIT) \ @@ -1479,22 +1541,15 @@ # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) \ && (defined(FEAT_XCLIPBOARD) || defined(FEAT_TITLE)) -static void xopen_message(struct timeval *tvp); +static void xopen_message(struct timeval *start_tv); /* * Give a message about the elapsed time for opening the X window. */ static void -xopen_message( - struct timeval *tvp) /* must contain start time */ +xopen_message(struct timeval *start_tv) { - struct timeval end_tv; - - /* Compute elapsed time. */ - gettimeofday(&end_tv, NULL); - smsg((char_u *)_("Opening the X display took %ld msec"), - (end_tv.tv_sec - tvp->tv_sec) * 1000L - + (end_tv.tv_usec - tvp->tv_usec) / 1000L); + smsg((char_u *)_("Opening the X display took %ld msec"), elapsed(start_tv)); } # endif #endif @@ -4847,15 +4902,11 @@ # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) if (wait_pid == 0) { - struct timeval now_tv; - long msec; + long msec = elapsed(&start_tv); /* Avoid that we keep looping here without * checking for a CTRL-C for a long time. Don't * break out too often to avoid losing typeahead. */ - gettimeofday(&now_tv, NULL); - msec = (now_tv.tv_sec - start_tv.tv_sec) * 1000L - + (now_tv.tv_usec - start_tv.tv_usec) / 1000L; if (msec > 2000) { noread_cnt = 5; @@ -5215,6 +5266,10 @@ if (stderr_works) perror("executing job failed"); +#ifdef EXITFREE + /* calling free_all_mem() here causes problems. Ignore valgrind + * reporting possibly leaked memory. */ +#endif _exit(EXEC_FAILED); /* exec failed, return failure code */ } @@ -5362,16 +5417,17 @@ * from inbuf[]. * "msec" == -1 will block forever. * Invokes timer callbacks when needed. - * When a GUI is being used, this will never get called -- webb + * "interrupted" (if not NULL) is set to TRUE when no character is available + * but something else needs to be done. * Returns TRUE when a character is available. + * When a GUI is being used, this will never get called -- webb */ static int -WaitForChar(long msec) +WaitForChar(long msec, int *interrupted) { #ifdef FEAT_TIMERS long due_time; long remaining = msec; - int break_loop = FALSE; int tb_change_cnt = typebuf.tb_change_cnt; /* When waiting very briefly don't trigger timers. */ @@ -5390,9 +5446,9 @@ } if (due_time <= 0 || (msec > 0 && due_time > remaining)) due_time = remaining; - if (WaitForCharOrMouse(due_time, &break_loop)) + if (WaitForCharOrMouse(due_time, interrupted)) return TRUE; - if (break_loop) + if (interrupted != NULL && *interrupted) /* Nothing available, but need to return so that side effects get * handled, such as handling a message on a channel. */ return FALSE; @@ -5401,7 +5457,7 @@ } return FALSE; #else - return WaitForCharOrMouse(msec, NULL); + return WaitForCharOrMouse(msec, interrupted); #endif } @@ -5409,10 +5465,12 @@ * Wait "msec" msec until a character is available from the mouse or keyboard * or from inbuf[]. * "msec" == -1 will block forever. + * "interrupted" (if not NULL) is set to TRUE when no character is available + * but something else needs to be done. * When a GUI is being used, this will never get called -- webb */ static int -WaitForCharOrMouse(long msec, int *break_loop) +WaitForCharOrMouse(long msec, int *interrupted) { #ifdef FEAT_MOUSE_GPM int gpm_process_wanted; @@ -5459,9 +5517,9 @@ # ifdef FEAT_MOUSE_GPM gpm_process_wanted = 0; avail = RealWaitForChar(read_cmd_fd, msec, - &gpm_process_wanted, break_loop); + &gpm_process_wanted, interrupted); # else - avail = RealWaitForChar(read_cmd_fd, msec, NULL, break_loop); + avail = RealWaitForChar(read_cmd_fd, msec, NULL, interrupted); # endif if (!avail) { @@ -5484,7 +5542,7 @@ ; #else - avail = RealWaitForChar(read_cmd_fd, msec, NULL, break_loop); + avail = RealWaitForChar(read_cmd_fd, msec, NULL, interrupted); #endif return avail; } @@ -5497,13 +5555,15 @@ * When a GUI is being used, this will not be used for input -- webb * Or when a Linux GPM mouse event is waiting. * Or when a clientserver message is on the queue. + * "interrupted" (if not NULL) is set to TRUE when no character is available + * but something else needs to be done. */ #if defined(__BEOS__) int #else static int #endif -RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *break_loop) +RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *interrupted) { int ret; int result; @@ -5517,25 +5577,10 @@ /* Remember at what time we started, so that we know how much longer we * should wait after being interrupted. */ # define USE_START_TV + long start_msec = msec; struct timeval start_tv; - if (msec > 0 && ( -# ifdef FEAT_XCLIPBOARD - xterm_Shell != (Widget)0 -# if defined(USE_XSMP) || defined(FEAT_MZSCHEME) - || -# endif -# endif -# ifdef USE_XSMP - xsmp_icefd != -1 -# ifdef FEAT_MZSCHEME - || -# endif -# endif -# ifdef FEAT_MZSCHEME - (mzthreads_allowed() && p_mzq > 0) -# endif - )) + if (msec > 0) gettimeofday(&start_tv, NULL); # endif @@ -5613,12 +5658,14 @@ #ifdef FEAT_JOB_CHANNEL nfd = channel_poll_setup(nfd, &fds); #endif + if (interrupted != NULL) + *interrupted = FALSE; ret = poll(fds, nfd, towait); result = ret > 0 && (fds[0].revents & POLLIN); - if (break_loop != NULL && ret > 0) - *break_loop = TRUE; + if (result == 0 && interrupted != NULL && ret > 0) + *interrupted = TRUE; # ifdef FEAT_MZSCHEME if (ret == 0 && mzquantum_used) @@ -5665,7 +5712,6 @@ ret = channel_poll_check(ret, &fds); #endif - #else /* HAVE_SELECT */ struct timeval tv; @@ -5746,13 +5792,15 @@ # ifdef FEAT_JOB_CHANNEL maxfd = channel_select_setup(maxfd, &rfds, &wfds); # endif + if (interrupted != NULL) + *interrupted = FALSE; ret = select(maxfd + 1, &rfds, &wfds, &efds, tvp); result = ret > 0 && FD_ISSET(fd, &rfds); if (result) --ret; - if (break_loop != NULL && ret > 0) - *break_loop = TRUE; + else if (interrupted != NULL && ret > 0) + *interrupted = TRUE; # ifdef EINTR if (ret == -1 && errno == EINTR) @@ -5847,12 +5895,8 @@ if (msec > 0) { # ifdef USE_START_TV - struct timeval mtv; - /* Compute remaining wait time. */ - gettimeofday(&mtv, NULL); - msec -= (mtv.tv_sec - start_tv.tv_sec) * 1000L - + (mtv.tv_usec - start_tv.tv_usec) / 1000L; + msec = start_msec - elapsed(&start_tv); # else /* Guess we got interrupted halfway. */ msec = msec / 2; diff -Nru vim-7.4.1830/src/proto/channel.pro vim-7.4.1907/src/proto/channel.pro --- vim-7.4.1830/src/proto/channel.pro 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/proto/channel.pro 2016-06-07 20:50:01.000000000 +0000 @@ -17,14 +17,16 @@ void channel_buffer_free(buf_T *buf); void channel_write_any_lines(void); void channel_write_new_lines(buf_T *buf); +readq_T *channel_peek(channel_T *channel, int part); +char_u *channel_first_nl(readq_T *node); char_u *channel_get(channel_T *channel, int part); -int channel_collapse(channel_T *channel, int part); +void channel_consume(channel_T *channel, int part, int len); +int channel_collapse(channel_T *channel, int part, int want_nl); int channel_can_write_to(channel_T *channel); int channel_is_open(channel_T *channel); char *channel_status(channel_T *channel); void channel_info(channel_T *channel, dict_T *dict); void channel_close(channel_T *channel, int invoke_close_cb); -char_u *channel_peek(channel_T *channel, int part); void channel_clear(channel_T *channel); void channel_free_all(void); char_u *channel_read_block(channel_T *channel, int part, int timeout); @@ -50,12 +52,14 @@ void free_job_options(jobopt_T *opt); int get_job_options(typval_T *tv, jobopt_T *opt, int supported); channel_T *get_channel_arg(typval_T *tv, int check_open, int reading, int part); +void job_free_all(void); int set_ref_in_job(int copyID); void job_unref(job_T *job); int free_unused_jobs_contents(int copyID, int mask); void free_unused_jobs(int copyID, int mask); void job_set_options(job_T *job, jobopt_T *opt); void job_stop_on_exit(void); +int has_pending_job(void); void job_check_ended(void); job_T *job_start(typval_T *argvars); char *job_status(job_T *job); diff -Nru vim-7.4.1830/src/proto/ex_cmds2.pro vim-7.4.1907/src/proto/ex_cmds2.pro --- vim-7.4.1830/src/proto/ex_cmds2.pro 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/proto/ex_cmds2.pro 2016-06-07 20:50:01.000000000 +0000 @@ -22,6 +22,7 @@ long check_due_timer(void); timer_T *find_timer(int id); void stop_timer(timer_T *timer); +int set_ref_in_timer(int copyID); void profile_divide(proftime_T *tm, int count, proftime_T *tm2); void profile_add(proftime_T *tm, proftime_T *tm2); void profile_self(proftime_T *self, proftime_T *total, proftime_T *children); diff -Nru vim-7.4.1830/src/proto/ex_cmds.pro vim-7.4.1907/src/proto/ex_cmds.pro --- vim-7.4.1830/src/proto/ex_cmds.pro 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/proto/ex_cmds.pro 2016-06-07 20:50:01.000000000 +0000 @@ -16,6 +16,7 @@ int viminfo_readline(vir_T *virp); char_u *viminfo_readstring(vir_T *virp, int off, int convert); void viminfo_writestring(FILE *fd, char_u *p); +int barline_writestring(FILE *fd, char_u *s, int remaining_start); void do_fixdel(exarg_T *eap); void print_line_no_prefix(linenr_T lnum, int use_number, int list); void print_line(linenr_T lnum, int use_number, int list); diff -Nru vim-7.4.1830/src/proto/ex_getln.pro vim-7.4.1907/src/proto/ex_getln.pro --- vim-7.4.1830/src/proto/ex_getln.pro 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/proto/ex_getln.pro 2016-06-07 20:50:01.000000000 +0000 @@ -37,19 +37,20 @@ int get_histtype(char_u *name); void add_to_history(int histype, char_u *new_entry, int in_map, int sep); int get_history_idx(int histype); -char_u *get_cmdline_str(void); -int get_cmdline_pos(void); -int set_cmdline_pos(int pos); -int get_cmdline_type(void); char_u *get_history_entry(int histype, int idx); int clr_history(int histype); int del_history_entry(int histype, char_u *str); int del_history_idx(int histype, int idx); void remove_key_from_history(void); +char_u *get_cmdline_str(void); +int get_cmdline_pos(void); +int set_cmdline_pos(int pos); +int get_cmdline_type(void); int get_list_range(char_u **str, int *num1, int *num2); void ex_history(exarg_T *eap); void prepare_viminfo_history(int asklen, int writing); int read_viminfo_history(vir_T *virp, int writing); +void handle_viminfo_history(bval_T *values, int count, int writing); void finish_viminfo_history(void); void write_viminfo_history(FILE *fp, int merge); void cmd_pchar(int c, int offset); diff -Nru vim-7.4.1830/src/proto/getchar.pro vim-7.4.1907/src/proto/getchar.pro --- vim-7.4.1830/src/proto/getchar.pro 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/proto/getchar.pro 2016-06-07 20:50:01.000000000 +0000 @@ -47,7 +47,6 @@ int vpeekc_any(void); int char_avail(void); void vungetc(int c); -int inchar(char_u *buf, int maxlen, long wait_time, int tb_change_cnt); int fix_input_buffer(char_u *buf, int len, int script); int input_available(void); int do_map(int maptype, char_u *arg, int mode, int abbrev); diff -Nru vim-7.4.1830/src/proto/gui_gtk_x11.pro vim-7.4.1907/src/proto/gui_gtk_x11.pro --- vim-7.4.1830/src/proto/gui_gtk_x11.pro 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/proto/gui_gtk_x11.pro 2016-06-07 20:50:01.000000000 +0000 @@ -1,6 +1,7 @@ /* gui_gtk_x11.c */ void gui_mch_prepare(int *argc, char **argv); void gui_mch_free_all(void); +int gui_mch_is_blinking(void); void gui_mch_set_blinking(long waittime, long on, long off); void gui_mch_stop_blink(void); void gui_mch_start_blink(void); diff -Nru vim-7.4.1830/src/proto/gui_mac.pro vim-7.4.1907/src/proto/gui_mac.pro --- vim-7.4.1830/src/proto/gui_mac.pro 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/proto/gui_mac.pro 2016-06-07 20:50:01.000000000 +0000 @@ -14,6 +14,7 @@ void gui_mac_focus_change(EventRecord *event); void gui_mac_update(EventRecord *event); short gui_mch_get_mac_menu_item_index(vimmenu_T *menu, vimmenu_T *parent); +int gui_mch_is_blinking(void); void gui_mch_set_blinking(long wait, long on, long off); void gui_mch_stop_blink(void); void gui_mch_start_blink(void); diff -Nru vim-7.4.1830/src/proto/gui_photon.pro vim-7.4.1907/src/proto/gui_photon.pro --- vim-7.4.1830/src/proto/gui_photon.pro 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/proto/gui_photon.pro 2016-06-07 20:50:01.000000000 +0000 @@ -39,6 +39,7 @@ void gui_mch_draw_string(int row, int col, char_u *s, int len, int flags); void gui_mch_draw_hollow_cursor(guicolor_T color); void gui_mch_draw_part_cursor(int w, int h, guicolor_T color); +int gui_mch_is_blinking(void); void gui_mch_set_blinking(long wait, long on, long off); void gui_mch_start_blink(void); void gui_mch_stop_blink(void); diff -Nru vim-7.4.1830/src/proto/gui_w32.pro vim-7.4.1907/src/proto/gui_w32.pro --- vim-7.4.1830/src/proto/gui_w32.pro 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/proto/gui_w32.pro 2016-06-07 20:50:01.000000000 +0000 @@ -1,6 +1,7 @@ /* gui_w32.c */ int directx_enabled(void); int gui_mch_set_rendering_options(char_u *s); +int gui_mch_is_blinking(void); void gui_mch_set_blinking(long wait, long on, long off); void gui_mch_stop_blink(void); void gui_mch_start_blink(void); diff -Nru vim-7.4.1830/src/proto/gui_x11.pro vim-7.4.1907/src/proto/gui_x11.pro --- vim-7.4.1830/src/proto/gui_x11.pro 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/proto/gui_x11.pro 2016-06-07 20:50:01.000000000 +0000 @@ -53,6 +53,7 @@ void gui_mch_menu_hidden(vimmenu_T *menu, int hidden); void gui_mch_draw_menubar(void); void gui_x11_menu_cb(Widget w, XtPointer client_data, XtPointer call_data); +int gui_mch_is_blinking(void); void gui_mch_set_blinking(long waittime, long on, long off); void gui_mch_stop_blink(void); void gui_mch_start_blink(void); diff -Nru vim-7.4.1830/src/quickfix.c vim-7.4.1907/src/quickfix.c --- vim-7.4.1830/src/quickfix.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/quickfix.c 2016-06-07 20:50:01.000000000 +0000 @@ -52,6 +52,7 @@ typedef struct qf_list_S { qfline_T *qf_start; /* pointer to the first error */ + qfline_T *qf_last; /* pointer to the last error */ qfline_T *qf_ptr; /* pointer to the current error */ int qf_count; /* number of errors (0 means no error list) */ int qf_index; /* current index in the error list */ @@ -110,7 +111,7 @@ static void qf_store_title(qf_info_T *qi, char_u *title); static void qf_new_list(qf_info_T *qi, char_u *qf_title); static void ll_free_all(qf_info_T **pqi); -static int qf_add_entry(qf_info_T *qi, qfline_T **prevp, char_u *dir, char_u *fname, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid); +static int qf_add_entry(qf_info_T *qi, char_u *dir, char_u *fname, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid); static qf_info_T *ll_new_list(void); static void qf_msg(qf_info_T *qi); static void qf_free(qf_info_T *qi, int idx); @@ -126,9 +127,9 @@ static int is_qf_win(win_T *win, qf_info_T *qi); static win_T *qf_find_win(qf_info_T *qi); static buf_T *qf_find_buf(qf_info_T *qi); -static void qf_update_buffer(qf_info_T *qi, int update_cursor); +static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last); static void qf_set_title_var(qf_info_T *qi); -static void qf_fill_buffer(qf_info_T *qi); +static void qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last); #endif static char_u *get_mef_name(void); static void restore_start_dir(char_u *dirname_start); @@ -179,10 +180,36 @@ */ #define LINE_MAXLEN 4096 + static char_u * +qf_grow_linebuf(char_u **growbuf, int *growbufsiz, int newsz, int *allocsz) +{ + /* + * If the line exceeds LINE_MAXLEN exclude the last + * byte since it's not a NL character. + */ + *allocsz = newsz > LINE_MAXLEN ? LINE_MAXLEN - 1 : newsz; + if (*growbuf == NULL) + { + *growbuf = alloc(*allocsz + 1); + if (*growbuf == NULL) + return NULL; + *growbufsiz = *allocsz; + } + else if (*allocsz > *growbufsiz) + { + *growbuf = vim_realloc(*growbuf, *allocsz + 1); + if (*growbuf == NULL) + return NULL; + *growbufsiz = *allocsz; + } + return *growbuf; +} + /* * Read the errorfile "efile" into memory, line by line, building the error * list. - * Alternative: when "efile" is null read errors from buffer "buf". + * Alternative: when "efile" is NULL read errors from buffer "buf". + * Alternative: when "tv" is not NULL get errors from the string or list. * Always use 'errorformat' from "buf" if there is a local value. * Then "lnumfirst" and "lnumlast" specify the range of lines to use. * Set the title of the list to "qf_title". @@ -219,7 +246,9 @@ long lnum = 0L; int enr = 0; FILE *fd = NULL; - qfline_T *qfprev = NULL; /* init to make SASC shut up */ +#ifdef FEAT_WINDOWS + qfline_T *old_last = NULL; +#endif char_u *efmp; efm_T *fmt_first = NULL; efm_T *fmt_last = NULL; @@ -278,11 +307,13 @@ if (newlist || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ qf_new_list(qi, qf_title); +#ifdef FEAT_WINDOWS else if (qi->qf_lists[qi->qf_curlist].qf_count > 0) - /* Adding to existing list, find last entry. */ - for (qfprev = qi->qf_lists[qi->qf_curlist].qf_start; - qfprev->qf_next != qfprev; qfprev = qfprev->qf_next) - ; + { + /* Adding to existing list, use last entry. */ + old_last = qi->qf_lists[qi->qf_curlist].qf_last; + } +#endif /* * Each part of the format string is copied and modified from errorformat to @@ -538,24 +569,10 @@ if (len > IOSIZE - 2) { - /* - * If the line exceeds LINE_MAXLEN exclude the last - * byte since it's not a NL character. - */ - linelen = len > LINE_MAXLEN ? LINE_MAXLEN - 1 : len; - if (growbuf == NULL) - { - growbuf = alloc(linelen + 1); - growbufsiz = linelen; - } - else if (linelen > growbufsiz) - { - growbuf = vim_realloc(growbuf, linelen + 1); - if (growbuf == NULL) - goto qf_init_end; - growbufsiz = linelen; - } - linebuf = growbuf; + linebuf = qf_grow_linebuf(&growbuf, &growbufsiz, len, + &linelen); + if (linebuf == NULL) + goto qf_init_end; } else { @@ -584,22 +601,10 @@ len = (int)STRLEN(p_li->li_tv.vval.v_string); if (len > IOSIZE - 2) { - linelen = len; - if (linelen > LINE_MAXLEN) - linelen = LINE_MAXLEN - 1; - if (growbuf == NULL) - { - growbuf = alloc(linelen + 1); - growbufsiz = linelen; - } - else if (linelen > growbufsiz) - { - if ((growbuf = vim_realloc(growbuf, - linelen + 1)) == NULL) - goto qf_init_end; - growbufsiz = linelen; - } - linebuf = growbuf; + linebuf = qf_grow_linebuf(&growbuf, &growbufsiz, len, + &linelen); + if (linebuf == NULL) + goto qf_init_end; } else { @@ -621,20 +626,10 @@ linelen = (int)STRLEN(p_buf); if (linelen > IOSIZE - 2) { - if (growbuf == NULL) - { - growbuf = alloc(linelen + 1); - growbufsiz = linelen; - } - else if (linelen > growbufsiz) - { - if (linelen > LINE_MAXLEN) - linelen = LINE_MAXLEN - 1; - if ((growbuf = vim_realloc(growbuf, linelen + 1)) == NULL) - goto qf_init_end; - growbufsiz = linelen; - } - linebuf = growbuf; + linebuf = qf_grow_linebuf(&growbuf, &growbufsiz, len, + &linelen); + if (linebuf == NULL) + goto qf_init_end; } else linebuf = IObuff; @@ -648,9 +643,9 @@ discard = FALSE; linelen = (int)STRLEN(IObuff); - if (linelen == IOSIZE - 1 && (IObuff[linelen - 1] != '\n' + if (linelen == IOSIZE - 1 && !(IObuff[linelen - 1] == '\n' #ifdef USE_CRNL - || IObuff[linelen - 1] != '\r' + || IObuff[linelen - 1] == '\r' #endif )) { @@ -940,6 +935,8 @@ } else if (vim_strchr((char_u *)"CZ", idx) != NULL) { /* continuation of multi-line msg */ + qfline_T *qfprev = qi->qf_lists[qi->qf_curlist].qf_last; + if (qfprev == NULL) goto error2; if (*errmsg && !multiignore) @@ -999,7 +996,7 @@ } } - if (qf_add_entry(qi, &qfprev, + if (qf_add_entry(qi, directory, (*namebuf || directory) ? namebuf @@ -1062,7 +1059,7 @@ vim_free(growbuf); #ifdef FEAT_WINDOWS - qf_update_buffer(qi, TRUE); + qf_update_buffer(qi, old_last); #endif return retval; @@ -1163,7 +1160,6 @@ static int qf_add_entry( qf_info_T *qi, /* quickfix list */ - qfline_T **prevp, /* pointer to previously added entry or NULL */ char_u *dir, /* optional directory name */ char_u *fname, /* file name or NULL */ int bufnum, /* buffer number or zero */ @@ -1177,11 +1173,18 @@ int valid) /* valid entry */ { qfline_T *qfp; + qfline_T **lastp; /* pointer to qf_last or NULL */ if ((qfp = (qfline_T *)alloc((unsigned)sizeof(qfline_T))) == NULL) return FAIL; if (bufnum != 0) + { + buf_T *buf = buflist_findnr(bufnum); + qfp->qf_fnum = bufnum; + if (buf != NULL) + buf->b_has_qf_entry = TRUE; + } else qfp->qf_fnum = qf_get_fnum(dir, fname); if ((qfp->qf_text = vim_strsave(mesg)) == NULL) @@ -1206,22 +1209,23 @@ qfp->qf_type = type; qfp->qf_valid = valid; + lastp = &qi->qf_lists[qi->qf_curlist].qf_last; if (qi->qf_lists[qi->qf_curlist].qf_count == 0) /* first element in the list */ { qi->qf_lists[qi->qf_curlist].qf_start = qfp; qi->qf_lists[qi->qf_curlist].qf_ptr = qfp; qi->qf_lists[qi->qf_curlist].qf_index = 0; - qfp->qf_prev = qfp; /* first element points to itself */ + qfp->qf_prev = NULL; } else { - qfp->qf_prev = *prevp; - (*prevp)->qf_next = qfp; + qfp->qf_prev = *lastp; + (*lastp)->qf_next = qfp; } - qfp->qf_next = qfp; /* last element points to itself */ + qfp->qf_next = NULL; qfp->qf_cleared = FALSE; - *prevp = qfp; + *lastp = qfp; ++qi->qf_lists[qi->qf_curlist].qf_count; if (qi->qf_lists[qi->qf_curlist].qf_index == 0 && qfp->qf_valid) /* first valid entry */ @@ -1319,6 +1323,7 @@ to_qfl->qf_count = 0; to_qfl->qf_index = 0; to_qfl->qf_start = NULL; + to_qfl->qf_last = NULL; to_qfl->qf_ptr = NULL; if (from_qfl->qf_title != NULL) to_qfl->qf_title = vim_strsave(from_qfl->qf_title); @@ -1328,13 +1333,14 @@ if (from_qfl->qf_count) { qfline_T *from_qfp; - qfline_T *prevp = NULL; + qfline_T *prevp; /* copy all the location entries in this list */ - for (i = 0, from_qfp = from_qfl->qf_start; i < from_qfl->qf_count; - ++i, from_qfp = from_qfp->qf_next) + for (i = 0, from_qfp = from_qfl->qf_start; + i < from_qfl->qf_count && from_qfp != NULL; + ++i, from_qfp = from_qfp->qf_next) { - if (qf_add_entry(to->w_llist, &prevp, + if (qf_add_entry(to->w_llist, NULL, NULL, 0, @@ -1355,6 +1361,7 @@ * directory and file names are not supplied. So the qf_fnum * field is copied here. */ + prevp = to->w_llist->qf_lists[to->w_llist->qf_curlist].qf_last; prevp->qf_fnum = from_qfp->qf_fnum; /* file number */ prevp->qf_type = from_qfp->qf_type; /* error type */ if (from_qfl->qf_ptr == from_qfp) @@ -1377,50 +1384,54 @@ } /* - * get buffer number for file "dir.name" + * Get buffer number for file "dir.name". + * Also sets the b_has_qf_entry flag. */ static int qf_get_fnum(char_u *directory, char_u *fname) { + char_u *ptr; + buf_T *buf; + if (fname == NULL || *fname == NUL) /* no file name */ return 0; - { - char_u *ptr; - int fnum; #ifdef VMS - vms_remove_version(fname); + vms_remove_version(fname); #endif #ifdef BACKSLASH_IN_FILENAME - if (directory != NULL) - slash_adjust(directory); - slash_adjust(fname); + if (directory != NULL) + slash_adjust(directory); + slash_adjust(fname); #endif - if (directory != NULL && !vim_isAbsName(fname) - && (ptr = concat_fnames(directory, fname, TRUE)) != NULL) + if (directory != NULL && !vim_isAbsName(fname) + && (ptr = concat_fnames(directory, fname, TRUE)) != NULL) + { + /* + * Here we check if the file really exists. + * This should normally be true, but if make works without + * "leaving directory"-messages we might have missed a + * directory change. + */ + if (mch_getperm(ptr) < 0) { - /* - * Here we check if the file really exists. - * This should normally be true, but if make works without - * "leaving directory"-messages we might have missed a - * directory change. - */ - if (mch_getperm(ptr) < 0) - { - vim_free(ptr); - directory = qf_guess_filepath(fname); - if (directory) - ptr = concat_fnames(directory, fname, TRUE); - else - ptr = vim_strsave(fname); - } - /* Use concatenated directory name and file name */ - fnum = buflist_add(ptr, 0); vim_free(ptr); - return fnum; + directory = qf_guess_filepath(fname); + if (directory) + ptr = concat_fnames(directory, fname, TRUE); + else + ptr = vim_strsave(fname); } - return buflist_add(fname, 0); + /* Use concatenated directory name and file name */ + buf = buflist_new(ptr, NULL, (linenr_T)0, 0); + vim_free(ptr); } + else + buf = buflist_new(fname, NULL, (linenr_T)0, 0); + if (buf == NULL) + return 0; + buf->b_has_qf_entry = TRUE; + return buf->b_fnum; } /* @@ -1615,7 +1626,7 @@ /* Search for the entry in the current list */ for (i = 0, qfp = qfl->qf_start; i < qfl->qf_count; ++i, qfp = qfp->qf_next) - if (qfp == qf_ptr) + if (qfp == NULL || qfp == qf_ptr) break; if (i == qfl->qf_count) /* Entry is not found */ @@ -2271,6 +2282,8 @@ } qfp = qfp->qf_next; + if (qfp == NULL) + break; ++i; ui_breakcheck(); } @@ -2358,7 +2371,7 @@ qi->qf_curlist + 1, qi->qf_listcount, qi->qf_lists[qi->qf_curlist].qf_count); #ifdef FEAT_WINDOWS - qf_update_buffer(qi, TRUE); + qf_update_buffer(qi, NULL); #endif } @@ -2369,24 +2382,26 @@ qf_free(qf_info_T *qi, int idx) { qfline_T *qfp; + qfline_T *qfpnext; int stop = FALSE; - while (qi->qf_lists[idx].qf_count) + while (qi->qf_lists[idx].qf_count && qi->qf_lists[idx].qf_start != NULL) { - qfp = qi->qf_lists[idx].qf_start->qf_next; + qfp = qi->qf_lists[idx].qf_start; + qfpnext = qfp->qf_next; if (qi->qf_lists[idx].qf_title != NULL && !stop) { - vim_free(qi->qf_lists[idx].qf_start->qf_text); - stop = (qi->qf_lists[idx].qf_start == qfp); - vim_free(qi->qf_lists[idx].qf_start->qf_pattern); - vim_free(qi->qf_lists[idx].qf_start); + vim_free(qfp->qf_text); + stop = (qfp == qfpnext); + vim_free(qfp->qf_pattern); + vim_free(qfp); if (stop) /* Somehow qf_count may have an incorrect value, set it to 1 * to avoid crashing when it's wrong. * TODO: Avoid qf_count being incorrect. */ qi->qf_lists[idx].qf_count = 1; } - qi->qf_lists[idx].qf_start = qfp; + qi->qf_lists[idx].qf_start = qfpnext; --qi->qf_lists[idx].qf_count; } vim_free(qi->qf_lists[idx].qf_title); @@ -2409,7 +2424,10 @@ qfline_T *qfp; int idx; qf_info_T *qi = &ql_info; + int found_one = FALSE; + if (!curbuf->b_has_qf_entry) + return; if (wp != NULL) { if (wp->w_llist == NULL) @@ -2420,9 +2438,11 @@ for (idx = 0; idx < qi->qf_listcount; ++idx) if (qi->qf_lists[idx].qf_count) for (i = 0, qfp = qi->qf_lists[idx].qf_start; - i < qi->qf_lists[idx].qf_count; ++i, qfp = qfp->qf_next) + i < qi->qf_lists[idx].qf_count && qfp != NULL; + ++i, qfp = qfp->qf_next) if (qfp->qf_fnum == curbuf->b_fnum) { + found_one = TRUE; if (qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2) { if (amount == MAXLNUM) @@ -2433,6 +2453,9 @@ else if (amount_after && qfp->qf_lnum > line2) qfp->qf_lnum += amount_after; } + + if (!found_one) + curbuf->b_has_qf_entry = FALSE; } /* @@ -2660,7 +2683,7 @@ /* * Fill the buffer with the quickfix list. */ - qf_fill_buffer(qi); + qf_fill_buffer(qi, curbuf, NULL); curwin->w_cursor.lnum = qi->qf_lists[qi->qf_curlist].qf_index; curwin->w_cursor.col = 0; @@ -2788,7 +2811,7 @@ * Find the quickfix buffer. If it exists, update the contents. */ static void -qf_update_buffer(qf_info_T *qi, int update_cursor) +qf_update_buffer(qf_info_T *qi, qfline_T *old_last) { buf_T *buf; win_T *win; @@ -2799,8 +2822,11 @@ buf = qf_find_buf(qi); if (buf != NULL) { - /* set curwin/curbuf to buf and save a few things */ - aucmd_prepbuf(&aco, buf); + linenr_T old_line_count = buf->b_ml.ml_line_count; + + if (old_last == NULL) + /* set curwin/curbuf to buf and save a few things */ + aucmd_prepbuf(&aco, buf); if ((win = qf_find_win(qi)) != NULL) { @@ -2810,13 +2836,20 @@ curwin = curwin_save; } - qf_fill_buffer(qi); - - /* restore curwin/curbuf and a few other things */ - aucmd_restbuf(&aco); + qf_fill_buffer(qi, buf, old_last); - if (update_cursor) + if (old_last == NULL) + { (void)qf_win_pos_update(qi, 0); + + /* restore curwin/curbuf and a few other things */ + aucmd_restbuf(&aco); + } + + /* Only redraw when added lines are visible. This avoids flickering + * when the added lines are not visible. */ + if ((win = qf_find_win(qi)) != NULL && old_line_count < win->w_botline) + redraw_buf_later(buf, NOT_VALID); } } @@ -2834,9 +2867,12 @@ /* * Fill current buffer with quickfix errors, replacing any previous contents. * curbuf must be the quickfix buffer! + * If "old_last" is not NULL append the items after this one. + * When "old_last" is NULL then "buf" must equal "curbuf"! Because + * ml_delete() is used and autocommands will be triggered. */ static void -qf_fill_buffer(qf_info_T *qi) +qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last) { linenr_T lnum; qfline_T *qfp; @@ -2844,16 +2880,34 @@ int len; int old_KeyTyped = KeyTyped; - /* delete all existing lines */ - while ((curbuf->b_ml.ml_flags & ML_EMPTY) == 0) - (void)ml_delete((linenr_T)1, FALSE); + if (old_last == NULL) + { + if (buf != curbuf) + { + EMSG2(_(e_intern2), "qf_fill_buffer()"); + return; + } + + /* delete all existing lines */ + while ((curbuf->b_ml.ml_flags & ML_EMPTY) == 0) + (void)ml_delete((linenr_T)1, FALSE); + } /* Check if there is anything to display */ if (qi->qf_curlist < qi->qf_listcount) { /* Add one line for each error */ - qfp = qi->qf_lists[qi->qf_curlist].qf_start; - for (lnum = 0; lnum < qi->qf_lists[qi->qf_curlist].qf_count; ++lnum) + if (old_last == NULL) + { + qfp = qi->qf_lists[qi->qf_curlist].qf_start; + lnum = 0; + } + else + { + qfp = old_last->qf_next; + lnum = buf->b_ml.ml_line_count; + } + while (lnum < qi->qf_lists[qi->qf_curlist].qf_count) { if (qfp->qf_fnum != 0 && (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL @@ -2898,35 +2952,42 @@ qf_fmt_text(len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text, IObuff + len, IOSIZE - len); - if (ml_append(lnum, IObuff, (colnr_T)STRLEN(IObuff) + 1, FALSE) - == FAIL) + if (ml_append_buf(buf, lnum, IObuff, + (colnr_T)STRLEN(IObuff) + 1, FALSE) == FAIL) break; + ++lnum; qfp = qfp->qf_next; + if (qfp == NULL) + break; } - /* Delete the empty line which is now at the end */ - (void)ml_delete(lnum + 1, FALSE); + + if (old_last == NULL) + /* Delete the empty line which is now at the end */ + (void)ml_delete(lnum + 1, FALSE); } /* correct cursor position */ check_lnums(TRUE); - /* Set the 'filetype' to "qf" each time after filling the buffer. This - * resembles reading a file into a buffer, it's more logical when using - * autocommands. */ - set_option_value((char_u *)"ft", 0L, (char_u *)"qf", OPT_LOCAL); - curbuf->b_p_ma = FALSE; + if (old_last == NULL) + { + /* Set the 'filetype' to "qf" each time after filling the buffer. + * This resembles reading a file into a buffer, it's more logical when + * using autocommands. */ + set_option_value((char_u *)"ft", 0L, (char_u *)"qf", OPT_LOCAL); + curbuf->b_p_ma = FALSE; #ifdef FEAT_AUTOCMD - keep_filetype = TRUE; /* don't detect 'filetype' */ - apply_autocmds(EVENT_BUFREADPOST, (char_u *)"quickfix", NULL, + keep_filetype = TRUE; /* don't detect 'filetype' */ + apply_autocmds(EVENT_BUFREADPOST, (char_u *)"quickfix", NULL, FALSE, curbuf); - apply_autocmds(EVENT_BUFWINENTER, (char_u *)"quickfix", NULL, + apply_autocmds(EVENT_BUFWINENTER, (char_u *)"quickfix", NULL, FALSE, curbuf); - keep_filetype = FALSE; + keep_filetype = FALSE; #endif - - /* make sure it will be redrawn */ - redraw_curbuf_later(NOT_VALID); + /* make sure it will be redrawn */ + redraw_curbuf_later(NOT_VALID); + } /* Restore KeyTyped, setting 'filetype' may reset it. */ KeyTyped = old_KeyTyped; @@ -3194,7 +3255,7 @@ } for (i = 0, qfp = qi->qf_lists[qi->qf_curlist].qf_start; - (i < qi->qf_lists[qi->qf_curlist].qf_count) && (qfp != NULL); + i < qi->qf_lists[qi->qf_curlist].qf_count && qfp != NULL; ++i, qfp = qfp->qf_next) { if (qfp->qf_valid) @@ -3300,7 +3361,7 @@ if (qfl->qf_count <= 0 || qfl->qf_nonevalid) return 1; - for (i = 1, eidx = 0; i <= qfl->qf_count && qfp!= NULL; + for (i = 1, eidx = 0; i <= qfl->qf_count && qfp != NULL; i++, qfp = qfp->qf_next) { if (qfp->qf_valid) @@ -3528,7 +3589,6 @@ #ifdef FEAT_AUTOCMD qfline_T *cur_qf_start; #endif - qfline_T *prevp = NULL; long lnum; buf_T *buf; int duplicate_name = FALSE; @@ -3627,11 +3687,6 @@ || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ qf_new_list(qi, title != NULL ? title : *eap->cmdlinep); - else if (qi->qf_lists[qi->qf_curlist].qf_count > 0) - /* Adding to existing list, find last entry. */ - for (prevp = qi->qf_lists[qi->qf_curlist].qf_start; - prevp->qf_next != prevp; prevp = prevp->qf_next) - ; /* parse the list of arguments */ if (get_arglist_exp(p, &fcount, &fnames, TRUE) == FAIL) @@ -3755,7 +3810,7 @@ col, NULL) > 0) { ; - if (qf_add_entry(qi, &prevp, + if (qf_add_entry(qi, NULL, /* dir */ fname, 0, @@ -3858,7 +3913,7 @@ qi->qf_lists[qi->qf_curlist].qf_index = 1; #ifdef FEAT_WINDOWS - qf_update_buffer(qi, TRUE); + qf_update_buffer(qi, NULL); #endif #ifdef FEAT_AUTOCMD @@ -4181,13 +4236,16 @@ return FAIL; qfp = qfp->qf_next; + if (qfp == NULL) + break; } return OK; } /* * Populate the quickfix list with the items supplied in the list - * of dictionaries. "title" will be copied to w:quickfix_title + * of dictionaries. "title" will be copied to w:quickfix_title. + * "action" is 'a' for add, 'r' for replace. Otherwise create a new list. */ int set_errorlist( @@ -4203,7 +4261,9 @@ long lnum; int col, nr; int vcol; - qfline_T *prevp = NULL; +#ifdef FEAT_WINDOWS + qfline_T *old_last = NULL; +#endif int valid, status; int retval = OK; qf_info_T *qi = &ql_info; @@ -4219,11 +4279,11 @@ if (action == ' ' || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ qf_new_list(qi, title); +#ifdef FEAT_WINDOWS else if (action == 'a' && qi->qf_lists[qi->qf_curlist].qf_count > 0) - /* Adding to existing list, find last entry. */ - for (prevp = qi->qf_lists[qi->qf_curlist].qf_start; - prevp->qf_next != prevp; prevp = prevp->qf_next) - ; + /* Adding to existing list, use last entry. */ + old_last = qi->qf_lists[qi->qf_curlist].qf_last; +#endif else if (action == 'r') { qf_free(qi, qi->qf_curlist); @@ -4268,7 +4328,7 @@ bufnum = 0; } - status = qf_add_entry(qi, &prevp, + status = qf_add_entry(qi, NULL, /* dir */ filename, bufnum, @@ -4307,7 +4367,7 @@ #ifdef FEAT_WINDOWS /* Don't update the cursor in quickfix window when appending entries */ - qf_update_buffer(qi, (action != 'a')); + qf_update_buffer(qi, old_last); #endif return retval; @@ -4432,7 +4492,6 @@ char_u **fnames; FILE *fd; int fi; - qfline_T *prevp = NULL; long lnum; #ifdef FEAT_MULTI_LANG char_u *lang; @@ -4558,7 +4617,7 @@ while (l > 0 && line[l - 1] <= ' ') line[--l] = NUL; - if (qf_add_entry(qi, &prevp, + if (qf_add_entry(qi, NULL, /* dir */ fnames[fi], 0, @@ -4614,7 +4673,7 @@ free_string_option(save_cpo); #ifdef FEAT_WINDOWS - qf_update_buffer(qi, TRUE); + qf_update_buffer(qi, NULL); #endif #ifdef FEAT_AUTOCMD diff -Nru vim-7.4.1830/src/screen.c vim-7.4.1907/src/screen.c --- vim-7.4.1830/src/screen.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/screen.c 2016-06-07 20:50:01.000000000 +0000 @@ -432,7 +432,10 @@ #ifdef FEAT_GUI if (gui.in_use) { - gui_update_cursor(TRUE, FALSE); + /* Don't update the cursor while it is blinking, it will get + * updated soon and this avoids interrupting the blinking. */ + if (!gui_mch_is_blinking()) + gui_update_cursor(FALSE, FALSE); gui_mch_flush(); } #endif @@ -801,6 +804,10 @@ int row; int j; + /* Don't do anything if the screen structures are (not yet) valid. */ + if (!screen_valid(TRUE)) + return; + if (lnum >= wp->w_topline && lnum < wp->w_botline && foldedCount(wp, lnum, &win_foldinfo) == 0) { diff -Nru vim-7.4.1830/src/structs.h vim-7.4.1907/src/structs.h --- vim-7.4.1830/src/structs.h 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/structs.h 2016-06-07 20:50:01.000000000 +0000 @@ -1014,6 +1014,7 @@ #ifdef FEAT_MBYTE vimconv_T vir_conv; /* encoding conversion */ #endif + int vir_version; /* viminfo version detected or -1 */ garray_T vir_barlines; /* lines starting with | */ } vir_T; @@ -1261,6 +1262,8 @@ { int pt_refcount; /* reference count */ char_u *pt_name; /* function name */ + int pt_auto; /* when TRUE the partial was created for using + dict.member in handle_subscript() */ int pt_argc; /* number of arguments */ typval_T *pt_argv; /* arguments in allocated array */ dict_T *pt_dict; /* dict for "self" */ @@ -1307,6 +1310,7 @@ struct readq_S { char_u *rq_buffer; + long_u rq_buflen; readq_T *rq_next; readq_T *rq_prev; }; @@ -1399,6 +1403,8 @@ partial_T *ch_partial; buf_T *ch_buffer; /* buffer to read from or write to */ + int ch_nomodifiable; /* TRUE when buffer can be 'nomodifiable' */ + int ch_nomod_error; /* TRUE when e_modifiable was given */ int ch_buf_append; /* write appended lines instead top-bot */ linenr_T ch_buf_top; /* next line to send */ linenr_T ch_buf_bot; /* last line to send */ @@ -1475,6 +1481,8 @@ #define JO_IN_BUF 0x4000000 /* "in_buf" (JO_OUT_BUF << 2) */ #define JO_CHANNEL 0x8000000 /* "channel" */ #define JO_BLOCK_WRITE 0x10000000 /* "block_write" */ +#define JO_OUT_MODIFIABLE 0x20000000 /* "out_modifiable" */ +#define JO_ERR_MODIFIABLE 0x40000000 /* "err_modifiable" (JO_OUT_ << 1) */ #define JO_ALL 0x7fffffff #define JO_MODE_ALL (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE) @@ -1498,6 +1506,7 @@ char_u jo_io_name_buf[4][NUMBUFLEN]; char_u *jo_io_name[4]; /* not allocated! */ int jo_io_buf[4]; + int jo_modifiable[4]; channel_T *jo_channel; linenr_T jo_in_top; @@ -1522,7 +1531,6 @@ int jo_id; char_u jo_soe_buf[NUMBUFLEN]; char_u *jo_stoponexit; - char_u jo_ecb_buf[NUMBUFLEN]; } jobopt_T; @@ -1859,9 +1867,10 @@ #ifdef FEAT_MBYTE int b_p_bomb; /* 'bomb' */ #endif -#if defined(FEAT_QUICKFIX) +#ifdef FEAT_QUICKFIX char_u *b_p_bh; /* 'bufhidden' */ char_u *b_p_bt; /* 'buftype' */ + int b_has_qf_entry; #endif int b_p_bl; /* 'buflisted' */ #ifdef FEAT_CINDENT @@ -2459,7 +2468,7 @@ int w_wrow, w_wcol; /* cursor position in window */ linenr_T w_botline; /* number of the line below the bottom of - the screen */ + the window */ int w_empty_rows; /* number of ~ rows in window */ #ifdef FEAT_DIFF int w_filler_rows; /* number of filler rows at the end of the diff -Nru vim-7.4.1830/src/syntax.c vim-7.4.1907/src/syntax.c --- vim-7.4.1830/src/syntax.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/syntax.c 2016-06-07 20:50:01.000000000 +0000 @@ -8486,11 +8486,11 @@ #ifdef FEAT_GUI return gui.norm_pixel; #endif -#if defined(FEAT_TERMGUICOLORS) && defined(FEAT_GUI) - else -#endif #ifdef FEAT_TERMGUICOLORS + if (cterm_normal_fg_gui_color != (long_u)INVALCOLOR) return cterm_normal_fg_gui_color; + /* Guess that the foreground is black or white. */ + return GUI_GET_COLOR((char_u *)(*p_bg == 'l' ? "black" : "white")); #endif } if (STRICMP(name, "bg") == 0 || STRICMP(name, "background") == 0) @@ -8501,11 +8501,11 @@ #ifdef FEAT_GUI return gui.back_pixel; #endif -#if defined(FEAT_TERMGUICOLORS) && defined(FEAT_GUI) - else -#endif #ifdef FEAT_TERMGUICOLORS + if (cterm_normal_bg_gui_color != (long_u)INVALCOLOR) return cterm_normal_bg_gui_color; + /* Guess that the background is white or black. */ + return GUI_GET_COLOR((char_u *)(*p_bg == 'l' ? "white" : "black")); #endif } @@ -8595,7 +8595,6 @@ && aep->ae_u.cterm.bg_rgb == taep->ae_u.cterm.bg_rgb #endif - ))) return i + ATTR_OFF; diff -Nru vim-7.4.1830/src/term.c vim-7.4.1907/src/term.c --- vim-7.4.1830/src/term.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/term.c 2016-06-07 20:50:01.000000000 +0000 @@ -5031,12 +5031,25 @@ * Compute the time elapsed since the previous mouse click. */ gettimeofday(&mouse_time, NULL); - timediff = (mouse_time.tv_usec - - orig_mouse_time.tv_usec) / 1000; - if (timediff < 0) - --orig_mouse_time.tv_sec; - timediff += (mouse_time.tv_sec - - orig_mouse_time.tv_sec) * 1000; + if (orig_mouse_time.tv_sec == 0) + { + /* + * Avoid computing the difference between mouse_time + * and orig_mouse_time for the first click, as the + * difference would be huge and would cause multiplication + * overflow. + */ + timediff = p_mouset; + } + else + { + timediff = (mouse_time.tv_usec + - orig_mouse_time.tv_usec) / 1000; + if (timediff < 0) + --orig_mouse_time.tv_sec; + timediff += (mouse_time.tv_sec + - orig_mouse_time.tv_sec) * 1000; + } orig_mouse_time = mouse_time; if (mouse_code == orig_mouse_code && timediff < p_mouset diff -Nru vim-7.4.1830/src/testdir/Make_all.mak vim-7.4.1907/src/testdir/Make_all.mak --- vim-7.4.1830/src/testdir/Make_all.mak 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/Make_all.mak 2016-06-07 20:50:01.000000000 +0000 @@ -179,6 +179,7 @@ test_perl.res \ test_quickfix.res \ test_syntax.res \ + test_usercommands.res \ test_viminfo.res \ test_viml.res \ test_visual.res \ diff -Nru vim-7.4.1830/src/testdir/Makefile vim-7.4.1907/src/testdir/Makefile --- vim-7.4.1830/src/testdir/Makefile 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/Makefile 2016-06-07 20:50:01.000000000 +0000 @@ -12,7 +12,7 @@ # The output goes into a file "valgrind.testN" # Vim should be compiled with EXITFREE to avoid false warnings. # This will make testing about 10 times as slow. -# VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=15 --log-file=valgrind.$* +# VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=25 --log-file=valgrind.$* default: nongui @@ -52,7 +52,7 @@ RM_ON_RUN = test.out X* viminfo RM_ON_START = tiny.vim small.vim mbyte.vim mzscheme.vim lua.vim test.ok benchmark.out -RUN_VIM = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -f -u unix.vim $(NO_PLUGIN) -s dotest.in +RUN_VIM = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_PLUGIN) -s dotest.in clean: -rm -rf *.out *.failed *.res *.rej *.orig test.log messages $(RM_ON_RUN) $(RM_ON_START) valgrind.* @@ -118,7 +118,7 @@ # New style of tests uses Vim script with assert calls. These are easier # to write and a lot easier to read and debug. # Limitation: Only works with the +eval feature. -RUN_VIMTEST = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -f -u unix.vim $(NO_PLUGIN) +RUN_VIMTEST = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_PLUGIN) newtests: newtestssilent @/bin/sh -c "if test -f messages && grep -q 'FAILED' messages; then cat messages && cat test.log; fi" diff -Nru vim-7.4.1830/src/testdir/README.txt vim-7.4.1907/src/testdir/README.txt --- vim-7.4.1830/src/testdir/README.txt 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/README.txt 2016-06-07 20:50:01.000000000 +0000 @@ -5,7 +5,7 @@ The numbered tests are older, we have switched to named tests. -And then you can chose between a new style test, which is a Vim script, or an +And then you can choose between a new style test, which is a Vim script, or an old style test, which uses Normal mode commands. Use a new style test if you can. @@ -21,13 +21,14 @@ What you can use (see test_assert.vim for an example): - Call assert_equal(), assert_true() and assert_false(). - Use try/catch to check for exceptions. -- Use alloc_fail() to have memory allocation fail. This makes it possible to +- Use alloc_fail() to have memory allocation fail. This makes it possible to check memory allocation failures are handled gracefully. You need to change the source code to add an ID to the allocation. Update LAST_ID_USED above alloc_id() to the highest ID used. - Use disable_char_avail_for_testing(1) if char_avail() must return FALSE for a while. E.g. to trigger the CursorMovedI autocommand event. See test_cursor_func.vim for an example +- See the start of runtest.vim for more help. TO ADD AN OLD STYLE TEST: diff -Nru vim-7.4.1830/src/testdir/runtest.vim vim-7.4.1907/src/testdir/runtest.vim --- vim-7.4.1830/src/testdir/runtest.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/runtest.vim 2016-06-07 20:50:01.000000000 +0000 @@ -60,7 +60,7 @@ let s:srcdir = expand('%:p:h:h') -" Prepare for calling garbagecollect_for_testing(). +" Prepare for calling test_garbagecollect_now(). let v:testing = 1 " Support function: get the alloc ID by name. diff -Nru vim-7.4.1830/src/testdir/test86.in vim-7.4.1907/src/testdir/test86.in --- vim-7.4.1830/src/testdir/test86.in 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test86.in 2016-06-07 20:50:01.000000000 +0000 @@ -877,6 +877,12 @@ :$put =string(pyeval('vim.Function(''tr'', args=[])')) :$put =string(pyeval('vim.Function(''tr'', self={})')) :$put =string(pyeval('vim.Function(''tr'', args=[123, 3, 4], self={})')) +:$put ='auto_rebind' +:$put =string(pyeval('vim.Function(''tr'', auto_rebind=False)')) +:$put =string(pyeval('vim.Function(''tr'', args=[123, 3, 4], auto_rebind=False)')) +:$put =string(pyeval('vim.Function(''tr'', args=[], auto_rebind=False)')) +:$put =string(pyeval('vim.Function(''tr'', self={}, auto_rebind=False)')) +:$put =string(pyeval('vim.Function(''tr'', args=[123, 3, 4], self={}, auto_rebind=False)')) :" :" Test vim.Function :function Args(...) @@ -915,11 +921,27 @@ psa2 = vim.Function('SelfArgs', args=[]) psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}) psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}) +psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0) +psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=()) +psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[]) +psa8 = vim.Function('SelfArgs', auto_rebind=False) +psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True) +psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1) +psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'}) +psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC']) cb.append('sa: ' + repr(sa)) cb.append('psa1: ' + repr(psa1)) cb.append('psa2: ' + repr(psa2)) cb.append('psa3: ' + repr(psa3)) cb.append('psa4: ' + repr(psa4)) +cb.append('psa5: ' + repr(psa5)) +cb.append('psa6: ' + repr(psa6)) +cb.append('psa7: ' + repr(psa7)) +cb.append('psa8: ' + repr(psa8)) +cb.append('psa9: ' + repr(psa9)) +cb.append('psaA: ' + repr(psaA)) +cb.append('psaB: ' + repr(psaB)) +cb.append('psaC: ' + repr(psaC)) psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'}) psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]] @@ -942,6 +964,19 @@ :$put ='s(psa2): '.string(pyeval('psa2')) :$put ='s(psa3): '.string(pyeval('psa3')) :$put ='s(psa4): '.string(pyeval('psa4')) +:$put ='s(psa5): '.string(pyeval('psa5')) +:$put ='s(psa6): '.string(pyeval('psa6')) +:$put ='s(psa7): '.string(pyeval('psa7')) +:$put ='s(psa8): '.string(pyeval('psa8')) +:$put ='s(psa9): '.string(pyeval('psa9')) +:$put ='s(psaA): '.string(pyeval('psaA')) +:$put ='s(psaB): '.string(pyeval('psaB')) +:$put ='s(psaC): '.string(pyeval('psaC')) +: +:for v in ['sa', 'psa1', 'psa2', 'psa3', 'psa4', 'psa5', 'psa6', 'psa7', 'psa8', 'psa9', 'psaA', 'psaB', 'psaC'] +: let d = {'f': pyeval(v)} +: $put ='d.'.v.'(): '.string(d.f()) +:endfor : :py ecall('a()', a, ) :py ecall('pa1()', pa1, ) @@ -1026,6 +1061,25 @@ cb.append('psa3.name: ' + s(psa3.name)) cb.append('psa4.name: ' + s(psa4.name)) +cb.append('a.auto_rebind: ' + s(a.auto_rebind)) +cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind)) +cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind)) +cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind)) +cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind)) +cb.append('sa.auto_rebind: ' + s(sa.auto_rebind)) +cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind)) +cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind)) +cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind)) +cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind)) +cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind)) +cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind)) +cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind)) +cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind)) +cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind)) +cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind)) +cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind)) +cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind)) + del s del a @@ -1038,6 +1092,14 @@ del psa2 del psa3 del psa4 +del psa5 +del psa6 +del psa7 +del psa8 +del psa9 +del psaA +del psaB +del psaC del psar del ecall diff -Nru vim-7.4.1830/src/testdir/test86.ok vim-7.4.1907/src/testdir/test86.ok --- vim-7.4.1830/src/testdir/test86.ok 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test86.ok 2016-06-07 20:50:01.000000000 +0000 @@ -448,7 +448,7 @@ range:__dir__,__members__,append,end,start dictionary:__dir__,__members__,get,has_key,items,keys,locked,pop,popitem,scope,update,values list:__dir__,__members__,extend,locked -function:__dir__,__members__,args,self,softspace +function:__dir__,__members__,args,auto_rebind,self,softspace output:__dir__,__members__,close,closed,flush,isatty,readable,seekable,softspace,writable,write,writelines {} {'a': 1} @@ -460,6 +460,12 @@ function('tr') function('tr', {}) function('tr', [123, 3, 4], {}) +auto_rebind +function('tr') +function('tr', [123, 3, 4]) +function('tr') +function('tr', {}) +function('tr', [123, 3, 4], {}) a: pa1: pa2: @@ -470,7 +476,15 @@ psa2: psa3: psa4: -psar: +psa5: +psa6: +psa7: +psa8: +psa9: +psaA: +psaB: +psaC: +psar: s(a): function('Args') s(pa1): function('Args', ['abcArgsPA1']) s(pa2): function('Args') @@ -481,6 +495,27 @@ s(psa2): function('SelfArgs') s(psa3): function('SelfArgs', ['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}) s(psa4): function('SelfArgs', {'abcSelfPSA4': 'abcSelfPSA4Val'}) +s(psa5): function('SelfArgs', {'abcSelfPSA5': 'abcSelfPSA5Val'}) +s(psa6): function('SelfArgs', ['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'}) +s(psa7): function('SelfArgs', ['abcArgsPSA7']) +s(psa8): function('SelfArgs') +s(psa9): function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'}) +s(psaA): function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'}) +s(psaB): function('SelfArgs', ['abcArgsPSAB']) +s(psaC): function('SelfArgs') +d.sa(): [[], {'f': function('SelfArgs')}] +d.psa1(): [['abcArgsPSA1'], {'f': function('SelfArgs', ['abcArgsPSA1'])}] +d.psa2(): [[], {'f': function('SelfArgs')}] +d.psa3(): [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}] +d.psa4(): [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}] +d.psa5(): [[], {'abcSelfPSA5': 'abcSelfPSA5Val'}] +d.psa6(): [['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'}] +d.psa7(): [['abcArgsPSA7'], {'f': function('SelfArgs', ['abcArgsPSA7'])}] +d.psa8(): [[], {'f': function('SelfArgs')}] +d.psa9(): [[], {'f': function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'})}] +d.psaA(): [['abcArgsPSAA'], {'f': function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'})}] +d.psaB(): [['abcArgsPSAB'], {'f': function('SelfArgs', ['abcArgsPSAB'])}] +d.psaC(): [[], {'f': function('SelfArgs')}] a(): !result: [] pa1(): !result: ['abcArgsPA1'] pa2(): !result: [] @@ -551,6 +586,24 @@ psa2.name: 'SelfArgs' psa3.name: 'SelfArgs' psa4.name: 'SelfArgs' +a.auto_rebind: 1 +pa1.auto_rebind: 1 +pa2.auto_rebind: 1 +pa3.auto_rebind: 0 +pa4.auto_rebind: 0 +sa.auto_rebind: 1 +psa1.auto_rebind: 1 +psa2.auto_rebind: 1 +psa3.auto_rebind: 0 +psa4.auto_rebind: 0 +psa5.auto_rebind: 0 +psa6.auto_rebind: 0 +psa7.auto_rebind: 1 +psa8.auto_rebind: 1 +psa9.auto_rebind: 1 +psaA.auto_rebind: 1 +psaB.auto_rebind: 1 +psaC.auto_rebind: 1 ' abcdef Error detected while processing function RunTest[]..Test: diff -Nru vim-7.4.1830/src/testdir/test87.in vim-7.4.1907/src/testdir/test87.in --- vim-7.4.1830/src/testdir/test87.in 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test87.in 2016-06-07 20:50:01.000000000 +0000 @@ -871,6 +871,12 @@ :$put =string(py3eval('vim.Function(''tr'', args=[])')) :$put =string(py3eval('vim.Function(''tr'', self={})')) :$put =string(py3eval('vim.Function(''tr'', args=[123, 3, 4], self={})')) +:$put ='auto_rebind' +:$put =string(py3eval('vim.Function(''tr'', auto_rebind=False)')) +:$put =string(py3eval('vim.Function(''tr'', args=[123, 3, 4], auto_rebind=False)')) +:$put =string(py3eval('vim.Function(''tr'', args=[], auto_rebind=False)')) +:$put =string(py3eval('vim.Function(''tr'', self={}, auto_rebind=False)')) +:$put =string(py3eval('vim.Function(''tr'', args=[123, 3, 4], self={}, auto_rebind=False)')) :" :" Test vim.Function :function Args(...) @@ -909,11 +915,27 @@ psa2 = vim.Function('SelfArgs', args=[]) psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}) psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}) +psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0) +psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=()) +psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[]) +psa8 = vim.Function('SelfArgs', auto_rebind=False) +psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True) +psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1) +psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'}) +psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC']) cb.append('sa: ' + repr(sa)) cb.append('psa1: ' + repr(psa1)) cb.append('psa2: ' + repr(psa2)) cb.append('psa3: ' + repr(psa3)) cb.append('psa4: ' + repr(psa4)) +cb.append('psa5: ' + repr(psa5)) +cb.append('psa6: ' + repr(psa6)) +cb.append('psa7: ' + repr(psa7)) +cb.append('psa8: ' + repr(psa8)) +cb.append('psa9: ' + repr(psa9)) +cb.append('psaA: ' + repr(psaA)) +cb.append('psaB: ' + repr(psaB)) +cb.append('psaC: ' + repr(psaC)) psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'}) psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]] @@ -936,6 +958,19 @@ :$put ='s(psa2): '.string(py3eval('psa2')) :$put ='s(psa3): '.string(py3eval('psa3')) :$put ='s(psa4): '.string(py3eval('psa4')) +:$put ='s(psa5): '.string(py3eval('psa5')) +:$put ='s(psa6): '.string(py3eval('psa6')) +:$put ='s(psa7): '.string(py3eval('psa7')) +:$put ='s(psa8): '.string(py3eval('psa8')) +:$put ='s(psa9): '.string(py3eval('psa9')) +:$put ='s(psaA): '.string(py3eval('psaA')) +:$put ='s(psaB): '.string(py3eval('psaB')) +:$put ='s(psaC): '.string(py3eval('psaC')) +: +:for v in ['sa', 'psa1', 'psa2', 'psa3', 'psa4', 'psa5', 'psa6', 'psa7', 'psa8', 'psa9', 'psaA', 'psaB', 'psaC'] +: let d = {'f': py3eval(v)} +: $put ='d.'.v.'(): '.string(d.f()) +:endfor : :py3 ecall('a()', a, ) :py3 ecall('pa1()', pa1, ) @@ -1020,6 +1055,25 @@ cb.append('psa3.name: ' + s(psa3.name)) cb.append('psa4.name: ' + s(psa4.name)) +cb.append('a.auto_rebind: ' + s(a.auto_rebind)) +cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind)) +cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind)) +cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind)) +cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind)) +cb.append('sa.auto_rebind: ' + s(sa.auto_rebind)) +cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind)) +cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind)) +cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind)) +cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind)) +cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind)) +cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind)) +cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind)) +cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind)) +cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind)) +cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind)) +cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind)) +cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind)) + del s del a @@ -1032,6 +1086,14 @@ del psa2 del psa3 del psa4 +del psa5 +del psa6 +del psa7 +del psa8 +del psa9 +del psaA +del psaB +del psaC del psar del ecall diff -Nru vim-7.4.1830/src/testdir/test87.ok vim-7.4.1907/src/testdir/test87.ok --- vim-7.4.1830/src/testdir/test87.ok 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test87.ok 2016-06-07 20:50:01.000000000 +0000 @@ -448,7 +448,7 @@ range:__dir__,append,end,start dictionary:__dir__,get,has_key,items,keys,locked,pop,popitem,scope,update,values list:__dir__,extend,locked -function:__dir__,args,self,softspace +function:__dir__,args,auto_rebind,self,softspace output:__dir__,close,closed,flush,isatty,readable,seekable,softspace,writable,write,writelines {} {'a': 1} @@ -460,6 +460,12 @@ function('tr') function('tr', {}) function('tr', [123, 3, 4], {}) +auto_rebind +function('tr') +function('tr', [123, 3, 4]) +function('tr') +function('tr', {}) +function('tr', [123, 3, 4], {}) a: pa1: pa2: @@ -470,7 +476,15 @@ psa2: psa3: psa4: -psar: +psa5: +psa6: +psa7: +psa8: +psa9: +psaA: +psaB: +psaC: +psar: s(a): function('Args') s(pa1): function('Args', ['abcArgsPA1']) s(pa2): function('Args') @@ -481,6 +495,27 @@ s(psa2): function('SelfArgs') s(psa3): function('SelfArgs', ['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}) s(psa4): function('SelfArgs', {'abcSelfPSA4': 'abcSelfPSA4Val'}) +s(psa5): function('SelfArgs', {'abcSelfPSA5': 'abcSelfPSA5Val'}) +s(psa6): function('SelfArgs', ['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'}) +s(psa7): function('SelfArgs', ['abcArgsPSA7']) +s(psa8): function('SelfArgs') +s(psa9): function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'}) +s(psaA): function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'}) +s(psaB): function('SelfArgs', ['abcArgsPSAB']) +s(psaC): function('SelfArgs') +d.sa(): [[], {'f': function('SelfArgs')}] +d.psa1(): [['abcArgsPSA1'], {'f': function('SelfArgs', ['abcArgsPSA1'])}] +d.psa2(): [[], {'f': function('SelfArgs')}] +d.psa3(): [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}] +d.psa4(): [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}] +d.psa5(): [[], {'abcSelfPSA5': 'abcSelfPSA5Val'}] +d.psa6(): [['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'}] +d.psa7(): [['abcArgsPSA7'], {'f': function('SelfArgs', ['abcArgsPSA7'])}] +d.psa8(): [[], {'f': function('SelfArgs')}] +d.psa9(): [[], {'f': function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'})}] +d.psaA(): [['abcArgsPSAA'], {'f': function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'})}] +d.psaB(): [['abcArgsPSAB'], {'f': function('SelfArgs', ['abcArgsPSAB'])}] +d.psaC(): [[], {'f': function('SelfArgs')}] a(): !result: [] pa1(): !result: ['abcArgsPA1'] pa2(): !result: [] @@ -551,6 +586,24 @@ psa2.name: 'SelfArgs' psa3.name: 'SelfArgs' psa4.name: 'SelfArgs' +a.auto_rebind: 1 +pa1.auto_rebind: 1 +pa2.auto_rebind: 1 +pa3.auto_rebind: 0 +pa4.auto_rebind: 0 +sa.auto_rebind: 1 +psa1.auto_rebind: 1 +psa2.auto_rebind: 1 +psa3.auto_rebind: 0 +psa4.auto_rebind: 0 +psa5.auto_rebind: 0 +psa6.auto_rebind: 0 +psa7.auto_rebind: 1 +psa8.auto_rebind: 1 +psa9.auto_rebind: 1 +psaA.auto_rebind: 1 +psaB.auto_rebind: 1 +psaC.auto_rebind: 1 ' abcdef Error detected while processing function RunTest[]..Test: diff -Nru vim-7.4.1830/src/testdir/test_alot.vim vim-7.4.1907/src/testdir/test_alot.vim --- vim-7.4.1830/src/testdir/test_alot.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_alot.vim 2016-06-07 20:50:01.000000000 +0000 @@ -32,3 +32,4 @@ source test_timers.vim source test_undolevels.vim source test_unlet.vim +source test_window_cmd.vim diff -Nru vim-7.4.1830/src/testdir/test_autocmd.vim vim-7.4.1907/src/testdir/test_autocmd.vim --- vim-7.4.1830/src/testdir/test_autocmd.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_autocmd.vim 2016-06-07 20:50:01.000000000 +0000 @@ -7,29 +7,56 @@ " becomes one. endfunc -if !has('timers') - finish +if has('timers') + func ExitInsertMode(id) + call feedkeys("\") + endfunc + + func Test_cursorhold_insert() + let g:triggered = 0 + au CursorHoldI * let g:triggered += 1 + set updatetime=20 + call timer_start(100, 'ExitInsertMode') + call feedkeys('a', 'x!') + call assert_equal(1, g:triggered) + endfunc + + func Test_cursorhold_insert_ctrl_x() + let g:triggered = 0 + au CursorHoldI * let g:triggered += 1 + set updatetime=20 + call timer_start(100, 'ExitInsertMode') + " CursorHoldI does not trigger after CTRL-X + call feedkeys("a\", 'x!') + call assert_equal(0, g:triggered) + endfunc endif -func ExitInsertMode(id) - call feedkeys("\") -endfunc +function Test_bufunload() + augroup test_bufunload_group + autocmd! + autocmd BufUnload * call add(s:li, "bufunload") + autocmd BufDelete * call add(s:li, "bufdelete") + autocmd BufWipeout * call add(s:li, "bufwipeout") + augroup END -func Test_cursorhold_insert() - let g:triggered = 0 - au CursorHoldI * let g:triggered += 1 - set updatetime=20 - call timer_start(100, 'ExitInsertMode') - call feedkeys('a', 'x!') - call assert_equal(1, g:triggered) -endfunc + let s:li=[] + new + setlocal bufhidden= + bunload + call assert_equal(["bufunload", "bufdelete"], s:li) + + let s:li=[] + new + setlocal bufhidden=delete + bunload + call assert_equal(["bufunload", "bufdelete"], s:li) + + let s:li=[] + new + setlocal bufhidden=unload + bwipeout + call assert_equal(["bufunload", "bufdelete", "bufwipeout"], s:li) -func Test_cursorhold_insert_ctrl_x() - let g:triggered = 0 - au CursorHoldI * let g:triggered += 1 - set updatetime=20 - call timer_start(100, 'ExitInsertMode') - " CursorHoldI does not trigger after CTRL-X - call feedkeys("a\", 'x!') - call assert_equal(0, g:triggered) + augroup! test_bufunload_group endfunc diff -Nru vim-7.4.1830/src/testdir/test_channel_pipe.py vim-7.4.1907/src/testdir/test_channel_pipe.py --- vim-7.4.1830/src/testdir/test_channel_pipe.py 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_channel_pipe.py 2016-06-07 20:50:01.000000000 +0000 @@ -6,6 +6,7 @@ from __future__ import print_function import sys +import time if __name__ == "__main__": @@ -31,6 +32,15 @@ if typed.startswith("double "): print(typed[7:-1] + "\nAND " + typed[7:-1]) sys.stdout.flush() + if typed.startswith("split "): + print(typed[6:-1], end='') + sys.stdout.flush() + time.sleep(0.05) + print(typed[6:-1], end='') + sys.stdout.flush() + time.sleep(0.05) + print(typed[6:-1]) + sys.stdout.flush() if typed.startswith("echoerr "): print(typed[8:-1], file=sys.stderr) sys.stderr.flush() diff -Nru vim-7.4.1830/src/testdir/test_channel.vim vim-7.4.1907/src/testdir/test_channel.vim --- vim-7.4.1830/src/testdir/test_channel.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_channel.vim 2016-06-07 20:50:01.000000000 +0000 @@ -183,7 +183,7 @@ call assert_equal('got it', s:responseMsg) " Collect garbage, tests that our handle isn't collected. - call garbagecollect_for_testing() + call test_garbagecollect_now() " check setting options (without testing the effect) call ch_setoptions(handle, {'callback': 's:NotUsed'}) @@ -538,6 +538,9 @@ call assert_equal("this", ch_readraw(handle)) call assert_equal("AND this", ch_readraw(handle)) + call ch_sendraw(handle, "split this line\n") + call assert_equal("this linethis linethis line", ch_readraw(handle)) + let reply = ch_evalraw(handle, "quit\n") call assert_equal("Goodbye!", reply) finally @@ -676,12 +679,17 @@ endtry endfunc -func Run_test_pipe_to_buffer(use_name) +func BufCloseCb(ch) + let s:bufClosed = 'yes' +endfunc + +func Run_test_pipe_to_buffer(use_name, nomod) if !has('job') return endif call ch_log('Test_pipe_to_buffer()') - let options = {'out_io': 'buffer'} + let s:bufClosed = 'no' + let options = {'out_io': 'buffer', 'close_cb': 'BufCloseCb'} if a:use_name let options['out_name'] = 'pipe-output' let firstline = 'Reading from channel output...' @@ -691,6 +699,9 @@ quit let firstline = '' endif + if a:nomod + let options['out_modifiable'] = 0 + endif let job = job_start(s:python . " test_channel_pipe.py", options) call assert_equal("run", job_status(job)) try @@ -700,11 +711,14 @@ call ch_sendraw(handle, "double this\n") call ch_sendraw(handle, "quit\n") sp pipe-output - call s:waitFor('line("$") >= 6') - if getline('$') == 'DETACH' - $del - endif + call s:waitFor('line("$") >= 6 && s:bufClosed == "yes"') call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this', 'Goodbye!'], getline(1, '$')) + if a:nomod + call assert_equal(0, &modifiable) + else + call assert_equal(1, &modifiable) + endif + call assert_equal('yes', s:bufClosed) bwipe! finally call job_stop(job) @@ -712,14 +726,18 @@ endfunc func Test_pipe_to_buffer_name() - call Run_test_pipe_to_buffer(1) + call Run_test_pipe_to_buffer(1, 0) endfunc func Test_pipe_to_buffer_nr() - call Run_test_pipe_to_buffer(0) + call Run_test_pipe_to_buffer(0, 0) endfunc -func Run_test_pipe_err_to_buffer(use_name) +func Test_pipe_to_buffer_name_nomod() + call Run_test_pipe_to_buffer(1, 1) +endfunc + +func Run_test_pipe_err_to_buffer(use_name, nomod) if !has('job') return endif @@ -734,6 +752,9 @@ quit let firstline = '' endif + if a:nomod + let options['err_modifiable'] = 0 + endif let job = job_start(s:python . " test_channel_pipe.py", options) call assert_equal("run", job_status(job)) try @@ -745,6 +766,11 @@ sp pipe-err call s:waitFor('line("$") >= 5') call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this'], getline(1, '$')) + if a:nomod + call assert_equal(0, &modifiable) + else + call assert_equal(1, &modifiable) + endif bwipe! finally call job_stop(job) @@ -752,11 +778,15 @@ endfunc func Test_pipe_err_to_buffer_name() - call Run_test_pipe_err_to_buffer(1) + call Run_test_pipe_err_to_buffer(1, 0) endfunc func Test_pipe_err_to_buffer_nr() - call Run_test_pipe_err_to_buffer(0) + call Run_test_pipe_err_to_buffer(0, 0) +endfunc + +func Test_pipe_err_to_buffer_name_nomod() + call Run_test_pipe_err_to_buffer(1, 1) endfunc func Test_pipe_both_to_buffer() @@ -1302,7 +1332,7 @@ func Test_using_freed_memory() let g:a = job_start(['ls']) sleep 10m - call garbagecollect_for_testing() + call test_garbagecollect_now() endfunc diff -Nru vim-7.4.1830/src/testdir/test_cursor_func.vim vim-7.4.1907/src/testdir/test_cursor_func.vim --- vim-7.4.1830/src/testdir/test_cursor_func.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_cursor_func.vim 2016-06-07 20:50:01.000000000 +0000 @@ -44,9 +44,9 @@ new call setline(1, ['func()', '{', '}', '----']) autocmd! CursorMovedI * call s:Highlight_Matching_Pair() - call disable_char_avail_for_testing(1) + call test_disable_char_avail(1) exe "normal! 3Ga\X\" - call disable_char_avail_for_testing(0) + call test_disable_char_avail(0) call assert_equal('-X---', getline(4)) autocmd! CursorMovedI * quit! diff -Nru vim-7.4.1830/src/testdir/test_expr.vim vim-7.4.1907/src/testdir/test_expr.vim --- vim-7.4.1830/src/testdir/test_expr.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_expr.vim 2016-06-07 20:50:01.000000000 +0000 @@ -85,8 +85,19 @@ endfunc func Test_loop_over_null_list() - let null_list = submatch(1, 1) + let null_list = test_null_list() for i in null_list call assert_true(0, 'should not get here') endfor endfunc + +func Test_compare_null_dict() + call assert_fails('let x = test_null_dict()[10]') + call assert_equal({}, {}) + call assert_equal(test_null_dict(), test_null_dict()) + call assert_notequal({}, test_null_dict()) +endfunc + +func Test_set_reg_null_list() + call setreg('x', test_null_list()) +endfunc diff -Nru vim-7.4.1830/src/testdir/test_help_tagjump.vim vim-7.4.1907/src/testdir/test_help_tagjump.vim --- vim-7.4.1830/src/testdir/test_help_tagjump.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_help_tagjump.vim 2016-06-07 20:50:01.000000000 +0000 @@ -25,6 +25,16 @@ call assert_equal("help", &filetype) call assert_true(getline('.') =~ '\*arglistid()\*') helpclose + + exec "help! 'autoindent'." + call assert_equal("help", &filetype) + call assert_true(getline('.') =~ "\\*'autoindent'\\*") + helpclose + + exec "help! {address}." + call assert_equal("help", &filetype) + call assert_true(getline('.') =~ '\*{address}\*') + helpclose endfunc let s:langs = ['en', 'ab', 'ja'] diff -Nru vim-7.4.1830/src/testdir/test_packadd.vim vim-7.4.1907/src/testdir/test_packadd.vim --- vim-7.4.1830/src/testdir/test_packadd.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_packadd.vim 2016-06-07 20:50:01.000000000 +0000 @@ -13,6 +13,7 @@ func Test_packadd() call mkdir(s:plugdir . '/plugin/also', 'p') call mkdir(s:plugdir . '/ftdetect', 'p') + call mkdir(s:plugdir . '/after', 'p') set rtp& let rtp = &rtp filetype on @@ -35,7 +36,8 @@ call assert_equal(77, g:plugin_also_works) call assert_equal(17, g:ftdetect_works) call assert_true(len(&rtp) > len(rtp)) - call assert_true(&rtp =~ 'testdir/Xdir/pack/mine/opt/mytest\($\|,\)') + call assert_true(&rtp =~ '/testdir/Xdir/pack/mine/opt/mytest\($\|,\)') + call assert_true(&rtp =~ '/testdir/Xdir/pack/mine/opt/mytest/after$') " Check exception call assert_fails("packadd directorynotfound", 'E919:') diff -Nru vim-7.4.1830/src/testdir/test_partial.vim vim-7.4.1907/src/testdir/test_partial.vim --- vim-7.4.1830/src/testdir/test_partial.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_partial.vim 2016-06-07 20:50:01.000000000 +0000 @@ -250,6 +250,25 @@ endif endfunc +func Test_job_start_fails() + if has('job') + let job = job_start('axdfxsdf') + for i in range(100) + let status = job_status(job) + if status == 'dead' || status == 'fail' + break + endif + sleep 10m + endfor + if has('unix') + call assert_equal('dead', job_status(job)) + else + call assert_equal('fail', job_status(job)) + endif + unlet job + endif +endfunc + func Test_ref_job_partial_dict() if has('job') let g:ref_job = job_start('echo') @@ -257,3 +276,106 @@ call job_setoptions(g:ref_job, {'exit_cb': function('string', [], d)}) endif endfunc + +func Test_auto_partial_rebind() + let dict1 = {'name': 'dict1'} + func! dict1.f1() + return self.name + endfunc + let dict1.f2 = function(dict1.f1, dict1) + + call assert_equal('dict1', dict1.f1()) + call assert_equal('dict1', dict1['f1']()) + call assert_equal('dict1', dict1.f2()) + call assert_equal('dict1', dict1['f2']()) + + let dict2 = {'name': 'dict2'} + let dict2.f1 = dict1.f1 + let dict2.f2 = dict1.f2 + + call assert_equal('dict2', dict2.f1()) + call assert_equal('dict2', dict2['f1']()) + call assert_equal('dict1', dict2.f2()) + call assert_equal('dict1', dict2['f2']()) +endfunc + +func Test_get_partial_items() + let dict = {'name': 'hello'} + let args = ["foo", "bar"] + let Func = function('MyDictFunc') + let Cb = function('MyDictFunc', args, dict) + + call assert_equal(Func, get(Cb, 'func')) + call assert_equal('MyDictFunc', get(Cb, 'name')) + call assert_equal(args, get(Cb, 'args')) + call assert_equal(dict, get(Cb, 'dict')) + call assert_fails('call get(Cb, "xxx")', 'E475:') + + call assert_equal(Func, get(Func, 'func')) + call assert_equal('MyDictFunc', get(Func, 'name')) + call assert_equal([], get(Func, 'args')) + call assert_true(empty( get(Func, 'dict'))) +endfunc + +func Test_compare_partials() + let d1 = {} + let d2 = {} + + function d1.f1() dict + endfunction + + function d1.f2() dict + endfunction + + let F1 = get(d1, 'f1') + let F2 = get(d1, 'f2') + + let F1d1 = function(F1, d1) + let F2d1 = function(F2, d2) + let F1d1a1 = function(F1d1, [1]) + let F1d1a12 = function(F1d1, [1, 2]) + let F1a1 = function(F1, [1]) + let F1a2 = function(F1, [2]) + let F1d2 = function(F1, d2) + let d3 = {'f1': F1, 'f2': F2} + let F1d3 = function(F1, d3) + let F1ad1 = function(F1, [d1]) + let F1ad3 = function(F1, [d3]) + + call assert_match('^function(''\d\+'')$', string(F1)) " Not a partial + call assert_match('^function(''\d\+'')$', string(F2)) " Not a partial + call assert_match('^function(''\d\+'', {.*})$', string(F1d1)) " A partial + call assert_match('^function(''\d\+'', {.*})$', string(F2d1)) " A partial + call assert_match('^function(''\d\+'', \[.*\])$', string(F1a1)) " No dict + + " != + let X = F1 + call assert_false(F1 != X) " same function + let X = F1d1 + call assert_false(F1d1 != X) " same partial + let X = F1d1a1 + call assert_false(F1d1a1 != X) " same partial + let X = F1a1 + call assert_false(F1a1 != X) " same partial + + call assert_true(F1 != F2) " Different functions + call assert_true(F1 != F1d1) " Partial /= non-partial + call assert_true(F1d1a1 != F1d1a12) " Different number of arguments + call assert_true(F1a1 != F1d1a12) " One has no dict + call assert_true(F1a1 != F1a2) " Different arguments + call assert_true(F1d2 != F1d1) " Different dictionaries + call assert_false(F1d1 != F1d3) " Equal dictionaries, even though d1 isnot d3 + + " isnot, option 1 + call assert_true(F1 isnot# F2) " Different functions + call assert_true(F1 isnot# F1d1) " Partial /= non-partial + call assert_true(F1d1 isnot# F1d3) " d1 isnot d3, even though d1 == d3 + call assert_true(F1a1 isnot# F1d1a12) " One has no dict + call assert_true(F1a1 isnot# F1a2) " Different number of arguments + call assert_true(F1ad1 isnot# F1ad3) " In arguments d1 isnot d3 + + " isnot, option 2 + call assert_true(F1 isnot# F2) " Different functions + call assert_true(F1 isnot# F1d1) " Partial /= non-partial + call assert_true(d1.f1 isnot# d1.f1) " handle_subscript creates new partial each time +endfunc diff -Nru vim-7.4.1830/src/testdir/test_quickfix.vim vim-7.4.1907/src/testdir/test_quickfix.vim --- vim-7.4.1830/src/testdir/test_quickfix.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_quickfix.vim 2016-06-07 20:50:01.000000000 +0000 @@ -280,19 +280,19 @@ endfunction function Test_nomem() - call alloc_fail(GetAllocId('qf_dirname_start'), 0, 0) + call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0) call assert_fails('vimgrep vim runtest.vim', 'E342:') - call alloc_fail(GetAllocId('qf_dirname_now'), 0, 0) + call test_alloc_fail(GetAllocId('qf_dirname_now'), 0, 0) call assert_fails('vimgrep vim runtest.vim', 'E342:') - call alloc_fail(GetAllocId('qf_namebuf'), 0, 0) + call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0) call assert_fails('cfile runtest.vim', 'E342:') - call alloc_fail(GetAllocId('qf_errmsg'), 0, 0) + call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0) call assert_fails('cfile runtest.vim', 'E342:') - call alloc_fail(GetAllocId('qf_pattern'), 0, 0) + call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0) call assert_fails('cfile runtest.vim', 'E342:') endfunc @@ -700,14 +700,14 @@ " Tests for the setqflist() and setloclist() functions function SetXlistTests(cchar, bnum) + let Xwindow = a:cchar . 'window' + let Xnext = a:cchar . 'next' if a:cchar == 'c' let Xsetlist = function('setqflist') let Xgetlist = function('getqflist') - let Xnext = 'cnext' else let Xsetlist = function('setloclist', [0]) let Xgetlist = function('getloclist', [0]) - let Xnext = 'lnext' endif call Xsetlist([{'bufnr': a:bnum, 'lnum': 1}, @@ -723,6 +723,15 @@ exe Xnext call assert_equal(3, line('.')) + " Appending entries to the list should not change the cursor position + " in the quickfix window + exe Xwindow + 1 + call Xsetlist([{'bufnr': a:bnum, 'lnum': 4}, + \ {'bufnr': a:bnum, 'lnum': 5}], 'a') + call assert_equal(1, line('.')) + close + call Xsetlist([{'bufnr': a:bnum, 'lnum': 3}, \ {'bufnr': a:bnum, 'lnum': 4}, \ {'bufnr': a:bnum, 'lnum': 5}], 'r') diff -Nru vim-7.4.1830/src/testdir/test_reltime.vim vim-7.4.1907/src/testdir/test_reltime.vim --- vim-7.4.1830/src/testdir/test_reltime.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_reltime.vim 2016-06-07 20:50:01.000000000 +0000 @@ -23,5 +23,4 @@ call assert_true(reltimestr(differs) != '0.0') call assert_true(reltimefloat(differs) < 0.1) call assert_true(reltimefloat(differs) > 0.0) - endfunc diff -Nru vim-7.4.1830/src/testdir/test_syn_attr.vim vim-7.4.1907/src/testdir/test_syn_attr.vim --- vim-7.4.1830/src/testdir/test_syn_attr.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_syn_attr.vim 2016-06-07 20:50:01.000000000 +0000 @@ -27,7 +27,7 @@ if fontname == '' let fontname = 'something' endif - exe 'hi Mine guifg=blue guibg=red font=' . escape(fontname, ' \') + exe "hi Mine guifg=blue guibg=red font='" . fontname . "'" call assert_equal('blue', synIDattr(hlID("Mine"), "fg", 'gui')) call assert_equal('red', synIDattr(hlID("Mine"), "bg", 'gui')) call assert_equal(fontname, synIDattr(hlID("Mine"), "font", 'gui')) diff -Nru vim-7.4.1830/src/testdir/test_tagjump.vim vim-7.4.1907/src/testdir/test_tagjump.vim --- vim-7.4.1830/src/testdir/test_tagjump.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_tagjump.vim 2016-06-07 20:50:01.000000000 +0000 @@ -6,4 +6,5 @@ call assert_fails('ptag does_not_exist_tag_name', 'E426') set tagstack&vim endfunc + " vim: sw=2 et diff -Nru vim-7.4.1830/src/testdir/test_timers.vim vim-7.4.1907/src/testdir/test_timers.vim --- vim-7.4.1830/src/testdir/test_timers.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_timers.vim 2016-06-07 20:50:01.000000000 +0000 @@ -8,6 +8,10 @@ let s:val += 1 endfunc +func MyHandlerWithLists(lists, timer) + let x = string(a:lists) +endfunc + func Test_oneshot() let s:val = 0 let timer = timer_start(50, 'MyHandler') @@ -42,4 +46,10 @@ sleep 200m call assert_equal(1, s:val) endfunc + +func Test_retain_partial() + call timer_start(100, function('MyHandlerWithLists', [['a']])) + call test_garbagecollect_now() + sleep 200m +endfunc " vim: ts=2 sw=0 et diff -Nru vim-7.4.1830/src/testdir/test_usercommands.vim vim-7.4.1907/src/testdir/test_usercommands.vim --- vim-7.4.1830/src/testdir/test_usercommands.vim 1970-01-01 00:00:00.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_usercommands.vim 2016-06-07 20:50:01.000000000 +0000 @@ -0,0 +1,48 @@ +" Tests for user defined commands + +" Test for in user defined commands +function Test_cmdmods() + let g:mods = '' + + command! -nargs=* MyCmd let g:mods .= ' ' + + MyCmd + aboveleft MyCmd + belowright MyCmd + botright MyCmd + browse MyCmd + confirm MyCmd + hide MyCmd + keepalt MyCmd + keepjumps MyCmd + keepmarks MyCmd + keeppatterns MyCmd + lockmarks MyCmd + noswapfile MyCmd + silent MyCmd + tab MyCmd + topleft MyCmd + verbose MyCmd + vertical MyCmd + + aboveleft belowright botright browse confirm hide keepalt keepjumps + \ keepmarks keeppatterns lockmarks noswapfile silent tab + \ topleft verbose vertical MyCmd + + call assert_equal(' aboveleft belowright botright browse confirm ' . + \ 'hide keepalt keepjumps keepmarks keeppatterns lockmarks ' . + \ 'noswapfile silent tab topleft verbose vertical aboveleft ' . + \ 'belowright botright browse confirm hide keepalt keepjumps ' . + \ 'keepmarks keeppatterns lockmarks noswapfile silent tab topleft ' . + \ 'verbose vertical ', g:mods) + + let g:mods = '' + command! -nargs=* MyQCmd let g:mods .= ' ' + + vertical MyQCmd + call assert_equal('"vertical" ', g:mods) + + delcommand MyCmd + delcommand MyQCmd + unlet g:mods +endfunction diff -Nru vim-7.4.1830/src/testdir/test_viminfo.vim vim-7.4.1907/src/testdir/test_viminfo.vim --- vim-7.4.1830/src/testdir/test_viminfo.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_viminfo.vim 2016-06-07 20:50:01.000000000 +0000 @@ -1,6 +1,7 @@ " Test for reading and writing .viminfo function Test_read_and_write() + call histdel(':') let lines = [ \ '# comment line', \ '*encoding=utf-8', @@ -18,14 +19,16 @@ for line in lines if line[0] == '|' if done == 0 - call assert_equal('|copied as-is', line) + call assert_equal('|1,2', line) elseif done == 1 + call assert_equal('|copied as-is', line) + elseif done == 2 call assert_equal('|and one more', line) endif let done += 1 endif endfor - call assert_equal(2, done) + call assert_equal(3, done) call delete('Xviminfo') endfunc @@ -48,3 +51,68 @@ call delete('Xviminfo') set viminfo-=! endfunc + +func Test_cmdline_history() + call histdel(':') + call test_settime(11) + call histadd(':', "echo 'one'") + call test_settime(12) + " split into two lines + let long800 = repeat(" 'eight'", 100) + call histadd(':', "echo " . long800) + call test_settime(13) + " split into three lines + let long1400 = repeat(" 'fourteeeeen'", 100) + call histadd(':', "echo " . long1400) + wviminfo Xviminfo + let lines = readfile('Xviminfo') + let done_colon = 0 + let done_bar = 0 + let lnum = 0 + while lnum < len(lines) + let line = lines[lnum] | let lnum += 1 + if line[0] == ':' + if done_colon == 0 + call assert_equal(":\x161408", line) + let line = lines[lnum] | let lnum += 1 + call assert_equal('1407", line) + let line = lines[lnum] | let lnum += 1 + call assert_equal('|<"echo ' . long1400[0:484], line) + let line = lines[lnum] | let lnum += 1 + call assert_equal('|<' . long1400[485:974], line) + let line = lines[lnum] | let lnum += 1 + call assert_equal('|<' . long1400[975:] . '"', line) + elseif done_bar == 1 + call assert_equal('|2,0,12,,>807', line) + let line = lines[lnum] | let lnum += 1 + call assert_equal('|<"echo ' . long800[0:484], line) + let line = lines[lnum] | let lnum += 1 + call assert_equal('|<' . long800[485:] . '"', line) + elseif done_bar == 2 + call assert_equal("|2,0,11,,\"echo 'one'\"", line) + endif + let done_bar += 1 + endif + endwhile + call assert_equal(3, done_colon) + call assert_equal(3, done_bar) + + call histdel(':') + rviminfo Xviminfo + call assert_equal("echo " . long1400, histget(':', -1)) + call assert_equal("echo " . long800, histget(':', -2)) + call assert_equal("echo 'one'", histget(':', -3)) + + call delete('Xviminfo') +endfunc diff -Nru vim-7.4.1830/src/testdir/test_viml.vim vim-7.4.1907/src/testdir/test_viml.vim --- vim-7.4.1830/src/testdir/test_viml.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_viml.vim 2016-06-07 20:50:01.000000000 +0000 @@ -1053,6 +1053,150 @@ endfunc "------------------------------------------------------------------------------- +" Test 93: :echo and string() {{{1 +"------------------------------------------------------------------------------- + +func Test_echo_and_string() + " String + let a = 'foo bar' + redir => result + echo a + echo string(a) + redir END + let l = split(result, "\n") + call assert_equal(["foo bar", + \ "'foo bar'"], l) + + " Float + if has('float') + let a = -1.2e0 + redir => result + echo a + echo string(a) + redir END + let l = split(result, "\n") + call assert_equal(["-1.2", + \ "-1.2"], l) + endif + + " Funcref + redir => result + echo function('string') + echo string(function('string')) + redir END + let l = split(result, "\n") + call assert_equal(["string", + \ "function('string')"], l) + + " Recursive dictionary + let a = {} + let a["a"] = a + redir => result + echo a + echo string(a) + redir END + let l = split(result, "\n") + call assert_equal(["{'a': {...}}", + \ "{'a': {...}}"], l) + + " Recursive list + let a = [0] + let a[0] = a + redir => result + echo a + echo string(a) + redir END + let l = split(result, "\n") + call assert_equal(["[[...]]", + \ "[[...]]"], l) + + " Empty dictionaries in a list + let a = {} + redir => result + echo [a, a, a] + echo string([a, a, a]) + redir END + let l = split(result, "\n") + call assert_equal(["[{}, {}, {}]", + \ "[{}, {}, {}]"], l) + + " Empty dictionaries in a dictionary + let a = {} + let b = {"a": a, "b": a} + redir => result + echo b + echo string(b) + redir END + let l = split(result, "\n") + call assert_equal(["{'a': {}, 'b': {}}", + \ "{'a': {}, 'b': {}}"], l) + + " Empty lists in a list + let a = [] + redir => result + echo [a, a, a] + echo string([a, a, a]) + redir END + let l = split(result, "\n") + call assert_equal(["[[], [], []]", + \ "[[], [], []]"], l) + + " Empty lists in a dictionary + let a = [] + let b = {"a": a, "b": a} + redir => result + echo b + echo string(b) + redir END + let l = split(result, "\n") + call assert_equal(["{'a': [], 'b': []}", + \ "{'a': [], 'b': []}"], l) + + " Dictionaries in a list + let a = {"one": "yes", "two": "yes", "three": "yes"} + redir => result + echo [a, a, a] + echo string([a, a, a]) + redir END + let l = split(result, "\n") + call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, {...}]", + \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}]"], l) + + " Dictionaries in a dictionary + let a = {"one": "yes", "two": "yes", "three": "yes"} + let b = {"a": a, "b": a} + redir => result + echo b + echo string(b) + redir END + let l = split(result, "\n") + call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {...}}", + \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l) + + " Lists in a list + let a = [1, 2, 3] + redir => result + echo [a, a, a] + echo string([a, a, a]) + redir END + let l = split(result, "\n") + call assert_equal(["[[1, 2, 3], [...], [...]]", + \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l) + + " Lists in a dictionary + let a = [1, 2, 3] + let b = {"a": a, "b": a} + redir => result + echo b + echo string(b) + redir END + let l = split(result, "\n") + call assert_equal(["{'a': [1, 2, 3], 'b': [...]}", + \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l) + +endfunc + +"------------------------------------------------------------------------------- " Modelines {{{1 " vim: ts=8 sw=4 tw=80 fdm=marker " vim: fdt=substitute(substitute(foldtext(),\ '\\%(^+--\\)\\@<=\\(\\s*\\)\\(.\\{-}\\)\:\ \\%(\"\ \\)\\=\\(Test\ \\d*\\)\:\\s*',\ '\\3\ (\\2)\:\ \\1',\ \"\"),\ '\\(Test\\s*\\)\\(\\d\\)\\D\\@=',\ '\\1\ \\2',\ "") diff -Nru vim-7.4.1830/src/testdir/test_window_cmd.vim vim-7.4.1907/src/testdir/test_window_cmd.vim --- vim-7.4.1830/src/testdir/test_window_cmd.vim 1970-01-01 00:00:00.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_window_cmd.vim 2016-06-07 20:50:01.000000000 +0000 @@ -0,0 +1,37 @@ +" Tests for window cmd (:wincmd, :split, :vsplit, :resize and etc...) + +func Test_window_cmd_ls0_with_split() + set ls=0 + set splitbelow + split + quit + call assert_equal(0, &lines - &cmdheight - winheight(0)) + new | only! + " + set splitbelow&vim + botright split + quit + call assert_equal(0, &lines - &cmdheight - winheight(0)) + new | only! + set ls&vim +endfunc + +func Test_window_cmd_cmdwin_with_vsp() + let efmt='Expected 0 but got %d (in ls=%d, %s window)' + for v in range(0, 2) + exec "set ls=" . v + vsplit + call feedkeys("q:\") + let ac = &lines - (&cmdheight + winheight(0) + !!v) + let emsg = printf(efmt, ac, v, 'left') + call assert_equal(0, ac, emsg) + wincmd w + let ac = &lines - (&cmdheight + winheight(0) + !!v) + let emsg = printf(efmt, ac, v, 'right') + call assert_equal(0, ac, emsg) + new | only! + endfor + set ls&vim +endfunc + +" vim: sw=2 et diff -Nru vim-7.4.1830/src/testdir/test_window_id.vim vim-7.4.1907/src/testdir/test_window_id.vim --- vim-7.4.1830/src/testdir/test_window_id.vim 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/testdir/test_window_id.vim 2016-06-07 20:50:01.000000000 +0000 @@ -3,17 +3,22 @@ func Test_win_getid() edit one let id1 = win_getid() + let w:one = 'one' split two let id2 = win_getid() let bufnr2 = bufnr('%') + let w:two = 'two' split three let id3 = win_getid() + let w:three = 'three' tabnew edit four let id4 = win_getid() + let w:four = 'four' split five let id5 = win_getid() let bufnr5 = bufnr('%') + let w:five = 'five' tabnext wincmd w @@ -28,6 +33,9 @@ call assert_equal("three", expand("%")) call assert_equal(id3, win_getid()) let nr3 = winnr() + call assert_equal('one', getwinvar(id1, 'one')) + call assert_equal('two', getwinvar(id2, 'two')) + call assert_equal('three', getwinvar(id3, 'three')) tabnext call assert_equal("five", expand("%")) call assert_equal(id5, win_getid()) @@ -36,7 +44,14 @@ call assert_equal("four", expand("%")) call assert_equal(id4, win_getid()) let nr4 = winnr() + call assert_equal('four', getwinvar(id4, 'four')) + call assert_equal('five', getwinvar(id5, 'five')) + call settabwinvar(1, id2, 'two', '2') + call setwinvar(id4, 'four', '4') tabnext + call assert_equal('4', gettabwinvar(2, id4, 'four')) + call assert_equal('five', gettabwinvar(2, id5, 'five')) + call assert_equal('2', getwinvar(id2, 'two')) exe nr1 . "wincmd w" call assert_equal(id1, win_getid()) diff -Nru vim-7.4.1830/src/version.c vim-7.4.1907/src/version.c --- vim-7.4.1830/src/version.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/version.c 2016-06-07 20:50:01.000000000 +0000 @@ -754,6 +754,160 @@ static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1907, +/**/ + 1906, +/**/ + 1905, +/**/ + 1904, +/**/ + 1903, +/**/ + 1902, +/**/ + 1901, +/**/ + 1900, +/**/ + 1899, +/**/ + 1898, +/**/ + 1897, +/**/ + 1896, +/**/ + 1895, +/**/ + 1894, +/**/ + 1893, +/**/ + 1892, +/**/ + 1891, +/**/ + 1890, +/**/ + 1889, +/**/ + 1888, +/**/ + 1887, +/**/ + 1886, +/**/ + 1885, +/**/ + 1884, +/**/ + 1883, +/**/ + 1882, +/**/ + 1881, +/**/ + 1880, +/**/ + 1879, +/**/ + 1878, +/**/ + 1877, +/**/ + 1876, +/**/ + 1875, +/**/ + 1874, +/**/ + 1873, +/**/ + 1872, +/**/ + 1871, +/**/ + 1870, +/**/ + 1869, +/**/ + 1868, +/**/ + 1867, +/**/ + 1866, +/**/ + 1865, +/**/ + 1864, +/**/ + 1863, +/**/ + 1862, +/**/ + 1861, +/**/ + 1860, +/**/ + 1859, +/**/ + 1858, +/**/ + 1857, +/**/ + 1856, +/**/ + 1855, +/**/ + 1854, +/**/ + 1853, +/**/ + 1852, +/**/ + 1851, +/**/ + 1850, +/**/ + 1849, +/**/ + 1848, +/**/ + 1847, +/**/ + 1846, +/**/ + 1845, +/**/ + 1844, +/**/ + 1843, +/**/ + 1842, +/**/ + 1841, +/**/ + 1840, +/**/ + 1839, +/**/ + 1838, +/**/ + 1837, +/**/ + 1836, +/**/ + 1835, +/**/ + 1834, +/**/ + 1833, +/**/ + 1832, +/**/ + 1831, +/**/ 1830, /**/ 1829, @@ -5013,7 +5167,7 @@ if (*mesg == ' ') { vim_strncpy(modby, (char_u *)_("Modified by "), MODBY_LEN - 1); - l = STRLEN(modby); + l = (int)STRLEN(modby); vim_strncpy(modby + l, (char_u *)MODIFIED_BY, MODBY_LEN - l - 1); mesg = modby; } diff -Nru vim-7.4.1830/src/vim.h vim-7.4.1907/src/vim.h --- vim-7.4.1830/src/vim.h 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/vim.h 2016-06-07 20:50:01.000000000 +0000 @@ -907,9 +907,10 @@ #define GETF_SWITCH 0x04 /* respect 'switchbuf' settings when jumping */ /* Values for buflist_new() flags */ -#define BLN_CURBUF 1 /* May re-use curbuf for new buffer */ -#define BLN_LISTED 2 /* Put new buffer in buffer list */ -#define BLN_DUMMY 4 /* Allocating dummy buffer */ +#define BLN_CURBUF 1 /* may re-use curbuf for new buffer */ +#define BLN_LISTED 2 /* put new buffer in buffer list */ +#define BLN_DUMMY 4 /* allocating dummy buffer */ +#define BLN_NEW 8 /* create a new buffer */ /* Values for in_cinkeys() */ #define KEY_OPEN_FORW 0x101 @@ -1062,7 +1063,7 @@ #define OPENLINE_COM_LIST 16 /* format comments with list/2nd line indent */ /* - * There are four history tables: + * There are five history tables: */ #define HIST_CMD 0 /* colon commands */ #define HIST_SEARCH 1 /* search commands */ @@ -1071,6 +1072,26 @@ #define HIST_DEBUG 4 /* debug commands */ #define HIST_COUNT 5 /* number of history tables */ +/* The type numbers are fixed for backwards compatibility. */ +#define BARTYPE_VERSION 1 +#define BARTYPE_HISTORY 2 + +typedef enum { + BVAL_NR, + BVAL_STRING, + BVAL_EMPTY +} btype_T; + +#define BVAL_MAX 4 /* Maximum number of fields in a barline. */ + +typedef struct { + btype_T bv_type; + long bv_nr; + char_u *bv_string; + int bv_len; /* length of bv_string */ + int bv_allocated; /* bv_string was allocated */ +} bval_T; + /* * Values for do_tag(). */ @@ -1876,35 +1897,37 @@ #define VV_FCS_CHOICE 38 #define VV_BEVAL_BUFNR 39 #define VV_BEVAL_WINNR 40 -#define VV_BEVAL_LNUM 41 -#define VV_BEVAL_COL 42 -#define VV_BEVAL_TEXT 43 -#define VV_SCROLLSTART 44 -#define VV_SWAPNAME 45 -#define VV_SWAPCHOICE 46 -#define VV_SWAPCOMMAND 47 -#define VV_CHAR 48 -#define VV_MOUSE_WIN 49 -#define VV_MOUSE_LNUM 50 -#define VV_MOUSE_COL 51 -#define VV_OP 52 -#define VV_SEARCHFORWARD 53 -#define VV_HLSEARCH 54 -#define VV_OLDFILES 55 -#define VV_WINDOWID 56 -#define VV_PROGPATH 57 -#define VV_COMPLETED_ITEM 58 -#define VV_OPTION_NEW 59 -#define VV_OPTION_OLD 60 -#define VV_OPTION_TYPE 61 -#define VV_ERRORS 62 -#define VV_FALSE 63 -#define VV_TRUE 64 -#define VV_NULL 65 -#define VV_NONE 66 -#define VV_VIM_DID_ENTER 67 -#define VV_TESTING 68 -#define VV_LEN 69 /* number of v: vars */ +#define VV_BEVAL_WINID 41 +#define VV_BEVAL_LNUM 42 +#define VV_BEVAL_COL 43 +#define VV_BEVAL_TEXT 44 +#define VV_SCROLLSTART 45 +#define VV_SWAPNAME 46 +#define VV_SWAPCHOICE 47 +#define VV_SWAPCOMMAND 48 +#define VV_CHAR 49 +#define VV_MOUSE_WIN 50 +#define VV_MOUSE_WINID 51 +#define VV_MOUSE_LNUM 52 +#define VV_MOUSE_COL 53 +#define VV_OP 54 +#define VV_SEARCHFORWARD 55 +#define VV_HLSEARCH 56 +#define VV_OLDFILES 57 +#define VV_WINDOWID 58 +#define VV_PROGPATH 59 +#define VV_COMPLETED_ITEM 60 +#define VV_OPTION_NEW 61 +#define VV_OPTION_OLD 62 +#define VV_OPTION_TYPE 63 +#define VV_ERRORS 64 +#define VV_FALSE 65 +#define VV_TRUE 66 +#define VV_NULL 67 +#define VV_NONE 68 +#define VV_VIM_DID_ENTER 69 +#define VV_TESTING 70 +#define VV_LEN 71 /* number of v: vars */ /* used for v_number in VAR_SPECIAL */ #define VVAL_FALSE 0L @@ -2331,4 +2354,7 @@ #define DIP_OPT 0x10 /* also use "opt" directory in 'packpath' */ #define DIP_NORTP 0x20 /* do not use 'runtimepath' */ +/* Lowest number used for window ID. Cannot have this many windows. */ +#define LOWEST_WIN_ID 1000 + #endif /* VIM__H */ diff -Nru vim-7.4.1830/src/VisVim/Commands.cpp vim-7.4.1907/src/VisVim/Commands.cpp --- vim-7.4.1830/src/VisVim/Commands.cpp 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/VisVim/Commands.cpp 2016-06-07 20:50:01.000000000 +0000 @@ -575,7 +575,7 @@ if (LineNr > 0) { // Goto line - sprintf(VimCmd, ":%d\n", LineNr); + sprintf(VimCmd, ":%ld\n", LineNr); if (! VimOle.Method(DispatchId, "s", TO_OLE_STR_BUF(VimCmd, Buf))) goto OleError; } diff -Nru vim-7.4.1830/src/window.c vim-7.4.1907/src/window.c --- vim-7.4.1830/src/window.c 2016-05-11 19:05:05.000000000 +0000 +++ vim-7.4.1907/src/window.c 2016-06-07 20:50:01.000000000 +0000 @@ -1165,8 +1165,13 @@ * one row for the status line */ win_new_height(wp, new_size); if (flags & (WSP_TOP | WSP_BOT)) - frame_new_height(curfrp, curfrp->fr_height - - (new_size + STATUS_HEIGHT), flags & WSP_TOP, FALSE); + { + int new_fr_height = curfrp->fr_height - new_size; + + if (!((flags & WSP_BOT) && p_ls == 0)) + new_fr_height -= STATUS_HEIGHT; + frame_new_height(curfrp, new_fr_height, flags & WSP_TOP, FALSE); + } else win_new_height(oldwin, oldwin_height - (new_size + STATUS_HEIGHT)); if (before) /* new window above current one */ @@ -1179,18 +1184,13 @@ { wp->w_winrow = oldwin->w_winrow + oldwin->w_height + STATUS_HEIGHT; wp->w_status_height = oldwin->w_status_height; - /* Don't set the status_height for oldwin yet, this might break - * frame_fix_height(oldwin), therefore will be set below. */ + if (!(flags & WSP_BOT)) + oldwin->w_status_height = STATUS_HEIGHT; } if (flags & WSP_BOT) frame_add_statusline(curfrp); frame_fix_height(wp); frame_fix_height(oldwin); - - if (!before) - /* new window above current one, set the status_height after - * frame_fix_height(oldwin) */ - oldwin->w_status_height = STATUS_HEIGHT; } if (flags & (WSP_TOP | WSP_BOT)) @@ -4422,7 +4422,7 @@ } #endif -static int last_win_id = 0; +static int last_win_id = LOWEST_WIN_ID - 1; /* * Allocate a window structure and link it in the window list when "hidden" is