Compare commits

...

121 Commits

Author SHA1 Message Date
Kazuki Sakamoto 4f87e76866 MacVim Snapshot 100
Binary targets OS X 10.8(Mountain Lion), 10.9(Mavericks), 10.10(Yosemite), and 10.11(El Capitan)

- Vim patch 7.4.1655

Script interfaces have compatibility with these versions

- Lua 5.2
- Perl 5.16
- Python2 2.7
- Python3 3.5
- Ruby 2.0
2016-03-25 23:33:20 -07:00
Kazuki Sakamoto 17d68e17b6 Use Xcode 7.3 on Travis-CI 2016-03-25 23:03:43 -07:00
Kazuki Sakamoto 7826fd71e1 Merge remote-tracking branch 'vim/master' 2016-03-25 20:51:06 -07:00
Bram Moolenaar 1e7885abe8 patch 7.4.1655
Problem:    remote_expr() hangs. (Ramel)
Solution:   Check for messages in the waiting loop.
2016-03-25 19:03:03 +01:00
Bram Moolenaar 52c6eaffd4 patch 7.4.1654
Problem:    Crash when using expand('%:S') in a buffer without a name.
Solution:   Don't set a NUL. (James McCoy, closes #714)
2016-03-25 18:42:46 +01:00
Bram Moolenaar da64ab322a patch 7.4.1653
Problem:    Users who loaded matchit.vim manually have to change their
            startup. (Gary Johnson)
Solution:   Add a file in the old location that loads the package.
2016-03-25 18:35:01 +01:00
Bram Moolenaar 610cc1b9b3 patch 7.4.1652
Problem:    Old style test for fnamemodify().
Solution:   Turn it into a new style test.
2016-03-25 17:55:42 +01:00
Bram Moolenaar 780d4c3fff patch 7.4.1651
Problem:    Some dead (MSDOS) code remains.
Solution:   Remove the unused lines. (Ken Takata)
2016-03-25 17:21:19 +01:00
Bram Moolenaar f68f1d7079 patch 7.4.1650
Problem:    Quickfix test fails.
Solution:   Accept any number of matches.
2016-03-25 17:14:06 +01:00
Bram Moolenaar aedfcbe1e6 patch 7.4.1649
Problem:    The matchit plugin needs to be copied to be used.
Solution:   Put the matchit plugin in an optional package.
2016-03-25 17:02:51 +01:00
Bram Moolenaar bee6c0cf86 patch 7.4.1648
Problem:    Compiler has a problem copying a string into di_key[]. (Yegappan
            Lakshmanan)
Solution:   Add dictitem16_T.
2016-03-25 15:40:50 +01:00
Bram Moolenaar 8b20179c65 patch 7.4.1647
Problem:    Using freed memory after setqflist() and ":caddbuffer".  (Dominique)
Solution:   Set qf_ptr when adding the first item to the quickfix list.
2016-03-25 15:01:10 +01:00
Kazuki Sakamoto c561f1d1bc Merge remote-tracking branch 'vim/master' 2016-03-24 20:47:23 -07:00
Bram Moolenaar 4c90861e9f patch 7.4.1646
Problem:    Using Python vim.bindeval() on a partial doesn't work. (Nikolai
            Pavlov)
Solution:   Add VAR_PARTIAL support in Python.
2016-03-24 21:58:12 +01:00
Bram Moolenaar c5fbe8af4c patch 7.4.1645
Problem:    When a dict contains a partial it can't be redefined as a
            function. (Nikolai Pavlov)
Solution:   Remove the partial when overwriting with a function.
2016-03-24 21:42:09 +01:00
Bram Moolenaar 24c77a1e3a patch 7.4.1644
Problem:    Using string() on a partial that exists in the dictionary it binds
            results in an error. (Nikolai Pavlov)
Solution:   Make string() not fail on a recursively nested structure. (Ken
            Takta)
2016-03-24 21:23:06 +01:00
Bram Moolenaar d4caf5c16a patch 7.4.1643
Problem:    Terminating file name has side effects.
Solution:   Restore the character. (mostly by James McCoy, closes #713)
2016-03-24 19:14:35 +01:00
Bram Moolenaar 6a08454b93 patch 7.4.1642
Problem:    Handling emoji characters as full width has problems with
            backwards compatibility.
Solution:   Only put characters in the 1f000 range in the emoji table.
2016-03-24 18:24:58 +01:00
Kazuki Sakamoto 8cd088eb67 Merge remote-tracking branch 'vim/master' 2016-03-23 20:33:01 -07:00
Bram Moolenaar 5ca84ce4aa patch 7.4.1641
Problem:    Using unterminated string.
Solution:   Add NUL before calling vim_strsave_shellescape(). (James McCoy)
2016-03-23 22:28:25 +01:00
Bram Moolenaar ffec3c5349 patch 7.4.1640
Problem:    Crash when an autocommand changes a quickfix list. (Dominique)
Solution:   Check wether an entry is still valid. (Yegappan Lakshmanan,
            Hirohito Higashi)
2016-03-23 20:55:42 +01:00
Kazuki Sakamoto e20c94642a Merge remote-tracking branch 'vim/master' 2016-03-22 21:37:32 -07:00
Bram Moolenaar 5f436fcf99 patch 7.4.1639
Problem:    Invoking garbage collection may cause a double free.
Solution:   Don't free the dict in a partial when recursive is FALSE.
2016-03-22 22:34:03 +01:00
Bram Moolenaar e4eb6ff089 patch 7.4.1638
Problem:    When binding a function to a dict the reference count is wrong.
Solution:   Decrement dict reference count, only reference the function when
            actually making a copy. (Ken Takata)
2016-03-22 21:00:09 +01:00
Bram Moolenaar 6c0e984f26 patch 7.4.1637
Problem:    Can't build with older MinGW compiler.
Solution:   Change option from c++11 to gnu++11. (Ken Takata)
2016-03-22 20:42:31 +01:00
Bram Moolenaar 6135d0d803 patch 7.4.1636
Problem:    When 'F' is in 'shortmess' the prompt for the encryption key isn't
            displayed. (Toothpik)
Solution:   Reset msg_silent.
2016-03-22 20:31:13 +01:00
Kazuki Sakamoto 79bbe33a79 Merge remote-tracking branch 'vim/master' 2016-03-21 20:15:36 -07:00
Bram Moolenaar 6a06363861 patch 7.4.1635
Problem:    Channel test is a bit flaky.
Solution:   Remove 'DETACH' if it's there.
2016-03-21 23:18:54 +01:00
Bram Moolenaar 8e08125d3a patch 7.4.1634
Problem:    Vertical movement after CTRL-A ends up in the wrong column.
            (Urtica Dioica)
Solution:   Set curswant when appropriate. (Hirohito Higashi)
2016-03-21 23:13:32 +01:00
Bram Moolenaar b763eba7ae patch 7.4.1633
Problem:    If the help tags file was removed "make install" fails. (Tony
            Mechelynck)
Solution:   Only try moving the file if it exists.
2016-03-21 22:40:03 +01:00
Bram Moolenaar 6098957458 patch 7.4.1632
Problem:    List of test targets is outdated.
Solution:   Update to current list of test targets.
2016-03-21 22:38:34 +01:00
Bram Moolenaar 573e445664 patch 7.4.1631
Problem:    Compiler doesn't understand switch on all enum values. (Tony
            Mechelynck)
Solution:   Initialize variable.
2016-03-21 22:35:10 +01:00
Bram Moolenaar d63aff0a65 patch 7.4.1630
Problem:    Unicode table for double width is outdated.
Solution:   Update to the latest Unicode standard.
2016-03-21 22:15:30 +01:00
Bram Moolenaar b86f10ee10 patch 7.4.1629
Problem:    Handling emoji characters as full width has problems with
            backwards compatibility.
Solution:   Remove ambiguous and double width characters from the emoji table.
            Use a separate table for the character class.
            (partly by Yasuhiro Matsumoto)
2016-03-21 22:09:44 +01:00
Bram Moolenaar 3f3fbd3fdb patch 7.4.1628
Problem:    64-bit Compiler warning.
Solution:   Change type of variable. (Mike Williams)
2016-03-21 12:36:28 +01:00
Kazuki Sakamoto c90e801a05 Merge remote-tracking branch 'vim/master' 2016-03-20 23:23:42 -07:00
Bram Moolenaar 75f7265dd4 patch 7.4.1627
Problem:    Channel out_cb and err_cb are not tested.
Solution:   Add a test.
2016-03-20 22:16:56 +01:00
Bram Moolenaar 580984e026 patch 7.4.1626
Problem:    Missing changes to structs.
Solution:   Include the changes.
2016-03-20 21:17:13 +01:00
Bram Moolenaar e18c0b3981 Updated runtime files. 2016-03-20 21:08:34 +01:00
Bram Moolenaar be6aa46c4d patch 7.4.1625
Problem:    Trying to close file descriptor that isn't open.
Solution:   Check for negative number.
2016-03-20 21:02:00 +01:00
Bram Moolenaar 03602ec28e patch 7.4.1624
Problem:    Can't get info about a channel.
Solution:   Add ch_info().
2016-03-20 20:57:45 +01:00
Bram Moolenaar e9d6a298df patch 7.4.1623
Problem:    All Channels share the message ID, it keeps getting bigger.
Solution:   Use a message ID per channel.
2016-03-20 19:31:33 +01:00
Bram Moolenaar 17b56c9f83 patch 7.4.1622
Problem:    Channel demo doesn't work with Python 2.6.
Solution:   Add number in formatting placeholder
2016-03-20 18:54:19 +01:00
Bram Moolenaar a63cdb5ed6 patch 7.4.1621
Problem:    Channel test doesn't work with Python 2.6.
Solution:   Add number in formatting placeholder. (Wiredool)
2016-03-20 18:24:45 +01:00
Bram Moolenaar 4077b33a83 patch 7.4.1620
Problem:    Emoji characters are not considered as a kind of word character.
Solution:   Give emoji characters a word class number. (Yasuhiro Matsumoto)
2016-03-20 18:15:21 +01:00
Bram Moolenaar 364fa5c7ec patch 7.4.1619
Problem:    When 'fileformats' is set in the vimrc it applies to new buffers
            but not the initial buffer.
Solution:   Set 'fileformat' when starting up. (Mike Williams)
2016-03-20 17:53:25 +01:00
Bram Moolenaar a4f6ca717b patch 7.4.1618
Problem:    Starting job with output to buffer changes options in the current
            buffer.
Solution:   Set "curbuf" earlier. (Yasuhiro Matsumoto)
2016-03-20 17:28:35 +01:00
Kazuki Sakamoto 2215429b26 Merge remote-tracking branch 'vim/master' 2016-03-20 09:16:36 -07:00
Bram Moolenaar ba61ac0d61 patch 7.4.1617
Problem:    When a JSON message is split it isn't decoded.
Solution:   Wait a short time for the rest of the message to arrive.
2016-03-20 16:40:37 +01:00
Bram Moolenaar ac74d5e86c patch 7.4.1616
Problem:    Malformed channel request causes a hang.
Solution:   Drop malformed message. (Damien)
2016-03-20 14:31:00 +01:00
Kazuki Sakamoto 58c7dadefc Fix merge 2016-03-19 21:12:03 -07:00
Kazuki Sakamoto aabd6e5d74 Merge remote-tracking branch 'vim/master' 2016-03-19 20:50:13 -07:00
Bram Moolenaar 829c8e3696 patch 7.4.1615
Problem:    Build fails with tiny features.
Solution:   Adjust #ifdefs.
2016-03-19 23:07:23 +01:00
Bram Moolenaar 7eba3d2cbf patch 7.4.1614
Problem:    Still quickfix test in old style.
Solution:   Turn test 10 into a new style test.
2016-03-19 22:54:09 +01:00
Bram Moolenaar 064154c3fe patch 7.4.1613
Problem:    Still can't build with small features.
Solution:   Adjust #ifdefs.
2016-03-19 22:50:43 +01:00
Bram Moolenaar d293b2b9d4 patch 7.4.1612
Problem:    Can't build with small features.
Solution:   Move code and #ifdefs.
2016-03-19 22:29:49 +01:00
Bram Moolenaar 44a2f923c0 patch 7.4.1611
Problem:    The versplit feature makes the code uneccessary complicated.
Solution:   Remove FEAT_VERTSPLIT, always support vertical splits when
            FEAT_WINDOWS is defined.
2016-03-19 22:11:51 +01:00
Bram Moolenaar cc6cf9b9f9 patch 7.4.1610
Problem:    Compiler warnings for non-virtual destructor.
Solution:   Mark the classe final. (Ken Takata)
2016-03-19 20:51:35 +01:00
Bram Moolenaar 4d581a826c patch 7.4.1609
Problem:    Contents file is only for Amiga distro.
Solution:   Move it to "READMEdir".  Update some info.
2016-03-19 20:29:39 +01:00
Bram Moolenaar 5c29154b52 patch 7.4.1608
Problem:    string() doesn't handle a partial.
Solution:   Make a string from a partial.
2016-03-19 20:05:45 +01:00
Bram Moolenaar f0e86a0dbd patch 7.4.1607
Problem:    Comparing a function that exists on two dicts is not backwards
            compatible. (Thinca)
Solution:   Only compare the function, not what the partial adds.
2016-03-19 19:38:12 +01:00
Bram Moolenaar 953cc7fb13 patch 7.4.1606
Problem:    Having type() handle a Funcref that is or isn't a partial
            differently causes problems for existing scripts.
Solution:   Make type() return the same value. (Thinca)
2016-03-19 18:52:29 +01:00
Bram Moolenaar 3905e291fe patch 7.4.1605
Problem:    Catching exception that won't be thrown.
Solution:   Remove try/catch.
2016-03-19 18:44:08 +01:00
Bram Moolenaar 3848e00e01 patch 7.4.1604
Problem:    Although emoji characters are ambiguous width, best is to treat
            them as full width.
Solution:   Update the Unicode character tables. Add the 'emoji' options.
            (Yasuhiro Matsumoto)
2016-03-19 18:42:29 +01:00
Bram Moolenaar bfb96c047b patch 7.4.1603
Problem:    Timer with an ":echo" command messes up display.
Solution:   Redraw depending on the mode. (Hirohito Higashi)  Avoid the more
            prompt being used recursively.
2016-03-19 17:05:20 +01:00
Bram Moolenaar cff572abb9 patch 7.4.1602
Problem:    Info files take space in the top directory.
Solution:   Move them to "READMEdir".
2016-03-19 16:24:14 +01:00
Bram Moolenaar 818c9e7edf patch 7.4.1601
Problem:    README files take a lot of space in the top directory.
Solution:   Move most of them to "READMEdir".
2016-03-19 16:09:42 +01:00
Bram Moolenaar 062cc1857d patch 7.4.1600
Problem:    libs directory is not useful.
Solution:   Remove arp.library, it was only for very old Amiga versions.
2016-03-19 15:25:51 +01:00
Bram Moolenaar 8a82c7fa5e patch 7.4.1599
Problem:    No link to Coverity.
Solution:   Add Coverity badge in README.
2016-03-19 15:15:01 +01:00
Bram Moolenaar 6d8d849f5a patch 7.4.1598
Problem:    When starting the GUI fails a swap file is left behind. (Joerg
            Plate)
Solution:   Preserve files before exiting. (closes #692)
2016-03-19 14:48:31 +01:00
Bram Moolenaar 9f6154f26e patch 7.4.1597
Problem:    Memory leak when out of memory. (Coverity)
Solution:   Free the name.
2016-03-19 14:22:11 +01:00
Bram Moolenaar ba8cd122ef patch 7.4.1596
Problem:    Memory leak. (Coverity)
Solution:   Free the pattern.
2016-03-19 14:16:39 +01:00
Bram Moolenaar c0a1d7f3ad patch 7.4.1595
Problem:    Not checking for failed open(). (Coverity)
Solution:   Check file descriptor not being negative.
2016-03-19 14:12:50 +01:00
Bram Moolenaar 943bb2b8eb patch 7.4.1594
Problem:    Timers don't work on Unix.
Solution:   Add missing code.
2016-03-19 14:11:18 +01:00
Bram Moolenaar a889cf4642 patch 7.4.1593
Problem:    Using channel timeout instead of request timeout. (Coverity)
Solution:   Remove the extra assignment.
2016-03-19 13:49:43 +01:00
Bram Moolenaar 0899d69803 patch 7.4.1592
Problem:    Quickfix code using memory after being freed. (Dominique Pelle)
Solution:   Detect that the window was closed. (Hirohito Higashi)
2016-03-19 13:35:03 +01:00
Kazuki Sakamoto 71b048830a Merge remote-tracking branch 'vim/master' 2016-03-18 18:42:10 -07:00
Bram Moolenaar 5584df65a0 patch 7.4.1591
Problem:    The quickfix title is truncated.
Solution:   Save the command before it is truncated. (Anton Lindqvist)
2016-03-18 21:00:51 +01:00
Bram Moolenaar 3f242a844e patch 7.4.1590
Problem:    Warning for shadowed variable. (Christian Brabandt)
Solution:   Move the variable into a local block.
2016-03-18 19:39:25 +01:00
Kazuki Sakamoto 755e60ad59 Merge remote-tracking branch 'vim/master' 2016-03-17 21:31:35 -07:00
Bram Moolenaar 9e63f61cb0 patch 7.4.1589
Problem:    Combining dict and args with partial doesn't always work.
Solution:   Use the arguments from the partial.
2016-03-17 23:13:28 +01:00
Bram Moolenaar 1ff2b64b11 patch 7.4.1588
Problem:    Old style test for quickfix.
Solution:   Turn test 96 into a new style test.
2016-03-17 22:07:02 +01:00
Bram Moolenaar 1c8b4edb9b patch 7.4.1587
Problem:    Compiler warnings with 64 bit compiler.
Solution:   Add type casts. (Mike Williams)
2016-03-17 21:51:03 +01:00
Bram Moolenaar 8a1bb04637 patch 7.4.1586
Problem:    Nesting partials doesn't work.
Solution:   Append arguments. (Ken Takata)
2016-03-17 21:11:53 +01:00
Bram Moolenaar d22a18928e patch 7.4.1585
Problem:    Partial is not recognized everywhere.
Solution:   Check for partial in trans_function_name(). (Yasuhiro Matsumoto)
            Add a test.
2016-03-17 20:50:47 +01:00
Bram Moolenaar 0e0b3dd335 patch 7.4.1584
Problem:    Timers don't work for Win32 console.
Solution:   Add check_due_timer() in WaitForChar().
2016-03-17 17:58:56 +01:00
Kazuki Sakamoto 132af44e19 Merge remote-tracking branch 'vim/master' 2016-03-16 18:39:30 -07:00
Bram Moolenaar 597385ab43 patch 7.4.1583
Problem:    Warning for unitinialized variable.
Solution:   Initialize it. (Dominique)
2016-03-16 23:24:43 +01:00
Bram Moolenaar 6f2e4b36c9 patch 7.4.1582
Problem:    Get E923 when using function(dict.func, [], dict). (Kent Sibilev)
            Storing a function with a dict in a variable drops the dict if the
            function is script-local.
Solution:   Translate the function name.  Use dict arg if present.
2016-03-16 22:52:12 +01:00
Bram Moolenaar 65639032bb patch 7.4.1581
Problem:    Using ":call dict.func()" where the function is a partial does
            not work.  Using "dict.func()" where the function does not take a
            Dictionary does not work.
Solution:   Handle partial properly in ":call". (Yasuhiro Matsumoto)
2016-03-16 21:40:30 +01:00
Bram Moolenaar 7a5c46a9df patch 7.4.1580
Problem:    Crash when using function reference. (Luchr)
Solution:   Set initial refcount. (Ken Takata, closes #690)
2016-03-16 20:41:21 +01:00
Kazuki Sakamoto bdc8cf330a Merge remote-tracking branch 'vim/master' 2016-03-15 20:29:23 -07:00
Bram Moolenaar a3dc5e92dc patch 7.4.1579
Problem:    Missing changes in channel.c
Solution:   Include the changes.
2016-03-15 23:19:14 +01:00
Bram Moolenaar 975b5271ee patch 7.4.1578
Problem:    There is no way to invoke a function later or periodically.
Solution:   Add timer support.
2016-03-15 23:10:59 +01:00
Bram Moolenaar ab1fa3955f patch 7.4.1577
Problem:    Cannot pass "dict.Myfunc" around as a partial.
Solution:   Create a partial when expected.
2016-03-15 19:33:34 +01:00
Bram Moolenaar 927030af23 patch 7.4.1576
Problem:    Write error of viminfo file is not handled properly. (Christian
            Neukirchen)
Solution:   Check the return value of fclose(). (closes #682)
2016-03-15 18:23:55 +01:00
Bram Moolenaar 89e375a88f patch 7.4.1575
Problem:    Using wrong size for struct.
Solution:   Use the size for wide API. (Ken Takata)
2016-03-15 18:09:57 +01:00
Bram Moolenaar 8067a64852 Add missing test file. 2016-03-15 17:52:10 +01:00
Bram Moolenaar d22e9465f6 patch 7.4.1574
Problem:    ":undo 0" does not work. (Florent Fayolle)
Solution:   Make it undo all the way. (closes #688)
2016-03-15 17:43:55 +01:00
Bram Moolenaar ce2ec0a82a patch 7.4.1573
Problem:    Tests get stuck at the more prompt.
Solution:   Move the backspace test out of test_alot.
2016-03-15 17:10:19 +01:00
Bram Moolenaar 85a7cb4dcf patch 7.4.1572
Problem:    Setting 'compatible' in test influences following tests.
Solution:   Turn 'compatible' off again.
2016-03-15 16:53:26 +01:00
Bram Moolenaar 8e15ffcde7 patch 7.4.1571
Problem:    No test for ":help".
Solution:   Add a test for what 7.4.1568 fixed. (Higashi Higashi)
2016-03-15 16:35:39 +01:00
Bram Moolenaar 426dd02195 patch 7.4.1570
Problem:    There is no way to avoid the message when editing a file.
Solution:   Add the "F" flag to 'shortmess'. (Shougo, closes #686)
2016-03-15 15:09:29 +01:00
Bram Moolenaar e27dba499a patch 7.4.1569
Problem:    Using old style tests for quickfix.
Solution:   Change them to new style tests. (Yegappan Lakshmanan)
2016-03-15 14:11:10 +01:00
Bram Moolenaar 00f9e0dbbd patch 7.4.1568
Problem:    Using CTRL-] in help on option in parentheses doesn't work.
Solution:   Skip the "(" in "('". (Hirohito Higashi)
2016-03-15 13:44:12 +01:00
Bram Moolenaar 1abb502635 patch 7.4.1567
Problem:    Crash in assert_fails().
Solution:   Check for NULL. (Dominique Pelle)  Add a test.
2016-03-15 13:33:55 +01:00
Bram Moolenaar 4f118be2bb patch 7.4.1566
Problem:    Compiler warning for shadowed variable. (Kazunobu Kuriyama)
Solution:   Remove the inner one.
2016-03-15 13:09:53 +01:00
Bram Moolenaar f155196444 patch 7.4.1565
Problem:    Crash when assert_equal() runs into a NULL string.
Solution:   Check for NULL. (Dominique) Add a test.
2016-03-15 12:55:58 +01:00
Bram Moolenaar 346418c624 patch 7.4.1564
Problem:    An empty list in function() causes an error.
Solution:   Handle an empty list like there is no list of arguments.
2016-03-15 12:36:08 +01:00
Bram Moolenaar 790500a8e6 patch 7.4.1563
Problem:    Partial test fails on windows.
Solution:   Return 1 or -1 from compare function.
2016-03-15 11:05:45 +01:00
Kazuki Sakamoto bd8b60d261 Merge remote-tracking branch 'vim/master' 2016-03-14 19:50:31 -07:00
Bram Moolenaar 9eb3bb2930 patch 7.4.1562
Problem:    ":helptags ALL" crashes. (Lcd)
Solution:   Don't free twice.
2016-03-14 23:45:35 +01:00
Bram Moolenaar 39afdea203 patch 7.4.1561
Problem:    Missing update to proto file.
Solution:   Change the proto file.
2016-03-14 23:27:29 +01:00
Bram Moolenaar d6c2f05260 patch 7.4.1560
Problem:    Dict options with a dash are more difficult to use.
Solution:   Use an underscore, so that dict.err_io can be used.
2016-03-14 23:22:59 +01:00
Bram Moolenaar 1735bc988c patch 7.4.1559
Problem:    Passing cookie to a callback is clumsy.
Solution:   Change function() to take arguments and return a partial.
2016-03-14 23:05:14 +01:00
Kazuki Sakamoto b6f08f7872 Merge remote-tracking branch 'vim/master' 2016-03-13 22:36:28 -07:00
Bram Moolenaar 9cdf86b86f patch 7.4.1558
Problem:    It is not easy to find out what windows display a buffer.
Solution:   Add win_findbuf().
2016-03-13 19:04:51 +01:00
Bram Moolenaar 86edef664e patch 7.4.1557
Problem:    Windows cannot be identified.
Solution:   Add a unique window number to each window and functions to use it.
2016-03-13 18:07:30 +01:00
Bram Moolenaar a3442cb505 patch 7.4.1556
Problem:    "make install" changes the help tags file, causing it to differ
            from the repository.
Solution:   Move it aside and restore it.
2016-03-13 14:34:12 +01:00
Bram Moolenaar fff341eb59 patch 7.4.1555
Problem:    List of test targets incomplete.
Solution:   Add newly added tests.
2016-03-13 13:27:36 +01:00
Bram Moolenaar 52f9c19015 patch 7.4.1554
Problem:    Completion for :colorscheme does not use 'packpath'.
Solution:   Make it work, add a test. (Hirohito Higashi)
2016-03-13 13:24:45 +01:00
147 changed files with 5052 additions and 2674 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ language: c
os:
- osx
osx_image: xcode7.2
osx_image: xcode7.3
compiler:
- clang
+32 -2
View File
@@ -495,7 +495,6 @@ RT_ALL = \
runtime/macros/life/click.me \
runtime/macros/life/life.vim \
runtime/macros/matchit.vim \
runtime/macros/matchit.txt \
runtime/macros/maze/README.txt \
runtime/macros/maze/[mM]akefile \
runtime/macros/maze/main.aap \
@@ -525,6 +524,9 @@ RT_ALL = \
runtime/tutor/tutor \
runtime/tutor/tutor.vim \
runtime/vimrc_example.vim \
runtime/pack/dist/opt/matchit/plugin/matchit.vim \
runtime/pack/dist/opt/matchit/doc/matchit.txt \
runtime/pack/dist/opt/matchit/doc/tags \
# runtime files for all distributions without CR-NL translation
RT_ALL_BIN = \
@@ -605,7 +607,6 @@ RT_AMI = \
README.txt.info \
README_ami.txt \
README_ami.txt.info \
libs/arp.library \
runtime/doc.info \
runtime/doc/*.info \
runtime/icons/README.txt \
@@ -693,6 +694,35 @@ EXTRA = \
src/tee/Make_mvc.mak \
src/tee/tee.c \
# files in READMEdir that are included from the top dir
IN_README_DIR = \
README.txt.info \
README_ami.txt \
README_ami.txt.info \
README_amibin.txt \
README_amibin.txt.info \
README_amisrc.txt \
README_amisrc.txt.info \
README_bindos.txt \
README_dos.txt \
README_extra.txt \
README_mac.txt \
README_ole.txt \
README_os2.txt \
README_os390.txt \
README_src.txt \
README_srcdos.txt \
README_unix.txt \
README_vms.txt \
README_w32s.txt \
Contents \
Contents.info \
Vim.info \
Xxd.info \
runtime.info \
src.info \
vimdir.info \
# generic language files
LANG_GEN = \
runtime/doc/*-de.1 \
+18 -22
View File
@@ -213,24 +213,13 @@ MINOR = 4
# > bigvim64.bat
#
#
# OBSOLETE systems: You can build this if you have an appropriate system.
# OBSOLETE systems: You can build these if you have an appropriate system.
#
# 16 bit DOS version: (doesn't build anywhere)
# - Set environment for compiling with Borland C++ 3.1.
# - "bmake -f Make_bc3.mak BOR=E:\borlandc" (compiling xxd might fail, in that
# case set environment for compiling with Borland C++ 4.0 and do
# "make -f make_bc3.mak BOR=E:\BC4 xxd/xxd.exe").
# NOTE: this currently fails because Vim is too big.
# - "make test" and check the output.
# - Rename the executables to "vimd16.exe", "xxdd16.exe", "installd16.exe" and
# "uninstald16.exe".
# 16 bit DOS version: You need to get a very old version of Vim, for several
# years even the tiny build is too big to fit in DOS memory.
#
# 32 bit DOS version: (requires Windows XP or earlier)
# - Set environment for compiling with DJGPP; "gmake -f Make_djg.mak".
# - "rm testdir/*.out", "gmake -f Make_djg.mak test" and check the output for
# "ALL DONE".
# - Rename the executables to "vimd32.exe", "xxdd32.exe", "installd32.exe" and
# "uninstald32.exe".
# 32 bit DOS version: Support was removed in 7.4.1399. When syncing to before
# that it probably won't build.
#
# Win32s GUI version: (requires a very old compiler)
# - Set environment for Visual C++ 4.1 (requires a new console window):
@@ -242,12 +231,9 @@ MINOR = 4
# - Rename "uninstal.exe" to "uninstalw32.exe"
# - The produced uninstalw32.exe and vimrun.exe are used.
#
# OS/2: (requires an OS/2 system)
# - Unpack the Unix archive.
# - "make -f Make_os2.mak".
# - Rename the executables to vimos2.exe, xxdos2.exe and teeos2.exe and copy
# them to here.
# - "make os2bin".
# OS/2 support was removed in patch 7.4.1008. If you want to give it a try
# sync to before that and check the old version of this Makefile for
# instructions.
VIMVER = vim-$(MAJOR).$(MINOR)
VERSION = $(MAJOR)$(MINOR)
@@ -269,9 +255,13 @@ dist:
mkdir dist
# Clean up some files to avoid they are included.
# Copy README files to the top directory.
prepare:
if test -f runtime/doc/uganda.nsis.txt; then \
rm runtime/doc/uganda.nsis.txt; fi
for name in $(IN_README_DIR); do \
cp READMEdir/"$$name" .; \
done
# For the zip files we need to create a file with the comment line
dist/comment:
@@ -336,6 +326,7 @@ unixall: dist prepare
$(EXTRA) \
$(LANG_SRC) \
| (cd dist/$(VIMRTDIR); tar xf -)
-rm $(IN_README_DIR)
# Need to use a "distclean" config.mk file
# Note: this file is not included in the repository to avoid problems, but it's
# OK to put it in the archive.
@@ -372,6 +363,7 @@ amirt: dist prepare
$(RT_NO_UNIX) \
$(RT_AMI_DOS) \
| (cd dist/Vim/$(VIMRTDIR); tar xf -)
-rm $(IN_README_DIR)
mv dist/Vim/$(VIMRTDIR)/vimdir.info dist/Vim.info
mv dist/Vim/$(VIMRTDIR)/runtime.info dist/Vim/$(VIMRTDIR).info
mv dist/Vim/$(VIMRTDIR)/runtime/* dist/Vim/$(VIMRTDIR)
@@ -392,6 +384,7 @@ amibin: dist prepare
Vim \
Xxd \
| (cd dist/Vim/$(VIMRTDIR); tar xf -)
-rm $(IN_README_DIR)
mv dist/Vim/$(VIMRTDIR)/vimdir.info dist/Vim.info
mv dist/Vim/$(VIMRTDIR)/runtime.info dist/Vim/$(VIMRTDIR).info
cd dist && tar cf vim$(VERSION)bin.tar Vim Vim.info
@@ -410,6 +403,7 @@ amisrc: dist prepare
$(SRC_AMI) \
$(SRC_AMI_DOS) \
| (cd dist/Vim/$(VIMRTDIR); tar xf -)
-rm $(IN_README_DIR)
mv dist/Vim/$(VIMRTDIR)/vimdir.info dist/Vim.info
mv dist/Vim/$(VIMRTDIR)/runtime.info dist/Vim/$(VIMRTDIR).info
cd dist && tar cf vim$(VERSION)src.tar Vim Vim.info
@@ -483,6 +477,7 @@ dosrt_files: dist prepare no_title.vim
$(RT_DOS_BIN) \
$(LANG_GEN_BIN) \
| (cd dist/vim/$(VIMRTDIR); tar xf -)
-rm $(IN_README_DIR)
mv dist/vim/$(VIMRTDIR)/runtime/* dist/vim/$(VIMRTDIR)
rmdir dist/vim/$(VIMRTDIR)/runtime
# Add the message translations. Trick: skip ja.mo and use ja.sjis.mo instead.
@@ -517,6 +512,7 @@ dosbin_gvim: dist no_title.vim dist/$(COMMENT_GVIM)
tar cf - \
$(BIN_DOS) \
| (cd dist/vim/$(VIMRTDIR); tar xf -)
-rm $(IN_README_DIR)
cp gvim.exe dist/vim/$(VIMRTDIR)/gvim.exe
cp xxdw32.exe dist/vim/$(VIMRTDIR)/xxd.exe
cp vimrun.exe dist/vim/$(VIMRTDIR)/vimrun.exe
+1
View File
@@ -2,6 +2,7 @@
[![Build Status](https://travis-ci.org/vim/vim.svg?branch=master)](https://travis-ci.org/vim/vim)
[![Coverage Status](https://coveralls.io/repos/vim/vim/badge.svg?branch=master&service=github)](https://coveralls.io/github/vim/vim?branch=master)
[![Appveyor Build status](https://ci.appveyor.com/api/projects/status/o2qht2kjm02sgghk?svg=true)](https://ci.appveyor.com/project/chrisbra/vim)
[![Coverity Scan](https://scan.coverity.com/projects/241/badge.svg)](https://scan.coverity.com/projects/vim)
## What is Vim? ##
+2 -2
View File
@@ -9,7 +9,7 @@ Vim Vi IMproved. A clone of the UNIX text editor Vi. Very useful
messages, shows current file name in window title, on-line
help, rectangular cut/paste, etc., etc., etc...
Version 7.4. Also runs under UNIX, MSDOS and other systems.
Version 7.4. Also runs under UNIX, MS-Windows, Mac, etc.
vim74rt.tgz contains the documentation and syntax files.
vim74bin.tgz contains the binaries.
vim74src.tgz contains the sources.
@@ -19,5 +19,5 @@ Vim Vi IMproved. A clone of the UNIX text editor Vi. Very useful
Xxd Hex dumper and reader. Can be used to view files as hex, edit
them and write them back. Can also be used to patch files.
Version 1.8 (1997 May 22)
Version 1.10 (1997 May 22)
Author: Juergen Weigert
View File
View File
View File
View File
View File
Executable → Regular
View File
Executable → Regular
View File
View File
Executable → Regular
View File
View File
BIN
View File
Binary file not shown.
+66 -63
View File
@@ -1,4 +1,4 @@
*channel.txt* For Vim version 7.4. Last change: 2016 Mar 12
*channel.txt* For Vim version 7.4. Last change: 2016 Mar 15
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -127,10 +127,10 @@ Use |ch_status()| to see if the channel could be opened.
"js" - Use JS (JavaScript) encoding, more efficient than JSON.
"nl" - Use messages that end in a NL character
"raw" - Use raw messages
"in-mode" mode specifically for stdin, only when using pipes
"out-mode" mode specifically for stdout, only when using pipes
"err-mode" mode specifically for stderr, only when using pipes
*in_mode* *out_mode* *err_mode*
"in_mode" mode specifically for stdin, only when using pipes
"out_mode" mode specifically for stdout, only when using pipes
"err_mode" mode specifically for stderr, only when using pipes
Note: when setting "mode" the part specific mode is
overwritten. Therefore set "mode" first and the part specific
mode later.
@@ -138,7 +138,7 @@ Use |ch_status()| to see if the channel could be opened.
Note: when writing to a file or buffer and when reading from a
buffer NL mode is used by default.
*channel-callback*
*channel-callback* *E921*
"callback" A function that is called when a message is received that is
not handled otherwise. It gets two arguments: the channel
and the received message. Example: >
@@ -153,17 +153,20 @@ Use |ch_status()| to see if the channel could be opened.
excluding the NL.
When "mode" is "raw" the "msg" argument is the whole message
as a string.
*out-cb*
"out-cb" A function like "callback" but used for stdout. Only for when
the channel uses pipes. When "out-cb" wasn't set the channel
For all callbacks: Use |function()| to bind it to arguments
and/or a dictionary.
*out_cb*
"out_cb" A function like "callback" but used for stdout. Only for when
the channel uses pipes. When "out_cb" wasn't set the channel
callback is used.
*err-cb*
"err-cb" A function like "callback" but used for stderr. Only for when
the channel uses pipes. When "err-cb" wasn't set the channel
*err_cb*
"err_cb" A function like "callback" but used for stderr. Only for when
the channel uses pipes. When "err_cb" wasn't set the channel
callback is used.
*close-cb*
"close-cb" A function that is called when the channel gets closed, other
*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*
@@ -179,9 +182,9 @@ Use |ch_status()| to see if the channel could be opened.
"timeout" The time to wait for a request when blocking, E.g. when using
ch_evalexpr(). In milliseconds. The default is 2000 (2
seconds).
*out-timeout* *err-timeout*
"out-timeout" Timeout for stdout. Only when using pipes.
"err-timeout" Timeout for stderr. Only when using pipes.
*out_timeout* *err_timeout*
"out_timeout" Timeout for stdout. Only when using pipes.
"err_timeout" Timeout for stderr. Only when using pipes.
Note: when setting "timeout" the part specific mode is
overwritten. Therefore set "timeout" first and the part
specific mode later.
@@ -440,7 +443,7 @@ been received and not parsed correctly.
If the command produces a line of output that you want to deal with, specify
a handler for stdout: >
let job = job_start(command, {"out-cb": "MyHandler"})
let job = job_start(command, {"out_cb": "MyHandler"})
The function will be called with the channel and a message. You would define
it like this: >
func MyHandler(channel, msg)
@@ -448,10 +451,10 @@ it like this: >
Without the handler you need to read the output with |ch_read()| or
|ch_readraw()|.
The handler defined for "out-cb" will not receive stderr. If you want to
handle that separately, add an "err-cb" handler: >
let job = job_start(command, {"out-cb": "MyHandler",
\ "err-cb": "ErrHandler"})
The handler defined for "out_cb" will not receive stderr. If you want to
handle that separately, add an "err_cb" handler: >
let job = job_start(command, {"out_cb": "MyHandler",
\ "err_cb": "ErrHandler"})
If you want to handle both stderr and stdout with one handler use the
"callback" option: >
@@ -463,7 +466,7 @@ JSON or JS mode you can use ch_evalexpr().
There are several options you can use, see |job-options|.
For example, to start a job and write its output in buffer "dummy": >
let logjob = job_start("tail -f /tmp/log",
\ {'out-io': 'buffer', 'out-name': 'dummy'})
\ {'out_io': 'buffer', 'out_name': 'dummy'})
sbuf dummy
@@ -471,16 +474,16 @@ Job input from a buffer ~
To run a job that reads from a buffer: >
let job = job_start({command},
\ {'in-io': 'buffer', 'in-name': 'mybuffer'})
\ {'in_io': 'buffer', 'in_name': 'mybuffer'})
<
*E915* *E918*
The buffer is found by name, similar to |bufnr()|. The buffer must exist and
be loaded when job_start() is called.
By default this reads the whole buffer. This can be changed with the "in-top"
and "in-bot" options.
By default this reads the whole buffer. This can be changed with the "in_top"
and "in_bot" options.
A special mode is when "in-top" is set to zero and "in-bot" is not set: Every
A special mode is when "in_top" is set to zero and "in_bot" is not set: Every
time a line is added to the buffer, the last-but-one line will be send to the
job stdin. This allows for editing the last line and sending it when pressing
Enter.
@@ -490,7 +493,7 @@ Enter.
To start another process without creating a channel: >
let job = job_start(command,
\ {"in-io": "null", "out-io": "null", "err-io": "null"})
\ {"in_io": "null", "out_io": "null", "err_io": "null"})
This starts {command} in the background, Vim does not wait for it to finish.
@@ -524,17 +527,17 @@ See |job_setoptions()| and |ch_setoptions()|.
*job-callback*
"callback": handler Callback for something to read on any part of the
channel.
*job-out-cb*
"out-cb": handler Callback for when there is something to read on
*job-out_cb*
"out_cb": handler Callback for when there is something to read on
stdout.
*job-err-cb*
"err-cb": handler Callback for when there is something to read on
*job-err_cb*
"err_cb": handler Callback for when there is something to read on
stderr.
*job-close-cb*
"close-cb": handler Callback for when the channel is closed. Same as
"close-cb" on ch_open().
*job-exit-cb*
"exit-cb": handler Callback for when the job ends. The arguments are the
*job-close_cb*
"close_cb": handler Callback for when the channel is closed. Same as
"close_cb" on ch_open().
*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
@@ -557,37 +560,37 @@ See |job_setoptions()| and |ch_setoptions()|.
cause I/O errors.
Existing callbacks and other settings remain.
*job-in-io* *in-top* *in-bot* *in-name* *in-buf*
"in-io": "null" disconnect stdin (read from /dev/null)
"in-io": "pipe" stdin is connected to the channel (default)
"in-io": "file" stdin reads from a file
"in-io": "buffer" stdin reads from a buffer
"in-top": number when using "buffer": first line to send (default: 1)
"in-bot": number when using "buffer": last line to send (default: last)
"in-name": "/path/file" the name of the file or buffer to read from
"in-buf": number the number of the buffer to read from
*job-in_io* *in_top* *in_bot* *in_name* *in_buf*
"in_io": "null" disconnect stdin (read from /dev/null)
"in_io": "pipe" stdin is connected to the channel (default)
"in_io": "file" stdin reads from a file
"in_io": "buffer" stdin reads from a buffer
"in_top": number when using "buffer": first line to send (default: 1)
"in_bot": number when using "buffer": last line to send (default: last)
"in_name": "/path/file" the name of the file or buffer to read from
"in_buf": number the number of the buffer to read from
*job-out-io* *out-name* *out-buf*
"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-name": "/path/file" the name of the file or buffer to write to
"out-buf": number the number of the buffer to write to
*job-out_io* *out_name* *out_buf*
"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_name": "/path/file" the name of the file or buffer to write to
"out_buf": number the number of the buffer to write to
*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-name": "/path/file" the name of the file or buffer to write to
"err-buf": number the number of the buffer to write to
*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_name": "/path/file" the name of the file or buffer to write to
"err_buf": number the number of the buffer to write to
Writing to a buffer ~
When the out-io or err-io mode is "buffer" and there is a callback, the text
When the out_io or err_io mode is "buffer" and there is a callback, the text
is appended to the buffer before invoking the callback.
When a buffer is used both for input and output, the output lines are put
@@ -614,7 +617,7 @@ Undo is synced for every added line.
Writing to a file ~
*E920*
The file is created with permissions 600 (read-write for the user, not
accessible for others). Use |setfperm()| to change this.
+184 -20
View File
@@ -1,4 +1,4 @@
*eval.txt* For Vim version 7.4. Last change: 2016 Mar 12
*eval.txt* For Vim version 7.4. Last change: 2016 Mar 20
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -350,10 +350,6 @@ This works like: >
: let index = index + 1
:endwhile
Note that all items in the list should be of the same type, otherwise this
results in error |E706|. To avoid this |:unlet| the variable at the end of
the loop.
If all you want to do is modify each item in the list then the |map()|
function will be a simpler method than a for loop.
@@ -757,20 +753,35 @@ recursively. Ignoring case means case is ignored when comparing item values.
*E693* *E694*
A |Funcref| can only be compared with a |Funcref| and only "equal" and "not
equal" can be used. Case is never ignored.
equal" can be used. Case is never ignored. Whether arguments or a Dictionary
are bound (with a partial) is ignored. This is so that when a function is
made a member of a Dictionary it is still considered to be the same function.
To compare partials to see if they bind the same argument and Dictionary
values use string(): >
echo string(Partial1) == string(Partial2)
When using "is" or "isnot" with a |List| or a |Dictionary| this checks if the
expressions are referring to the same |List| or |Dictionary| instance. A copy
of a |List| is different from the original |List|. When using "is" without
a |List| or a |Dictionary| it is equivalent to using "equal", using "isnot"
equivalent to using "not equal". Except that a different type means the
values are different: "4 == '4'" is true, "4 is '4'" is false and "0 is []" is
false and not an error. "is#"/"isnot#" and "is?"/"isnot?" can be used to match
and ignore case.
values are different: >
echo 4 == '4'
1
echo 4 is '4'
0
echo 0 is []
0
"is#"/"isnot#" and "is?"/"isnot?" can be used to match and ignore case.
When comparing a String with a Number, the String is converted to a Number,
and the comparison is done on Numbers. This means that "0 == 'x'" is TRUE,
because 'x' converted to a Number is zero.
and the comparison is done on Numbers. This means that: >
echo 0 == 'x'
1
because 'x' converted to a Number is zero. However: >
echo [0] == ['x']
0
Inside a List or Dictionary this conversion is not used.
When comparing two Strings, this is done with strcmp() or stricmp(). This
results in the mathematical difference (comparing byte values), not
@@ -1816,6 +1827,7 @@ ch_evalraw( {handle}, {string} [, {options}])
any evaluate {string} on raw {handle}
ch_getbufnr( {handle}, {what}) Number get buffer number for {handle}/{what}
ch_getjob( {channel}) Job get the Job of {channel}
ch_info( {handle}) String info about channel {handle}
ch_log( {msg} [, {handle}]) none write {msg} in the channel log file
ch_logfile( {fname} [, {mode}]) none start logging channel activity
ch_open( {address} [, {options}]) Channel open a channel to {address}
@@ -1826,7 +1838,7 @@ ch_sendexpr( {handle}, {expr} [, {options}])
ch_sendraw( {handle}, {string} [, {options}])
any send {string} over raw {handle}
ch_setoptions( {handle}, {options}) none set options for {handle}
ch_status( {handle}) String status of {handle}
ch_status( {handle}) String status of channel {handle}
changenr() Number current change number
char2nr( {expr}[, {utf8}]) Number ASCII/UTF8 value of first char in {expr}
cindent( {lnum}) Number C indent for line {lnum}
@@ -1885,7 +1897,8 @@ foldlevel( {lnum}) Number fold level at {lnum}
foldtext() String line displayed for closed fold
foldtextresult( {lnum}) String text for closed fold at {lnum}
foreground() Number bring the Vim window to the foreground
function( {name}) Funcref reference to function {name}
function({name} [, {arglist}] [, {dict}])
Funcref reference to function {name}
garbagecollect( [{atexit}]) none free memory, breaking cyclic references
get( {list}, {idx} [, {def}]) any get item {idx} from {list} or {def}
get( {dict}, {key} [, {def}]) any get item {key} from {dict} or {def}
@@ -2122,9 +2135,12 @@ tabpagewinnr( {tabarg}[, {arg}])
Number number of current window in tab page
taglist( {expr}) List list of tags matching {expr}
tagfiles() List tags files used
tempname() String name for a temporary file
tan( {expr}) Float tangent of {expr}
tanh( {expr}) Float hyperbolic tangent of {expr}
tempname() String name for a temporary file
timer_start( {time}, {callback} [, {options}])
Number create a timer
timer_stop( {timer}) none stop a timer
tolower( {expr}) String the String {expr} switched to lowercase
toupper( {expr}) String the String {expr} switched to uppercase
tr( {src}, {fromstr}, {tostr}) String translate chars of {src} in {fromstr}
@@ -2139,6 +2155,11 @@ values( {dict}) List values in {dict}
virtcol( {expr}) Number screen column of cursor or mark
visualmode( [expr]) String last visual mode used
wildmenumode() Number whether 'wildmenu' mode is active
win_findbuf( {bufnr}) List find windows containing {bufnr}
win_getid( [{win} [, {tab}]]) Number get window ID for {win} in {tab}
win_gotoid( {expr}) Number go to window with ID {expr}
win_id2tabwin( {expr}) List get tab and window nr from window ID
win_id2win( {expr}) Number get window nr from window ID
winbufnr( {nr}) Number buffer number of window {nr}
wincol() Number window column of the cursor
winheight( {nr}) Number height of window {nr}
@@ -2744,6 +2765,32 @@ ch_getjob({channel}) *ch_getjob()*
{only available when compiled with the |+channel| and
|+job| features}
ch_info({handle}) *ch_info()*
Returns a Dictionary with information about {handle}. The
items are:
"id" number of the channel
"status" "open" (any part is open) or "closed"
When opened with ch_open():
"hostname" the hostname of the address
"port" the port of the address
"sock_status" "open" or "closed"
"sock_mode" "NL", "RAW", "JSON" or "JS"
"sock_io" "socket"
"sock_timeout" timeout in msec
When opened with job_start():
"out_status" "open" or "closed"
"out_mode" "NL", "RAW", "JSON" or "JS"
"out_io" "null", "pipe", "file" or "buffer"
"out_timeout" timeout in msec
"err_status" "open" or "closed"
"err_mode" "NL", "RAW", "JSON" or "JS"
"err_io" "out", "null", "pipe", "file" or "buffer"
"err_timeout" timeout in msec
"in_status" "open" or "closed"
"in_mode" "NL", "RAW", "JSON" or "JS"
"in_io" "null", "pipe", "file" or "buffer"
"in_timeout" timeout in msec
ch_log({msg} [, {handle}]) *ch_log()*
Write {msg} in the channel log file, if it was opened with
|ch_logfile()|.
@@ -3553,9 +3600,68 @@ foreground() Move the Vim window to the foreground. Useful when sent from
Win32 console version}
function({name}) *function()* *E700*
*function()* *E700* *E922* *E923*
function({name} [, {arglist}] [, {dict}])
Return a |Funcref| variable that refers to function {name}.
{name} can be a user defined function or an internal function.
{name} can be the name of a user defined function or an
internal function.
{name} can also be a Funcref, also a partial. When it is a
partial the dict stored in it will be used and the {dict}
argument is not allowed. E.g.: >
let FuncWithArg = function(dict.Func, [arg])
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
the Funcref and will be used when the Funcref is called.
The arguments are passed to the function in front of other
arguments. Example: >
func Callback(arg1, arg2, name)
...
let Func = function('Callback', ['one', 'two'])
...
call Func('name')
< Invokes the function as with: >
call Callback('one', 'two', 'name')
< The function() call can be nested to add more arguments to the
Funcref. The extra arguments are appended to the list of
arguments. Example: >
func Callback(arg1, arg2, name)
...
let Func = function('Callback', ['one'])
let Func2 = function(Func, ['two'])
...
call Func2('name')
< Invokes the function as with: >
call Callback('one', 'two', 'name')
< The Dictionary is only useful when calling a "dict" function.
In that case the {dict} is passed in as "self". Example: >
function Callback() dict
echo "called for " . self.name
endfunction
...
let context = {"name": "example"}
let Func = function('Callback', context)
...
call Func() " will echo: called for example
< The use of function() is not needed when there are no extra
arguments, these two are equivalent: >
let Func = function('Callback', context)
let Func = context.Callback
< The argument list and the Dictionary can be combined: >
function Callback(arg1, count) dict
...
let context = {"name": "example"}
let Func = function('Callback', ['one'], context)
...
call Func(500)
< Invokes the function as with: >
call context.Callback('one', 500)
garbagecollect([{atexit}]) *garbagecollect()*
@@ -4471,13 +4577,13 @@ job_info({job}) *job_info()*
"status" what |job_status()| returns
"channel" what |job_getchannel()| returns
"exitval" only valid when "status" is "dead"
"exit-cb" function to be called on exit
"exit_cb" function to be called on exit
"stoponexit" |job-stoponexit|
job_setoptions({job}, {options}) *job_setoptions()*
Change options for {job}. Supported are:
"stoponexit" |job-stoponexit|
"exit-cb" |job-exit-cb|
"exit_cb" |job-exit_cb|
job_start({command} [, {options}]) *job_start()*
Start a job and return a Job object. Unlike |system()| and
@@ -6845,8 +6951,7 @@ systemlist({expr} [, {input}]) *systemlist()*
is the same as |readfile()| will output with {binary} argument
set to "b".
Returns an empty string on error, so be careful not to run
into |E706|.
Returns an empty string on error.
tabpagebuflist([{arg}]) *tabpagebuflist()*
@@ -6962,6 +7067,37 @@ tanh({expr}) *tanh()*
{only available when compiled with the |+float| feature}
*timer_start()*
timer_start({time}, {callback} [, {options}])
Create a timer and return the timer ID.
{time} is the waiting time in milliseconds. This is the
minimum time before invoking the callback. When the system is
busy or Vim is not waiting for input the time will be longer.
{callback} is the function to call. It can be the name of a
function or a Funcref. It is called with one argument, which
is the timer ID. The callback is only invoked when Vim is
waiting for input.
{options} is a dictionary. Supported entries:
"repeat" Number of times to repeat calling the
callback. -1 means forever.
Example: >
func MyHandler(timer)
echo 'Handler called'
endfunc
let timer = timer_start(500, 'MyHandler',
\ {'repeat': 3})
< This will invoke MyHandler() three times at 500 msec
intervals.
{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.
tolower({expr}) *tolower()*
The result is a copy of the String given, with all uppercase
characters turned into lowercase (just like applying |gu| to
@@ -7162,6 +7298,33 @@ wildmenumode() *wildmenumode()*
(Note, this needs the 'wildcharm' option set appropriately).
win_findbuf({bufnr}) *win_findbuf()*
Returns a list with window IDs for windows that contain buffer
{bufnr}. When there is none the list is empty.
win_getid([{win} [, {tab}]]) *win_getid()*
Get the window ID for the specified window.
When {win} is missing use the current window.
With {win} this is the window number. The top window has
number 1.
Without {tab} use the current tab, otherwise the tab with
number {tab}. The first tab has number one.
Return zero if the window cannot be found.
win_gotoid({expr}) *win_gotoid()*
Go to window with ID {expr}. This may also change the current
tabpage.
Return 1 if successful, 0 if the window cannot be found.
win_id2tabwin({expr} *win_id2tabwin()*
Return a list with the tab number and window number of window
with ID {expr}: [tabnr, winnr].
Return [0, 0] if the window cannot be found.
win_id2win({expr}) *win_id2win()*
Return the window number of window with ID {expr}.
Return 0 if the window cannot be found in the current tabpage.
*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
@@ -7494,6 +7657,7 @@ termresponse Compiled with support for |t_RV| and |v:termresponse|.
textobjects Compiled with support for |text-objects|.
tgetent Compiled with tgetent support, able to use a termcap
or terminfo file.
timers Compiled with |timer_start()| support.
title Compiled with window title support |'title'|.
toolbar Compiled with support for |gui-toolbar|.
transparency Compiled with 'transparency' support.
+4 -1
View File
@@ -1,4 +1,4 @@
*helphelp.txt* For Vim version 7.4. Last change: 2014 Sep 19
*helphelp.txt* For Vim version 7.4. Last change: 2016 Mar 12
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -197,6 +197,9 @@ command: >
*E154* *E150* *E151* *E152* *E153* *E670*
:helpt[ags] [++t] {dir}
Generate the help tags file(s) for directory {dir}.
When {dir} is ALL then all "doc" directories in
'runtimepath' will be used.
All "*.txt" and "*.??x" files in the directory and
sub-directories are scanned for a help tag definition
in between stars. The "*.??x" files are for
+13 -6
View File
@@ -410,13 +410,20 @@ This means that Vim will search for the Lua DLL or shared library file only
when needed. When you don't use the Lua interface you don't need it, thus
you can use Vim without this file.
On MS-Windows to use the Lua interface the Lua DLL must be in your search path.
In a console window type "path" to see what directories are used. The version
of the DLL must match the Lua version Vim was compiled with.
On Unix the 'luadll' option can be used to specify the Lua shared library file
instead of DYNAMIC_LUA_DLL file what was specified at compile time. The
version of the shared library must match the Lua version Vim was compiled with.
MS-Windows ~
To use the Lua interface the Lua DLL must be in your search path. In a
console window type "path" to see what directories are used. The 'luadll'
option can be also used to specify the Lua DLL. The version of the DLL must
match the Lua version Vim was compiled with.
Unix ~
The 'luadll' option can be used to specify the Lua shared library file instead
of DYNAMIC_LUA_DLL file what was specified at compile time. The version of
the shared library must match the Lua version Vim was compiled with.
==============================================================================
+2 -1
View File
@@ -284,7 +284,8 @@ used for building Vim.
To use the Perl interface the Perl DLL must be in your search path.
If Vim reports it cannot find the perl512.dll, make sure your $PATH includes
the directory where it is located. The Perl installer normally does that.
In a console window type "path" to see what directories are used.
In a console window type "path" to see what directories are used. The
'perldll' option can be also used to specify the Perl DLL.
The name of the DLL must match the Perl version Vim was compiled with.
Currently the name is "perl512.dll". That is for Perl 5.12. To know for
+13 -7
View File
@@ -686,18 +686,24 @@ This means that Vim will search for the Python DLL or shared library file only
when needed. When you don't use the Python interface you don't need it, thus
you can use Vim without this file.
On MS-Windows to use the Python interface the Python DLL must be in your search
path. In a console window type "path" to see what directories are used.
MS-Windows ~
To use the Python interface the Python DLL must be in your search path. In a
console window type "path" to see what directories are used. The 'pythondll'
or 'pythonthreedll' option can be also used to specify the Python DLL.
The name of the DLL must match the Python version Vim was compiled with.
Currently the name is "python24.dll". That is for Python 2.4. To know for
sure edit "gvim.exe" and search for "python\d*.dll\c".
On Unix the 'pythondll' or 'pythonthreedll' option can be used to specify the
Python shared library file instead of DYNAMIC_PYTHON_DLL or
DYNAMIC_PYTHON3_DLL file what were specified at compile time. The version of
the shared library must match the Python 2.x or Python 3 version Vim was
compiled with.
Unix ~
The 'pythondll' or 'pythonthreedll' option can be used to specify the Python
shared library file instead of DYNAMIC_PYTHON_DLL or DYNAMIC_PYTHON3_DLL file
what were specified at compile time. The version of the shared library must
match the Python 2.x or Python 3 version Vim was compiled with.
==============================================================================
10. Python 3 *python3*
+4 -1
View File
@@ -199,6 +199,7 @@ This means that Vim will search for the Ruby DLL file or shared library only
when needed. When you don't use the Ruby interface you don't need it, thus
you can use Vim even though this library file is not on your system.
MS-Windows ~
You need to install the right version of Ruby for this to work. You can find
@@ -207,7 +208,8 @@ http://www.garbagecollect.jp/ruby/mswin32/en/download/release.html
Currently that is ruby-1.9.1-p429-i386-mswin32.zip
To use the Ruby interface the Ruby DLL must be in your search path. In a
console window type "path" to see what directories are used.
console window type "path" to see what directories are used. The 'rubydll'
option can be also used to specify the Ruby DLL.
The name of the DLL must match the Ruby version Vim was compiled with.
Currently the name is "msvcrt-ruby191.dll". That is for Ruby 1.9.1. To know
@@ -218,6 +220,7 @@ and comment-out the check for _MSC_VER.
You may also need to rename the include directory name to match the version,
strangely for Ruby 1.9.3 the directory is called 1.9.1.
Unix ~
The 'rubydll' option can be used to specify the Ruby shared library file
+2 -1
View File
@@ -526,7 +526,8 @@ can use Vim without this file.
MS-Windows ~
To use the Tcl interface the Tcl DLL must be in your search path. In a
console window type "path" to see what directories are used.
console window type "path" to see what directories are used. The 'tcldll'
option can be also used to specify the Tcl DLL.
The name of the DLL must match the Tcl version Vim was compiled with.
Currently the name is "tcl86.dll". That is for Tcl 8.6. To know for sure
+2 -1
View File
@@ -1,4 +1,4 @@
*index.txt* For Vim version 7.4. Last change: 2016 Mar 04
*index.txt* For Vim version 7.4. Last change: 2016 Mar 12
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -1397,6 +1397,7 @@ tag command action ~
|:ounmenu| :ounme[nu] remove menu for Operator-pending mode
|:ownsyntax| :ow[nsyntax] set new local syntax highlight for this window
|:packadd| :pa[ckadd] add a plugin from 'packpath'
|:packloadall| :packl[oadall] load all packages under 'packpath'
|:pclose| :pc[lose] close preview window
|:pedit| :ped[it] edit file in the preview window
|:perl| :pe[rl] execute Perl command
+25 -14
View File
@@ -1,4 +1,4 @@
*options.txt* For Vim version 7.4. Last change: 2016 Mar 08
*options.txt* For Vim version 7.4. Last change: 2016 Mar 19
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -69,7 +69,7 @@ achieve special effects. These options come in three forms:
:se[t] {option}:{value}
Set string or number option to {value}.
For numeric options the value can be given in decimal,
hex (preceded with 0x) or octal (preceded with '0').
hex (preceded with 0x) or octal (preceded with '0').
The old value can be inserted by typing 'wildchar' (by
default this is a <Tab> or CTRL-E if 'compatible' is
set). See |cmdline-completion|.
@@ -1007,7 +1007,7 @@ A jump table for the options with a short description can be found at |Q_op|.
- The backup file will be created in the first directory in the list
where this is possible. The directory must exist, Vim will not
create it for you.
- Empty means that no backup file will be created ( 'patchmode' is
- Empty means that no backup file will be created ('patchmode' is
impossible!). Writing may fail because of this.
- A directory "." means to put the backup file in the same directory
as the edited file.
@@ -1805,7 +1805,7 @@ A jump table for the options with a short description can be found at |Q_op|.
when CTRL-P or CTRL-N are used. It is also used for whole-line
completion |i_CTRL-X_CTRL-L|. It indicates the type of completion
and the places to scan. It is a comma separated list of flags:
. scan the current buffer ( 'wrapscan' is ignored)
. scan the current buffer ('wrapscan' is ignored)
w scan buffers from other windows
b scan other loaded buffers that are in the buffer list
u scan the unloaded buffers that are in the buffer list
@@ -2657,6 +2657,15 @@ A jump table for the options with a short description can be found at |Q_op|.
also 'gdefault' option.
Switching this option on is discouraged!
*'emoji'* *'emo'*
'emoji' 'emo' boolean (default: on)
global
{not in Vi}
{only available when compiled with the |+multi_byte|
feature}
When on all Unicode emoji characters are considered to be full width.
*'encoding'* *'enc'* *E543*
'encoding' 'enc' string (default: "latin1" or value from $LANG)
global
@@ -3839,7 +3848,7 @@ A jump table for the options with a short description can be found at |Q_op|.
The same applies to the modeless selection.
*'go-P'*
'P' Like autoselect but using the "+ register instead of the "*
register.
register.
*'go-A'*
'A' Autoselect for the modeless selection. Like 'a', but only
applies to the modeless selection.
@@ -4951,7 +4960,7 @@ A jump table for the options with a short description can be found at |Q_op|.
reset this option. |-u| |--noplugin|
*'luadll'*
'luadll' string (default depends on the build)
'luadll' string (default depends on the build)
global
{not in Vi}
{only available when compiled with the |+lua/dyn|
@@ -5434,7 +5443,7 @@ A jump table for the options with a short description can be found at |Q_op|.
respectively; see |CTRL-A| for more info on these commands.
alpha If included, single alphabetical characters will be
incremented or decremented. This is useful for a list with a
letter index a), b), etc. *octal-nrformats*
letter index a), b), etc. *octal-nrformats*
octal If included, numbers that start with a zero will be considered
to be octal. Example: Using CTRL-A on "007" results in "010".
hex If included, numbers starting with "0x" or "0X" will be
@@ -5464,7 +5473,7 @@ A jump table for the options with a short description can be found at |Q_op|.
relative to the cursor. Together with 'number' there are these
four combinations (cursor in line 3):
'nonu' 'nu' 'nonu' 'nu'
'nonu' 'nu' 'nonu' 'nu'
'nornu' 'nornu' 'rnu' 'rnu'
|apple | 1 apple | 2 apple | 2 apple
@@ -5703,7 +5712,7 @@ A jump table for the options with a short description can be found at |Q_op|.
this doesn't work when $INCL contains a comma or white space.
*'perldll'*
'perldll' string (default depends on the build)
'perldll' string (default depends on the build)
global
{not in Vi}
{only available when compiled with the |+perl/dyn|
@@ -5840,7 +5849,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|ins-completion-menu|.
*'pythondll'*
'pythondll' string (default depends on the build)
'pythondll' string (default depends on the build)
global
{not in Vi}
{only available when compiled with the |+python/dyn|
@@ -6081,7 +6090,7 @@ A jump table for the options with a short description can be found at |Q_op|.
The 'rightleft' option must be set for 'rightleftcmd' to take effect.
*'rubydll'*
'rubydll' string (default: depends on the build)
'rubydll' string (default: depends on the build)
global
{not in Vi}
{only available when compiled with the |+ruby/dyn|
@@ -6669,7 +6678,9 @@ A jump table for the options with a short description can be found at |Q_op|.
c don't give |ins-completion-menu| messages. For example,
"-- XXX completion (YYY)", "match 1 of 2", "The only match",
"Pattern not found", "Back at original", etc.
q use "recording" instead of "recording @a"
q use "recording" instead of "recording @a"
F don't give the file info when editing a file, like `:silent`
was used for the command
This gives you the opportunity to avoid that a change between buffers
requires you to hit <Enter>, but still gives as useful a message as
@@ -7573,7 +7584,7 @@ A jump table for the options with a short description can be found at |Q_op|.
mapping which should not change the tagstack.
*'tcldll'*
'tcldll' string (default depends on the build)
'tcldll' string (default depends on the build)
global
{not in Vi}
{only available when compiled with the |+tcl/dyn|
@@ -7629,7 +7640,7 @@ A jump table for the options with a short description can be found at |Q_op|.
{not in Vi}
Encoding used for the terminal. This specifies what character
encoding the keyboard produces and the display will understand. For
the GUI it only applies to the keyboard ( 'encoding' is used for the
the GUI it only applies to the keyboard ('encoding' is used for the
display). Except for the Mac when 'macatsui' is off, then
'termencoding' should be "macroman" (for the Carbon GUI).
In the Win32 console version the default value is the console codepage
+9 -1
View File
@@ -1,4 +1,4 @@
*quickfix.txt* For Vim version 7.4. Last change: 2016 Jan 21
*quickfix.txt* For Vim version 7.4. Last change: 2016 Mar 23
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -56,6 +56,14 @@ The following quickfix commands can be used. The location list commands are
similar to the quickfix commands, replacing the 'c' prefix in the quickfix
command with 'l'.
*E924*
If the current window was closed by an |autocommand| while processing a
location list command, it will be aborted.
*E925* *E926*
If the current quickfix or location list was changed by an |autocommand| while
processing a quickfix or location list command, it will be aborted.
*:cc*
:cc[!] [nr] Display error [nr]. If [nr] is omitted, the same
error is displayed again. Without [!] this doesn't
+7 -4
View File
@@ -1,4 +1,4 @@
*repeat.txt* For Vim version 7.4. Last change: 2016 Mar 09
*repeat.txt* For Vim version 7.4. Last change: 2016 Mar 15
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -249,15 +249,18 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
Also see |pack-add|.
*:packl* *:packloadall*
:packloadall[!] Load all packages in the "start" directories under
'packpath'. The directories found are added to
'runtimepath'.
This normally done during startup, after loading your
.vimrc file. With this command it can be done
earlier.
This is normally done automatically during startup,
after loading your .vimrc file. With this command it
can be done earlier.
Packages will be loaded only once. After this command
it won't happen again. When the optional ! is added
this command will load packages even when done before.
An Error only causes sourcing the script where it
happens to be aborted, further plugins will be loaded.
See |packages|.
:scripte[ncoding] [encoding] *:scripte* *:scriptencoding* *E167*
+4 -4
View File
@@ -1,4 +1,4 @@
*syntax.txt* For Vim version 7.4. Last change: 2016 Feb 25
*syntax.txt* For Vim version 7.4. Last change: 2016 Mar 12
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -4534,9 +4534,9 @@ in their own color.
:colo[rscheme] {name} Load color scheme {name}. This searches 'runtimepath'
for the file "colors/{name}.vim". The first one that
is found is loaded.
To see the name of the currently active color scheme: >
:colo
< The name is also stored in the g:colors_name variable.
Also searches all plugins in 'packpath', first below
"start" and then under "opt".
Doesn't work recursively, thus you can't use
":colorscheme" in a color scheme script.
After the color scheme has been loaded the
+43 -22
View File
@@ -209,6 +209,8 @@ $VIM_POSIX vi_diff.txt /*$VIM_POSIX*
'efm' options.txt /*'efm'*
'ei' options.txt /*'ei'*
'ek' options.txt /*'ek'*
'emo' options.txt /*'emo'*
'emoji' options.txt /*'emoji'*
'enc' options.txt /*'enc'*
'encoding' options.txt /*'encoding'*
'endofline' options.txt /*'endofline'*
@@ -1304,6 +1306,7 @@ $VIM_POSIX vi_diff.txt /*$VIM_POSIX*
+termresponse various.txt /*+termresponse*
+textobjects various.txt /*+textobjects*
+tgetent various.txt /*+tgetent*
+timers various.txt /*+timers*
+title various.txt /*+title*
+toolbar various.txt /*+toolbar*
+transparency various.txt /*+transparency*
@@ -2643,6 +2646,8 @@ $VIM_POSIX vi_diff.txt /*$VIM_POSIX*
:p various.txt /*:p*
:pa repeat.txt /*:pa*
:packadd repeat.txt /*:packadd*
:packl repeat.txt /*:packl*
:packloadall repeat.txt /*:packloadall*
:pc windows.txt /*:pc*
:pclose windows.txt /*:pclose*
:pe if_perl.txt /*:pe*
@@ -4261,7 +4266,6 @@ E702 eval.txt /*E702*
E703 eval.txt /*E703*
E704 eval.txt /*E704*
E705 eval.txt /*E705*
E706 eval.txt /*E706*
E707 eval.txt /*E707*
E708 eval.txt /*E708*
E709 eval.txt /*E709*
@@ -4493,6 +4497,11 @@ E917 eval.txt /*E917*
E918 channel.txt /*E918*
E919 repeat.txt /*E919*
E92 message.txt /*E92*
E920 channel.txt /*E920*
E921 channel.txt /*E921*
E922 eval.txt /*E922*
E923 eval.txt /*E923*
E924 quickfix.txt /*E924*
E93 windows.txt /*E93*
E94 windows.txt /*E94*
E95 message.txt /*E95*
@@ -5222,6 +5231,7 @@ ch_evalexpr() eval.txt /*ch_evalexpr()*
ch_evalraw() eval.txt /*ch_evalraw()*
ch_getbufnr() eval.txt /*ch_getbufnr()*
ch_getjob() eval.txt /*ch_getjob()*
ch_info() eval.txt /*ch_info()*
ch_log() eval.txt /*ch_log()*
ch_logfile() eval.txt /*ch_logfile()*
ch_open() eval.txt /*ch_open()*
@@ -5330,7 +5340,7 @@ clipboard-html options.txt /*clipboard-html*
clipboard-unnamed options.txt /*clipboard-unnamed*
clipboard-unnamedplus options.txt /*clipboard-unnamedplus*
clojure-indent indent.txt /*clojure-indent*
close-cb channel.txt /*close-cb*
close_cb channel.txt /*close_cb*
cmd-key gui_mac.txt /*cmd-key*
cmd-movement gui_mac.txt /*cmd-movement*
cmd-shortcuts gui_mac.txt /*cmd-shortcuts*
@@ -5698,10 +5708,11 @@ end intro.txt /*end*
end-of-file pattern.txt /*end-of-file*
enlightened-terminal syntax.txt /*enlightened-terminal*
erlang.vim syntax.txt /*erlang.vim*
err-buf channel.txt /*err-buf*
err-cb channel.txt /*err-cb*
err-name channel.txt /*err-name*
err-timeout channel.txt /*err-timeout*
err_buf channel.txt /*err_buf*
err_cb channel.txt /*err_cb*
err_mode channel.txt /*err_mode*
err_name channel.txt /*err_name*
err_timeout channel.txt /*err_timeout*
errmsg-variable eval.txt /*errmsg-variable*
error-file-format quickfix.txt /*error-file-format*
error-messages message.txt /*error-messages*
@@ -6824,10 +6835,11 @@ improved-viminfo version5.txt /*improved-viminfo*
improvements-5 version5.txt /*improvements-5*
improvements-6 version6.txt /*improvements-6*
improvements-7 version7.txt /*improvements-7*
in-bot channel.txt /*in-bot*
in-buf channel.txt /*in-buf*
in-name channel.txt /*in-name*
in-top channel.txt /*in-top*
in_bot channel.txt /*in_bot*
in_buf channel.txt /*in_buf*
in_mode channel.txt /*in_mode*
in_name channel.txt /*in_name*
in_top channel.txt /*in_top*
inactive-buffer windows.txt /*inactive-buffer*
include-search tagsrch.txt /*include-search*
inclusive motion.txt /*inclusive*
@@ -6905,21 +6917,22 @@ javascript-indenting indent.txt /*javascript-indenting*
job channel.txt /*job*
job-callback channel.txt /*job-callback*
job-channel-overview channel.txt /*job-channel-overview*
job-close-cb channel.txt /*job-close-cb*
job-close_cb channel.txt /*job-close_cb*
job-control channel.txt /*job-control*
job-err-cb channel.txt /*job-err-cb*
job-err-io channel.txt /*job-err-io*
job-exit-cb channel.txt /*job-exit-cb*
job-in-io channel.txt /*job-in-io*
job-err_cb channel.txt /*job-err_cb*
job-err_io channel.txt /*job-err_io*
job-exit_cb channel.txt /*job-exit_cb*
job-in_io channel.txt /*job-in_io*
job-options channel.txt /*job-options*
job-out-cb channel.txt /*job-out-cb*
job-out-io channel.txt /*job-out-io*
job-out_cb channel.txt /*job-out_cb*
job-out_io channel.txt /*job-out_io*
job-start channel.txt /*job-start*
job-start-if-needed channel.txt /*job-start-if-needed*
job-start-nochannel channel.txt /*job-start-nochannel*
job-stoponexit channel.txt /*job-stoponexit*
job-term channel.txt /*job-term*
job_getchannel() eval.txt /*job_getchannel()*
job_info() eval.txt /*job_info()*
job_setoptions() eval.txt /*job_setoptions()*
job_start() eval.txt /*job_start()*
job_status() eval.txt /*job_status()*
@@ -7604,6 +7617,7 @@ news intro.txt /*news*
nextnonblank() eval.txt /*nextnonblank()*
nice todo.txt /*nice*
no-eval-feature eval.txt /*no-eval-feature*
no-type-checking eval.txt /*no-type-checking*
no_buffers_menu gui.txt /*no_buffers_menu*
non-greedy pattern.txt /*non-greedy*
non-zero-arg eval.txt /*non-zero-arg*
@@ -7673,10 +7687,11 @@ os_unix.txt os_unix.txt /*os_unix.txt*
os_vms.txt os_vms.txt /*os_vms.txt*
os_win32.txt os_win32.txt /*os_win32.txt*
other-features vi_diff.txt /*other-features*
out-buf channel.txt /*out-buf*
out-cb channel.txt /*out-cb*
out-name channel.txt /*out-name*
out-timeout channel.txt /*out-timeout*
out_buf channel.txt /*out_buf*
out_cb channel.txt /*out_cb*
out_mode channel.txt /*out_mode*
out_name channel.txt /*out_name*
out_timeout channel.txt /*out_timeout*
p change.txt /*p*
pack-add repeat.txt /*pack-add*
packages repeat.txt /*packages*
@@ -8293,7 +8308,6 @@ startup-terminal term.txt /*startup-terminal*
static-tag tagsrch.txt /*static-tag*
status-line windows.txt /*status-line*
statusmsg-variable eval.txt /*statusmsg-variable*
sticky-type-checking eval.txt /*sticky-type-checking*
str2float() eval.txt /*str2float()*
str2nr() eval.txt /*str2nr()*
strcasestr() eval.txt /*strcasestr()*
@@ -8674,6 +8688,8 @@ throw-from-catch eval.txt /*throw-from-catch*
throw-variables eval.txt /*throw-variables*
throwpoint-variable eval.txt /*throwpoint-variable*
time-functions usr_41.txt /*time-functions*
timer_start() eval.txt /*timer_start()*
timer_stop() eval.txt /*timer_stop()*
timestamp editing.txt /*timestamp*
timestamps editing.txt /*timestamps*
tips tips.txt /*tips*
@@ -9123,6 +9139,11 @@ win32-term os_win32.txt /*win32-term*
win32-vimrun gui_w32.txt /*win32-vimrun*
win32-win3.1 os_win32.txt /*win32-win3.1*
win32s os_win32.txt /*win32s*
win_findbuf() eval.txt /*win_findbuf()*
win_getid() eval.txt /*win_getid()*
win_gotoid() eval.txt /*win_gotoid()*
win_id2tabwin() eval.txt /*win_id2tabwin()*
win_id2win() eval.txt /*win_id2win()*
winbufnr() eval.txt /*winbufnr()*
wincol() eval.txt /*wincol()*
window windows.txt /*window*
+28 -68
View File
@@ -1,4 +1,4 @@
*todo.txt* For Vim version 7.4. Last change: 2016 Mar 11
*todo.txt* For Vim version 7.4. Last change: 2016 Mar 20
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -35,15 +35,8 @@ not be repeated below, unless there is extra information.
-------------------- Known bugs and current work -----------------------
+channel:
- CHANNEL_PIPES -> FEAT_JOB
- FEAT_JOB / FEAT_CHANNEL -> FEAT_JOBCHANNEL ?
- move code from eval.c to channel.c
- add job_info(): process ID, run/dead, etc.
- add ch_info(): in/out/err mode, timeout, callbacks, etc.
- add test for out-cb and err-cb.
- Move more details from eval.txt to channel.txt. Add tags in eval.txt.
- When receiving malformed json starting with a quote it doesn't get
discarded. Any invalid JSON or JSON that isn't a list will block further
parsing?
- When decoding json, don't read all the typeahead at once, use the reader
properly.
- When a message in the queue but there is no callback, drop it after a while?
@@ -64,47 +57,9 @@ Later
- job_start(): run job in a newly opened terminal.
With xterm could use -S{pty}.
emoji patch from Yasuhiro Matsumoto. Asked Thomas Dickey.
Packages: how about "after" directory?
Remove sticky type checking.
Packages:
- Add command to update help tags in 'runtimepath'. Pathogen has something
like that.
- colorscheme command in .vimrc doesn't work.
- Also search in 'packpath', both "start" and "opt", don't add dir to 'rtp'
- command like :runtime that also search 'packpath'. :packruntime
use "ever" or "opt"? both?
- command to load packages now?
More plugin support:
- Have a way to install a callback from the main loop. Called every second or
so.
- Need way to uniquely identify a window, no matter how windows are
rearranged. Same for tab pages.
getwinid() ID of current winow
getwinid({nr}) ID of window {nr}
getwinid({nr}, {tab}) ID of window {nr} in tab page {tab}
getwinnr({id}) window nr of {id} or -1 if not open
gettabnr({id}) tab page nr of {id} or -1 if not open
gotowin({id})
Make it so that the window ID can be used where currently a window nr is used
Patch from Anton Lindqvist, 2016 Feb 21, to make bufwinnr() return a list.
Perhaps add bufwinid() instead.
This difference is unexpected:
echo v:true == 1
1
echo [v:true] == [1]
0
It's because tv_equal() works different.
Compiler warnings. (John Marriott, Feb 17)
Compiler warnings in if_ole.cpp. Patch by Ken Takata, Feb 18.
When running "make install" don't overwrite the doc/tags file, generate it
elsewhere, so that the distributed file doesn't change.
Make it so that the window ID can be used where currently a window nr is used
Fix to support --nofork for Windows batch files. (Kevin Cantú, 2016 Feb 23,
#658, #659) Also add "setlocal" at top of batch file?
@@ -170,6 +125,12 @@ Christian Brabandt, 2016 Feb 18.
Also include update_curswant() fix for getcurpos(). (Christian Brabandt, 2016
Feb 9)
Patch to list some messages and clear messages. (Yasuhiro Matsumoto, 2016 Mar
12)
Patch to fix escaping special characters for delete(). (tc-0, 2016 Mar 20,
#700) Test fails on MS-Windows.
Patch to put undo options together in undo window.
(Gary Johnson, 2016 Jan 28)
@@ -182,6 +143,10 @@ Feb 3)
Patch for test86 and test87. (Roland Puntaier, #622)
Cannot delete a file with square brackets with delete(). (#696)
Patch to add 'topbot' to 'belloff' option. (Coot, 2016 Mar 18, #695)
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 .)?
@@ -200,9 +165,14 @@ After 7.5 is released:
- Drop support for older MS-Windows systems, before XP.
Patch from Ken Takata, 2016 Mar 8.
Add stronger encryption. Could use libsodium (NaCl).
https://github.com/jedisct1/libsodium/
Possibly include the needed code so that it can be build everywhere.
Patch to add setbufline(). (email from Yasuhiro Matsumoto, patch by Ozaki
Kiichi, 2016 Feb 28)
Update Mar 8: https://gist.github.com/mattn/23c1f50999084992ca98
Update Mar 13: https://gist.github.com/mattn/23c1f50999084992ca98
Need to try out instructions in INSSTALLpc.txt about how to install all
interfaces and how to build Vim with them.
@@ -210,9 +180,6 @@ Appveyor build with self-installing executable, includes getting most
interfaces: https://github.com/k-takata/vim/tree/chrisbra-appveyor-build
result: https://ci.appveyor.com/project/k-takata/vim/history
Still using freed memory after using setloclist(). (lcd, 2014 Jul 23)
More info Jul 24. Not clear why.
Duplication of completion suggestions for ":!hom". Issue 539.
Patch by Christian, 2016 Jan 29
>
@@ -242,9 +209,6 @@ Should use /usr/local/share/applications or /usr/share/applications.
Or use $XDG_DATA_DIRS.
Also need to run update-desktop-database (Kuriyama Kazunobu, 2015 Nov 4)
Move the README files that are for including in archives to a subdirectory.
"readmedir/" ?
Access to uninitialized memory in match_backref() regexp_nda.c:4882
(Dominique Pelle, 2015 Nov 6)
@@ -333,6 +297,9 @@ Patch to add :mapgroup, put mappings in a group like augroup.
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)
Can we cache the syntax attributes, so that updates for 'relativenumber' and
'cursorline'/'cursorcolumn' are a lot faster?
@@ -412,8 +379,6 @@ Patch to fix checking global option value when not using it.
When 'showbreak' is set repeating a Visual operation counts the size of the
'showbreak' text as part of the operation. (Axel Bender, 2015 Jul 20)
Patch to apply 'fileformats' when starting Vim. (Mike Williams, 2015 Jul 22)
Patch for matchit plugin related to multibyte chars. (Ken Takata, 2015 Jul 22)
Patch for multi-byte characters in langmap and applying a mapping on them.
@@ -471,6 +436,7 @@ Mixup of highlighting when there is a match and SpellBad. (ZyX, 2015 Jan 1)
Patch for drag&drop reordering of GUI tab pages reordering.
(Ken Takata, 2013 Nov 22, second one, also by Masamichi Abe)
Now on Git: https://gist.github.com/nocd5/165286495c782b815b94
Update 2016 Mar 15.
Patch on Issue 72: 'autochdir' causes problems for :vimgrep.
@@ -3732,7 +3698,7 @@ Syntax highlighting:
unprintable char another color. Would be useful for ^M at end of line.
Built-in script language:
Vim script language:
8 Make the filename and line number available to script functions, so that
they can give useful debugging info. The whole call stack would be ideal.
At least use this for error messages.
@@ -3753,14 +3719,10 @@ Built-in script language:
7 ":include" command: just like ":source" but doesn't start a new scriptID?
Will be tricky for the list of script names.
8 Have a look at VSEL. Would it be useful to include? (Bigham)
8 Add ":fungroup" command, to group function definitions together. When
encountered, all functions in the group are removed. Suggest using an
obscure name to avoid name clashes. Require a ":fungroup END" in the same
sourced file? Assume the group ends at the end of the file. Handle
nested packages?
Alternative: Support packages. {package-name}:{function-name}().
Packages are loaded automatically when first used, from
$VIMRUNTIME/packages (or use a search path).
8 Have a prefix for a function to make it unique. When using packages it
can be the plugin name.
Perhaps also have a way to remove everything that the package added?
including autocommands.
7 Pre-parse or compile Vim scripts into a bytecode.
1. Put the bytecode with the original script, with an ":if
has('bytecode')" around it, so that it's only used with a Vim that
@@ -3777,8 +3739,6 @@ Built-in script language:
8 Add functions:
has(":command") Check if ":command" works. compare function
with "ex_ni". E.g. for ":simalt".
system() With a List argument. Bypasses the shell, use
exec() directly. (Bob Hiestand)
escape() Add argument to specify what to escape with.
modestack() Instead of just the current mode return the
stack of Insert / CTRL-O / :normal things.
+58 -22
View File
@@ -1,4 +1,4 @@
*usr_05.txt* For Vim version 7.4. Last change: 2012 Nov 20
*usr_05.txt* For Vim version 7.4. Last change: 2016 Mar 25
VIM USER MANUAL - by Bram Moolenaar
@@ -12,10 +12,11 @@ Vim's capabilities. Or define your own macros.
|05.1| The vimrc file
|05.2| The example vimrc file explained
|05.3| Simple mappings
|05.4| Adding a plugin
|05.5| Adding a help file
|05.6| The option window
|05.7| Often used options
|05.4| Adding a package
|05.5| Adding a plugin
|05.6| Adding a help file
|05.7| The option window
|05.8| Often used options
Next chapter: |usr_06.txt| Using syntax highlighting
Previous chapter: |usr_04.txt| Making small changes
@@ -263,7 +264,46 @@ The ":map" command (with no arguments) lists your current mappings. At
least the ones for Normal mode. More about mappings in section |40.1|.
==============================================================================
*05.4* Adding a plugin *add-plugin* *plugin*
*05.4* Adding a package *add-package* *matchit-install*
A package is a set of files that you can add to Vim. There are two kinds of
packages: optional and automatically loaded on startup.
The Vim distribution comes with a few packages that you can optionally use.
For example, the matchit plugin. This plugin makes the "%" command jump to
matching HTML tags, if/else/endif in Vim scripts, etc. Very useful, although
it's not backwards compatible (that's why it is not enabled by default).
To start using the matchit plugin, add one line to your vimrc file: >
packadd matchit
That's all! You can also type the command to try it out. Now you can find
help about this plugin: >
:help matchit
This works, because when `:packadd` loaded the plugin it also added the
package directory in 'runtimepath', so that the help file can be found.
You can find packages on the Internet in various places. It usually comes as
an archive or as a repository. For an archive you can follow these steps:
1. create the package directory: >
mkdir -p ~/.vim/pack/fancy
< "fancy" can be any name of your liking. Use one that describes the
package.
2. unpack the archive in that directory. This assumes the top
directory in the archive is "start": >
cd ~/.vim/pack/fancy
unzip /tmp/fancy.zip
< If the archive layout is different make sure that you end up with a
path like this:
~/.vim/pack/fancy/start/fancytext/plugin/fancy.vim ~
Here "fancytext" is the name of the package, it can be anything
else.
More information about packages can be found here: |packages|.
==============================================================================
*05.5* Adding a plugin *add-plugin* *plugin*
Vim's functionality can be extended by adding plugins. A plugin is nothing
more than a Vim script file that is loaded automatically when Vim starts. You
@@ -415,23 +455,19 @@ Further reading:
|new-filetype| How to detect a new file type.
==============================================================================
*05.5* Adding a help file *add-local-help* *matchit-install*
*05.6* Adding a help file *add-local-help*
If you are lucky, the plugin you installed also comes with a help file. We
will explain how to install the help file, so that you can easily find help
for your new plugin.
Let us use the "matchit.vim" plugin as an example (it is included with
Vim). This plugin makes the "%" command jump to matching HTML tags,
if/else/endif in Vim scripts, etc. Very useful, although it's not backwards
compatible (that's why it is not enabled by default).
This plugin comes with documentation: "matchit.txt". Let's first copy the
plugin to the right directory. This time we will do it from inside Vim, so
that we can use $VIMRUNTIME. (You may skip some of the "mkdir" commands if
you already have the directory.) >
Let us use the "doit.vim" plugin as an example. This plugin comes with
documentation: "doit.txt". Let's first copy the plugin to the right
directory. This time we will do it from inside Vim. (You may skip some of
the "mkdir" commands if you already have the directory.) >
:!mkdir ~/.vim
:!mkdir ~/.vim/plugin
:!cp $VIMRUNTIME/macros/matchit.vim ~/.vim/plugin
:!cp /tmp/doit.vim ~/.vim/plugin
The "cp" command is for Unix, on MS-DOS you can use "copy".
@@ -441,7 +477,7 @@ Now create a "doc" directory in one of the directories in 'runtimepath'. >
Copy the help file to the "doc" directory. >
:!cp $VIMRUNTIME/macros/matchit.txt ~/.vim/doc
:!cp /tmp/doit.txt ~/.vim/doc
Now comes the trick, which allows you to jump to the subjects in the new help
file: Generate the local tags file with the |:helptags| command. >
@@ -450,10 +486,10 @@ file: Generate the local tags file with the |:helptags| command. >
Now you can use the >
:help g%
:help doit
command to find help for "g%" in the help file you just added. You can see an
entry for the local help file when you do: >
command to find help for "doit" in the help file you just added. You can see
an entry for the local help file when you do: >
:help local-additions
@@ -464,7 +500,7 @@ them through the tag.
For writing a local help file, see |write-local-help|.
==============================================================================
*05.6* The option window
*05.7* The option window
If you are looking for an option that does what you want, you can search in
the help files here: |options|. Another way is by using this command: >
@@ -503,7 +539,7 @@ border. This is what the 'scrolloff' option does, it specifies an offset
from the window border where scrolling starts.
==============================================================================
*05.7* Often used options
*05.8* Often used options
There are an awful lot of options. Most of them you will hardly ever use.
Some of the more useful ones will be mentioned here. Don't forget you can
+5 -3
View File
@@ -1,4 +1,4 @@
*usr_41.txt* For Vim version 7.4. Last change: 2016 Feb 14
*usr_41.txt* For Vim version 7.4. Last change: 2016 Mar 15
VIM USER MANUAL - by Bram Moolenaar
@@ -889,9 +889,11 @@ Mappings: *mapping-functions*
wildmenumode() check if the wildmode is active
Testing: *test-functions*
assert_equal() assert that two expressions values are equal
assert_equal() assert that two expressions values are equal
assert_false() assert that an expression is false
assert_true() assert that an expression is true
assert_exception() assert that a command throws an exception
assert_fails() assert that a function call fails
Inter-process communication:
ch_open() open a channel
@@ -932,7 +934,7 @@ Various: *various-functions*
perleval() evaluate Perl expression (|+perl|)
py3eval() evaluate Python expression (|+python3|)
pyeval() evaluate Python expression (|+python|)
wordcount() get byte/word/char count of buffer
wordcount() get byte/word/char count of buffer
==============================================================================
*41.7* Defining a function
+6 -5
View File
@@ -1,4 +1,4 @@
*usr_toc.txt* For Vim version 7.4. Last change: 2010 Jul 20
*usr_toc.txt* For Vim version 7.4. Last change: 2016 Mar 25
VIM USER MANUAL - by Bram Moolenaar
@@ -104,10 +104,11 @@ Read this from start to end to learn the essential commands.
|05.1| The vimrc file
|05.2| The example vimrc file explained
|05.3| Simple mappings
|05.4| Adding a plugin
|05.5| Adding a help file
|05.6| The option window
|05.7| Often used options
|05.4| Adding a package
|05.5| Adding a plugin
|05.6| Adding a help file
|05.7| The option window
|05.8| Often used options
|usr_06.txt| Using syntax highlighting
|06.1| Switching it on
+2 -1
View File
@@ -1,4 +1,4 @@
*various.txt* For Vim version 7.4. Last change: 2016 Feb 27
*various.txt* For Vim version 7.4. Last change: 2016 Mar 20
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -428,6 +428,7 @@ m *+tcl/dyn* Tcl interface |tcl-dynamic| |/dyn|
N *+termresponse* support for |t_RV| and |v:termresponse|
N *+textobjects* |text-objects| selection
*+tgetent* non-Unix only: able to use external termcap
N *+timers* the |timer_start()| function
N *+title* Setting the window 'title' and 'icon'
N *+toolbar* |gui-toolbar|
m *+transparency* MacVim only: window background transparency
+5 -3
View File
@@ -15,8 +15,6 @@ dvorak for when you use a Dvorak keyboard
justify.vim user function for justifying text
matchit.vim + matchit.txt make % match if-fi, HTML tags, and much more
less.sh + less.vim make Vim work like less (or more)
shellmenu.vim menus for editing shell scripts in the GUI version
@@ -26,5 +24,9 @@ swapmous.vim swap left and right mouse buttons
editexisting.vim when editing a file that is already edited with
another Vim instance
This one is only for Unix. It can be found in the extra archive:
This one is only for Unix.
file_select.vim macros that make a handy file selector
The matchit plugin has been moved to an optional package. To load it put this
line in your vimrc file:
:packadd matchit
+3 -813
View File
@@ -1,813 +1,3 @@
" matchit.vim: (global plugin) Extended "%" matching
" Last Change: Fri Jan 25 10:00 AM 2008 EST
" Maintainer: Benji Fisher PhD <benji@member.AMS.org>
" Version: 1.13.2, for Vim 6.3+
" URL: http://www.vim.org/script.php?script_id=39
" Documentation:
" The documentation is in a separate file, matchit.txt .
" Credits:
" Vim editor by Bram Moolenaar (Thanks, Bram!)
" Original script and design by Raul Segura Acevedo
" Support for comments by Douglas Potts
" Support for back references and other improvements by Benji Fisher
" Support for many languages by Johannes Zellner
" Suggestions for improvement, bug reports, and support for additional
" languages by Jordi-Albert Batalla, Neil Bird, Servatius Brandt, Mark
" Collett, Stephen Wall, Dany St-Amant, Yuheng Xie, and Johannes Zellner.
" Debugging:
" If you'd like to try the built-in debugging commands...
" :MatchDebug to activate debugging for the current buffer
" This saves the values of several key script variables as buffer-local
" variables. See the MatchDebug() function, below, for details.
" TODO: I should think about multi-line patterns for b:match_words.
" This would require an option: how many lines to scan (default 1).
" This would be useful for Python, maybe also for *ML.
" TODO: Maybe I should add a menu so that people will actually use some of
" the features that I have implemented.
" TODO: Eliminate the MultiMatch function. Add yet another argument to
" Match_wrapper() instead.
" TODO: Allow :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1'
" TODO: Make backrefs safer by using '\V' (very no-magic).
" TODO: Add a level of indirection, so that custom % scripts can use my
" work but extend it.
" allow user to prevent loading
" and prevent duplicate loading
if exists("loaded_matchit") || &cp
finish
endif
let loaded_matchit = 1
let s:last_mps = ""
let s:last_words = ":"
let s:save_cpo = &cpo
set cpo&vim
nnoremap <silent> % :<C-U>call <SID>Match_wrapper('',1,'n') <CR>
nnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'n') <CR>
vnoremap <silent> % :<C-U>call <SID>Match_wrapper('',1,'v') <CR>m'gv``
vnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'v') <CR>m'gv``
onoremap <silent> % v:<C-U>call <SID>Match_wrapper('',1,'o') <CR>
onoremap <silent> g% v:<C-U>call <SID>Match_wrapper('',0,'o') <CR>
" Analogues of [{ and ]} using matching patterns:
nnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "n") <CR>
nnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W", "n") <CR>
vmap [% <Esc>[%m'gv``
vmap ]% <Esc>]%m'gv``
" vnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "v") <CR>m'gv``
" vnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W", "v") <CR>m'gv``
onoremap <silent> [% v:<C-U>call <SID>MultiMatch("bW", "o") <CR>
onoremap <silent> ]% v:<C-U>call <SID>MultiMatch("W", "o") <CR>
" text object:
vmap a% <Esc>[%v]%
" Auto-complete mappings: (not yet "ready for prime time")
" TODO Read :help write-plugin for the "right" way to let the user
" specify a key binding.
" let g:match_auto = '<C-]>'
" let g:match_autoCR = '<C-CR>'
" if exists("g:match_auto")
" execute "inoremap " . g:match_auto . ' x<Esc>"=<SID>Autocomplete()<CR>Pls'
" endif
" if exists("g:match_autoCR")
" execute "inoremap " . g:match_autoCR . ' <CR><C-R>=<SID>Autocomplete()<CR>'
" endif
" if exists("g:match_gthhoh")
" execute "inoremap " . g:match_gthhoh . ' <C-O>:call <SID>Gthhoh()<CR>'
" endif " gthhoh = "Get the heck out of here!"
let s:notslash = '\\\@<!\%(\\\\\)*'
function! s:Match_wrapper(word, forward, mode) range
" In s:CleanUp(), :execute "set" restore_options .
let restore_options = (&ic ? " " : " no") . "ignorecase"
if exists("b:match_ignorecase")
let &ignorecase = b:match_ignorecase
endif
let restore_options = " ve=" . &ve . restore_options
set ve=
" If this function was called from Visual mode, make sure that the cursor
" is at the correct end of the Visual range:
if a:mode == "v"
execute "normal! gv\<Esc>"
endif
" In s:CleanUp(), we may need to check whether the cursor moved forward.
let startline = line(".")
let startcol = col(".")
" Use default behavior if called with a count.
if v:count
exe "normal! " . v:count . "%"
return s:CleanUp(restore_options, a:mode, startline, startcol)
end
" First step: if not already done, set the script variables
" s:do_BR flag for whether there are backrefs
" s:pat parsed version of b:match_words
" s:all regexp based on s:pat and the default groups
"
if !exists("b:match_words") || b:match_words == ""
let match_words = ""
" Allow b:match_words = "GetVimMatchWords()" .
elseif b:match_words =~ ":"
let match_words = b:match_words
else
execute "let match_words =" b:match_words
endif
" 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.
" quote the special chars in 'matchpairs', replace [,:] with \| and then
" append the builtin pairs (/*, */, #if, #ifdef, #else, #elif, #endif)
" let default = substitute(escape(&mps, '[$^.*~\\/?]'), '[,:]\+',
" \ '\\|', 'g').'\|\/\*\|\*\/\|#if\>\|#ifdef\>\|#else\>\|#elif\>\|#endif\>'
let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
\ '\/\*:\*\/,#\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
if match_words !~ s:notslash . '\\\d'
let s:do_BR = 0
let s:pat = match_words
else
let s:do_BR = 1
let s:pat = s:ParseWords(match_words)
endif
let s:all = substitute(s:pat, s:notslash . '\zs[,:]\+', '\\|', 'g')
let s:all = '\%(' . s:all . '\)'
" let s:all = '\%(' . substitute(s:all, '\\\ze[,:]', '', 'g') . '\)'
if exists("b:match_debug")
let b:match_pat = s:pat
endif
endif
" Second step: set the following local variables:
" matchline = line on which the cursor started
" curcol = number of characters before match
" prefix = regexp for start of line to start of match
" suffix = regexp for end of match to end of line
" Require match to end on or after the cursor and prefer it to
" start on or before the cursor.
let matchline = getline(startline)
if a:word != ''
" word given
if a:word !~ s:all
echohl WarningMsg|echo 'Missing rule for word:"'.a:word.'"'|echohl NONE
return s:CleanUp(restore_options, a:mode, startline, startcol)
endif
let matchline = a:word
let curcol = 0
let prefix = '^\%('
let suffix = '\)$'
" Now the case when "word" is not given
else " Find the match that ends on or after the cursor and set curcol.
let regexp = s:Wholematch(matchline, s:all, startcol-1)
let curcol = match(matchline, regexp)
" If there is no match, give up.
if curcol == -1
return s:CleanUp(restore_options, a:mode, startline, startcol)
endif
let endcol = matchend(matchline, regexp)
let suf = strlen(matchline) - endcol
let prefix = (curcol ? '^.*\%' . (curcol + 1) . 'c\%(' : '^\%(')
let suffix = (suf ? '\)\%' . (endcol + 1) . 'c.*$' : '\)$')
endif
if exists("b:match_debug")
let b:match_match = matchstr(matchline, regexp)
let b:match_col = curcol+1
endif
" Third step: Find the group and single word that match, and the original
" (backref) versions of these. Then, resolve the backrefs.
" Set the following local variable:
" group = colon-separated list of patterns, one of which matches
" = ini:mid:fin or ini:fin
"
" Reconstruct the version with unresolved backrefs.
let patBR = substitute(match_words.',',
\ s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
let patBR = substitute(patBR, s:notslash.'\zs:\{2,}', ':', 'g')
" Now, set group and groupBR to the matching group: 'if:endif' or
" 'while:endwhile' or whatever. A bit of a kluge: s:Choose() returns
" group . "," . groupBR, and we pick it apart.
let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR)
let i = matchend(group, s:notslash . ",")
let groupBR = strpart(group, i)
let group = strpart(group, 0, i-1)
" Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix
if s:do_BR " Do the hard part: resolve those backrefs!
let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline)
endif
if exists("b:match_debug")
let b:match_wholeBR = groupBR
let i = matchend(groupBR, s:notslash . ":")
let b:match_iniBR = strpart(groupBR, 0, i-1)
endif
" Fourth step: Set the arguments for searchpair().
let i = matchend(group, s:notslash . ":")
let j = matchend(group, '.*' . s:notslash . ":")
let ini = strpart(group, 0, i-1)
let mid = substitute(strpart(group, i,j-i-1), s:notslash.'\zs:', '\\|', 'g')
let fin = strpart(group, j)
"Un-escape the remaining , and : characters.
let ini = substitute(ini, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
let mid = substitute(mid, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
let fin = substitute(fin, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
" searchpair() requires that these patterns avoid \(\) groups.
let ini = substitute(ini, s:notslash . '\zs\\(', '\\%(', 'g')
let mid = substitute(mid, s:notslash . '\zs\\(', '\\%(', 'g')
let fin = substitute(fin, s:notslash . '\zs\\(', '\\%(', 'g')
" Set mid. This is optimized for readability, not micro-efficiency!
if a:forward && matchline =~ prefix . fin . suffix
\ || !a:forward && matchline =~ prefix . ini . suffix
let mid = ""
endif
" Set flag. This is optimized for readability, not micro-efficiency!
if a:forward && matchline =~ prefix . fin . suffix
\ || !a:forward && matchline !~ prefix . ini . suffix
let flag = "bW"
else
let flag = "W"
endif
" Set skip.
if exists("b:match_skip")
let skip = b:match_skip
elseif exists("b:match_comment") " backwards compatibility and testing!
let skip = "r:" . b:match_comment
else
let skip = 's:comment\|string'
endif
let skip = s:ParseSkip(skip)
if exists("b:match_debug")
let b:match_ini = ini
let b:match_tail = (strlen(mid) ? mid.'\|' : '') . fin
endif
" Fifth step: actually start moving the cursor and call searchpair().
" Later, :execute restore_cursor to get to the original screen.
let restore_cursor = virtcol(".") . "|"
normal! g0
let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor
normal! H
let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
execute restore_cursor
call cursor(0, curcol + 1)
" normal! 0
" if curcol
" execute "normal!" . curcol . "l"
" endif
if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
let skip = "0"
else
execute "if " . skip . "| let skip = '0' | endif"
endif
let sp_return = searchpair(ini, mid, fin, flag, skip)
let final_position = "call cursor(" . line(".") . "," . col(".") . ")"
" Restore cursor position and original screen.
execute restore_cursor
normal! m'
if sp_return > 0
execute final_position
endif
return s:CleanUp(restore_options, a:mode, startline, startcol, mid.'\|'.fin)
endfun
" Restore options and do some special handling for Operator-pending mode.
" The optional argument is the tail of the matching group.
fun! s:CleanUp(options, mode, startline, startcol, ...)
execute "set" a:options
" Open folds, if appropriate.
if a:mode != "o"
if &foldopen =~ "percent"
normal! zv
endif
" In Operator-pending mode, we want to include the whole match
" (for example, d%).
" This is only a problem if we end up moving in the forward direction.
elseif (a:startline < line(".")) ||
\ (a:startline == line(".") && a:startcol < col("."))
if a:0
" Check whether the match is a single character. If not, move to the
" end of the match.
let matchline = getline(".")
let currcol = col(".")
let regexp = s:Wholematch(matchline, a:1, currcol-1)
let endcol = matchend(matchline, regexp)
if endcol > currcol " This is NOT off by one!
call cursor(0, endcol)
endif
endif " a:0
endif " a:mode != "o" && etc.
return 0
endfun
" Example (simplified HTML patterns): if
" a:groupBR = '<\(\k\+\)>:</\1>'
" a:prefix = '^.\{3}\('
" a:group = '<\(\k\+\)>:</\(\k\+\)>'
" a:suffix = '\).\{2}$'
" a:matchline = "123<tag>12" or "123</tag>12"
" then extract "tag" from a:matchline and return "<tag>:</tag>" .
fun! s:InsertRefs(groupBR, prefix, group, suffix, matchline)
if a:matchline !~ a:prefix .
\ substitute(a:group, s:notslash . '\zs:', '\\|', 'g') . a:suffix
return a:group
endif
let i = matchend(a:groupBR, s:notslash . ':')
let ini = strpart(a:groupBR, 0, i-1)
let tailBR = strpart(a:groupBR, i)
let word = s:Choose(a:group, a:matchline, ":", "", a:prefix, a:suffix,
\ a:groupBR)
let i = matchend(word, s:notslash . ":")
let wordBR = strpart(word, i)
let word = strpart(word, 0, i-1)
" Now, a:matchline =~ a:prefix . word . a:suffix
if wordBR != ini
let table = s:Resolve(ini, wordBR, "table")
else
" let table = "----------"
let table = ""
let d = 0
while d < 10
if tailBR =~ s:notslash . '\\' . d
" let table[d] = d
let table = table . d
else
let table = table . "-"
endif
let d = d + 1
endwhile
endif
let d = 9
while d
if table[d] != "-"
let backref = substitute(a:matchline, a:prefix.word.a:suffix,
\ '\'.table[d], "")
" Are there any other characters that should be escaped?
let backref = escape(backref, '*,:')
execute s:Ref(ini, d, "start", "len")
let ini = strpart(ini, 0, start) . backref . strpart(ini, start+len)
let tailBR = substitute(tailBR, s:notslash . '\zs\\' . d,
\ escape(backref, '\\&'), 'g')
endif
let d = d-1
endwhile
if exists("b:match_debug")
if s:do_BR
let b:match_table = table
let b:match_word = word
else
let b:match_table = ""
let b:match_word = ""
endif
endif
return ini . ":" . tailBR
endfun
" Input a comma-separated list of groups with backrefs, such as
" a:groups = '\(foo\):end\1,\(bar\):end\1'
" and return a comma-separated list of groups with backrefs replaced:
" return '\(foo\):end\(foo\),\(bar\):end\(bar\)'
fun! s:ParseWords(groups)
let groups = substitute(a:groups.",", s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
let groups = substitute(groups, s:notslash . '\zs:\{2,}', ':', 'g')
let parsed = ""
while groups =~ '[^,:]'
let i = matchend(groups, s:notslash . ':')
let j = matchend(groups, s:notslash . ',')
let ini = strpart(groups, 0, i-1)
let tail = strpart(groups, i, j-i-1) . ":"
let groups = strpart(groups, j)
let parsed = parsed . ini
let i = matchend(tail, s:notslash . ':')
while i != -1
" In 'if:else:endif', ini='if' and word='else' and then word='endif'.
let word = strpart(tail, 0, i-1)
let tail = strpart(tail, i)
let i = matchend(tail, s:notslash . ':')
let parsed = parsed . ":" . s:Resolve(ini, word, "word")
endwhile " Now, tail has been used up.
let parsed = parsed . ","
endwhile " groups =~ '[^,:]'
let parsed = substitute(parsed, ',$', '', '')
return parsed
endfun
" TODO I think this can be simplified and/or made more efficient.
" TODO What should I do if a:start is out of range?
" Return a regexp that matches all of a:string, such that
" matchstr(a:string, regexp) represents the match for a:pat that starts
" as close to a:start as possible, before being preferred to after, and
" ends after a:start .
" Usage:
" let regexp = s:Wholematch(getline("."), 'foo\|bar', col(".")-1)
" let i = match(getline("."), regexp)
" let j = matchend(getline("."), regexp)
" let match = matchstr(getline("."), regexp)
fun! s:Wholematch(string, pat, start)
let group = '\%(' . a:pat . '\)'
let prefix = (a:start ? '\(^.*\%<' . (a:start + 2) . 'c\)\zs' : '^')
let len = strlen(a:string)
let suffix = (a:start+1 < len ? '\(\%>'.(a:start+1).'c.*$\)\@=' : '$')
if a:string !~ prefix . group . suffix
let prefix = ''
endif
return prefix . group . suffix
endfun
" No extra arguments: s:Ref(string, d) will
" find the d'th occurrence of '\(' and return it, along with everything up
" to and including the matching '\)'.
" One argument: s:Ref(string, d, "start") returns the index of the start
" of the d'th '\(' and any other argument returns the length of the group.
" Two arguments: s:Ref(string, d, "foo", "bar") returns a string to be
" executed, having the effect of
" :let foo = s:Ref(string, d, "start")
" :let bar = s:Ref(string, d, "len")
fun! s:Ref(string, d, ...)
let len = strlen(a:string)
if a:d == 0
let start = 0
else
let cnt = a:d
let match = a:string
while cnt
let cnt = cnt - 1
let index = matchend(match, s:notslash . '\\(')
if index == -1
return ""
endif
let match = strpart(match, index)
endwhile
let start = len - strlen(match)
if a:0 == 1 && a:1 == "start"
return start - 2
endif
let cnt = 1
while cnt
let index = matchend(match, s:notslash . '\\(\|\\)') - 1
if index == -2
return ""
endif
" Increment if an open, decrement if a ')':
let cnt = cnt + (match[index]=="(" ? 1 : -1) " ')'
" let cnt = stridx('0(', match[index]) + cnt
let match = strpart(match, index+1)
endwhile
let start = start - 2
let len = len - start - strlen(match)
endif
if a:0 == 1
return len
elseif a:0 == 2
return "let " . a:1 . "=" . start . "| let " . a:2 . "=" . len
else
return strpart(a:string, start, len)
endif
endfun
" Count the number of disjoint copies of pattern in string.
" If the pattern is a literal string and contains no '0' or '1' characters
" then s:Count(string, pattern, '0', '1') should be faster than
" s:Count(string, pattern).
fun! s:Count(string, pattern, ...)
let pat = escape(a:pattern, '\\')
if a:0 > 1
let foo = substitute(a:string, '[^'.a:pattern.']', "a:1", "g")
let foo = substitute(a:string, pat, a:2, "g")
let foo = substitute(foo, '[^' . a:2 . ']', "", "g")
return strlen(foo)
endif
let result = 0
let foo = a:string
let index = matchend(foo, pat)
while index != -1
let result = result + 1
let foo = strpart(foo, index)
let index = matchend(foo, pat)
endwhile
return result
endfun
" s:Resolve('\(a\)\(b\)', '\(c\)\2\1\1\2') should return table.word, where
" word = '\(c\)\(b\)\(a\)\3\2' and table = '-32-------'. That is, the first
" '\1' in target is replaced by '\(a\)' in word, table[1] = 3, and this
" indicates that all other instances of '\1' in target are to be replaced
" by '\3'. The hard part is dealing with nesting...
" Note that ":" is an illegal character for source and target,
" unless it is preceded by "\".
fun! s:Resolve(source, target, output)
let word = a:target
let i = matchend(word, s:notslash . '\\\d') - 1
let table = "----------"
while i != -2 " There are back references to be replaced.
let d = word[i]
let backref = s:Ref(a:source, d)
" The idea is to replace '\d' with backref. Before we do this,
" replace any \(\) groups in backref with :1, :2, ... if they
" correspond to the first, second, ... group already inserted
" into backref. Later, replace :1 with \1 and so on. The group
" number w+b within backref corresponds to the group number
" s within a:source.
" w = number of '\(' in word before the current one
let w = s:Count(
\ substitute(strpart(word, 0, i-1), '\\\\', '', 'g'), '\(', '1')
let b = 1 " number of the current '\(' in backref
let s = d " number of the current '\(' in a:source
while b <= s:Count(substitute(backref, '\\\\', '', 'g'), '\(', '1')
\ && s < 10
if table[s] == "-"
if w + b < 10
" let table[s] = w + b
let table = strpart(table, 0, s) . (w+b) . strpart(table, s+1)
endif
let b = b + 1
let s = s + 1
else
execute s:Ref(backref, b, "start", "len")
let ref = strpart(backref, start, len)
let backref = strpart(backref, 0, start) . ":". table[s]
\ . strpart(backref, start+len)
let s = s + s:Count(substitute(ref, '\\\\', '', 'g'), '\(', '1')
endif
endwhile
let word = strpart(word, 0, i-1) . backref . strpart(word, i+1)
let i = matchend(word, s:notslash . '\\\d') - 1
endwhile
let word = substitute(word, s:notslash . '\zs:', '\\', 'g')
if a:output == "table"
return table
elseif a:output == "word"
return word
else
return table . word
endif
endfun
" Assume a:comma = ",". Then the format for a:patterns and a:1 is
" a:patterns = "<pat1>,<pat2>,..."
" a:1 = "<alt1>,<alt2>,..."
" If <patn> is the first pattern that matches a:string then return <patn>
" if no optional arguments are given; return <patn>,<altn> if a:1 is given.
fun! s:Choose(patterns, string, comma, branch, prefix, suffix, ...)
let tail = (a:patterns =~ a:comma."$" ? a:patterns : a:patterns . a:comma)
let i = matchend(tail, s:notslash . a:comma)
if a:0
let alttail = (a:1 =~ a:comma."$" ? a:1 : a:1 . a:comma)
let j = matchend(alttail, s:notslash . a:comma)
endif
let current = strpart(tail, 0, i-1)
if a:branch == ""
let currpat = current
else
let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
endif
while a:string !~ a:prefix . currpat . a:suffix
let tail = strpart(tail, i)
let i = matchend(tail, s:notslash . a:comma)
if i == -1
return -1
endif
let current = strpart(tail, 0, i-1)
if a:branch == ""
let currpat = current
else
let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
endif
if a:0
let alttail = strpart(alttail, j)
let j = matchend(alttail, s:notslash . a:comma)
endif
endwhile
if a:0
let current = current . a:comma . strpart(alttail, 0, j-1)
endif
return current
endfun
" Call this function to turn on debugging information. Every time the main
" script is run, buffer variables will be saved. These can be used directly
" or viewed using the menu items below.
if !exists(":MatchDebug")
command! -nargs=0 MatchDebug call s:Match_debug()
endif
fun! s:Match_debug()
let b:match_debug = 1 " Save debugging information.
" pat = all of b:match_words with backrefs parsed
amenu &Matchit.&pat :echo b:match_pat<CR>
" match = bit of text that is recognized as a match
amenu &Matchit.&match :echo b:match_match<CR>
" curcol = cursor column of the start of the matching text
amenu &Matchit.&curcol :echo b:match_col<CR>
" wholeBR = matching group, original version
amenu &Matchit.wh&oleBR :echo b:match_wholeBR<CR>
" iniBR = 'if' piece, original version
amenu &Matchit.ini&BR :echo b:match_iniBR<CR>
" ini = 'if' piece, with all backrefs resolved from match
amenu &Matchit.&ini :echo b:match_ini<CR>
" tail = 'else\|endif' piece, with all backrefs resolved from match
amenu &Matchit.&tail :echo b:match_tail<CR>
" fin = 'endif' piece, with all backrefs resolved from match
amenu &Matchit.&word :echo b:match_word<CR>
" '\'.d in ini refers to the same thing as '\'.table[d] in word.
amenu &Matchit.t&able :echo '0:' . b:match_table . ':9'<CR>
endfun
" Jump to the nearest unmatched "(" or "if" or "<tag>" if a:spflag == "bW"
" or the nearest unmatched "</tag>" or "endif" or ")" if a:spflag == "W".
" Return a "mark" for the original position, so that
" let m = MultiMatch("bW", "n") ... execute m
" will return to the original position. If there is a problem, do not
" move the cursor and return "", unless a count is given, in which case
" go up or down as many levels as possible and again return "".
" TODO This relies on the same patterns as % matching. It might be a good
" idea to give it its own matching patterns.
fun! s:MultiMatch(spflag, mode)
if !exists("b:match_words") || b:match_words == ""
return ""
end
let restore_options = (&ic ? "" : "no") . "ignorecase"
if exists("b:match_ignorecase")
let &ignorecase = b:match_ignorecase
endif
let startline = line(".")
let startcol = col(".")
" First step: if not already done, set the script variables
" s:do_BR flag for whether there are backrefs
" s:pat parsed version of b:match_words
" s:all regexp based on s:pat and the default groups
" This part is copied and slightly modified from s:Match_wrapper().
let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
\ '\/\*:\*\/,#\s*if\%(def\)\=:#\s*else\>:#\s*elif\>:#\s*endif\>'
" Allow b:match_words = "GetVimMatchWords()" .
if b:match_words =~ ":"
let match_words = b:match_words
else
execute "let match_words =" b:match_words
endif
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
if match_words !~ s:notslash . '\\\d'
let s:do_BR = 0
let s:pat = match_words
else
let s:do_BR = 1
let s:pat = s:ParseWords(match_words)
endif
let s:all = '\%(' . substitute(s:pat . (strlen(s:pat)?",":"") . default,
\ '[,:]\+','\\|','g') . '\)'
if exists("b:match_debug")
let b:match_pat = s:pat
endif
endif
" Second step: figure out the patterns for searchpair()
" and save the screen, cursor position, and 'ignorecase'.
" - TODO: A lot of this is copied from s:Match_wrapper().
" - maybe even more functionality should be split off
" - into separate functions!
let cdefault = (s:pat =~ '[^,]$' ? "," : "") . default
let open = substitute(s:pat . cdefault,
\ s:notslash . '\zs:.\{-}' . s:notslash . ',', '\\),\\(', 'g')
let open = '\(' . substitute(open, s:notslash . '\zs:.*$', '\\)', '')
let close = substitute(s:pat . cdefault,
\ s:notslash . '\zs,.\{-}' . s:notslash . ':', '\\),\\(', 'g')
let close = substitute(close, '^.\{-}' . s:notslash . ':', '\\(', '') . '\)'
if exists("b:match_skip")
let skip = b:match_skip
elseif exists("b:match_comment") " backwards compatibility and testing!
let skip = "r:" . b:match_comment
else
let skip = 's:comment\|string'
endif
let skip = s:ParseSkip(skip)
" let restore_cursor = line(".") . "G" . virtcol(".") . "|"
" normal! H
" let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
let restore_cursor = virtcol(".") . "|"
normal! g0
let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor
normal! H
let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
execute restore_cursor
" Third step: call searchpair().
" Replace '\('--but not '\\('--with '\%(' and ',' with '\|'.
let openpat = substitute(open, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g')
let openpat = substitute(openpat, ',', '\\|', 'g')
let closepat = substitute(close, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g')
let closepat = substitute(closepat, ',', '\\|', 'g')
if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
let skip = '0'
else
execute "if " . skip . "| let skip = '0' | endif"
endif
mark '
let level = v:count1
while level
if searchpair(openpat, '', closepat, a:spflag, skip) < 1
call s:CleanUp(restore_options, a:mode, startline, startcol)
return ""
endif
let level = level - 1
endwhile
" Restore options and return a string to restore the original position.
call s:CleanUp(restore_options, a:mode, startline, startcol)
return restore_cursor
endfun
" Search backwards for "if" or "while" or "<tag>" or ...
" and return "endif" or "endwhile" or "</tag>" or ... .
" For now, this uses b:match_words and the same script variables
" as s:Match_wrapper() . Later, it may get its own patterns,
" either from a buffer variable or passed as arguments.
" fun! s:Autocomplete()
" echo "autocomplete not yet implemented :-("
" if !exists("b:match_words") || b:match_words == ""
" return ""
" end
" let startpos = s:MultiMatch("bW")
"
" if startpos == ""
" return ""
" endif
" " - TODO: figure out whether 'if' or '<tag>' matched, and construct
" " - the appropriate closing.
" let matchline = getline(".")
" let curcol = col(".") - 1
" " - TODO: Change the s:all argument if there is a new set of match pats.
" let regexp = s:Wholematch(matchline, s:all, curcol)
" let suf = strlen(matchline) - matchend(matchline, regexp)
" let prefix = (curcol ? '^.\{' . curcol . '}\%(' : '^\%(')
" let suffix = (suf ? '\).\{' . suf . '}$' : '\)$')
" " Reconstruct the version with unresolved backrefs.
" let patBR = substitute(b:match_words.',', '[,:]*,[,:]*', ',', 'g')
" let patBR = substitute(patBR, ':\{2,}', ':', "g")
" " Now, set group and groupBR to the matching group: 'if:endif' or
" " 'while:endwhile' or whatever.
" let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR)
" let i = matchend(group, s:notslash . ",")
" let groupBR = strpart(group, i)
" let group = strpart(group, 0, i-1)
" " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix
" if s:do_BR
" let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline)
" endif
" " let g:group = group
"
" " - TODO: Construct the closing from group.
" let fake = "end" . expand("<cword>")
" execute startpos
" return fake
" endfun
" Close all open structures. "Get the heck out of here!"
" fun! s:Gthhoh()
" let close = s:Autocomplete()
" while strlen(close)
" put=close
" let close = s:Autocomplete()
" endwhile
" endfun
" Parse special strings as typical skip arguments for searchpair():
" s:foo becomes (current syntax item) =~ foo
" S:foo becomes (current syntax item) !~ foo
" r:foo becomes (line before cursor) =~ foo
" R:foo becomes (line before cursor) !~ foo
fun! s:ParseSkip(str)
let skip = a:str
if skip[1] == ":"
if skip[0] == "s"
let skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" .
\ strpart(skip,2) . "'"
elseif skip[0] == "S"
let skip = "synIDattr(synID(line('.'),col('.'),1),'name') !~? '" .
\ strpart(skip,2) . "'"
elseif skip[0] == "r"
let skip = "strpart(getline('.'),0,col('.'))=~'" . strpart(skip,2). "'"
elseif skip[0] == "R"
let skip = "strpart(getline('.'),0,col('.'))!~'" . strpart(skip,2). "'"
endif
endif
return skip
endfun
let &cpo = s:save_cpo
unlet s:save_cpo
" vim:sts=2:sw=2:
" Load the matchit package.
" For those users who were loading the matchit plugin from here.
packadd matchit
+3 -1
View File
@@ -1,7 +1,7 @@
" These commands create the option window.
"
" Maintainer: Bram Moolenaar <Bram@vim.org>
" Last Change: 2016 Feb 21
" Last Change: 2016 Mar 19
" If there already is an option window, jump to that one.
if bufwinnr("option-window") > 0
@@ -1269,6 +1269,8 @@ if has("multi_byte")
endif
call append("$", "ambiwidth\twidth of ambiguous width characters")
call <SID>OptionG("ambw", &ambw)
call append("$", "emoji\temoji characters are full width")
call <SID>BinOptionG("emo", &emo)
endif
+50
View File
@@ -0,0 +1,50 @@
:MatchDebug matchit.txt /*:MatchDebug*
MatchError matchit.txt /*MatchError*
[% matchit.txt /*[%*
]% matchit.txt /*]%*
b:match_col matchit.txt /*b:match_col*
b:match_debug matchit.txt /*b:match_debug*
b:match_ignorecase matchit.txt /*b:match_ignorecase*
b:match_ini matchit.txt /*b:match_ini*
b:match_iniBR matchit.txt /*b:match_iniBR*
b:match_match matchit.txt /*b:match_match*
b:match_pat matchit.txt /*b:match_pat*
b:match_skip matchit.txt /*b:match_skip*
b:match_table matchit.txt /*b:match_table*
b:match_tail matchit.txt /*b:match_tail*
b:match_wholeBR matchit.txt /*b:match_wholeBR*
b:match_word matchit.txt /*b:match_word*
b:match_words matchit.txt /*b:match_words*
g% matchit.txt /*g%*
matchit matchit.txt /*matchit*
matchit-% matchit.txt /*matchit-%*
matchit-\1 matchit.txt /*matchit-\\1*
matchit-activate matchit.txt /*matchit-activate*
matchit-backref matchit.txt /*matchit-backref*
matchit-bugs matchit.txt /*matchit-bugs*
matchit-choose matchit.txt /*matchit-choose*
matchit-configure matchit.txt /*matchit-configure*
matchit-debug matchit.txt /*matchit-debug*
matchit-details matchit.txt /*matchit-details*
matchit-highlight matchit.txt /*matchit-highlight*
matchit-hl matchit.txt /*matchit-hl*
matchit-intro matchit.txt /*matchit-intro*
matchit-languages matchit.txt /*matchit-languages*
matchit-modes matchit.txt /*matchit-modes*
matchit-newlang matchit.txt /*matchit-newlang*
matchit-o_% matchit.txt /*matchit-o_%*
matchit-parse matchit.txt /*matchit-parse*
matchit-s:notend matchit.txt /*matchit-s:notend*
matchit-s:sol matchit.txt /*matchit-s:sol*
matchit-spaces matchit.txt /*matchit-spaces*
matchit-troubleshoot matchit.txt /*matchit-troubleshoot*
matchit-v_% matchit.txt /*matchit-v_%*
matchit.txt matchit.txt /*matchit.txt*
matchit.vim matchit.txt /*matchit.vim*
o_[% matchit.txt /*o_[%*
o_]% matchit.txt /*o_]%*
o_g% matchit.txt /*o_g%*
v_[% matchit.txt /*v_[%*
v_]% matchit.txt /*v_]%*
v_a% matchit.txt /*v_a%*
v_g% matchit.txt /*v_g%*
+813
View File
@@ -0,0 +1,813 @@
" matchit.vim: (global plugin) Extended "%" matching
" Last Change: Fri Jan 25 10:00 AM 2008 EST
" Maintainer: Benji Fisher PhD <benji@member.AMS.org>
" Version: 1.13.2, for Vim 6.3+
" URL: http://www.vim.org/script.php?script_id=39
" Documentation:
" The documentation is in a separate file, matchit.txt .
" Credits:
" Vim editor by Bram Moolenaar (Thanks, Bram!)
" Original script and design by Raul Segura Acevedo
" Support for comments by Douglas Potts
" Support for back references and other improvements by Benji Fisher
" Support for many languages by Johannes Zellner
" Suggestions for improvement, bug reports, and support for additional
" languages by Jordi-Albert Batalla, Neil Bird, Servatius Brandt, Mark
" Collett, Stephen Wall, Dany St-Amant, Yuheng Xie, and Johannes Zellner.
" Debugging:
" If you'd like to try the built-in debugging commands...
" :MatchDebug to activate debugging for the current buffer
" This saves the values of several key script variables as buffer-local
" variables. See the MatchDebug() function, below, for details.
" TODO: I should think about multi-line patterns for b:match_words.
" This would require an option: how many lines to scan (default 1).
" This would be useful for Python, maybe also for *ML.
" TODO: Maybe I should add a menu so that people will actually use some of
" the features that I have implemented.
" TODO: Eliminate the MultiMatch function. Add yet another argument to
" Match_wrapper() instead.
" TODO: Allow :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1'
" TODO: Make backrefs safer by using '\V' (very no-magic).
" TODO: Add a level of indirection, so that custom % scripts can use my
" work but extend it.
" allow user to prevent loading
" and prevent duplicate loading
if exists("loaded_matchit") || &cp
finish
endif
let loaded_matchit = 1
let s:last_mps = ""
let s:last_words = ":"
let s:save_cpo = &cpo
set cpo&vim
nnoremap <silent> % :<C-U>call <SID>Match_wrapper('',1,'n') <CR>
nnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'n') <CR>
vnoremap <silent> % :<C-U>call <SID>Match_wrapper('',1,'v') <CR>m'gv``
vnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'v') <CR>m'gv``
onoremap <silent> % v:<C-U>call <SID>Match_wrapper('',1,'o') <CR>
onoremap <silent> g% v:<C-U>call <SID>Match_wrapper('',0,'o') <CR>
" Analogues of [{ and ]} using matching patterns:
nnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "n") <CR>
nnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W", "n") <CR>
vmap [% <Esc>[%m'gv``
vmap ]% <Esc>]%m'gv``
" vnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "v") <CR>m'gv``
" vnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W", "v") <CR>m'gv``
onoremap <silent> [% v:<C-U>call <SID>MultiMatch("bW", "o") <CR>
onoremap <silent> ]% v:<C-U>call <SID>MultiMatch("W", "o") <CR>
" text object:
vmap a% <Esc>[%v]%
" Auto-complete mappings: (not yet "ready for prime time")
" TODO Read :help write-plugin for the "right" way to let the user
" specify a key binding.
" let g:match_auto = '<C-]>'
" let g:match_autoCR = '<C-CR>'
" if exists("g:match_auto")
" execute "inoremap " . g:match_auto . ' x<Esc>"=<SID>Autocomplete()<CR>Pls'
" endif
" if exists("g:match_autoCR")
" execute "inoremap " . g:match_autoCR . ' <CR><C-R>=<SID>Autocomplete()<CR>'
" endif
" if exists("g:match_gthhoh")
" execute "inoremap " . g:match_gthhoh . ' <C-O>:call <SID>Gthhoh()<CR>'
" endif " gthhoh = "Get the heck out of here!"
let s:notslash = '\\\@<!\%(\\\\\)*'
function! s:Match_wrapper(word, forward, mode) range
" In s:CleanUp(), :execute "set" restore_options .
let restore_options = (&ic ? " " : " no") . "ignorecase"
if exists("b:match_ignorecase")
let &ignorecase = b:match_ignorecase
endif
let restore_options = " ve=" . &ve . restore_options
set ve=
" If this function was called from Visual mode, make sure that the cursor
" is at the correct end of the Visual range:
if a:mode == "v"
execute "normal! gv\<Esc>"
endif
" In s:CleanUp(), we may need to check whether the cursor moved forward.
let startline = line(".")
let startcol = col(".")
" Use default behavior if called with a count.
if v:count
exe "normal! " . v:count . "%"
return s:CleanUp(restore_options, a:mode, startline, startcol)
end
" First step: if not already done, set the script variables
" s:do_BR flag for whether there are backrefs
" s:pat parsed version of b:match_words
" s:all regexp based on s:pat and the default groups
"
if !exists("b:match_words") || b:match_words == ""
let match_words = ""
" Allow b:match_words = "GetVimMatchWords()" .
elseif b:match_words =~ ":"
let match_words = b:match_words
else
execute "let match_words =" b:match_words
endif
" 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.
" quote the special chars in 'matchpairs', replace [,:] with \| and then
" append the builtin pairs (/*, */, #if, #ifdef, #else, #elif, #endif)
" let default = substitute(escape(&mps, '[$^.*~\\/?]'), '[,:]\+',
" \ '\\|', 'g').'\|\/\*\|\*\/\|#if\>\|#ifdef\>\|#else\>\|#elif\>\|#endif\>'
let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
\ '\/\*:\*\/,#\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
if match_words !~ s:notslash . '\\\d'
let s:do_BR = 0
let s:pat = match_words
else
let s:do_BR = 1
let s:pat = s:ParseWords(match_words)
endif
let s:all = substitute(s:pat, s:notslash . '\zs[,:]\+', '\\|', 'g')
let s:all = '\%(' . s:all . '\)'
" let s:all = '\%(' . substitute(s:all, '\\\ze[,:]', '', 'g') . '\)'
if exists("b:match_debug")
let b:match_pat = s:pat
endif
endif
" Second step: set the following local variables:
" matchline = line on which the cursor started
" curcol = number of characters before match
" prefix = regexp for start of line to start of match
" suffix = regexp for end of match to end of line
" Require match to end on or after the cursor and prefer it to
" start on or before the cursor.
let matchline = getline(startline)
if a:word != ''
" word given
if a:word !~ s:all
echohl WarningMsg|echo 'Missing rule for word:"'.a:word.'"'|echohl NONE
return s:CleanUp(restore_options, a:mode, startline, startcol)
endif
let matchline = a:word
let curcol = 0
let prefix = '^\%('
let suffix = '\)$'
" Now the case when "word" is not given
else " Find the match that ends on or after the cursor and set curcol.
let regexp = s:Wholematch(matchline, s:all, startcol-1)
let curcol = match(matchline, regexp)
" If there is no match, give up.
if curcol == -1
return s:CleanUp(restore_options, a:mode, startline, startcol)
endif
let endcol = matchend(matchline, regexp)
let suf = strlen(matchline) - endcol
let prefix = (curcol ? '^.*\%' . (curcol + 1) . 'c\%(' : '^\%(')
let suffix = (suf ? '\)\%' . (endcol + 1) . 'c.*$' : '\)$')
endif
if exists("b:match_debug")
let b:match_match = matchstr(matchline, regexp)
let b:match_col = curcol+1
endif
" Third step: Find the group and single word that match, and the original
" (backref) versions of these. Then, resolve the backrefs.
" Set the following local variable:
" group = colon-separated list of patterns, one of which matches
" = ini:mid:fin or ini:fin
"
" Reconstruct the version with unresolved backrefs.
let patBR = substitute(match_words.',',
\ s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
let patBR = substitute(patBR, s:notslash.'\zs:\{2,}', ':', 'g')
" Now, set group and groupBR to the matching group: 'if:endif' or
" 'while:endwhile' or whatever. A bit of a kluge: s:Choose() returns
" group . "," . groupBR, and we pick it apart.
let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR)
let i = matchend(group, s:notslash . ",")
let groupBR = strpart(group, i)
let group = strpart(group, 0, i-1)
" Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix
if s:do_BR " Do the hard part: resolve those backrefs!
let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline)
endif
if exists("b:match_debug")
let b:match_wholeBR = groupBR
let i = matchend(groupBR, s:notslash . ":")
let b:match_iniBR = strpart(groupBR, 0, i-1)
endif
" Fourth step: Set the arguments for searchpair().
let i = matchend(group, s:notslash . ":")
let j = matchend(group, '.*' . s:notslash . ":")
let ini = strpart(group, 0, i-1)
let mid = substitute(strpart(group, i,j-i-1), s:notslash.'\zs:', '\\|', 'g')
let fin = strpart(group, j)
"Un-escape the remaining , and : characters.
let ini = substitute(ini, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
let mid = substitute(mid, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
let fin = substitute(fin, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
" searchpair() requires that these patterns avoid \(\) groups.
let ini = substitute(ini, s:notslash . '\zs\\(', '\\%(', 'g')
let mid = substitute(mid, s:notslash . '\zs\\(', '\\%(', 'g')
let fin = substitute(fin, s:notslash . '\zs\\(', '\\%(', 'g')
" Set mid. This is optimized for readability, not micro-efficiency!
if a:forward && matchline =~ prefix . fin . suffix
\ || !a:forward && matchline =~ prefix . ini . suffix
let mid = ""
endif
" Set flag. This is optimized for readability, not micro-efficiency!
if a:forward && matchline =~ prefix . fin . suffix
\ || !a:forward && matchline !~ prefix . ini . suffix
let flag = "bW"
else
let flag = "W"
endif
" Set skip.
if exists("b:match_skip")
let skip = b:match_skip
elseif exists("b:match_comment") " backwards compatibility and testing!
let skip = "r:" . b:match_comment
else
let skip = 's:comment\|string'
endif
let skip = s:ParseSkip(skip)
if exists("b:match_debug")
let b:match_ini = ini
let b:match_tail = (strlen(mid) ? mid.'\|' : '') . fin
endif
" Fifth step: actually start moving the cursor and call searchpair().
" Later, :execute restore_cursor to get to the original screen.
let restore_cursor = virtcol(".") . "|"
normal! g0
let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor
normal! H
let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
execute restore_cursor
call cursor(0, curcol + 1)
" normal! 0
" if curcol
" execute "normal!" . curcol . "l"
" endif
if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
let skip = "0"
else
execute "if " . skip . "| let skip = '0' | endif"
endif
let sp_return = searchpair(ini, mid, fin, flag, skip)
let final_position = "call cursor(" . line(".") . "," . col(".") . ")"
" Restore cursor position and original screen.
execute restore_cursor
normal! m'
if sp_return > 0
execute final_position
endif
return s:CleanUp(restore_options, a:mode, startline, startcol, mid.'\|'.fin)
endfun
" Restore options and do some special handling for Operator-pending mode.
" The optional argument is the tail of the matching group.
fun! s:CleanUp(options, mode, startline, startcol, ...)
execute "set" a:options
" Open folds, if appropriate.
if a:mode != "o"
if &foldopen =~ "percent"
normal! zv
endif
" In Operator-pending mode, we want to include the whole match
" (for example, d%).
" This is only a problem if we end up moving in the forward direction.
elseif (a:startline < line(".")) ||
\ (a:startline == line(".") && a:startcol < col("."))
if a:0
" Check whether the match is a single character. If not, move to the
" end of the match.
let matchline = getline(".")
let currcol = col(".")
let regexp = s:Wholematch(matchline, a:1, currcol-1)
let endcol = matchend(matchline, regexp)
if endcol > currcol " This is NOT off by one!
call cursor(0, endcol)
endif
endif " a:0
endif " a:mode != "o" && etc.
return 0
endfun
" Example (simplified HTML patterns): if
" a:groupBR = '<\(\k\+\)>:</\1>'
" a:prefix = '^.\{3}\('
" a:group = '<\(\k\+\)>:</\(\k\+\)>'
" a:suffix = '\).\{2}$'
" a:matchline = "123<tag>12" or "123</tag>12"
" then extract "tag" from a:matchline and return "<tag>:</tag>" .
fun! s:InsertRefs(groupBR, prefix, group, suffix, matchline)
if a:matchline !~ a:prefix .
\ substitute(a:group, s:notslash . '\zs:', '\\|', 'g') . a:suffix
return a:group
endif
let i = matchend(a:groupBR, s:notslash . ':')
let ini = strpart(a:groupBR, 0, i-1)
let tailBR = strpart(a:groupBR, i)
let word = s:Choose(a:group, a:matchline, ":", "", a:prefix, a:suffix,
\ a:groupBR)
let i = matchend(word, s:notslash . ":")
let wordBR = strpart(word, i)
let word = strpart(word, 0, i-1)
" Now, a:matchline =~ a:prefix . word . a:suffix
if wordBR != ini
let table = s:Resolve(ini, wordBR, "table")
else
" let table = "----------"
let table = ""
let d = 0
while d < 10
if tailBR =~ s:notslash . '\\' . d
" let table[d] = d
let table = table . d
else
let table = table . "-"
endif
let d = d + 1
endwhile
endif
let d = 9
while d
if table[d] != "-"
let backref = substitute(a:matchline, a:prefix.word.a:suffix,
\ '\'.table[d], "")
" Are there any other characters that should be escaped?
let backref = escape(backref, '*,:')
execute s:Ref(ini, d, "start", "len")
let ini = strpart(ini, 0, start) . backref . strpart(ini, start+len)
let tailBR = substitute(tailBR, s:notslash . '\zs\\' . d,
\ escape(backref, '\\&'), 'g')
endif
let d = d-1
endwhile
if exists("b:match_debug")
if s:do_BR
let b:match_table = table
let b:match_word = word
else
let b:match_table = ""
let b:match_word = ""
endif
endif
return ini . ":" . tailBR
endfun
" Input a comma-separated list of groups with backrefs, such as
" a:groups = '\(foo\):end\1,\(bar\):end\1'
" and return a comma-separated list of groups with backrefs replaced:
" return '\(foo\):end\(foo\),\(bar\):end\(bar\)'
fun! s:ParseWords(groups)
let groups = substitute(a:groups.",", s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
let groups = substitute(groups, s:notslash . '\zs:\{2,}', ':', 'g')
let parsed = ""
while groups =~ '[^,:]'
let i = matchend(groups, s:notslash . ':')
let j = matchend(groups, s:notslash . ',')
let ini = strpart(groups, 0, i-1)
let tail = strpart(groups, i, j-i-1) . ":"
let groups = strpart(groups, j)
let parsed = parsed . ini
let i = matchend(tail, s:notslash . ':')
while i != -1
" In 'if:else:endif', ini='if' and word='else' and then word='endif'.
let word = strpart(tail, 0, i-1)
let tail = strpart(tail, i)
let i = matchend(tail, s:notslash . ':')
let parsed = parsed . ":" . s:Resolve(ini, word, "word")
endwhile " Now, tail has been used up.
let parsed = parsed . ","
endwhile " groups =~ '[^,:]'
let parsed = substitute(parsed, ',$', '', '')
return parsed
endfun
" TODO I think this can be simplified and/or made more efficient.
" TODO What should I do if a:start is out of range?
" Return a regexp that matches all of a:string, such that
" matchstr(a:string, regexp) represents the match for a:pat that starts
" as close to a:start as possible, before being preferred to after, and
" ends after a:start .
" Usage:
" let regexp = s:Wholematch(getline("."), 'foo\|bar', col(".")-1)
" let i = match(getline("."), regexp)
" let j = matchend(getline("."), regexp)
" let match = matchstr(getline("."), regexp)
fun! s:Wholematch(string, pat, start)
let group = '\%(' . a:pat . '\)'
let prefix = (a:start ? '\(^.*\%<' . (a:start + 2) . 'c\)\zs' : '^')
let len = strlen(a:string)
let suffix = (a:start+1 < len ? '\(\%>'.(a:start+1).'c.*$\)\@=' : '$')
if a:string !~ prefix . group . suffix
let prefix = ''
endif
return prefix . group . suffix
endfun
" No extra arguments: s:Ref(string, d) will
" find the d'th occurrence of '\(' and return it, along with everything up
" to and including the matching '\)'.
" One argument: s:Ref(string, d, "start") returns the index of the start
" of the d'th '\(' and any other argument returns the length of the group.
" Two arguments: s:Ref(string, d, "foo", "bar") returns a string to be
" executed, having the effect of
" :let foo = s:Ref(string, d, "start")
" :let bar = s:Ref(string, d, "len")
fun! s:Ref(string, d, ...)
let len = strlen(a:string)
if a:d == 0
let start = 0
else
let cnt = a:d
let match = a:string
while cnt
let cnt = cnt - 1
let index = matchend(match, s:notslash . '\\(')
if index == -1
return ""
endif
let match = strpart(match, index)
endwhile
let start = len - strlen(match)
if a:0 == 1 && a:1 == "start"
return start - 2
endif
let cnt = 1
while cnt
let index = matchend(match, s:notslash . '\\(\|\\)') - 1
if index == -2
return ""
endif
" Increment if an open, decrement if a ')':
let cnt = cnt + (match[index]=="(" ? 1 : -1) " ')'
" let cnt = stridx('0(', match[index]) + cnt
let match = strpart(match, index+1)
endwhile
let start = start - 2
let len = len - start - strlen(match)
endif
if a:0 == 1
return len
elseif a:0 == 2
return "let " . a:1 . "=" . start . "| let " . a:2 . "=" . len
else
return strpart(a:string, start, len)
endif
endfun
" Count the number of disjoint copies of pattern in string.
" If the pattern is a literal string and contains no '0' or '1' characters
" then s:Count(string, pattern, '0', '1') should be faster than
" s:Count(string, pattern).
fun! s:Count(string, pattern, ...)
let pat = escape(a:pattern, '\\')
if a:0 > 1
let foo = substitute(a:string, '[^'.a:pattern.']', "a:1", "g")
let foo = substitute(a:string, pat, a:2, "g")
let foo = substitute(foo, '[^' . a:2 . ']', "", "g")
return strlen(foo)
endif
let result = 0
let foo = a:string
let index = matchend(foo, pat)
while index != -1
let result = result + 1
let foo = strpart(foo, index)
let index = matchend(foo, pat)
endwhile
return result
endfun
" s:Resolve('\(a\)\(b\)', '\(c\)\2\1\1\2') should return table.word, where
" word = '\(c\)\(b\)\(a\)\3\2' and table = '-32-------'. That is, the first
" '\1' in target is replaced by '\(a\)' in word, table[1] = 3, and this
" indicates that all other instances of '\1' in target are to be replaced
" by '\3'. The hard part is dealing with nesting...
" Note that ":" is an illegal character for source and target,
" unless it is preceded by "\".
fun! s:Resolve(source, target, output)
let word = a:target
let i = matchend(word, s:notslash . '\\\d') - 1
let table = "----------"
while i != -2 " There are back references to be replaced.
let d = word[i]
let backref = s:Ref(a:source, d)
" The idea is to replace '\d' with backref. Before we do this,
" replace any \(\) groups in backref with :1, :2, ... if they
" correspond to the first, second, ... group already inserted
" into backref. Later, replace :1 with \1 and so on. The group
" number w+b within backref corresponds to the group number
" s within a:source.
" w = number of '\(' in word before the current one
let w = s:Count(
\ substitute(strpart(word, 0, i-1), '\\\\', '', 'g'), '\(', '1')
let b = 1 " number of the current '\(' in backref
let s = d " number of the current '\(' in a:source
while b <= s:Count(substitute(backref, '\\\\', '', 'g'), '\(', '1')
\ && s < 10
if table[s] == "-"
if w + b < 10
" let table[s] = w + b
let table = strpart(table, 0, s) . (w+b) . strpart(table, s+1)
endif
let b = b + 1
let s = s + 1
else
execute s:Ref(backref, b, "start", "len")
let ref = strpart(backref, start, len)
let backref = strpart(backref, 0, start) . ":". table[s]
\ . strpart(backref, start+len)
let s = s + s:Count(substitute(ref, '\\\\', '', 'g'), '\(', '1')
endif
endwhile
let word = strpart(word, 0, i-1) . backref . strpart(word, i+1)
let i = matchend(word, s:notslash . '\\\d') - 1
endwhile
let word = substitute(word, s:notslash . '\zs:', '\\', 'g')
if a:output == "table"
return table
elseif a:output == "word"
return word
else
return table . word
endif
endfun
" Assume a:comma = ",". Then the format for a:patterns and a:1 is
" a:patterns = "<pat1>,<pat2>,..."
" a:1 = "<alt1>,<alt2>,..."
" If <patn> is the first pattern that matches a:string then return <patn>
" if no optional arguments are given; return <patn>,<altn> if a:1 is given.
fun! s:Choose(patterns, string, comma, branch, prefix, suffix, ...)
let tail = (a:patterns =~ a:comma."$" ? a:patterns : a:patterns . a:comma)
let i = matchend(tail, s:notslash . a:comma)
if a:0
let alttail = (a:1 =~ a:comma."$" ? a:1 : a:1 . a:comma)
let j = matchend(alttail, s:notslash . a:comma)
endif
let current = strpart(tail, 0, i-1)
if a:branch == ""
let currpat = current
else
let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
endif
while a:string !~ a:prefix . currpat . a:suffix
let tail = strpart(tail, i)
let i = matchend(tail, s:notslash . a:comma)
if i == -1
return -1
endif
let current = strpart(tail, 0, i-1)
if a:branch == ""
let currpat = current
else
let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
endif
if a:0
let alttail = strpart(alttail, j)
let j = matchend(alttail, s:notslash . a:comma)
endif
endwhile
if a:0
let current = current . a:comma . strpart(alttail, 0, j-1)
endif
return current
endfun
" Call this function to turn on debugging information. Every time the main
" script is run, buffer variables will be saved. These can be used directly
" or viewed using the menu items below.
if !exists(":MatchDebug")
command! -nargs=0 MatchDebug call s:Match_debug()
endif
fun! s:Match_debug()
let b:match_debug = 1 " Save debugging information.
" pat = all of b:match_words with backrefs parsed
amenu &Matchit.&pat :echo b:match_pat<CR>
" match = bit of text that is recognized as a match
amenu &Matchit.&match :echo b:match_match<CR>
" curcol = cursor column of the start of the matching text
amenu &Matchit.&curcol :echo b:match_col<CR>
" wholeBR = matching group, original version
amenu &Matchit.wh&oleBR :echo b:match_wholeBR<CR>
" iniBR = 'if' piece, original version
amenu &Matchit.ini&BR :echo b:match_iniBR<CR>
" ini = 'if' piece, with all backrefs resolved from match
amenu &Matchit.&ini :echo b:match_ini<CR>
" tail = 'else\|endif' piece, with all backrefs resolved from match
amenu &Matchit.&tail :echo b:match_tail<CR>
" fin = 'endif' piece, with all backrefs resolved from match
amenu &Matchit.&word :echo b:match_word<CR>
" '\'.d in ini refers to the same thing as '\'.table[d] in word.
amenu &Matchit.t&able :echo '0:' . b:match_table . ':9'<CR>
endfun
" Jump to the nearest unmatched "(" or "if" or "<tag>" if a:spflag == "bW"
" or the nearest unmatched "</tag>" or "endif" or ")" if a:spflag == "W".
" Return a "mark" for the original position, so that
" let m = MultiMatch("bW", "n") ... execute m
" will return to the original position. If there is a problem, do not
" move the cursor and return "", unless a count is given, in which case
" go up or down as many levels as possible and again return "".
" TODO This relies on the same patterns as % matching. It might be a good
" idea to give it its own matching patterns.
fun! s:MultiMatch(spflag, mode)
if !exists("b:match_words") || b:match_words == ""
return ""
end
let restore_options = (&ic ? "" : "no") . "ignorecase"
if exists("b:match_ignorecase")
let &ignorecase = b:match_ignorecase
endif
let startline = line(".")
let startcol = col(".")
" First step: if not already done, set the script variables
" s:do_BR flag for whether there are backrefs
" s:pat parsed version of b:match_words
" s:all regexp based on s:pat and the default groups
" This part is copied and slightly modified from s:Match_wrapper().
let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
\ '\/\*:\*\/,#\s*if\%(def\)\=:#\s*else\>:#\s*elif\>:#\s*endif\>'
" Allow b:match_words = "GetVimMatchWords()" .
if b:match_words =~ ":"
let match_words = b:match_words
else
execute "let match_words =" b:match_words
endif
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
if match_words !~ s:notslash . '\\\d'
let s:do_BR = 0
let s:pat = match_words
else
let s:do_BR = 1
let s:pat = s:ParseWords(match_words)
endif
let s:all = '\%(' . substitute(s:pat . (strlen(s:pat)?",":"") . default,
\ '[,:]\+','\\|','g') . '\)'
if exists("b:match_debug")
let b:match_pat = s:pat
endif
endif
" Second step: figure out the patterns for searchpair()
" and save the screen, cursor position, and 'ignorecase'.
" - TODO: A lot of this is copied from s:Match_wrapper().
" - maybe even more functionality should be split off
" - into separate functions!
let cdefault = (s:pat =~ '[^,]$' ? "," : "") . default
let open = substitute(s:pat . cdefault,
\ s:notslash . '\zs:.\{-}' . s:notslash . ',', '\\),\\(', 'g')
let open = '\(' . substitute(open, s:notslash . '\zs:.*$', '\\)', '')
let close = substitute(s:pat . cdefault,
\ s:notslash . '\zs,.\{-}' . s:notslash . ':', '\\),\\(', 'g')
let close = substitute(close, '^.\{-}' . s:notslash . ':', '\\(', '') . '\)'
if exists("b:match_skip")
let skip = b:match_skip
elseif exists("b:match_comment") " backwards compatibility and testing!
let skip = "r:" . b:match_comment
else
let skip = 's:comment\|string'
endif
let skip = s:ParseSkip(skip)
" let restore_cursor = line(".") . "G" . virtcol(".") . "|"
" normal! H
" let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
let restore_cursor = virtcol(".") . "|"
normal! g0
let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor
normal! H
let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
execute restore_cursor
" Third step: call searchpair().
" Replace '\('--but not '\\('--with '\%(' and ',' with '\|'.
let openpat = substitute(open, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g')
let openpat = substitute(openpat, ',', '\\|', 'g')
let closepat = substitute(close, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g')
let closepat = substitute(closepat, ',', '\\|', 'g')
if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
let skip = '0'
else
execute "if " . skip . "| let skip = '0' | endif"
endif
mark '
let level = v:count1
while level
if searchpair(openpat, '', closepat, a:spflag, skip) < 1
call s:CleanUp(restore_options, a:mode, startline, startcol)
return ""
endif
let level = level - 1
endwhile
" Restore options and return a string to restore the original position.
call s:CleanUp(restore_options, a:mode, startline, startcol)
return restore_cursor
endfun
" Search backwards for "if" or "while" or "<tag>" or ...
" and return "endif" or "endwhile" or "</tag>" or ... .
" For now, this uses b:match_words and the same script variables
" as s:Match_wrapper() . Later, it may get its own patterns,
" either from a buffer variable or passed as arguments.
" fun! s:Autocomplete()
" echo "autocomplete not yet implemented :-("
" if !exists("b:match_words") || b:match_words == ""
" return ""
" end
" let startpos = s:MultiMatch("bW")
"
" if startpos == ""
" return ""
" endif
" " - TODO: figure out whether 'if' or '<tag>' matched, and construct
" " - the appropriate closing.
" let matchline = getline(".")
" let curcol = col(".") - 1
" " - TODO: Change the s:all argument if there is a new set of match pats.
" let regexp = s:Wholematch(matchline, s:all, curcol)
" let suf = strlen(matchline) - matchend(matchline, regexp)
" let prefix = (curcol ? '^.\{' . curcol . '}\%(' : '^\%(')
" let suffix = (suf ? '\).\{' . suf . '}$' : '\)$')
" " Reconstruct the version with unresolved backrefs.
" let patBR = substitute(b:match_words.',', '[,:]*,[,:]*', ',', 'g')
" let patBR = substitute(patBR, ':\{2,}', ':', "g")
" " Now, set group and groupBR to the matching group: 'if:endif' or
" " 'while:endwhile' or whatever.
" let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR)
" let i = matchend(group, s:notslash . ",")
" let groupBR = strpart(group, i)
" let group = strpart(group, 0, i-1)
" " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix
" if s:do_BR
" let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline)
" endif
" " let g:group = group
"
" " - TODO: Construct the closing from group.
" let fake = "end" . expand("<cword>")
" execute startpos
" return fake
" endfun
" Close all open structures. "Get the heck out of here!"
" fun! s:Gthhoh()
" let close = s:Autocomplete()
" while strlen(close)
" put=close
" let close = s:Autocomplete()
" endwhile
" endfun
" Parse special strings as typical skip arguments for searchpair():
" s:foo becomes (current syntax item) =~ foo
" S:foo becomes (current syntax item) !~ foo
" r:foo becomes (line before cursor) =~ foo
" R:foo becomes (line before cursor) !~ foo
fun! s:ParseSkip(str)
let skip = a:str
if skip[1] == ":"
if skip[0] == "s"
let skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" .
\ strpart(skip,2) . "'"
elseif skip[0] == "S"
let skip = "synIDattr(synID(line('.'),col('.'),1),'name') !~? '" .
\ strpart(skip,2) . "'"
elseif skip[0] == "r"
let skip = "strpart(getline('.'),0,col('.'))=~'" . strpart(skip,2). "'"
elseif skip[0] == "R"
let skip = "strpart(getline('.'),0,col('.'))!~'" . strpart(skip,2). "'"
endif
endif
return skip
endfun
let &cpo = s:save_cpo
unlet s:save_cpo
" vim:sts=2:sw=2:
+4 -4
View File
@@ -50,7 +50,7 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
if data == '':
print("=== socket closed ===")
break
print("received: {}".format(data))
print("received: {0}".format(data))
try:
decoded = json.loads(data)
except ValueError:
@@ -65,7 +65,7 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
else:
response = "what?"
encoded = json.dumps([decoded[0], response])
print("sending {}".format(encoded))
print("sending {0}".format(encoded))
self.request.sendall(encoded.encode('utf-8'))
thesocket = None
@@ -87,7 +87,7 @@ if __name__ == "__main__":
server_thread.start()
print("Server loop running in thread: ", server_thread.name)
print("Listening on port {}".format(PORT))
print("Listening on port {0}".format(PORT))
while True:
typed = sys.stdin.readline()
if "quit" in typed:
@@ -96,7 +96,7 @@ if __name__ == "__main__":
if thesocket is None:
print("No socket yet")
else:
print("sending {}".format(typed))
print("sending {0}".format(typed))
thesocket.sendall(typed.encode('utf-8'))
server.shutdown()
+156 -59
View File
@@ -32,8 +32,8 @@ func! ParseFoldProps()
if line !~ '^#' && line !~ '^\s*$'
let l = split(line, '\s*;\s*', 1)
if len(l) != 4
echoerr 'Found ' . len(l) . ' items in line ' . lnum . ', expected 4'
return
echoerr 'Found ' . len(l) . ' items in line ' . lnum . ', expected 4'
return
endif
call add(s:foldprops, l)
endif
@@ -50,8 +50,8 @@ func! ParseWidthProps()
if line !~ '^#' && line !~ '^\s*$'
let l = split(line, '\s*;\s*', 1)
if len(l) != 2
echoerr 'Found ' . len(l) . ' items in line ' . lnum . ', expected 2'
return
echoerr 'Found ' . len(l) . ' items in line ' . lnum . ', expected 2'
return
endif
call add(s:widthprops, l)
endif
@@ -72,18 +72,18 @@ func! BuildCaseTable(name, index)
let n = ('0x' . p[0]) + 0
let nl = ('0x' . p[a:index]) + 0
if start >= 0 && add == nl - n && (step == 0 || n - end == step)
" continue with same range.
let step = n - end
let end = n
" continue with same range.
let step = n - end
let end = n
else
if start >= 0
" produce previous range
call Range(ranges, start, end, step, add)
endif
let start = n
let end = n
let step = 0
let add = nl - n
if start >= 0
" produce previous range
call Range(ranges, start, end, step, add)
endif
let start = n
let end = n
let step = 0
let add = nl - n
endif
endif
endfor
@@ -115,18 +115,18 @@ func! BuildFoldTable()
let n = ('0x' . p[0]) + 0
let nl = ('0x' . p[2]) + 0
if start >= 0 && add == nl - n && (step == 0 || n - end == step)
" continue with same range.
let step = n - end
let end = n
" continue with same range.
let step = n - end
let end = n
else
if start >= 0
" produce previous range
call Range(ranges, start, end, step, add)
endif
let start = n
let end = n
let step = 0
let add = nl - n
if start >= 0
" produce previous range
call Range(ranges, start, end, step, add)
endif
let start = n
let end = n
let step = 0
let add = nl - n
endif
endif
endfor
@@ -160,15 +160,15 @@ func! BuildCombiningTable()
if p[2] == 'Mn' || p[2] == 'Mc' || p[2] == 'Me'
let n = ('0x' . p[0]) + 0
if start >= 0 && end + 1 == n
" continue with same range.
let end = n
" continue with same range.
let end = n
else
if start >= 0
" produce previous range
call add(ranges, printf("\t{0x%04x, 0x%04x},", start, end))
endif
let start = n
let end = n
if start >= 0
" produce previous range
call add(ranges, printf("\t{0x%04x, 0x%04x},", start, end))
endif
let start = n
let end = n
endif
endif
endfor
@@ -197,47 +197,57 @@ func! BuildWidthTable(pattern, tableName)
for p in s:widthprops
if p[1][0] =~ a:pattern
if p[0] =~ '\.\.'
" It is a range. we don't check for composing char then.
let rng = split(p[0], '\.\.')
if len(rng) != 2
echoerr "Cannot parse range: '" . p[0] . "' in width table"
endif
let n = ('0x' . rng[0]) + 0
let n_last = ('0x' . rng[1]) + 0
" It is a range. we don't check for composing char then.
let rng = split(p[0], '\.\.')
if len(rng) != 2
echoerr "Cannot parse range: '" . p[0] . "' in width table"
endif
let n = ('0x' . rng[0]) + 0
let n_last = ('0x' . rng[1]) + 0
else
let n = ('0x' . p[0]) + 0
let n_last = n
let n = ('0x' . p[0]) + 0
let n_last = n
endif
" Find this char in the data table.
while 1
let dn = ('0x' . s:dataprops[dataidx][0]) + 0
if dn >= n
break
endif
let dataidx += 1
let dn = ('0x' . s:dataprops[dataidx][0]) + 0
if dn >= n
break
endif
let dataidx += 1
endwhile
if dn != n && n_last == n
echoerr "Cannot find character " . n . " in data table"
echoerr "Cannot find character " . n . " in data table"
endif
" Only use the char when it's not a composing char.
" But use all chars from a range.
let dp = s:dataprops[dataidx]
if n_last > n || (dp[2] != 'Mn' && dp[2] != 'Mc' && dp[2] != 'Me')
if start >= 0 && end + 1 == n
" continue with same range.
else
if start >= 0
" produce previous range
call add(ranges, printf("\t{0x%04x, 0x%04x},", start, end))
endif
let start = n
endif
let end = n_last
if start >= 0 && end + 1 == n
" continue with same range.
else
if start >= 0
" produce previous range
call add(ranges, printf("\t{0x%04x, 0x%04x},", start, end))
if a:pattern == 'A'
call add(s:ambitable, [start, end])
else
call add(s:doubletable, [start, end])
endif
endif
let start = n
endif
let end = n_last
endif
endif
endfor
if start >= 0
call add(ranges, printf("\t{0x%04x, 0x%04x},", start, end))
if a:pattern == 'A'
call add(s:ambitable, [start, end])
else
call add(s:doubletable, [start, end])
endif
endif
" New buffer to put the result in.
@@ -251,6 +261,84 @@ func! BuildWidthTable(pattern, tableName)
wincmd p
endfunc
" Build the amoji width table in a new buffer.
func! BuildEmojiTable(pattern, tableName)
let alltokens = []
let widthtokens = []
let lines = map(filter(filter(getline(1, '$'), 'v:val=~"^[1-9]"'), 'v:val=~a:pattern'), 'matchstr(v:val,"^\\S\\+")')
for n in range(len(lines))
let line = lines[n]
let token = split(line, '\.\.')
let first = ('0x' . token[0]) + 0
if len(token) == 1
let last = first
else
let last = ('0x' . token[1]) + 0
endif
let token = [first, last]
if len(alltokens) > 0 && (token[0] - 1 == alltokens[-1][1])
let alltokens[-1][1] = token[1]
else
call add(alltokens, token)
endif
" Characters below 1F000 may be considered single width traditionally,
" making them double width causes problems.
if first < 0x1f000
continue
endif
" exclude characters that are in the "ambiguous" or "doublewidth" table
for ambi in s:ambitable
if first >= ambi[0] && first <= ambi[1]
let first = ambi[1] + 1
endif
if last >= ambi[0] && last <= ambi[1]
let last = ambi[0] - 1
endif
endfor
for double in s:doubletable
if first >= double[0] && first <= double[1]
let first = double[1] + 1
endif
if last >= double[0] && last <= double[1]
let last = double[0] - 1
endif
endfor
if first <= last
let token = [first, last]
if len(widthtokens) > 0 && (token[0] - 1 == widthtokens[-1][1])
let widthtokens[-1][1] = token[1]
else
call add(widthtokens, token)
endif
endif
endfor
let allranges = map(alltokens, 'printf("\t{0x%04x, 0x%04x},", v:val[0], v:val[1])')
let widthranges = map(widthtokens, 'printf("\t{0x%04x, 0x%04x},", v:val[0], v:val[1])')
" New buffer to put the result in.
new
exe "file " . a:tableName . '_all'
call setline(1, " static struct interval " . a:tableName . "_all[] =")
call setline(2, " {")
call append('$', allranges)
call setline('$', getline('$')[:-2]) " remove last comma
call setline(line('$') + 1, " };")
wincmd p
" New buffer to put the result in.
new
exe "file " . a:tableName . '_width'
call setline(1, " static struct interval " . a:tableName . "_width[] =")
call setline(2, " {")
call append('$', widthranges)
call setline('$', getline('$')[:-2]) " remove last comma
call setline(line('$') + 1, " };")
wincmd p
endfunc
" Try to avoid hitting E36
set equalalways
@@ -286,7 +374,16 @@ edit http://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt
call ParseWidthProps()
" Build the double width table.
let s:doubletable = []
call BuildWidthTable('[WF]', 'doublewidth')
" Build the ambiguous width table.
let s:ambitable = []
call BuildWidthTable('A', 'ambiguous')
" Edit the emoji text file. Requires the netrw plugin.
edit http://www.unicode.org/Public/emoji/3.0/emoji-data.txt
" Build the emoji table. Ver. 1.0 - 6.0
" Must come after the "ambiguous" table
call BuildEmojiTable('; Emoji\s\+# [1-6]\.[0-9]', 'emoji')
+8 -1
View File
@@ -1,7 +1,7 @@
" An example for a vimrc file.
"
" Maintainer: Bram Moolenaar <Bram@vim.org>
" Last change: 2015 Mar 24
" Last change: 2016 Mar 25
"
" To use it, copy it to
" for Unix and OS/2: ~/.vimrc
@@ -100,3 +100,10 @@ if has('langmap') && exists('+langnoremap')
" compatible).
set langnoremap
endif
" Add optional packages.
"
" The matchit plugin makes the % command work better, but it is not backwards
" compatible.
packadd matchit
+1 -1
View File
@@ -1255,7 +1255,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>99</string>
<string>100</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
+3 -2
View File
@@ -415,6 +415,7 @@ WINDRES_CC = $(CC)
###########################################################################
CFLAGS = -Iproto $(DEFINES) -pipe -march=$(ARCH) -Wall
CXXFLAGS = -std=gnu++11
WINDRES_FLAGS = --preprocessor="$(WINDRES_CC) -E -xc" -DRC_INVOKED
EXTRA_LIBS =
@@ -864,14 +865,14 @@ $(OUTDIR)/gui_w32.o: gui_w32.c $(INCL)
$(CC) -c $(CFLAGS) gui_w32.c -o $(OUTDIR)/gui_w32.o
$(OUTDIR)/gui_dwrite.o: gui_dwrite.cpp $(INCL) gui_dwrite.h
$(CC) -c $(CFLAGS) gui_dwrite.cpp -o $(OUTDIR)/gui_dwrite.o
$(CC) -c $(CFLAGS) $(CXXFLAGS) gui_dwrite.cpp -o $(OUTDIR)/gui_dwrite.o
$(OUTDIR)/if_cscope.o: if_cscope.c $(INCL) if_cscope.h
$(CC) -c $(CFLAGS) if_cscope.c -o $(OUTDIR)/if_cscope.o
# Remove -D__IID_DEFINED__ for newer versions of the w32api
$(OUTDIR)/if_ole.o: if_ole.cpp $(INCL)
$(CC) $(CFLAGS) -c -o $(OUTDIR)/if_ole.o if_ole.cpp
$(CC) $(CFLAGS) $(CXXFLAGS) -c -o $(OUTDIR)/if_ole.o if_ole.cpp
$(OUTDIR)/if_ruby.o: if_ruby.c $(INCL)
ifeq (16, $(RUBY))
+40 -9
View File
@@ -130,6 +130,7 @@
# make installlinks only installs the Vim binary links
# make installmanlinks only installs the Vim manpage links
# make installmacros only installs the Vim macros
# make installpack only installs the packages
# make installtutorbin only installs the Vim tutor program
# make installtutor only installs the Vim tutor files
# make installspell only installs the spell files
@@ -424,7 +425,7 @@ CClink = $(CC)
# NOTE: This may cause threading to be enabled, which has side effects (such
# as using different libraries and debugging becomes more difficult).
# NOTE: Using this together with Perl may cause a crash in initialization.
# For Python3 support make a symbolic link in /usr/local/bin:
# For Python3 support make a symbolic link in /usr/local/bin:
# ln -s python3 python3.1
# If both python2.x and python3.x are enabled then the linking will be via
# dlopen(), dlsym(), dlclose(), i.e. pythonX.Y.so must be available
@@ -1008,6 +1009,7 @@ LANGSUBDIR = /lang
COMPSUBDIR = /compiler
KMAPSUBDIR = /keymap
MACROSUBDIR = /macros
PACKSUBDIR = /pack
TOOLSSUBDIR = /tools
TUTORSUBDIR = /tutor
SPELLSUBDIR = /spell
@@ -1029,6 +1031,7 @@ PODIR = po
### COMPSUBLOC location for compiler files
### KMAPSUBLOC location for keymap files
### MACROSUBLOC location for macro files
### PACKSUBLOC location for packages
### TOOLSSUBLOC location for tools files
### TUTORSUBLOC location for tutor files
### SPELLSUBLOC location for spell files
@@ -1050,6 +1053,7 @@ LANGSUBLOC = $(VIMRTLOC)$(LANGSUBDIR)
COMPSUBLOC = $(VIMRTLOC)$(COMPSUBDIR)
KMAPSUBLOC = $(VIMRTLOC)$(KMAPSUBDIR)
MACROSUBLOC = $(VIMRTLOC)$(MACROSUBDIR)
PACKSUBLOC = $(VIMRTLOC)$(PACKSUBDIR)
TOOLSSUBLOC = $(VIMRTLOC)$(TOOLSSUBDIR)
TUTORSUBLOC = $(VIMRTLOC)$(TUTORSUBDIR)
SPELLSUBLOC = $(VIMRTLOC)$(SPELLSUBDIR)
@@ -1155,6 +1159,9 @@ FTPLUGSOURCE = ../runtime/ftplugin
# Where to copy the macro files from
MACROSOURCE = ../runtime/macros
# Where to copy the package files from
PACKSOURCE = ../runtime/pack
# Where to copy the tools files from
TOOLSSOURCE = ../runtime/tools
@@ -1447,6 +1454,7 @@ DEST_LANG = $(DESTDIR)$(LANGSUBLOC)
DEST_COMP = $(DESTDIR)$(COMPSUBLOC)
DEST_KMAP = $(DESTDIR)$(KMAPSUBLOC)
DEST_MACRO = $(DESTDIR)$(MACROSUBLOC)
DEST_PACK = $(DESTDIR)$(PACKSUBLOC)
DEST_TOOLS = $(DESTDIR)$(TOOLSSUBLOC)
DEST_TUTOR = $(DESTDIR)$(TUTORSUBLOC)
DEST_SPELL = $(DESTDIR)$(SPELLSUBLOC)
@@ -1989,7 +1997,6 @@ test1 \
test_match_conceal \
test_nested_function \
test_options \
test_qf_title \
test_ruby \
test_search_mbyte \
test_signs \
@@ -1999,7 +2006,7 @@ test1 \
test_wordcount \
test_writefile \
test2 test3 test4 test5 test6 test7 test8 test9 \
test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 \
test11 test12 test13 test14 test15 test16 test17 test18 test19 \
test20 test21 test22 test23 test24 test25 test26 test27 test28 test29 \
test30 test31 test32 test33 test34 test35 test36 test37 test38 test39 \
test40 test41 test42 test43 test44 test45 test46 test47 test48 test49 \
@@ -2007,37 +2014,51 @@ test1 \
test60 test61 test62 test63 test64 test65 test66 test67 test68 test69 \
test70 test71 test72 test73 test74 test75 test76 test77 test78 test79 \
test80 test81 test82 test83 test84 test85 test86 test87 test88 test89 \
test90 test91 test92 test93 test94 test95 test96 test97 test98 test99 \
test100 test101 test102 test103 test104 test105 test106 test107 test108:
test90 test91 test92 test93 test94 test95 test97 test98 test99 \
test100 test101 test102 test103 test104 test105 test107 test108:
cd testdir; rm -f $@.out; $(MAKE) -f Makefile $@.out VIMPROG=../$(VIMTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
# Run individual NEW style test, assuming that Vim was already compiled.
test_arglist \
test_assert \
test_assign \
test_backspace_opt \
test_cdo \
test_channel \
test_cursor_func \
test_delete \
test_ex_undo \
test_expr \
test_expand \
test_feedkeys \
test_file_perm \
test_glob2regpat \
test_hardcopy \
test_help_tagjump \
test_history \
test_increment \
test_join \
test_json \
test_langmap \
test_lispwords \
test_menu \
test_packadd \
test_partial \
test_perl \
test_quickfix \
test_reltime \
test_searchpos \
test_set \
test_sort \
test_syn_attr \
test_syntax \
test_timers \
test_undolevels \
test_unlet \
test_viminfo \
test_viml \
test_visual \
test_window_id \
test_alot:
cd testdir; rm -f $@.res test.log messages; $(MAKE) -f Makefile $@.res VIMPROG=../$(VIMTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
@if test -f testdir/test.log; then \
@@ -2111,7 +2132,7 @@ INSTALLMANARGS = $(VIMLOC) $(SCRIPTLOC) $(VIMRCLOC) $(HELPSOURCE) $(MANMOD) \
$(VIMNAME) $(VIMDIFFNAME) $(EVIMNAME)
# Install most of the runtime files
installruntime: installrtbase installmacros installtutor installspell
installruntime: installrtbase installmacros installpack installtutor installspell
# install the help files; first adjust the contents for the final location
installrtbase: $(HELPSOURCE)/vim.1 $(DEST_VIM) $(DEST_RT) \
@@ -2119,8 +2140,11 @@ installrtbase: $(HELPSOURCE)/vim.1 $(DEST_VIM) $(DEST_RT) \
$(DEST_FTP) $(DEST_AUTO) $(DEST_AUTO)/xml $(DEST_PLUG) \
$(DEST_TUTOR) $(DEST_SPELL) $(DEST_COMP)
-$(SHELL) ./installman.sh install $(DEST_MAN) "" $(INSTALLMANARGS)
@echo generating help tags
# Generate the help tags with ":helptags" to handle all languages.
# Move the distributed tags file aside and restore it, to avoid it being
# different from the repository.
cd $(HELPSOURCE); if test -f tags; then mv -f tags tags.dist; fi
@echo generating help tags
-@cd $(HELPSOURCE); $(MAKE) VIMEXE=$(DEST_BIN)/$(VIMTARGET) vimtags
cd $(HELPSOURCE); \
files=`ls *.txt tags`; \
@@ -2130,6 +2154,7 @@ installrtbase: $(HELPSOURCE)/vim.1 $(DEST_VIM) $(DEST_RT) \
chmod $(HELPMOD) $$files
$(INSTALL_DATA) $(HELPSOURCE)/*.pl $(DEST_HELP)
chmod $(SCRIPTMOD) $(DEST_HELP)/*.pl
cd $(HELPSOURCE); if test -f tags.dist; then mv -f tags.dist tags; fi
# install the menu files
$(INSTALL_DATA) $(SCRIPTSOURCE)/menu.vim $(SYS_MENU_FILE)
chmod $(VIMSCRIPTMOD) $(SYS_MENU_FILE)
@@ -2206,6 +2231,11 @@ installmacros: $(DEST_VIM) $(DEST_RT) $(DEST_MACRO)
rm -rf $$cvs; \
fi
installpack: $(DEST_VIM) $(DEST_RT) $(DEST_PACK)
$(INSTALL_DATA_R) $(PACKSOURCE)/* $(DEST_PACK)
chmod $(DIRMOD) `find $(DEST_PACK) -type d -print`
chmod $(FILEMOD) `find $(DEST_PACK) -type f -print`
# install the tutor files
installtutorbin: $(DEST_VIM)
$(INSTALL_DATA) vimtutor $(DEST_BIN)/$(VIMNAME)tutor
@@ -2355,8 +2385,8 @@ $(HELPSOURCE)/vim.1 $(MACROSOURCE) $(TOOLSSOURCE):
$(DESTDIR)$(exec_prefix) $(DEST_BIN) \
$(DEST_VIM) $(DEST_RT) $(DEST_HELP) \
$(DEST_PRINT) $(DEST_COL) $(DEST_SYN) $(DEST_IND) $(DEST_FTP) \
$(DEST_LANG) $(DEST_KMAP) $(DEST_COMP) \
$(DEST_MACRO) $(DEST_TOOLS) $(DEST_TUTOR) $(DEST_SPELL) \
$(DEST_LANG) $(DEST_KMAP) $(DEST_COMP) $(DEST_MACRO) \
$(DEST_PACK) $(DEST_TOOLS) $(DEST_TUTOR) $(DEST_SPELL) \
$(DEST_AUTO) $(DEST_AUTO)/xml $(DEST_PLUG):
-$(SHELL) ./mkinstalldirs $@
-chmod $(DIRMOD) $@
@@ -2501,6 +2531,7 @@ uninstall_runtime:
-rm -f $(DEST_SYN)/*.vim $(DEST_SYN)/README.txt
-rm -f $(DEST_IND)/*.vim $(DEST_IND)/README.txt
-rm -rf $(DEST_MACRO)
-rm -rf $(DEST_PACK)
-rm -rf $(DEST_TUTOR)
-rm -rf $(DEST_SPELL)
-rm -rf $(DEST_TOOLS)
+9 -9
View File
@@ -139,14 +139,19 @@ open_buffer(
#endif
)
{
int old_msg_silent = msg_silent;
#ifdef FEAT_NETBEANS_INTG
int oldFire = netbeansFireChanges;
netbeansFireChanges = 0;
#endif
if (shortmess(SHM_FILEINFO))
msg_silent = 1;
retval = readfile(curbuf->b_ffname, curbuf->b_fname,
(linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap,
flags | READ_NEW);
msg_silent = old_msg_silent;
#ifdef FEAT_NETBEANS_INTG
netbeansFireChanges = oldFire;
#endif
@@ -4612,9 +4617,9 @@ do_arg_all(
old_curwin = curwin;
old_curtab = curtab;
#ifdef FEAT_GUI
# ifdef FEAT_GUI
need_mouse_correct = TRUE;
#endif
# endif
/*
* Try closing all windows that are not in the argument list.
@@ -4634,10 +4639,7 @@ do_arg_all(
buf = wp->w_buffer;
if (buf->b_ffname == NULL
|| (!keep_tabs && buf->b_nwindows > 1)
#ifdef FEAT_VERTSPLIT
|| wp->w_width != Columns
#endif
)
|| wp->w_width != Columns)
i = opened_len;
else
{
@@ -4906,13 +4908,11 @@ ex_buffer_all(exarg_T *eap)
{
wpnext = wp->w_next;
if ((wp->w_buffer->b_nwindows > 1
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
|| ((cmdmod.split & WSP_VERT)
? wp->w_height + wp->w_status_height < Rows - p_ch
- tabline_height()
: wp->w_width != Columns)
#endif
#ifdef FEAT_WINDOWS
|| (had_tab > 0 && wp != firstwin)
#endif
) && firstwin != lastwin
+336 -121
View File
@@ -857,6 +857,8 @@ channel_open(
channel->CH_SOCK_FD = (sock_T)sd;
channel->ch_nb_close_cb = nb_close_cb;
channel->ch_hostname = (char *)vim_strsave((char_u *)hostname);
channel->ch_port = port_in;
#ifdef FEAT_GUI
channel_gui_register_one(channel, PART_SOCK);
@@ -1022,11 +1024,11 @@ find_buffer(char_u *name, int err)
buf = buflist_new(name == NULL || *name == NUL ? NULL : name,
NULL, (linenr_T)0, BLN_LISTED);
buf_copy_options(buf, BCO_ENTER);
curbuf = buf;
#ifdef FEAT_QUICKFIX
set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL);
#endif
curbuf = buf;
if (curbuf->b_ml.ml_mfp == NULL)
ml_open(curbuf);
ml_replace(1, (char_u *)(err ? "Reading from channel error..."
@@ -1044,8 +1046,9 @@ find_buffer(char_u *name, int err)
void
channel_set_options(channel_T *channel, jobopt_T *opt)
{
int part;
char_u **cbp;
int part;
char_u **cbp;
partial_T **pp;
if (opt->jo_set & JO_MODE)
for (part = PART_SOCK; part <= PART_IN; ++part)
@@ -1068,38 +1071,58 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
if (opt->jo_set & JO_CALLBACK)
{
cbp = &channel->ch_callback;
pp = &channel->ch_partial;
vim_free(*cbp);
partial_unref(*pp);
if (opt->jo_callback != NULL && *opt->jo_callback != NUL)
*cbp = vim_strsave(opt->jo_callback);
else
*cbp = NULL;
*pp = opt->jo_partial;
if (*pp != NULL)
++(*pp)->pt_refcount;
}
if (opt->jo_set & JO_OUT_CALLBACK)
{
cbp = &channel->ch_part[PART_OUT].ch_callback;
pp = &channel->ch_part[PART_OUT].ch_partial;
vim_free(*cbp);
partial_unref(*pp);
if (opt->jo_out_cb != NULL && *opt->jo_out_cb != NUL)
*cbp = vim_strsave(opt->jo_out_cb);
else
*cbp = NULL;
*pp = opt->jo_out_partial;
if (*pp != NULL)
++(*pp)->pt_refcount;
}
if (opt->jo_set & JO_ERR_CALLBACK)
{
cbp = &channel->ch_part[PART_ERR].ch_callback;
pp = &channel->ch_part[PART_ERR].ch_partial;
vim_free(*cbp);
partial_unref(*pp);
if (opt->jo_err_cb != NULL && *opt->jo_err_cb != NUL)
*cbp = vim_strsave(opt->jo_err_cb);
else
*cbp = NULL;
*pp = opt->jo_err_partial;
if (*pp != NULL)
++(*pp)->pt_refcount;
}
if (opt->jo_set & JO_CLOSE_CALLBACK)
{
cbp = &channel->ch_close_cb;
pp = &channel->ch_close_partial;
vim_free(*cbp);
partial_unref(*pp);
if (opt->jo_close_cb != NULL && *opt->jo_close_cb != NUL)
*cbp = vim_strsave(opt->jo_close_cb);
else
*cbp = NULL;
*pp = opt->jo_err_partial;
if (*pp != NULL)
++(*pp)->pt_refcount;
}
if ((opt->jo_set & JO_OUT_IO) && opt->jo_io[PART_OUT] == JIO_BUFFER)
@@ -1136,6 +1159,10 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
ch_logs(channel, "writing err to buffer '%s'",
(char *)channel->ch_part[PART_ERR].ch_buffer->b_ffname);
}
channel->ch_part[PART_OUT].ch_io = opt->jo_io[PART_OUT];
channel->ch_part[PART_ERR].ch_io = opt->jo_io[PART_ERR];
channel->ch_part[PART_IN].ch_io = opt->jo_io[PART_IN];
}
/*
@@ -1143,10 +1170,11 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
*/
void
channel_set_req_callback(
channel_T *channel,
int part,
char_u *callback,
int id)
channel_T *channel,
int part,
char_u *callback,
partial_T *partial,
int id)
{
cbq_T *head = &channel->ch_part[part].ch_cb_head;
cbq_T *item = (cbq_T *)alloc((int)sizeof(cbq_T));
@@ -1154,6 +1182,9 @@ channel_set_req_callback(
if (item != NULL)
{
item->cq_callback = vim_strsave(callback);
item->cq_partial = partial;
if (partial != NULL)
++partial->pt_refcount;
item->cq_seq_nr = id;
item->cq_prev = head->cq_prev;
head->cq_prev = item;
@@ -1266,7 +1297,8 @@ channel_write_new_lines(buf_T *buf)
* Invoke the "callback" on channel "channel".
*/
static void
invoke_callback(channel_T *channel, char_u *callback, typval_T *argv)
invoke_callback(channel_T *channel, char_u *callback, partial_T *partial,
typval_T *argv)
{
typval_T rettv;
int dummy;
@@ -1275,22 +1307,10 @@ invoke_callback(channel_T *channel, char_u *callback, typval_T *argv)
argv[0].vval.v_channel = channel;
call_func(callback, (int)STRLEN(callback),
&rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL);
&rettv, 2, argv, 0L, 0L, &dummy, TRUE, partial, NULL);
clear_tv(&rettv);
/* If an echo command was used the cursor needs to be put back where
* it belongs. If highlighting was changed a redraw is needed. */
update_screen(0);
setcursor();
cursor_on();
out_flush();
#ifdef FEAT_GUI
if (gui.in_use)
{
gui_update_cursor(TRUE, FALSE);
gui_mch_flush();
}
#endif
redraw_after_callback();
}
/*
@@ -1367,7 +1387,7 @@ channel_collapse(channel_T *channel, int part)
* Returns OK or FAIL.
*/
static int
channel_save(channel_T *channel, int part, char_u *buf, int len)
channel_save(channel_T *channel, int part, char_u *buf, int len, char *lead)
{
readq_T *node;
readq_T *head = &channel->ch_part[part].ch_head;
@@ -1408,9 +1428,9 @@ channel_save(channel_T *channel, int part, char_u *buf, int len)
head->rq_prev->rq_next = node;
head->rq_prev = node;
if (log_fd != NULL)
if (log_fd != NULL && lead != NULL)
{
ch_log_lead("RECV ", channel);
ch_log_lead(lead, channel);
fprintf(log_fd, "'");
if (fwrite(buf, len, 1, log_fd) != 1)
return FAIL;
@@ -1420,7 +1440,7 @@ channel_save(channel_T *channel, int part, char_u *buf, int len)
}
/*
* Use the read buffer of "channel"/"part" and parse a JSON messages that is
* Use the read buffer of "channel"/"part" and parse a JSON message that is
* complete. The messages are added to the queue.
* Return TRUE if there is more to read.
*/
@@ -1430,7 +1450,9 @@ channel_parse_json(channel_T *channel, int part)
js_read_T reader;
typval_T listtv;
jsonq_T *item;
jsonq_T *head = &channel->ch_part[part].ch_json_head;
chanpart_T *chanpart = &channel->ch_part[part];
jsonq_T *head = &chanpart->ch_json_head;
int status;
int ret;
if (channel_peek(channel, part) == NULL)
@@ -1443,15 +1465,23 @@ channel_parse_json(channel_T *channel, int part)
reader.js_fill = NULL;
/* reader.js_fill = channel_fill; */
reader.js_cookie = channel;
ret = json_decode(&reader, &listtv,
channel->ch_part[part].ch_mode == MODE_JS ? JSON_JS : 0);
if (ret == OK)
/* When a message is incomplete we wait for a short while for more to
* arrive. After the delay drop the input, otherwise a truncated string
* or list will make us hang. */
status = json_decode(&reader, &listtv,
chanpart->ch_mode == MODE_JS ? JSON_JS : 0);
if (status == OK)
{
/* Only accept the response when it is a list with at least two
* items. */
if (listtv.v_type != VAR_LIST || listtv.vval.v_list->lv_len < 2)
{
/* TODO: give error */
if (listtv.v_type != VAR_LIST)
ch_error(channel, "Did not receive a list, discarding");
else
ch_errorn(channel, "Expected list with two items, got %d",
listtv.vval.v_list->lv_len);
clear_tv(&listtv);
}
else
@@ -1482,13 +1512,70 @@ channel_parse_json(channel_T *channel, int part)
}
}
/* Put the unread part back into the channel.
* TODO: insert in front */
if (reader.js_buf[reader.js_used] != NUL)
if (status == OK)
chanpart->ch_waiting = FALSE;
else if (status == MAYBE)
{
if (!chanpart->ch_waiting)
{
/* First time encountering incomplete message, set a deadline of
* 100 msec. */
ch_log(channel, "Incomplete message - wait for more");
reader.js_used = 0;
chanpart->ch_waiting = TRUE;
#ifdef WIN32
chanpart->ch_deadline = GetTickCount() + 100L;
#else
gettimeofday(&chanpart->ch_deadline, NULL);
chanpart->ch_deadline.tv_usec += 100 * 1000;
if (chanpart->ch_deadline.tv_usec > 1000 * 1000)
{
chanpart->ch_deadline.tv_usec -= 1000 * 1000;
++chanpart->ch_deadline.tv_sec;
}
#endif
}
else
{
int timeout;
#ifdef WIN32
timeout = GetTickCount() > chanpart->ch_deadline;
#else
{
struct timeval now_tv;
gettimeofday(&now_tv, NULL);
timeout = now_tv.tv_sec > chanpart->ch_deadline.tv_sec
|| (now_tv.tv_sec == chanpart->ch_deadline.tv_sec
&& now_tv.tv_usec > chanpart->ch_deadline.tv_usec);
}
#endif
if (timeout)
{
status = FAIL;
chanpart->ch_waiting = FALSE;
}
else
{
reader.js_used = 0;
ch_log(channel, "still waiting on incomplete message");
}
}
}
if (status == FAIL)
{
ch_error(channel, "Decoding failed - discarding input");
ret = FALSE;
chanpart->ch_waiting = FALSE;
}
else if (reader.js_buf[reader.js_used] != NUL)
{
/* Put the unread part back into the channel.
* TODO: insert in front */
channel_save(channel, part, reader.js_buf + reader.js_used,
(int)(reader.js_end - reader.js_buf) - reader.js_used);
ret = TRUE;
(int)(reader.js_end - reader.js_buf) - reader.js_used, NULL);
ret = status == MAYBE ? FALSE: TRUE;
}
else
ret = FALSE;
@@ -1556,6 +1643,8 @@ channel_get_json(channel_T *channel, int part, int id, typval_T **rettv)
|| tv->vval.v_number != channel->ch_part[part].ch_block_id)))
{
*rettv = item->jq_value;
if (tv->v_type == VAR_NUMBER)
ch_logn(channel, "Getting JSON message %d", tv->vval.v_number);
remove_json_node(head, item);
return OK;
}
@@ -1591,12 +1680,14 @@ channel_exe_cmd(channel_T *channel, int part, typval_T *argv)
if (STRCMP(cmd, "ex") == 0)
{
ch_logs(channel, "Executing ex command '%s'", (char *)arg);
do_cmdline_cmd(arg);
}
else if (STRCMP(cmd, "normal") == 0)
{
exarg_T ea;
ch_logs(channel, "Executing normal command '%s'", (char *)arg);
ea.arg = arg;
ea.addr_count = 0;
ea.forceit = TRUE; /* no mapping */
@@ -1606,6 +1697,7 @@ channel_exe_cmd(channel_T *channel, int part, typval_T *argv)
{
exarg_T ea;
ch_log(channel, "redraw");
ea.forceit = *arg != NUL;
ex_redraw(&ea);
showruler(FALSE);
@@ -1647,11 +1739,18 @@ channel_exe_cmd(channel_T *channel, int part, typval_T *argv)
/* Don't pollute the display with errors. */
++emsg_skip;
if (!is_call)
{
ch_logs(channel, "Evaluating expression '%s'", (char *)arg);
tv = eval_expr(arg, NULL);
else if (func_call(arg, &argv[2], NULL, &res_tv) == OK)
tv = &res_tv;
}
else
tv = NULL;
{
ch_logs(channel, "Calling '%s'", (char *)arg);
if (func_call(arg, &argv[2], NULL, NULL, &res_tv) == OK)
tv = &res_tv;
else
tv = NULL;
}
if (argv[id_idx].v_type == VAR_NUMBER)
{
@@ -1704,8 +1803,9 @@ invoke_one_time_callback(
/* Remove the item from the list first, if the callback
* invokes ch_close() the list will be cleared. */
remove_cb_node(cbhead, item);
invoke_callback(channel, item->cq_callback, argv);
invoke_callback(channel, item->cq_callback, item->cq_partial, argv);
vim_free(item->cq_callback);
partial_unref(item->cq_partial);
vim_free(item);
}
@@ -1794,6 +1894,7 @@ may_invoke_callback(channel_T *channel, int part)
cbq_T *cbhead = &channel->ch_part[part].ch_cb_head;
cbq_T *cbitem;
char_u *callback = NULL;
partial_T *partial = NULL;
buf_T *buffer = NULL;
if (channel->ch_nb_close_cb != NULL)
@@ -1805,11 +1906,20 @@ may_invoke_callback(channel_T *channel, int part)
if (cbitem->cq_seq_nr == 0)
break;
if (cbitem != NULL)
{
callback = cbitem->cq_callback;
partial = cbitem->cq_partial;
}
else if (channel->ch_part[part].ch_callback != NULL)
{
callback = channel->ch_part[part].ch_callback;
partial = channel->ch_part[part].ch_partial;
}
else
{
callback = channel->ch_callback;
partial = channel->ch_partial;
}
buffer = channel->ch_part[part].ch_buffer;
if (buffer != NULL && !buf_valid(buffer))
@@ -1842,10 +1952,7 @@ may_invoke_callback(channel_T *channel, int part)
if (argv[0].v_type == VAR_STRING)
{
char_u *cmd = argv[0].vval.v_string;
/* ["cmd", arg] or ["cmd", arg, arg] or ["cmd", arg, arg, arg] */
ch_logs(channel, "Executing %s command", (char *)cmd);
channel_exe_cmd(channel, part, argv);
free_tv(listtv);
return TRUE;
@@ -1955,7 +2062,7 @@ may_invoke_callback(channel_T *channel, int part)
/* invoke the channel callback */
ch_logs(channel, "Invoking channel callback %s",
(char *)callback);
invoke_callback(channel, callback, argv);
invoke_callback(channel, callback, partial, argv);
}
}
}
@@ -2006,6 +2113,69 @@ channel_status(channel_T *channel)
return "closed";
}
static void
channel_part_info(channel_T *channel, dict_T *dict, char *name, int part)
{
chanpart_T *chanpart = &channel->ch_part[part];
char namebuf[20];
size_t tail;
char *s = "";
STRCPY(namebuf, name);
STRCAT(namebuf, "_");
tail = STRLEN(namebuf);
STRCPY(namebuf + tail, "status");
dict_add_nr_str(dict, namebuf, 0,
(char_u *)(chanpart->ch_fd == INVALID_FD ? "closed" : "open"));
STRCPY(namebuf + tail, "mode");
switch (chanpart->ch_mode)
{
case MODE_NL: s = "NL"; break;
case MODE_RAW: s = "RAW"; break;
case MODE_JSON: s = "JSON"; break;
case MODE_JS: s = "JS"; break;
}
dict_add_nr_str(dict, namebuf, 0, (char_u *)s);
STRCPY(namebuf + tail, "io");
if (part == PART_SOCK)
s = "socket";
else switch (chanpart->ch_io)
{
case JIO_NULL: s = "null"; break;
case JIO_PIPE: s = "pipe"; break;
case JIO_FILE: s = "file"; break;
case JIO_BUFFER: s = "buffer"; break;
case JIO_OUT: s = "out"; break;
}
dict_add_nr_str(dict, namebuf, 0, (char_u *)s);
STRCPY(namebuf + tail, "timeout");
dict_add_nr_str(dict, namebuf, chanpart->ch_timeout, NULL);
}
void
channel_info(channel_T *channel, dict_T *dict)
{
dict_add_nr_str(dict, "id", channel->ch_id, NULL);
dict_add_nr_str(dict, "status", 0, (char_u *)channel_status(channel));
if (channel->ch_hostname != NULL)
{
dict_add_nr_str(dict, "hostname", 0, (char_u *)channel->ch_hostname);
dict_add_nr_str(dict, "port", channel->ch_port, NULL);
channel_part_info(channel, dict, "sock", PART_SOCK);
}
else
{
channel_part_info(channel, dict, "out", PART_OUT);
channel_part_info(channel, dict, "err", PART_ERR);
channel_part_info(channel, dict, "in", PART_IN);
}
}
/*
* Close channel "channel".
* Trigger the close callback if "invoke_close_cb" is TRUE.
@@ -2043,13 +2213,16 @@ channel_close(channel_T *channel, int invoke_close_cb)
argv[0].vval.v_channel = channel;
++channel->ch_refcount;
call_func(channel->ch_close_cb, (int)STRLEN(channel->ch_close_cb),
&rettv, 1, argv, 0L, 0L, &dummy, TRUE, NULL);
&rettv, 1, argv, 0L, 0L, &dummy, TRUE,
channel->ch_close_partial, NULL);
clear_tv(&rettv);
--channel->ch_refcount;
/* the callback is only called once */
vim_free(channel->ch_close_cb);
channel->ch_close_cb = NULL;
partial_unref(channel->ch_close_partial);
channel->ch_close_partial = NULL;
}
channel->ch_nb_close_cb = NULL;
@@ -2087,6 +2260,7 @@ channel_clear_one(channel_T *channel, int part)
remove_cb_node(cb_head, node);
vim_free(node->cq_callback);
partial_unref(node->cq_partial);
vim_free(node);
}
@@ -2098,6 +2272,8 @@ channel_clear_one(channel_T *channel, int part)
vim_free(channel->ch_part[part].ch_callback);
channel->ch_part[part].ch_callback = NULL;
partial_unref(channel->ch_part[part].ch_partial);
channel->ch_part[part].ch_partial = NULL;
}
/*
@@ -2107,13 +2283,19 @@ channel_clear_one(channel_T *channel, int part)
channel_clear(channel_T *channel)
{
ch_log(channel, "Clearing channel");
vim_free(channel->ch_hostname);
channel->ch_hostname = NULL;
channel_clear_one(channel, PART_SOCK);
channel_clear_one(channel, PART_OUT);
channel_clear_one(channel, PART_ERR);
vim_free(channel->ch_callback);
channel->ch_callback = NULL;
partial_unref(channel->ch_partial);
channel->ch_partial = NULL;
vim_free(channel->ch_close_cb);
channel->ch_close_cb = NULL;
partial_unref(channel->ch_close_partial);
channel->ch_close_partial = NULL;
}
#if defined(EXITFREE) || defined(PROTO)
@@ -2202,17 +2384,6 @@ channel_wait(channel_T *channel, sock_T fd, int timeout)
return FAIL;
}
/*
* Return a unique ID to be used in a message.
*/
int
channel_get_id(void)
{
static int next_id = 1;
return next_id++;
}
/*
* Read from channel "channel" for as long as there is something to read.
* "part" is PART_SOCK, PART_OUT or PART_ERR.
@@ -2258,7 +2429,7 @@ channel_read(channel_T *channel, int part, char *func)
break; /* error or nothing more to read */
/* Store the read message in the queue. */
channel_save(channel, part, buf, len);
channel_save(channel, part, buf, len, "RECV ");
readlen += len;
if (len < MAXMSGSIZE)
break; /* did read everything that's available */
@@ -2285,7 +2456,7 @@ channel_read(channel_T *channel, int part, char *func)
if (channel->ch_part[part].ch_mode == MODE_RAW
|| channel->ch_part[part].ch_mode == MODE_NL)
channel_save(channel, part, (char_u *)DETACH_MSG_RAW,
(int)STRLEN(DETACH_MSG_RAW));
(int)STRLEN(DETACH_MSG_RAW), "PUT ");
/* TODO: When reading from stdout is not possible, should we try to
* keep stdin and stderr open? Probably not, assume the other side
@@ -2330,9 +2501,13 @@ channel_read_block(channel_T *channel, int part, int timeout)
continue;
/* Wait for up to the channel timeout. */
if (fd == INVALID_FD
|| channel_wait(channel, fd, timeout) == FAIL)
if (fd == INVALID_FD)
return NULL;
if (channel_wait(channel, fd, timeout) == FAIL)
{
ch_log(channel, "Timed out");
return NULL;
}
channel_read(channel, part, "channel_read_block");
}
@@ -2372,16 +2547,18 @@ channel_read_block(channel_T *channel, int part, int timeout)
channel_read_json_block(
channel_T *channel,
int part,
int timeout,
int timeout_arg,
int id,
typval_T **rettv)
{
int more;
sock_T fd;
int timeout;
chanpart_T *chanpart = &channel->ch_part[part];
ch_log(channel, "Reading JSON");
if (id != -1)
channel->ch_part[part].ch_block_id = id;
chanpart->ch_block_id = id;
for (;;)
{
more = channel_parse_json(channel, part);
@@ -2389,7 +2566,7 @@ channel_read_json_block(
/* search for messsage "id" */
if (channel_get_json(channel, part, id, rettv) == OK)
{
channel->ch_part[part].ch_block_id = 0;
chanpart->ch_block_id = 0;
return OK;
}
@@ -2400,14 +2577,50 @@ channel_read_json_block(
if (channel_parse_messages())
continue;
/* Wait for up to the timeout. */
fd = channel->ch_part[part].ch_fd;
/* Wait for up to the timeout. If there was an incomplete message
* use the deadline for that. */
timeout = timeout_arg;
if (chanpart->ch_waiting)
{
#ifdef WIN32
timeout = chanpart->ch_deadline - GetTickCount() + 1;
#else
{
struct timeval now_tv;
gettimeofday(&now_tv, NULL);
timeout = (chanpart->ch_deadline.tv_sec
- now_tv.tv_sec) * 1000
+ (chanpart->ch_deadline.tv_usec
- now_tv.tv_usec) / 1000
+ 1;
}
#endif
if (timeout < 0)
{
/* Something went wrong, channel_parse_json() didn't
* discard message. Cancel waiting. */
chanpart->ch_waiting = FALSE;
timeout = timeout_arg;
}
else if (timeout > timeout_arg)
timeout = timeout_arg;
}
fd = chanpart->ch_fd;
if (fd == INVALID_FD || channel_wait(channel, fd, timeout) == FAIL)
break;
channel_read(channel, part, "channel_read_json_block");
{
if (timeout == timeout_arg)
{
if (fd != INVALID_FD)
ch_log(channel, "Timed out");
break;
}
}
else
channel_read(channel, part, "channel_read_json_block");
}
}
channel->ch_part[part].ch_block_id = 0;
chanpart->ch_block_id = 0;
return FAIL;
}
@@ -2611,7 +2824,8 @@ send_common(
EMSG2(_("E917: Cannot use a callback with %s()"), fun);
return NULL;
}
channel_set_req_callback(channel, part_send, opt->jo_callback, id);
channel_set_req_callback(channel, part_send,
opt->jo_callback, opt->jo_partial, id);
}
if (channel_send(channel, part_send, text, fun) == OK
@@ -2652,7 +2866,7 @@ ch_expr_common(typval_T *argvars, typval_T *rettv, int eval)
return;
}
id = channel_get_id();
id = ++channel->ch_last_msg_id;
text = json_encode_nr_expr(id, &argvars[1],
ch_mode == MODE_JS ? JSON_JS : 0);
if (text == NULL)
@@ -2667,7 +2881,6 @@ ch_expr_common(typval_T *argvars, typval_T *rettv, int eval)
timeout = opt.jo_timeout;
else
timeout = channel_get_timeout(channel, part_read);
timeout = channel_get_timeout(channel, part_read);
if (channel_read_json_block(channel, part_read, timeout, id, &listtv)
== OK)
{
@@ -2995,22 +3208,6 @@ channel_get_timeout(channel_T *channel, int part)
return channel->ch_part[part].ch_timeout;
}
/*
* Get a callback from "arg". It can be a Funcref or a function name.
* When "arg" is zero return an empty string.
* Return NULL for an invalid argument.
*/
static char_u *
get_callback(typval_T *arg)
{
if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
return arg->vval.v_string;
if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
return (char_u *)"";
EMSG(_("E999: Invalid callback argument"));
return NULL;
}
static int
handle_mode(typval_T *item, jobopt_T *opt, ch_mode_T *modep, int jo)
{
@@ -3113,7 +3310,7 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
if (handle_mode(item, opt, &opt->jo_mode, JO_MODE) == FAIL)
return FAIL;
}
else if (STRCMP(hi->hi_key, "in-mode") == 0)
else if (STRCMP(hi->hi_key, "in_mode") == 0)
{
if (!(supported & JO_IN_MODE))
break;
@@ -3121,7 +3318,7 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
== FAIL)
return FAIL;
}
else if (STRCMP(hi->hi_key, "out-mode") == 0)
else if (STRCMP(hi->hi_key, "out_mode") == 0)
{
if (!(supported & JO_OUT_MODE))
break;
@@ -3129,7 +3326,7 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
== FAIL)
return FAIL;
}
else if (STRCMP(hi->hi_key, "err-mode") == 0)
else if (STRCMP(hi->hi_key, "err_mode") == 0)
{
if (!(supported & JO_ERR_MODE))
break;
@@ -3137,18 +3334,18 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
== FAIL)
return FAIL;
}
else if (STRCMP(hi->hi_key, "in-io") == 0
|| STRCMP(hi->hi_key, "out-io") == 0
|| STRCMP(hi->hi_key, "err-io") == 0)
else if (STRCMP(hi->hi_key, "in_io") == 0
|| STRCMP(hi->hi_key, "out_io") == 0
|| STRCMP(hi->hi_key, "err_io") == 0)
{
if (!(supported & JO_OUT_IO))
break;
if (handle_io(item, part_from_char(*hi->hi_key), opt) == FAIL)
return FAIL;
}
else if (STRCMP(hi->hi_key, "in-name") == 0
|| STRCMP(hi->hi_key, "out-name") == 0
|| STRCMP(hi->hi_key, "err-name") == 0)
else if (STRCMP(hi->hi_key, "in_name") == 0
|| STRCMP(hi->hi_key, "out_name") == 0
|| STRCMP(hi->hi_key, "err_name") == 0)
{
part = part_from_char(*hi->hi_key);
@@ -3158,9 +3355,9 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
opt->jo_io_name[part] =
get_tv_string_buf_chk(item, opt->jo_io_name_buf[part]);
}
else if (STRCMP(hi->hi_key, "in-buf") == 0
|| STRCMP(hi->hi_key, "out-buf") == 0
|| STRCMP(hi->hi_key, "err-buf") == 0)
else if (STRCMP(hi->hi_key, "in_buf") == 0
|| STRCMP(hi->hi_key, "out_buf") == 0
|| STRCMP(hi->hi_key, "err_buf") == 0)
{
part = part_from_char(*hi->hi_key);
@@ -3179,8 +3376,8 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
return FAIL;
}
}
else if (STRCMP(hi->hi_key, "in-top") == 0
|| STRCMP(hi->hi_key, "in-bot") == 0)
else if (STRCMP(hi->hi_key, "in_top") == 0
|| STRCMP(hi->hi_key, "in_bot") == 0)
{
linenr_T *lp;
@@ -3220,46 +3417,46 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
if (!(supported & JO_CALLBACK))
break;
opt->jo_set |= JO_CALLBACK;
opt->jo_callback = get_callback(item);
opt->jo_callback = get_callback(item, &opt->jo_partial);
if (opt->jo_callback == NULL)
{
EMSG2(_(e_invarg2), "callback");
return FAIL;
}
}
else if (STRCMP(hi->hi_key, "out-cb") == 0)
else if (STRCMP(hi->hi_key, "out_cb") == 0)
{
if (!(supported & JO_OUT_CALLBACK))
break;
opt->jo_set |= JO_OUT_CALLBACK;
opt->jo_out_cb = get_callback(item);
opt->jo_out_cb = get_callback(item, &opt->jo_out_partial);
if (opt->jo_out_cb == NULL)
{
EMSG2(_(e_invarg2), "out-cb");
EMSG2(_(e_invarg2), "out_cb");
return FAIL;
}
}
else if (STRCMP(hi->hi_key, "err-cb") == 0)
else if (STRCMP(hi->hi_key, "err_cb") == 0)
{
if (!(supported & JO_ERR_CALLBACK))
break;
opt->jo_set |= JO_ERR_CALLBACK;
opt->jo_err_cb = get_callback(item);
opt->jo_err_cb = get_callback(item, &opt->jo_err_partial);
if (opt->jo_err_cb == NULL)
{
EMSG2(_(e_invarg2), "err-cb");
EMSG2(_(e_invarg2), "err_cb");
return FAIL;
}
}
else if (STRCMP(hi->hi_key, "close-cb") == 0)
else if (STRCMP(hi->hi_key, "close_cb") == 0)
{
if (!(supported & JO_CLOSE_CALLBACK))
break;
opt->jo_set |= JO_CLOSE_CALLBACK;
opt->jo_close_cb = get_callback(item);
opt->jo_close_cb = get_callback(item, &opt->jo_close_partial);
if (opt->jo_close_cb == NULL)
{
EMSG2(_(e_invarg2), "close-cb");
EMSG2(_(e_invarg2), "close_cb");
return FAIL;
}
}
@@ -3277,14 +3474,14 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
opt->jo_set |= JO_TIMEOUT;
opt->jo_timeout = get_tv_number(item);
}
else if (STRCMP(hi->hi_key, "out-timeout") == 0)
else if (STRCMP(hi->hi_key, "out_timeout") == 0)
{
if (!(supported & JO_OUT_TIMEOUT))
break;
opt->jo_set |= JO_OUT_TIMEOUT;
opt->jo_out_timeout = get_tv_number(item);
}
else if (STRCMP(hi->hi_key, "err-timeout") == 0)
else if (STRCMP(hi->hi_key, "err_timeout") == 0)
{
if (!(supported & JO_ERR_TIMEOUT))
break;
@@ -3325,15 +3522,22 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported)
return FAIL;
}
}
else if (STRCMP(hi->hi_key, "exit-cb") == 0)
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_tv_string_buf_chk(item, opt->jo_ecb_buf);
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");
EMSG2(_(e_invarg2), "exit_cb");
return FAIL;
}
}
@@ -3409,6 +3613,7 @@ job_free(job_T *job)
vim_free(job->jv_stoponexit);
vim_free(job->jv_exit_cb);
partial_unref(job->jv_exit_partial);
vim_free(job);
}
@@ -3473,10 +3678,19 @@ job_set_options(job_T *job, jobopt_T *opt)
if (opt->jo_set & JO_EXIT_CB)
{
vim_free(job->jv_exit_cb);
partial_unref(job->jv_exit_partial);
if (opt->jo_exit_cb == NULL || *opt->jo_exit_cb == NUL)
{
job->jv_exit_cb = NULL;
job->jv_exit_partial = NULL;
}
else
{
job->jv_exit_cb = vim_strsave(opt->jo_exit_cb);
job->jv_exit_partial = opt->jo_exit_partial;
if (job->jv_exit_partial != NULL)
++job->jv_exit_partial->pt_refcount;
}
}
}
@@ -3494,7 +3708,7 @@ job_stop_on_exit()
}
/*
* Called once in a while: check if any jobs with an "exit-cb" have ended.
* Called once in a while: check if any jobs with an "exit_cb" have ended.
*/
void
job_check_ended(void)
@@ -3557,7 +3771,7 @@ job_start(typval_T *argvars)
&& (!(opt.jo_set & (JO_OUT_NAME << (part - PART_OUT)))
|| *opt.jo_io_name[part] == NUL))
{
EMSG(_("E920: -io file requires -name to be set"));
EMSG(_("E920: _io file requires _name to be set"));
return job;
}
@@ -3574,7 +3788,7 @@ job_start(typval_T *argvars)
}
else if (!(opt.jo_set & JO_IN_NAME))
{
EMSG(_("E915: in-io buffer requires in-buf or in-name to be set"));
EMSG(_("E915: in_io buffer requires in_buf or in_name to be set"));
}
else
buf = buflist_find_by_name(opt.jo_io_name[PART_IN], FALSE);
@@ -3740,7 +3954,8 @@ job_status(job_T *job)
argv[1].v_type = VAR_NUMBER;
argv[1].vval.v_number = job->jv_exitval;
call_func(job->jv_exit_cb, (int)STRLEN(job->jv_exit_cb),
&rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL);
&rettv, 2, argv, 0L, 0L, &dummy, TRUE,
job->jv_exit_partial, NULL);
clear_tv(&rettv);
--job->jv_refcount;
}
@@ -3784,7 +3999,7 @@ job_info(job_T *job, dict_T *dict)
dict_add_nr_str(dict, "process", nr, NULL);
dict_add_nr_str(dict, "exitval", job->jv_exitval, NULL);
dict_add_nr_str(dict, "exit-cb", 0L, job->jv_exit_cb);
dict_add_nr_str(dict, "exit_cb", 0L, job->jv_exit_cb);
dict_add_nr_str(dict, "stoponexit", 0L, job->jv_stoponexit);
}
+3 -3
View File
@@ -1093,7 +1093,7 @@ win_lbr_chartabsize(
&& vim_isbreak(c)
&& !vim_isbreak(s[1])
&& wp->w_p_wrap
# ifdef FEAT_VERTSPLIT
# ifdef FEAT_WINDOWS
&& wp->w_width != 0
# endif
)
@@ -1250,10 +1250,10 @@ in_win_border(win_T *wp, colnr_T vcol)
int width1; /* width of first line (after line number) */
int width2; /* width of further lines */
#ifdef FEAT_VERTSPLIT
# ifdef FEAT_WINDOWS
if (wp->w_width == 0) /* there is no border */
return FALSE;
#endif
# endif
width1 = W_WIDTH(wp) - win_col_off(wp);
if ((int)vcol < width1 - 1)
return FALSE;
+721 -130
View File
File diff suppressed because it is too large Load Diff
+23 -15
View File
@@ -2065,26 +2065,30 @@ write_viminfo(char_u *file, int forceit)
viminfo_errcnt = 0;
do_viminfo(fp_in, fp_out, forceit ? 0 : (VIF_WANT_INFO | VIF_WANT_MARKS));
fclose(fp_out); /* errors are ignored !? */
if (fclose(fp_out) == EOF)
++viminfo_errcnt;
if (fp_in != NULL)
{
fclose(fp_in);
/* In case of an error keep the original viminfo file. Otherwise
* rename the newly written file. Give an error if that fails. */
if (viminfo_errcnt == 0 && vim_rename(tempname, fname) == -1)
if (viminfo_errcnt == 0)
{
++viminfo_errcnt;
EMSG2(_("E886: Can't rename viminfo file to %s!"), fname);
if (vim_rename(tempname, fname) == -1)
{
++viminfo_errcnt;
EMSG2(_("E886: Can't rename viminfo file to %s!"), fname);
}
# ifdef WIN3264
/* If the viminfo file was hidden then also hide the new file. */
else if (hidden)
mch_hide(fname);
# endif
}
if (viminfo_errcnt > 0)
mch_remove(tempname);
#ifdef WIN3264
/* If the viminfo file was hidden then also hide the new file. */
if (hidden)
mch_hide(fname);
#endif
}
end:
@@ -2605,7 +2609,8 @@ ex_file(exarg_T *eap)
return;
}
/* print full file name if :cd used */
fileinfo(FALSE, FALSE, eap->forceit);
if (!shortmess(SHM_FILEINFO))
fileinfo(FALSE, FALSE, eap->forceit);
}
/*
@@ -3884,7 +3889,8 @@ do_ecmd(
msg_scroll = msg_scroll_save;
msg_scrolled_ign = TRUE;
fileinfo(FALSE, TRUE, FALSE);
if (!shortmess(SHM_FILEINFO))
fileinfo(FALSE, TRUE, FALSE);
msg_scrolled_ign = FALSE;
}
@@ -5861,11 +5867,9 @@ ex_help(exarg_T *eap)
* specified, the current window is vertically split and
* narrow. */
n = WSP_HELP;
# ifdef FEAT_VERTSPLIT
if (cmdmod.split == 0 && curwin->w_width != Columns
&& curwin->w_width < 80)
n |= WSP_TOP;
# endif
if (win_split(0, n) == FAIL)
goto erret;
#else
@@ -6114,6 +6118,11 @@ find_help_tags(
|| (arg[0] == '\\' && arg[1] == '{'))
*d++ = '\\';
/*
* If tag starts with "('", skip the "(". Fixes CTRL-] on ('option'.
*/
if (*arg == '(' && arg[1] == '\'')
arg++;
for (s = arg; *s; ++s)
{
/*
@@ -6859,7 +6868,6 @@ do_helptags(char_u *dirname, int add_help_tags)
|| filecount == 0)
{
EMSG2("E151: No match: %s", NameBuff);
vim_free(dirname);
return;
}
+171 -2
View File
@@ -1088,6 +1088,174 @@ profile_zero(proftime_T *tm)
# endif /* FEAT_PROFILE || FEAT_RELTIME */
# if defined(FEAT_TIMERS) || defined(PROTO)
static timer_T *first_timer = NULL;
static int last_timer_id = 0;
/*
* Insert a timer in the list of timers.
*/
static void
insert_timer(timer_T *timer)
{
timer->tr_next = first_timer;
timer->tr_prev = NULL;
if (first_timer != NULL)
first_timer->tr_prev = timer;
first_timer = timer;
}
/*
* Take a timer out of the list of timers.
*/
static void
remove_timer(timer_T *timer)
{
if (timer->tr_prev == NULL)
first_timer = timer->tr_next;
else
timer->tr_prev->tr_next = timer->tr_next;
if (timer->tr_next != NULL)
timer->tr_next->tr_prev = timer->tr_prev;
}
static void
free_timer(timer_T *timer)
{
vim_free(timer->tr_callback);
partial_unref(timer->tr_partial);
vim_free(timer);
}
/*
* Create a timer and return it. NULL if out of memory.
* Caller should set the callback.
*/
timer_T *
create_timer(long msec, int repeat)
{
timer_T *timer = (timer_T *)alloc_clear(sizeof(timer_T));
if (timer == NULL)
return NULL;
timer->tr_id = ++last_timer_id;
insert_timer(timer);
if (repeat != 0)
{
timer->tr_repeat = repeat - 1;
timer->tr_interval = msec;
}
profile_setlimit(msec, &timer->tr_due);
return timer;
}
/*
* Invoke the callback of "timer".
*/
static void
timer_callback(timer_T *timer)
{
typval_T rettv;
int dummy;
typval_T argv[2];
argv[0].v_type = VAR_NUMBER;
argv[0].vval.v_number = timer->tr_id;
argv[1].v_type = VAR_UNKNOWN;
call_func(timer->tr_callback, (int)STRLEN(timer->tr_callback),
&rettv, 1, argv, 0L, 0L, &dummy, TRUE,
timer->tr_partial, NULL);
clear_tv(&rettv);
}
/*
* Call timers that are due.
* Return the time in msec until the next timer is due.
*/
long
check_due_timer()
{
timer_T *timer;
long this_due;
long next_due = -1;
proftime_T now;
int did_one = FALSE;
# ifdef WIN3264
LARGE_INTEGER fr;
QueryPerformanceFrequency(&fr);
# endif
while (!got_int)
{
profile_start(&now);
next_due = -1;
for (timer = first_timer; timer != NULL; timer = timer->tr_next)
{
# ifdef WIN3264
this_due = (long)(((double)(timer->tr_due.QuadPart - now.QuadPart)
/ (double)fr.QuadPart) * 1000);
# else
this_due = (timer->tr_due.tv_sec - now.tv_sec) * 1000
+ (timer->tr_due.tv_usec - now.tv_usec) / 1000;
# endif
if (this_due <= 1)
{
remove_timer(timer);
timer_callback(timer);
did_one = TRUE;
if (timer->tr_repeat != 0)
{
profile_setlimit(timer->tr_interval, &timer->tr_due);
if (timer->tr_repeat > 0)
--timer->tr_repeat;
insert_timer(timer);
}
else
free_timer(timer);
/* the callback may do anything, start all over */
break;
}
if (next_due == -1 || next_due > this_due)
next_due = this_due;
}
if (timer == NULL)
break;
}
if (did_one)
redraw_after_callback();
return next_due;
}
/*
* Find a timer by ID. Returns NULL if not found;
*/
timer_T *
find_timer(int id)
{
timer_T *timer;
for (timer = first_timer; timer != NULL; timer = timer->tr_next)
if (timer->tr_id == id)
break;
return timer;
}
/*
* Stop a timer and delete it.
*/
void
stop_timer(timer_T *timer)
{
remove_timer(timer);
free_timer(timer);
}
# endif
#if defined(FEAT_SYN_HL) && defined(FEAT_RELTIME) && defined(FEAT_FLOAT)
# if defined(HAVE_MATH_H)
# include <math.h>
@@ -3177,7 +3345,7 @@ do_in_runtimepath(
if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_START))
{
len = STRLEN(start_dir) + STRLEN(name);
len = (int)(STRLEN(start_dir) + STRLEN(name));
s = alloc(len);
if (s == NULL)
return FAIL;
@@ -3188,7 +3356,7 @@ do_in_runtimepath(
if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_OPT))
{
len = STRLEN(opt_dir) + STRLEN(name);
len = (int)(STRLEN(opt_dir) + STRLEN(name));
s = alloc(len);
if (s == NULL)
return FAIL;
@@ -3309,6 +3477,7 @@ add_pack_plugin(char_u *fname, void *cookie)
vim_free(cmd);
}
#endif
vim_free(pat);
}
theend:
+17 -21
View File
@@ -2020,7 +2020,7 @@ do_one_cmd(
case 'v': if (checkforcmd(&ea.cmd, "vertical", 4))
{
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
cmdmod.split |= WSP_VERT;
#endif
continue;
@@ -7941,14 +7941,6 @@ ex_splitview(exarg_T *eap)
int browse_flag = cmdmod.browse;
# endif
# ifndef FEAT_VERTSPLIT
if (eap->cmdidx == CMD_vsplit || eap->cmdidx == CMD_vnew)
{
ex_ni(eap);
return;
}
# endif
# ifdef FEAT_GUI
need_mouse_correct = TRUE;
# endif
@@ -7960,10 +7952,8 @@ ex_splitview(exarg_T *eap)
{
if (eap->cmdidx == CMD_split)
eap->cmdidx = CMD_new;
# ifdef FEAT_VERTSPLIT
if (eap->cmdidx == CMD_vsplit)
eap->cmdidx = CMD_vnew;
# endif
}
# endif
@@ -7982,9 +7972,7 @@ ex_splitview(exarg_T *eap)
# endif
# ifdef FEAT_BROWSE
if (cmdmod.browse
# ifdef FEAT_VERTSPLIT
&& eap->cmdidx != CMD_vnew
# endif
&& eap->cmdidx != CMD_new)
{
# ifdef FEAT_AUTOCMD
@@ -8242,11 +8230,10 @@ ex_resize(exarg_T *eap)
;
}
#ifdef FEAT_GUI
# ifdef FEAT_GUI
need_mouse_correct = TRUE;
#endif
# endif
n = atol((char *)eap->arg);
#ifdef FEAT_VERTSPLIT
if (cmdmod.split & WSP_VERT)
{
if (*eap->arg == '-' || *eap->arg == '+')
@@ -8256,7 +8243,6 @@ ex_resize(exarg_T *eap)
win_setwidth_win((int)n, wp);
}
else
#endif
{
if (*eap->arg == '-' || *eap->arg == '+')
n += curwin->w_height;
@@ -8415,7 +8401,7 @@ do_exedit(
if ((eap->cmdidx == CMD_new
|| eap->cmdidx == CMD_tabnew
|| eap->cmdidx == CMD_tabedit
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
|| eap->cmdidx == CMD_vnew
#endif
) && *eap->arg == NUL)
@@ -8427,7 +8413,7 @@ do_exedit(
old_curwin == NULL ? curwin : NULL);
}
else if ((eap->cmdidx != CMD_split
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
&& eap->cmdidx != CMD_vsplit
#endif
)
@@ -8913,12 +8899,22 @@ ex_sleep(exarg_T *eap)
do_sleep(long msec)
{
long done;
long wait_now;
cursor_on();
out_flush();
for (done = 0; !got_int && done < msec; done += 1000L)
for (done = 0; !got_int && done < msec; done += wait_now)
{
ui_delay(msec - done > 1000L ? 1000L : msec - done, TRUE);
wait_now = msec - done > 1000L ? 1000L : msec - done;
#ifdef FEAT_TIMERS
{
long due_time = check_due_timer();
if (due_time > 0 && due_time < wait_now)
wait_now = due_time;
}
#endif
ui_delay(wait_now, TRUE);
ui_breakcheck();
#ifdef MESSAGE_QUEUE
/* Process the netbeans and clientserver messages that may have been
+145 -101
View File
@@ -111,7 +111,7 @@ static int ExpandFromContext(expand_T *xp, char_u *, int *, char_u ***, int);
static int expand_showtail(expand_T *xp);
#ifdef FEAT_CMDL_COMPL
static int expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, int flagsarg);
static int ExpandRTDir(char_u *pat, int *num_file, char_u ***file, char *dirname[]);
static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file, char *dirname[]);
static int ExpandPackAddDir(char_u *pat, int *num_file, char_u ***file);
# ifdef FEAT_CMDHIST
static char_u *get_history_arg(expand_T *xp, int idx);
@@ -500,11 +500,7 @@ getcmdline(
}
else
{
# ifdef FEAT_VERTSPLIT
win_redraw_last_status(topframe);
# else
lastwin->w_redr_status = TRUE;
# endif
redraw_statuslines();
}
KeyTyped = skt;
@@ -2001,6 +1997,7 @@ getcmdline_prompt(
char_u *s;
struct cmdline_info save_ccline;
int msg_col_save = msg_col;
int msg_silent_save = msg_silent;
save_cmdline(&save_ccline);
ccline.cmdprompt = prompt;
@@ -2010,8 +2007,10 @@ getcmdline_prompt(
ccline.xp_arg = xp_arg;
ccline.input_fn = (firstc == '@');
# endif
msg_silent = 0;
s = getcmdline(firstc, 1L, 0);
restore_cmdline(&save_ccline);
msg_silent = msg_silent_save;
/* Restore msg_col, the prompt from input() may have changed it.
* But only if called recursively and the commandline is therefore being
* restored to an old one; if not, the input() prompt stays on the screen,
@@ -4639,22 +4638,23 @@ ExpandFromContext(
if (xp->xp_context == EXPAND_COLORS)
{
char *directories[] = {"colors", NULL};
return ExpandRTDir(pat, num_file, file, directories);
return ExpandRTDir(pat, DIP_START + DIP_OPT, num_file, file,
directories);
}
if (xp->xp_context == EXPAND_COMPILER)
{
char *directories[] = {"compiler", NULL};
return ExpandRTDir(pat, num_file, file, directories);
return ExpandRTDir(pat, 0, num_file, file, directories);
}
if (xp->xp_context == EXPAND_OWNSYNTAX)
{
char *directories[] = {"syntax", NULL};
return ExpandRTDir(pat, num_file, file, directories);
return ExpandRTDir(pat, 0, num_file, file, directories);
}
if (xp->xp_context == EXPAND_FILETYPE)
{
char *directories[] = {"syntax", "indent", "ftplugin", NULL};
return ExpandRTDir(pat, num_file, file, directories);
return ExpandRTDir(pat, 0, num_file, file, directories);
}
# if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
if (xp->xp_context == EXPAND_USER_LIST)
@@ -5133,13 +5133,19 @@ ExpandUserList(
#endif
/*
* Expand color scheme, compiler or filetype names:
* 'runtimepath'/{dirnames}/{pat}.vim
* Expand color scheme, compiler or filetype names.
* Search from 'runtimepath':
* 'runtimepath'/{dirnames}/{pat}.vim
* When "flags" has DIP_START: search also from 'start' of 'packpath':
* 'packpath'/pack/ * /start/ * /{dirnames}/{pat}.vim
* When "flags" has DIP_OPT: search also from 'opt' of 'packpath':
* 'packpath'/pack/ * /opt/ * /{dirnames}/{pat}.vim
* "dirnames" is an array with one or more directory names.
*/
static int
ExpandRTDir(
char_u *pat,
int flags,
int *num_file,
char_u ***file,
char *dirnames[])
@@ -5169,6 +5175,36 @@ ExpandRTDir(
vim_free(s);
}
if (flags & DIP_START) {
for (i = 0; dirnames[i] != NULL; ++i)
{
s = alloc((unsigned)(STRLEN(dirnames[i]) + pat_len + 22));
if (s == NULL)
{
ga_clear_strings(&ga);
return FAIL;
}
sprintf((char *)s, "pack/*/start/*/%s/%s*.vim", dirnames[i], pat);
globpath(p_pp, s, &ga, 0);
vim_free(s);
}
}
if (flags & DIP_OPT) {
for (i = 0; dirnames[i] != NULL; ++i)
{
s = alloc((unsigned)(STRLEN(dirnames[i]) + pat_len + 20));
if (s == NULL)
{
ga_clear_strings(&ga);
return FAIL;
}
sprintf((char *)s, "pack/*/opt/*/%s/%s*.vim", dirnames[i], pat);
globpath(p_pp, s, &ga, 0);
vim_free(s);
}
}
for (i = 0; i < ga.ga_len; ++i)
{
match = ((char_u **)ga.ga_data)[i];
@@ -5634,96 +5670,6 @@ get_history_idx(int histype)
return history[histype][hisidx[histype]].hisnum;
}
static struct cmdline_info *get_ccline_ptr(void);
/*
* Get pointer to the command line info to use. cmdline_paste() may clear
* ccline and put the previous value in prev_ccline.
*/
static struct cmdline_info *
get_ccline_ptr(void)
{
if ((State & CMDLINE) == 0)
return NULL;
if (ccline.cmdbuff != NULL)
return &ccline;
if (prev_ccline_used && prev_ccline.cmdbuff != NULL)
return &prev_ccline;
return NULL;
}
/*
* Get the current command line in allocated memory.
* Only works when the command line is being edited.
* Returns NULL when something is wrong.
*/
char_u *
get_cmdline_str(void)
{
struct cmdline_info *p = get_ccline_ptr();
if (p == NULL)
return NULL;
return vim_strnsave(p->cmdbuff, p->cmdlen);
}
/*
* Get the current command line position, counted in bytes.
* Zero is the first position.
* Only works when the command line is being edited.
* Returns -1 when something is wrong.
*/
int
get_cmdline_pos(void)
{
struct cmdline_info *p = get_ccline_ptr();
if (p == NULL)
return -1;
return p->cmdpos;
}
/*
* Set the command line byte position to "pos". Zero is the first position.
* Only works when the command line is being edited.
* Returns 1 when failed, 0 when OK.
*/
int
set_cmdline_pos(
int pos)
{
struct cmdline_info *p = get_ccline_ptr();
if (p == NULL)
return 1;
/* The position is not set directly but after CTRL-\ e or CTRL-R = has
* changed the command line. */
if (pos < 0)
new_cmdpos = 0;
else
new_cmdpos = pos;
return 0;
}
/*
* Get the current command-line type.
* Returns ':' or '/' or '?' or '@' or '>' or '-'
* Only works when the command line is being edited.
* Returns NUL when something is wrong.
*/
int
get_cmdline_type(void)
{
struct cmdline_info *p = get_ccline_ptr();
if (p == NULL)
return NUL;
if (p->cmdfirstc == NUL)
return (p->input_fn) ? '@' : '-';
return p->cmdfirstc;
}
/*
* Calculate history index from a number:
* num > 0: seen as identifying number of a history entry
@@ -5932,6 +5878,104 @@ remove_key_from_history(void)
#endif /* FEAT_CMDHIST */
#if defined(FEAT_EVAL) || defined(FEAT_CMDWIN) || defined(PROTO)
/*
* Get pointer to the command line info to use. cmdline_paste() may clear
* ccline and put the previous value in prev_ccline.
*/
static struct cmdline_info *
get_ccline_ptr(void)
{
if ((State & CMDLINE) == 0)
return NULL;
if (ccline.cmdbuff != NULL)
return &ccline;
if (prev_ccline_used && prev_ccline.cmdbuff != NULL)
return &prev_ccline;
return NULL;
}
#endif
#if defined(FEAT_EVAL) || defined(PROTO)
/*
* Get the current command line in allocated memory.
* Only works when the command line is being edited.
* Returns NULL when something is wrong.
*/
char_u *
get_cmdline_str(void)
{
struct cmdline_info *p = get_ccline_ptr();
if (p == NULL)
return NULL;
return vim_strnsave(p->cmdbuff, p->cmdlen);
}
/*
* Get the current command line position, counted in bytes.
* Zero is the first position.
* Only works when the command line is being edited.
* Returns -1 when something is wrong.
*/
int
get_cmdline_pos(void)
{
struct cmdline_info *p = get_ccline_ptr();
if (p == NULL)
return -1;
return p->cmdpos;
}
/*
* Set the command line byte position to "pos". Zero is the first position.
* Only works when the command line is being edited.
* Returns 1 when failed, 0 when OK.
*/
int
set_cmdline_pos(
int pos)
{
struct cmdline_info *p = get_ccline_ptr();
if (p == NULL)
return 1;
/* The position is not set directly but after CTRL-\ e or CTRL-R = has
* changed the command line. */
if (pos < 0)
new_cmdpos = 0;
else
new_cmdpos = pos;
return 0;
}
#endif
#if defined(FEAT_EVAL) || defined(FEAT_CMDWIN) || defined(PROTO)
/*
* Get the current command-line type.
* Returns ':' or '/' or '?' or '@' or '>' or '-'
* Only works when the command line is being edited.
* Returns NUL when something is wrong.
*/
int
get_cmdline_type(void)
{
struct cmdline_info *p = get_ccline_ptr();
if (p == NULL)
return NUL;
if (p->cmdfirstc == NUL)
return
# ifdef FEAT_EVAL
(p->input_fn) ? '@' :
# endif
'-';
return p->cmdfirstc;
}
#endif
#if defined(FEAT_QUICKFIX) || defined(FEAT_CMDHIST) || defined(PROTO)
/*
* Get indices "num1,num2" that specify a range within a list (not a range of
+11 -13
View File
@@ -97,6 +97,7 @@
/*
* +windows Multiple windows. Without this there is no help
* window and no status lines.
* +vertsplit Vertically split windows.
*/
#ifdef FEAT_SMALL
# define FEAT_WINDOWS
@@ -111,16 +112,6 @@
# define FEAT_LISTCMDS
#endif
/*
* +vertsplit Vertically split windows.
*/
#ifdef FEAT_NORMAL
# define FEAT_VERTSPLIT
#endif
#if defined(FEAT_VERTSPLIT) && !defined(FEAT_WINDOWS)
# define FEAT_WINDOWS
#endif
/*
* +cmdhist Command line history.
*/
@@ -144,8 +135,8 @@
# define FEAT_JUMPLIST
#endif
/* the cmdline-window requires FEAT_VERTSPLIT and FEAT_CMDHIST */
#if defined(FEAT_VERTSPLIT) && defined(FEAT_CMDHIST)
/* the cmdline-window requires FEAT_WINDOWS and FEAT_CMDHIST */
#if defined(FEAT_WINDOWS) && defined(FEAT_CMDHIST)
# define FEAT_CMDWIN
#endif
@@ -399,6 +390,13 @@
# define FEAT_RELTIME
#endif
/*
* +timers timer_start()
*/
#if defined(FEAT_RELTIME) && (defined(UNIX) || defined(WIN32))
# define FEAT_TIMERS
#endif
/*
* +textobjects Text objects: "vaw", "das", etc.
*/
@@ -594,7 +592,7 @@
* +mksession ":mksession" command.
* Requires +windows and +vertsplit.
*/
#if defined(FEAT_NORMAL) && defined(FEAT_WINDOWS) && defined(FEAT_VERTSPLIT)
#if defined(FEAT_NORMAL) && defined(FEAT_WINDOWS)
# define FEAT_SESSION
#endif
+1 -3
View File
@@ -427,7 +427,7 @@ EXTERN int gui_prev_topfill INIT(= 0);
EXTERN int drag_status_line INIT(= FALSE); /* dragging the status line */
EXTERN int postponed_mouseshape INIT(= FALSE); /* postponed updating the
mouse pointer shape */
# ifdef FEAT_VERTSPLIT
# ifdef FEAT_WINDOWS
EXTERN int drag_sep_line INIT(= FALSE); /* dragging vert separator */
# endif
# endif
@@ -1551,9 +1551,7 @@ EXTERN char_u e_umark[] INIT(= N_("E78: Unknown mark"));
EXTERN char_u e_wildexpand[] INIT(= N_("E79: Cannot expand wildcards"));
#ifdef FEAT_WINDOWS
EXTERN char_u e_winheight[] INIT(= N_("E591: 'winheight' cannot be smaller than 'winminheight'"));
# ifdef FEAT_VERTSPLIT
EXTERN char_u e_winwidth[] INIT(= N_("E592: 'winwidth' cannot be smaller than 'winminwidth'"));
# endif
#endif
EXTERN char_u e_write[] INIT(= N_("E80: Error while writing"));
EXTERN char_u e_zerocount[] INIT(= N_("Zero count"));
+43 -20
View File
@@ -105,7 +105,7 @@ gui_start(void)
/* If there is 'f' in 'guioptions' and specify -g argument,
* gui_mch_init_check() was not called yet. */
if (gui_mch_init_check() != OK)
exit(1);
getout_preserve_modified(1);
#endif
gui_attempt_start();
}
@@ -272,7 +272,7 @@ gui_do_fork(void)
#ifdef FEAT_GUI_GTK
/* Call gtk_init_check() here after fork(). See gui_init_check(). */
if (gui_mch_init_check() != OK)
exit(1);
getout_preserve_modified(1);
#endif
# if defined(HAVE_SETSID) || defined(HAVE_SETPGID)
@@ -309,7 +309,7 @@ gui_do_fork(void)
/* If we failed to start the GUI, exit now. */
if (!gui.in_use)
exit(1);
getout_preserve_modified(1);
}
/*
@@ -1829,7 +1829,7 @@ gui_write(
gui.scroll_region_bot = arg1;
}
break;
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
case 'V': /* Set vertical scroll region */
if (arg1 < arg2)
{
@@ -2892,6 +2892,35 @@ gui_insert_lines(int row, int count)
}
}
static int
gui_wait_for_chars_or_timer(long wtime)
{
#ifdef FEAT_TIMERS
int due_time;
long remaining = wtime;
/* When waiting very briefly don't trigger timers. */
if (wtime >= 0 && wtime < 10L)
return gui_mch_wait_for_chars(wtime);
while (wtime < 0 || remaining > 0)
{
/* Trigger timers and then get the time in wtime until the next one is
* due. Wait up to that time. */
due_time = check_due_timer();
if (due_time <= 0 || (wtime > 0 && due_time > remaining))
due_time = remaining;
if (gui_mch_wait_for_chars(due_time))
return TRUE;
if (wtime > 0)
remaining -= due_time;
}
return FALSE;
#else
return gui_mch_wait_for_chars(wtime);
#endif
}
/*
* The main GUI input routine. Waits for a character from the keyboard.
* wtime == -1 Wait forever.
@@ -2928,7 +2957,7 @@ gui_wait_for_chars(long wtime)
/* Blink when waiting for a character. Probably only does something
* for showmatch() */
gui_mch_start_blink();
retval = gui_mch_wait_for_chars(wtime);
retval = gui_wait_for_chars_or_timer(wtime);
gui_mch_stop_blink();
return retval;
}
@@ -2944,7 +2973,7 @@ gui_wait_for_chars(long wtime)
* 'updatetime' and if nothing is typed within that time put the
* K_CURSORHOLD key in the input buffer.
*/
if (gui_mch_wait_for_chars(p_ut) == OK)
if (gui_wait_for_chars_or_timer(p_ut) == OK)
retval = OK;
#ifdef FEAT_AUTOCMD
else if (trigger_cursorhold())
@@ -2965,7 +2994,7 @@ gui_wait_for_chars(long wtime)
{
/* Blocking wait. */
before_blocking();
retval = gui_mch_wait_for_chars(-1L);
retval = gui_wait_for_chars_or_timer(-1L);
}
gui_mch_stop_blink();
@@ -3142,7 +3171,7 @@ button_set:
&& button != MOUSE_DRAG
# ifdef FEAT_MOUSESHAPE
&& !drag_status_line
# ifdef FEAT_VERTSPLIT
# ifdef FEAT_WINDOWS
&& !drag_sep_line
# endif
# endif
@@ -3420,7 +3449,7 @@ gui_init_which_components(char_u *oldval UNUSED)
case GO_RIGHT:
gui.which_scrollbars[SBAR_RIGHT] = TRUE;
break;
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
case GO_VLEFT:
if (win_hasvertsplit())
gui.which_scrollbars[SBAR_LEFT] = TRUE;
@@ -3858,7 +3887,7 @@ gui_create_scrollbar(scrollbar_T *sb, int type, win_T *wp)
sb->max = 1;
sb->top = 0;
sb->height = 0;
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
sb->width = 0;
#endif
sb->status_height = 0;
@@ -4140,7 +4169,7 @@ gui_update_scrollbars(
long val, size, max; /* need 32 bits here */
int which_sb;
int h, y;
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
static win_T *prev_curwin = NULL;
#endif
@@ -4238,10 +4267,8 @@ gui_update_scrollbars(
#ifdef FEAT_WINDOWS
|| sb->top != wp->w_winrow
|| sb->status_height != wp->w_status_height
# ifdef FEAT_VERTSPLIT
|| sb->width != wp->w_width
|| prev_curwin != curwin
# endif
#endif
)
{
@@ -4251,9 +4278,7 @@ gui_update_scrollbars(
#ifdef FEAT_WINDOWS
sb->top = wp->w_winrow;
sb->status_height = wp->w_status_height;
# ifdef FEAT_VERTSPLIT
sb->width = wp->w_width;
# endif
#endif
/* Calculate height and position in pixels */
@@ -4336,7 +4361,7 @@ gui_update_scrollbars(
val, size, max);
}
}
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
prev_curwin = curwin;
#endif
--hold_gui_events;
@@ -4353,7 +4378,7 @@ gui_do_scrollbar(
int which, /* SBAR_LEFT or SBAR_RIGHT */
int enable) /* TRUE to enable scrollbar */
{
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
int midcol = curwin->w_wincol + curwin->w_width / 2;
int has_midcol = (wp->w_wincol <= midcol
&& wp->w_wincol + wp->w_width >= midcol);
@@ -4877,7 +4902,7 @@ gui_mouse_moved(int x, int y)
st[2] = KE_FILLER;
st[3] = (char_u)MOUSE_LEFT;
fill_mouse_coord(st + 4,
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
wp->w_wincol == 0 ? -1 : wp->w_wincol + MOUSE_COLOFF,
#else
-1,
@@ -4963,11 +4988,9 @@ xy2win(int x UNUSED, int y UNUSED)
}
else if (row > wp->w_height) /* below status line */
update_mouseshape(SHAPE_IDX_CLINE);
# ifdef FEAT_VERTSPLIT
else if (!(State & CMDLINE) && W_VSEP_WIDTH(wp) > 0 && col == wp->w_width
&& (row != wp->w_height || !stl_connected(wp)) && msg_scrolled == 0)
update_mouseshape(SHAPE_IDX_VSEP);
# endif
else if (!(State & CMDLINE) && W_STATUS_HEIGHT(wp) > 0
&& row == wp->w_height && msg_scrolled == 0)
update_mouseshape(SHAPE_IDX_STATUS);
+1 -1
View File
@@ -182,7 +182,7 @@ typedef struct GuiScrollbar
/* Values measured in characters: */
int top; /* Top of scroll bar (chars from row 0) */
int height; /* Current height of scroll bar in rows */
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
int width; /* Current width of scroll bar in cols */
#endif
int status_height; /* Height of status line */
+7 -1
View File
@@ -33,6 +33,12 @@
# define __out SAL__out
#endif
#if (defined(_MSC_VER) && (_MSC_VER >= 1700)) || (__cplusplus >= 201103L)
# define FINAL final
#else
# define FINAL
#endif
#ifdef DYNAMIC_DIRECTX
extern "C" HINSTANCE vimLoadLib(char *name);
@@ -222,7 +228,7 @@ public:
}
};
class GdiTextRenderer : public IDWriteTextRenderer
class GdiTextRenderer FINAL : public IDWriteTextRenderer
{
public:
GdiTextRenderer(
+2 -3
View File
@@ -3682,10 +3682,9 @@ gui_mch_browseW(
filterp = convert_filterW(filter);
vim_memset(&fileStruct, 0, sizeof(OPENFILENAMEW));
#ifdef OPENFILENAME_SIZE_VERSION_400
#ifdef OPENFILENAME_SIZE_VERSION_400W
/* be compatible with Windows NT 4.0 */
/* TODO: what to use for OPENFILENAMEW??? */
fileStruct.lStructSize = OPENFILENAME_SIZE_VERSION_400;
fileStruct.lStructSize = OPENFILENAME_SIZE_VERSION_400W;
#else
fileStruct.lStructSize = sizeof(fileStruct);
#endif
+2 -2
View File
@@ -1177,7 +1177,7 @@ luaV_window_index(lua_State *L)
lua_pushinteger(L, w->w_cursor.lnum);
else if (strncmp(s, "col", 3) == 0)
lua_pushinteger(L, w->w_cursor.col + 1);
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
else if (strncmp(s, "width", 5) == 0)
lua_pushinteger(L, W_WIDTH(w));
#endif
@@ -1220,7 +1220,7 @@ luaV_window_newindex (lua_State *L)
w->w_cursor.col = v - 1;
update_screen(VALID);
}
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
else if (strncmp(s, "width", 5) == 0)
{
win_T *win = curwin;
+3 -3
View File
@@ -145,7 +145,7 @@ static Scheme_Object *get_window_num(void *, int, Scheme_Object **);
static Scheme_Object *get_window_buffer(void *, int, Scheme_Object **);
static Scheme_Object *get_window_height(void *, int, Scheme_Object **);
static Scheme_Object *set_window_height(void *, int, Scheme_Object **);
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
static Scheme_Object *get_window_width(void *, int, Scheme_Object **);
static Scheme_Object *set_window_width(void *, int, Scheme_Object **);
#endif
@@ -2066,7 +2066,7 @@ set_window_height(void *data, int argc, Scheme_Object **argv)
return scheme_void;
}
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
/* (get-win-width [window]) */
static Scheme_Object *
get_window_width(void *data, int argc, Scheme_Object **argv)
@@ -3718,7 +3718,7 @@ static Vim_Prim prims[]=
{get_window_buffer, "get-win-buffer", 0, 1},
{get_window_height, "get-win-height", 0, 1},
{set_window_height, "set-win-height", 1, 2},
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
{get_window_width, "get-win-width", 0, 1},
{set_window_width, "set-win-width", 1, 2},
#endif
+8 -2
View File
@@ -34,6 +34,12 @@ extern HWND s_hwnd;
extern HWND vim_parent_hwnd;
}
#if (defined(_MSC_VER) && (_MSC_VER >= 1700)) || (__cplusplus >= 201103L)
# define FINAL final
#else
# define FINAL
#endif
#if (defined(_MSC_VER) && _MSC_VER < 1300) || !defined(MAXULONG_PTR)
/* Work around old versions of basetsd.h which wrongly declares
* UINT_PTR as unsigned long */
@@ -93,7 +99,7 @@ static CVim *app = 0;
* ----------
*/
class CVim : public IVim
class CVim FINAL : public IVim
{
public:
virtual ~CVim();
@@ -428,7 +434,7 @@ CVim::Eval(BSTR expr, BSTR *result)
* ----------
*/
class CVimCF : public IClassFactory
class CVimCF FINAL : public IClassFactory
{
public:
static CVimCF *Create();
+16 -5
View File
@@ -2944,7 +2944,7 @@ FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
Python_Lock_Vim();
VimTryStart();
error = func_call(name, &args, selfdict, &rettv);
error = func_call(name, &args, NULL, selfdict, &rettv);
Python_Release_Vim();
Py_END_ALLOW_THREADS
@@ -3673,8 +3673,6 @@ WindowAttr(WindowObject *self, char *name)
#ifdef FEAT_WINDOWS
else if (strcmp(name, "row") == 0)
return PyLong_FromLong((long)(self->win->w_winrow));
#endif
#ifdef FEAT_VERTSPLIT
else if (strcmp(name, "width") == 0)
return PyLong_FromLong((long)(W_WIDTH(self->win)));
else if (strcmp(name, "col") == 0)
@@ -3765,7 +3763,7 @@ WindowSetattr(WindowObject *self, char *name, PyObject *valObject)
return 0;
}
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
else if (strcmp(name, "width") == 0)
{
long width;
@@ -6034,13 +6032,26 @@ ConvertToPyObject(typval_T *tv)
case VAR_FUNC:
return NEW_FUNCTION(tv->vval.v_string == NULL
? (char_u *)"" : tv->vval.v_string);
case VAR_PARTIAL:
return NEW_FUNCTION(tv->vval.v_partial == NULL
? (char_u *)"" : tv->vval.v_partial->pt_name);
case VAR_UNKNOWN:
case VAR_CHANNEL:
case VAR_JOB:
Py_INCREF(Py_None);
return Py_None;
default:
case VAR_SPECIAL:
switch (tv->vval.v_number)
{
case VVAL_FALSE: return AlwaysFalse(NULL);
case VVAL_TRUE: return AlwaysTrue(NULL);
case VVAL_NONE:
case VVAL_NULL: return AlwaysNone(NULL);
}
PyErr_SET_VIM(N_("internal error: invalid value type"));
return NULL;
}
return NULL;
}
typedef struct
+1
View File
@@ -1565,6 +1565,7 @@ do_pyeval (char_u *str, typval_T *rettv)
case VAR_DICT: ++rettv->vval.v_dict->dv_refcount; break;
case VAR_LIST: ++rettv->vval.v_list->lv_refcount; break;
case VAR_FUNC: func_ref(rettv->vval.v_string); break;
case VAR_PARTIAL: ++rettv->vval.v_partial->pt_refcount; break;
case VAR_UNKNOWN:
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
+1
View File
@@ -1654,6 +1654,7 @@ do_py3eval (char_u *str, typval_T *rettv)
case VAR_DICT: ++rettv->vval.v_dict->dv_refcount; break;
case VAR_LIST: ++rettv->vval.v_list->lv_refcount; break;
case VAR_FUNC: func_ref(rettv->vval.v_string); break;
case VAR_PARTIAL: ++rettv->vval.v_partial->pt_refcount; break;
case VAR_UNKNOWN:
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
+1 -1
View File
@@ -1457,7 +1457,7 @@ static VALUE window_width(VALUE self UNUSED)
static VALUE window_set_width(VALUE self UNUSED, VALUE width)
{
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
win_T *win = get_win(self);
win_T *savewin = curwin;
+1
View File
@@ -607,6 +607,7 @@ ServerWait(
{
while (XCheckWindowEvent(dpy, commWindow, PropertyChangeMask, &event))
serverEventProc(dpy, &event, 1);
server_parse_messages();
if (endCond(endData) != 0)
break;
+5 -3
View File
@@ -212,6 +212,7 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
break;
case VAR_FUNC:
case VAR_PARTIAL:
case VAR_JOB:
case VAR_CHANNEL:
/* no JSON equivalent TODO: better error */
@@ -876,8 +877,9 @@ json_decode_all(js_read_T *reader, typval_T *res, int options)
/*
* Decode the JSON from "reader" and store the result in "res".
* "options" can be JSON_JS or zero;
* Return FAIL if the message has a decoding error or the message is
* truncated. Consumes the message anyway.
* Return FAIL for a decoding error.
* Return MAYBE for an incomplete message.
* Consumes the message anyway.
*/
int
json_decode(js_read_T *reader, typval_T *res, int options)
@@ -890,7 +892,7 @@ json_decode(js_read_T *reader, typval_T *res, int options)
ret = json_decode_item(reader, res, options);
json_skip_white(reader);
return ret == OK ? OK : FAIL;
return ret;
}
/*
+5 -4
View File
@@ -1424,8 +1424,7 @@ main_loop(
}
#if defined(USE_XSMP) || defined(FEAT_GUI_MSWIN) || defined(PROTO) \
|| defined(FEAT_GUI_MACVIM)
#if defined(USE_XSMP) || defined(FEAT_GUI) || defined(PROTO)
/*
* Exit, but leave behind swap files for modified buffers.
*/
@@ -1447,7 +1446,9 @@ getout_preserve_modified(int exitval)
#endif
/* Exit properly */
/*
* Exit properly.
*/
void
getout(int exitval)
{
@@ -2165,7 +2166,7 @@ command_line_scan(mparm_T *parmp)
break;
case 'O': /* "-O[N]" open N vertical split windows */
#if defined(FEAT_VERTSPLIT) && defined(FEAT_WINDOWS)
#ifdef FEAT_WINDOWS
/* default is 0: open window for each file */
parmp->window_count = get_number_arg((char_u *)argv[0],
&argv_idx, 0);
+149 -82
View File
@@ -1181,7 +1181,6 @@ struct interval
long first;
long last;
};
static int intable(struct interval *table, size_t size, int c);
/*
* Return TRUE if "c" is in "table[size / sizeof(struct interval)]".
@@ -1262,85 +1261,6 @@ utf_char2cells(int c)
{0x30000, 0x3fffd}
};
/* Sorted list of non-overlapping intervals of Emoji characters,
* based on http://unicode.org/emoji/charts/emoji-list.html */
static struct interval emoji[] =
{
{0x231a, 0x231b},
{0x2328, 0x2328},
{0x23cf, 0x23cf},
{0x23e9, 0x23f3},
{0x23f8, 0x23fa},
{0x24c2, 0x24c2},
{0x25fb, 0x25fe},
{0x2600, 0x2604},
{0x260e, 0x260e},
{0x2611, 0x2611},
{0x2614, 0x2615},
{0x2618, 0x2618},
{0x261d, 0x261d},
{0x2620, 0x2620},
{0x2622, 0x2623},
{0x2626, 0x2626},
{0x262a, 0x262a},
{0x262e, 0x262f},
{0x2638, 0x2639},
{0x2648, 0x2653},
{0x2668, 0x2668},
{0x267b, 0x267b},
{0x267f, 0x267f},
{0x2692, 0x2694},
{0x2696, 0x2697},
{0x2699, 0x2699},
{0x269b, 0x269c},
{0x26a0, 0x26a1},
{0x26aa, 0x26ab},
{0x26b0, 0x26b1},
{0x26bd, 0x26be},
{0x26c4, 0x26c5},
{0x26c8, 0x26c8},
{0x26ce, 0x26cf},
{0x26d1, 0x26d1},
{0x26d3, 0x26d4},
{0x26e9, 0x26ea},
{0x26f0, 0x26f5},
{0x26f7, 0x26fa},
{0x26fd, 0x26fd},
{0x2702, 0x2702},
{0x2705, 0x2705},
{0x2708, 0x270b},
{0x270d, 0x270d},
{0x270f, 0x270f},
{0x2712, 0x2712},
{0x2714, 0x2714},
{0x2716, 0x2716},
{0x271d, 0x271d},
{0x2721, 0x2721},
{0x2728, 0x2728},
{0x2733, 0x2734},
{0x2744, 0x2744},
{0x2747, 0x2747},
{0x274c, 0x274c},
{0x274e, 0x274e},
{0x2753, 0x2755},
{0x2757, 0x2757},
{0x2764, 0x2764},
{0x2795, 0x2797},
{0x27a1, 0x27a1},
{0x27b0, 0x27b0},
{0x27bf, 0x27bf},
{0x2934, 0x2935},
{0x2b05, 0x2b07},
{0x2b1b, 0x2b1c},
{0x2b50, 0x2b50},
{0x2b55, 0x2b55},
{0x3030, 0x3030},
{0x303d, 0x303d},
{0x3297, 0x3297},
{0x3299, 0x3299},
{0x1f000, 0x1fffd}
};
/* Sorted list of non-overlapping intervals of East Asian Ambiguous
* characters, generated with ../runtime/tools/unicode.vim. */
static struct interval ambiguous[] =
@@ -1435,7 +1355,6 @@ utf_char2cells(int c)
{0x2170, 0x2179},
{0x2189, 0x2189},
{0x2190, 0x2199},
{0x21a9, 0x21aa},
{0x21b8, 0x21b9},
{0x21d2, 0x21d2},
{0x21d4, 0x21d4},
@@ -1521,6 +1440,32 @@ utf_char2cells(int c)
{0x100000, 0x10fffd}
};
/* Sorted list of non-overlapping intervals of Emoji characters that don't
* have ambiguous or double width,
* based on http://unicode.org/emoji/charts/emoji-list.html */
static struct interval emoji_width[] =
{
{0x1f004, 0x1f004},
{0x1f0cf, 0x1f0cf},
{0x1f1e6, 0x1f1ff},
{0x1f300, 0x1f320},
{0x1f330, 0x1f335},
{0x1f337, 0x1f37c},
{0x1f380, 0x1f393},
{0x1f3a0, 0x1f3c4},
{0x1f3c6, 0x1f3ca},
{0x1f3e0, 0x1f3f0},
{0x1f400, 0x1f43e},
{0x1f440, 0x1f440},
{0x1f442, 0x1f4f7},
{0x1f4f9, 0x1f4fc},
{0x1f500, 0x1f53d},
{0x1f550, 0x1f567},
{0x1f5fb, 0x1f640},
{0x1f645, 0x1f64f},
{0x1f680, 0x1f6c5}
};
if (c >= 0x100)
{
#ifdef USE_WCHAR_FUNCTIONS
@@ -1540,7 +1485,7 @@ utf_char2cells(int c)
if (intable(doublewidth, sizeof(doublewidth), c))
return 2;
#endif
if (intable(emoji, sizeof(emoji), c))
if (p_emoji && intable(emoji_width, sizeof(emoji_width), c))
return 2;
}
@@ -2618,6 +2563,123 @@ utf_class(int c)
{0x2b740, 0x2b81f, 0x4e00}, /* CJK Ideographs */
{0x2f800, 0x2fa1f, 0x4e00}, /* CJK Ideographs */
};
/* Sorted list of non-overlapping intervals of all Emoji characters,
* based on http://unicode.org/emoji/charts/emoji-list.html */
static struct interval emoji_all[] =
{
{0x203c, 0x203c},
{0x2049, 0x2049},
{0x2122, 0x2122},
{0x2139, 0x2139},
{0x2194, 0x2199},
{0x21a9, 0x21aa},
{0x231a, 0x231b},
{0x2328, 0x2328},
{0x23cf, 0x23cf},
{0x23e9, 0x23f3},
{0x24c2, 0x24c2},
{0x25aa, 0x25ab},
{0x25b6, 0x25b6},
{0x25c0, 0x25c0},
{0x25fb, 0x25fe},
{0x2600, 0x2604},
{0x260e, 0x260e},
{0x2611, 0x2611},
{0x2614, 0x2615},
{0x2618, 0x2618},
{0x261d, 0x261d},
{0x2620, 0x2620},
{0x2622, 0x2623},
{0x2626, 0x2626},
{0x262a, 0x262a},
{0x262e, 0x262f},
{0x2638, 0x263a},
{0x2648, 0x2653},
{0x2660, 0x2660},
{0x2663, 0x2663},
{0x2665, 0x2666},
{0x2668, 0x2668},
{0x267b, 0x267b},
{0x267f, 0x267f},
{0x2692, 0x2694},
{0x2696, 0x2697},
{0x2699, 0x2699},
{0x269b, 0x269c},
{0x26a0, 0x26a1},
{0x26aa, 0x26ab},
{0x26b0, 0x26b1},
{0x26bd, 0x26be},
{0x26c4, 0x26c5},
{0x26c8, 0x26c8},
{0x26ce, 0x26cf},
{0x26d1, 0x26d1},
{0x26d3, 0x26d4},
{0x26e9, 0x26ea},
{0x26f0, 0x26f5},
{0x26f7, 0x26fa},
{0x26fd, 0x26fd},
{0x2702, 0x2702},
{0x2705, 0x2705},
{0x2708, 0x270d},
{0x270f, 0x270f},
{0x2712, 0x2712},
{0x2714, 0x2714},
{0x2716, 0x2716},
{0x271d, 0x271d},
{0x2721, 0x2721},
{0x2728, 0x2728},
{0x2733, 0x2734},
{0x2744, 0x2744},
{0x2747, 0x2747},
{0x274c, 0x274c},
{0x274e, 0x274e},
{0x2753, 0x2755},
{0x2757, 0x2757},
{0x2763, 0x2764},
{0x2795, 0x2797},
{0x27a1, 0x27a1},
{0x27b0, 0x27b0},
{0x27bf, 0x27bf},
{0x2934, 0x2935},
{0x2b05, 0x2b07},
{0x2b1b, 0x2b1c},
{0x2b50, 0x2b50},
{0x2b55, 0x2b55},
{0x3030, 0x3030},
{0x303d, 0x303d},
{0x3297, 0x3297},
{0x3299, 0x3299},
{0x1f004, 0x1f004},
{0x1f0cf, 0x1f0cf},
{0x1f170, 0x1f171},
{0x1f17e, 0x1f17f},
{0x1f18e, 0x1f18e},
{0x1f191, 0x1f19a},
{0x1f1e6, 0x1f1ff},
{0x1f201, 0x1f202},
{0x1f21a, 0x1f21a},
{0x1f22f, 0x1f22f},
{0x1f232, 0x1f23a},
{0x1f250, 0x1f251},
{0x1f300, 0x1f320},
{0x1f330, 0x1f335},
{0x1f337, 0x1f37c},
{0x1f380, 0x1f393},
{0x1f3a0, 0x1f3c4},
{0x1f3c6, 0x1f3ca},
{0x1f3e0, 0x1f3f0},
{0x1f400, 0x1f43e},
{0x1f440, 0x1f440},
{0x1f442, 0x1f4f7},
{0x1f4f9, 0x1f4fc},
{0x1f500, 0x1f53d},
{0x1f550, 0x1f567},
{0x1f5fb, 0x1f640},
{0x1f645, 0x1f64f},
{0x1f680, 0x1f6c5}
};
int bot = 0;
int top = sizeof(classes) / sizeof(struct clinterval) - 1;
int mid;
@@ -2644,6 +2706,10 @@ utf_class(int c)
return (int)classes[mid].class;
}
/* emoji */
if (intable(emoji_all, sizeof(emoji_all), c))
return 3;
/* most other characters are "word" characters */
return 2;
}
@@ -3232,6 +3298,7 @@ static convertStruct toUpper[] =
{0x10cc0,0x10cf2,1,-64},
{0x118c0,0x118df,1,-32}
};
/*
* Return the upper-case equivalent of "a", which is a UCS-4 character. Use
* simple case folding.
+11
View File
@@ -870,6 +870,8 @@ wait_return(int redraw)
#ifdef USE_ON_FLY_SCROLL
dont_scroll = TRUE; /* disallow scrolling here */
#endif
cmdline_row = msg_row;
/* Avoid the sequence that the user types ":" at the hit-return prompt
* to start an Ex command, but the file-changed dialog gets in the
* way. */
@@ -2430,6 +2432,7 @@ msg_puts_printf(char_u *str, int maxlen)
static int
do_more_prompt(int typed_char)
{
static int entered = FALSE;
int used_typed_char = typed_char;
int oldState = State;
int c;
@@ -2441,6 +2444,13 @@ do_more_prompt(int typed_char)
msgchunk_T *mp;
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)
return FALSE;
entered = TRUE;
if (typed_char == 'G')
{
/* "g<": Find first line on the last page. */
@@ -2679,6 +2689,7 @@ do_more_prompt(int typed_char)
msg_col = Columns - 1;
#endif
entered = FALSE;
#ifdef FEAT_CON_DIALOG
return retval;
#else
+4 -45
View File
@@ -1976,7 +1976,7 @@ plines_win_nofill(
if (!wp->w_p_wrap)
return 1;
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
if (wp->w_width == 0)
return 1;
#endif
@@ -2052,7 +2052,7 @@ plines_win_col(win_T *wp, linenr_T lnum, long column)
if (!wp->w_p_wrap)
return lines + 1;
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
if (wp->w_width == 0)
return lines + 1;
#endif
@@ -9743,18 +9743,6 @@ pstrcmp(const void *a, const void *b)
return (pathcmp(*(char **)a, *(char **)b, -1));
}
# ifndef WIN3264
static void
namelowcpy(
char_u *d,
char_u *s)
{
while (*s)
*d++ = TOLOWER_LOC(*s++);
*d = NUL;
}
# endif
/*
* Recursively expand one path component into all matching files and/or
* directories. Adds matches to "gap". Handles "*", "?", "[a-z]", "**", etc.
@@ -9783,16 +9771,12 @@ dos_expandpath(
int len;
int starstar = FALSE;
static int stardepth = 0; /* depth for "**" expansion */
#ifdef WIN3264
WIN32_FIND_DATA fb;
HANDLE hFind = (HANDLE)0;
# ifdef FEAT_MBYTE
WIN32_FIND_DATAW wfb;
WCHAR *wn = NULL; /* UCS-2 name, NULL when not used. */
# endif
#else
struct ffblk fb;
#endif
char_u *matchname;
int ok;
@@ -9833,7 +9817,7 @@ dos_expandpath(
else if (path_end >= path + wildoff
&& vim_strchr((char_u *)"*?[~", *path_end) != NULL)
e = p;
#ifdef FEAT_MBYTE
# ifdef FEAT_MBYTE
if (has_mbyte)
{
len = (*mb_ptr2len)(path_end);
@@ -9842,7 +9826,7 @@ dos_expandpath(
path_end += len;
}
else
#endif
# endif
*p++ = *path_end++;
}
e = p;
@@ -9903,7 +9887,6 @@ dos_expandpath(
/* Scan all files in the directory with "dir/ *.*" */
STRCPY(s, "*.*");
#ifdef WIN3264
# ifdef FEAT_MBYTE
if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
{
@@ -9927,24 +9910,15 @@ dos_expandpath(
# endif
hFind = FindFirstFile((LPCSTR)buf, &fb);
ok = (hFind != INVALID_HANDLE_VALUE);
#else
/* If we are expanding wildcards we try both files and directories */
ok = (findfirst((char *)buf, &fb,
(*path_end != NUL || (flags & EW_DIR)) ? FA_DIREC : 0) == 0);
#endif
while (ok)
{
#ifdef WIN3264
# ifdef FEAT_MBYTE
if (wn != NULL)
p = utf16_to_enc(wfb.cFileName, NULL); /* p is allocated here */
else
# endif
p = (char_u *)fb.cFileName;
#else
p = (char_u *)fb.ff_name;
#endif
/* Ignore entries starting with a dot, unless when asked for. Accept
* all entries found with "matchname". */
if ((p[0] != '.' || starts_with_dot
@@ -9956,11 +9930,7 @@ dos_expandpath(
|| ((flags & EW_NOTWILD)
&& fnamencmp(path + (s - buf), p, e - s) == 0)))
{
#ifdef WIN3264
STRCPY(s, p);
#else
namelowcpy(s, p);
#endif
len = (int)STRLEN(buf);
if (starstar && stardepth < 100)
@@ -9992,7 +9962,6 @@ dos_expandpath(
}
}
#ifdef WIN3264
# ifdef FEAT_MBYTE
if (wn != NULL)
{
@@ -10002,16 +9971,12 @@ dos_expandpath(
else
# endif
ok = FindNextFile(hFind, &fb);
#else
ok = (findnext(&fb) == 0);
#endif
/* If no more matches and no match was used, try expanding the name
* itself. Finds the long name of a short filename. */
if (!ok && matchname != NULL && gap->ga_len == start_len)
{
STRCPY(s, matchname);
#ifdef WIN3264
FindClose(hFind);
# ifdef FEAT_MBYTE
if (wn != NULL)
@@ -10025,21 +9990,15 @@ dos_expandpath(
# endif
hFind = FindFirstFile((LPCSTR)buf, &fb);
ok = (hFind != INVALID_HANDLE_VALUE);
#else
ok = (findfirst((char *)buf, &fb,
(*path_end != NUL || (flags & EW_DIR)) ? FA_DIREC : 0) == 0);
#endif
vim_free(matchname);
matchname = NULL;
}
}
#ifdef WIN3264
FindClose(hFind);
# ifdef FEAT_MBYTE
vim_free(wn);
# endif
#endif
vim_free(buf);
vim_regfree(regmatch.regprog);
vim_free(matchname);
+2 -2
View File
@@ -169,7 +169,7 @@ coladvance2(
if (finetune
&& curwin->w_p_wrap
# ifdef FEAT_VERTSPLIT
# ifdef FEAT_WINDOWS
&& curwin->w_width != 0
# endif
&& wcol >= (colnr_T)width)
@@ -3639,7 +3639,7 @@ get_shape_idx(int mouse)
}
if (mouse && drag_status_line)
return SHAPE_IDX_SDRAG;
# ifdef FEAT_VERTSPLIT
# ifdef FEAT_WINDOWS
if (mouse && drag_sep_line)
return SHAPE_IDX_VDRAG;
# endif
+5 -5
View File
@@ -1019,7 +1019,7 @@ curs_columns(
curwin->w_wrow = curwin->w_height - 1;
}
else if (curwin->w_p_wrap
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
&& curwin->w_width != 0
#endif
)
@@ -1125,7 +1125,7 @@ curs_columns(
&& curwin->w_height != 0
&& curwin->w_cursor.lnum == curwin->w_topline
&& width > 0
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
&& curwin->w_width != 0
#endif
)
@@ -1288,7 +1288,7 @@ scrolldown(
*/
wrow = curwin->w_wrow;
if (curwin->w_p_wrap
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
&& curwin->w_width != 0
#endif
)
@@ -1497,7 +1497,7 @@ scrolldown_clamp(void)
end_row += plines(curwin->w_topline - 1);
#endif
if (curwin->w_p_wrap
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
&& curwin->w_width != 0
#endif
)
@@ -1561,7 +1561,7 @@ scrollup_clamp(void)
start_row = curwin->w_wrow - plines(curwin->w_topline);
#endif
if (curwin->w_p_wrap
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
&& curwin->w_width != 0
#endif
)
+6 -12
View File
@@ -2306,8 +2306,6 @@ do_mouse(
int in_status_line; /* mouse in status line */
#ifdef FEAT_WINDOWS
static int in_tab_line = FALSE; /* mouse clicked in tab line */
#endif
#ifdef FEAT_VERTSPLIT
int in_sep_line; /* mouse in vertical separator line */
#endif
int c1, c2;
@@ -2384,13 +2382,11 @@ do_mouse(
drag_status_line = FALSE;
update_mouseshape(SHAPE_IDX_STATUS);
}
# ifdef FEAT_VERTSPLIT
if (!is_drag && drag_sep_line)
{
drag_sep_line = FALSE;
update_mouseshape(SHAPE_IDX_VSEP);
}
# endif
#endif
/*
@@ -2786,7 +2782,7 @@ do_mouse(
oap == NULL ? NULL : &(oap->inclusive), which_button);
moved = (jump_flags & CURSOR_MOVED);
in_status_line = (jump_flags & IN_STATUS_LINE);
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
in_sep_line = (jump_flags & IN_SEP_LINE);
#endif
@@ -3024,7 +3020,7 @@ do_mouse(
}
#endif
}
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
else if (in_sep_line)
{
# ifdef FEAT_MOUSESHAPE
@@ -4406,10 +4402,10 @@ nv_screengo(oparg_T *oap, int dir, long dist)
if (width2 == 0)
width2 = 1; /* avoid divide by zero */
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
if (curwin->w_width != 0)
{
#endif
{
/*
* Instead of sticking at the last character of the buffer line we
* try to stick in the last column of the screen.
@@ -4496,9 +4492,7 @@ nv_screengo(oparg_T *oap, int dir, long dist)
}
}
}
#ifdef FEAT_VERTSPLIT
}
#endif
if (virtual_active() && atend)
coladvance(MAXCOL);
@@ -8021,7 +8015,7 @@ nv_g_cmd(cmdarg_T *cap)
oap->motion_type = MCHAR;
oap->inclusive = FALSE;
if (curwin->w_p_wrap
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
&& curwin->w_width != 0
#endif
)
@@ -8088,7 +8082,7 @@ nv_g_cmd(cmdarg_T *cap)
oap->motion_type = MCHAR;
oap->inclusive = TRUE;
if (curwin->w_p_wrap
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
&& curwin->w_width != 0
#endif
)
+2
View File
@@ -5783,6 +5783,8 @@ do_addsub(
theend:
if (visual)
curwin->w_cursor = save_cursor;
else if (did_change)
curwin->w_set_curswant = TRUE;
return did_change;
}
+30 -17
View File
@@ -246,8 +246,6 @@
#define PV_UL OPT_BOTH(OPT_BUF(BV_UL))
#ifdef FEAT_WINDOWS
# define PV_WFH OPT_WIN(WV_WFH)
#endif
#ifdef FEAT_VERTSPLIT
# define PV_WFW OPT_WIN(WV_WFW)
#endif
#define PV_WRAP OPT_WIN(WV_WRAP)
@@ -472,10 +470,9 @@ struct vimoption
# define ISP_LATIN1 (char_u *)"@,161-255"
#endif
/* The 16 bit MS-DOS version is low on space, make the string as short as
* possible when compiling with few features. */
/* Make the string as short as possible when compiling with few features. */
#if defined(FEAT_DIFF) || defined(FEAT_FOLDING) || defined(FEAT_SPELL) \
|| defined(FEAT_VERTSPLIT) || defined(FEAT_CLIPBOARD) \
|| defined(FEAT_WINDOWS) || defined(FEAT_CLIPBOARD) \
|| defined(FEAT_INS_EXPAND) || defined(FEAT_SYN_HL) || defined(FEAT_CONCEAL)
# define HIGHLIGHT_INIT "8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,N:CursorLineNr,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn"
#else
@@ -1052,7 +1049,7 @@ static struct vimoption options[] =
(char_u *)&p_dy, PV_NONE,
{(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
{"eadirection", "ead", P_STRING|P_VI_DEF,
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
(char_u *)&p_ead, PV_NONE,
{(char_u *)"both", (char_u *)0L}
#else
@@ -1063,6 +1060,15 @@ static struct vimoption options[] =
{"edcompatible","ed", P_BOOL|P_VI_DEF,
(char_u *)&p_ed, PV_NONE,
{(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
{"emoji", "emo", P_BOOL|P_VI_DEF|P_RCLR,
#if defined(FEAT_MBYTE)
(char_u *)&p_emoji, PV_NONE,
{(char_u *)TRUE, (char_u *)0L}
#else
(char_u *)NULL, PV_NONE,
{(char_u *)0L, (char_u *)0L}
#endif
SCRIPTID_INIT},
{"encoding", "enc", P_STRING|P_VI_DEF|P_RCLR|P_NO_ML,
#ifdef FEAT_MBYTE
(char_u *)&p_enc, PV_NONE,
@@ -2531,7 +2537,7 @@ static struct vimoption options[] =
#endif
{(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
{"splitright", "spr", P_BOOL|P_VI_DEF,
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
(char_u *)&p_spr, PV_NONE,
#else
(char_u *)NULL, PV_NONE,
@@ -2938,7 +2944,7 @@ static struct vimoption options[] =
#endif
{(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
{"winfixwidth", "wfw", P_BOOL|P_VI_DEF|P_RSTAT,
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
(char_u *)VAR_WIN, PV_WFW,
#else
(char_u *)NULL, PV_NONE,
@@ -2952,14 +2958,14 @@ static struct vimoption options[] =
#endif
{(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
{"winminwidth", "wmw", P_NUM|P_VI_DEF,
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
(char_u *)&p_wmw, PV_NONE,
#else
(char_u *)NULL, PV_NONE,
#endif
{(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
{"winwidth", "wiw", P_NUM|P_VI_DEF,
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
(char_u *)&p_wiw, PV_NONE,
#else
(char_u *)NULL, PV_NONE,
@@ -3012,7 +3018,7 @@ static struct vimoption options[] =
p_term("t_CS", T_CCS)
p_term("t_Cs", T_UCS)
p_term("t_cs", T_CS)
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
p_term("t_CV", T_CSV)
#endif
p_term("t_da", T_DA)
@@ -3095,7 +3101,7 @@ static char *(p_bsdir_values[]) = {"current", "last", "buffer", NULL};
static char *(p_scbopt_values[]) = {"ver", "hor", "jump", NULL};
#endif
static char *(p_debug_values[]) = {"msg", "throw", "beep", NULL};
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
static char *(p_ead_values[]) = {"both", "ver", "hor", NULL};
#endif
#if defined(FEAT_QUICKFIX)
@@ -4087,6 +4093,15 @@ set_init_3(void)
}
#endif
if (bufempty())
{
int idx_ffs = findoption((char_u *)"ffs");
/* Apply the first entry of 'fileformats' to the initial buffer. */
if (idx_ffs >= 0 && (options[idx_ffs].flags & P_WAS_SET))
set_fileformat(default_fileformat(), OPT_LOCAL);
}
#ifdef FEAT_TITLE
set_title_defaults();
#endif
@@ -6066,7 +6081,7 @@ did_set_string_option(
/* 'ambiwidth' */
#ifdef FEAT_MBYTE
else if (varp == &p_ambw)
else if (varp == &p_ambw || varp == &p_emoji)
{
if (check_opt_strings(p_ambw, p_ambw_values, FALSE) != OK)
errmsg = e_invarg;
@@ -6872,7 +6887,7 @@ did_set_string_option(
}
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
/* 'eadirection' */
else if (varp == &p_ead)
{
@@ -8598,7 +8613,7 @@ set_num_option(
win_setminheight();
}
# ifdef FEAT_VERTSPLIT
# ifdef FEAT_WINDOWS
else if (pp == &p_wiw)
{
if (p_wiw < 1)
@@ -10416,8 +10431,6 @@ get_varp(struct vimoption *p)
#endif
#ifdef FEAT_WINDOWS
case PV_WFH: return (char_u *)&(curwin->w_p_wfh);
#endif
#ifdef FEAT_VERTSPLIT
case PV_WFW: return (char_u *)&(curwin->w_p_wfw);
#endif
#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+5 -7
View File
@@ -214,7 +214,8 @@
#define SHM_INTRO 'I' /* intro messages */
#define SHM_COMPLETIONMENU 'c' /* completion menu messages */
#define SHM_RECORDING 'q' /* short recording message */
#define SHM_ALL "rmfixlnwaWtToOsAIcq" /* all possible flags for 'shm' */
#define SHM_FILEINFO 'F' /* no file info messages */
#define SHM_ALL "rmfixlnwaWtToOsAIcqF" /* all possible flags for 'shm' */
/* characters for p_go: */
#define GO_ASEL 'a' /* autoselect */
@@ -317,6 +318,7 @@ EXTERN int p_acd; /* 'autochdir' */
#endif
#ifdef FEAT_MBYTE
EXTERN char_u *p_ambw; /* 'ambiwidth' */
EXTERN char_u *p_emoji; /* 'emoji' */
#endif
#ifdef FEAT_ANTIALIAS
EXTERN int p_antialias; /* 'antialias' */
@@ -461,7 +463,7 @@ static char *(p_dy_values[]) = {"lastline", "uhex", NULL};
#define DY_LASTLINE 0x001
#define DY_UHEX 0x002
EXTERN int p_ed; /* 'edcompatible' */
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
EXTERN char_u *p_ead; /* 'eadirection' */
#endif
EXTERN int p_ea; /* 'equalalways' */
@@ -815,7 +817,7 @@ EXTERN char_u *p_tal; /* 'tabline' */
#ifdef FEAT_SPELL
EXTERN char_u *p_sps; /* 'spellsuggest' */
#endif
#ifdef FEAT_VERTSPLIT
#ifdef FEAT_WINDOWS
EXTERN int p_spr; /* 'splitright' */
#endif
EXTERN int p_sol; /* 'startofline' */
@@ -974,8 +976,6 @@ EXTERN int p_wmnu; /* 'wildmenu' */
#ifdef FEAT_WINDOWS
EXTERN long p_wh; /* 'winheight' */
EXTERN long p_wmh; /* 'winminheight' */
#endif
#ifdef FEAT_VERTSPLIT
EXTERN long p_wmw; /* 'winminwidth' */
EXTERN long p_wiw; /* 'winwidth' */
#endif
@@ -1192,8 +1192,6 @@ enum
#endif
#ifdef FEAT_WINDOWS
, WV_WFH
#endif
#ifdef FEAT_VERTSPLIT
, WV_WFW
#endif
, WV_WRAP
+46 -8
View File
@@ -176,6 +176,7 @@ typedef int waitstatus;
static pid_t wait4pid(pid_t, waitstatus *);
static int WaitForChar(long);
static int WaitForCharOrMouse(long);
#if defined(__BEOS__) || defined(VMS)
int RealWaitForChar(int, long, int *);
#else
@@ -5171,7 +5172,7 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
null_fd = open("/dev/null", O_RDWR | O_EXTRA, 0);
/* set up stdin for the child */
if (use_null_for_in)
if (use_null_for_in && null_fd >= 0)
{
close(0);
ignored = dup(null_fd);
@@ -5186,7 +5187,7 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
}
/* set up stderr for the child */
if (use_null_for_err)
if (use_null_for_err && null_fd >= 0)
{
close(2);
ignored = dup(null_fd);
@@ -5206,7 +5207,7 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
}
/* set up stdout for the child */
if (use_null_for_out)
if (use_null_for_out && null_fd >= 0)
{
close(0);
ignored = dup(null_fd);
@@ -5235,11 +5236,11 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
job->jv_channel = channel; /* ch_refcount was set above */
/* child stdin, stdout and stderr */
if (!use_file_for_in)
if (!use_file_for_in && fd_in[0] >= 0)
close(fd_in[0]);
if (!use_file_for_out)
if (!use_file_for_out && fd_out[1] >= 0)
close(fd_out[1]);
if (!use_out_for_err && !use_file_for_err)
if (!use_out_for_err && !use_file_for_err && fd_err[1] >= 0)
close(fd_err[1]);
if (channel != NULL)
{
@@ -5369,13 +5370,50 @@ mch_breakcheck(void)
}
/*
* Wait "msec" msec until a character is available from the keyboard or from
* inbuf[]. msec == -1 will block forever.
* Wait "msec" msec until a character is available from the mouse, keyboard,
* from inbuf[].
* "msec" == -1 will block forever.
* Invokes timer callbacks when needed.
* When a GUI is being used, this will never get called -- webb
*/
static int
WaitForChar(long msec)
{
#ifdef FEAT_TIMERS
long due_time;
long remaining = msec;
/* When waiting very briefly don't trigger timers. */
if (msec >= 0 && msec < 10L)
return WaitForCharOrMouse(msec);
while (msec < 0 || remaining > 0)
{
/* Trigger timers and then get the time in msec until the next one is
* due. Wait up to that time. */
due_time = check_due_timer();
if (due_time <= 0 || (msec > 0 && due_time > remaining))
due_time = remaining;
if (WaitForCharOrMouse(due_time))
return TRUE;
if (msec > 0)
remaining -= due_time;
}
return FALSE;
#else
return WaitForCharOrMouse(msec);
#endif
}
/*
* Wait "msec" msec until a character is available from the mouse or keyboard
* or from inbuf[].
* "msec" == -1 will block forever.
* When a GUI is being used, this will never get called -- webb
*/
static int
WaitForCharOrMouse(long msec)
{
#ifdef FEAT_MOUSE_GPM
int gpm_process_wanted;
#endif
+17 -3
View File
@@ -214,7 +214,6 @@ static void standend(void);
static void visual_bell(void);
static void cursor_visible(BOOL fVisible);
static DWORD write_chars(char_u *pchBuf, DWORD cbToWrite);
static WCHAR tgetch(int *pmodifiers, WCHAR *pch2);
static void create_conin(void);
static int s_cursor_visible = TRUE;
static int did_create_conin = FALSE;
@@ -1502,6 +1501,21 @@ WaitForChar(long msec)
&& (msec < 0 || (long)dwWaitTime > p_mzq))
dwWaitTime = p_mzq; /* don't wait longer than 'mzquantum' */
#endif
#ifdef FEAT_TIMERS
{
long due_time;
/* When waiting very briefly don't trigger timers. */
if (dwWaitTime > 10)
{
/* Trigger timers and then get the time in msec until the
* next one is due. Wait up to that time. */
due_time = check_due_timer();
if (due_time > 0 && dwWaitTime > (DWORD)due_time)
dwWaitTime = due_time;
}
}
#endif
#ifdef FEAT_CLIENTSERVER
/* Wait for either an event on the console input or a message in
* the client-server window. */
@@ -1604,7 +1618,7 @@ create_conin(void)
}
/*
* Get a keystroke or a mouse event
* Get a keystroke or a mouse event, use a blocking wait.
*/
static WCHAR
tgetch(int *pmodifiers, WCHAR *pch2)
@@ -6074,7 +6088,7 @@ mch_write(
/*
* Delay for half a second.
* Delay for "msec" milliseconds.
*/
/*ARGSUSED*/
void
+3 -3
View File
@@ -12,7 +12,7 @@ channel_T *channel_open_func(typval_T *argvars);
void channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err);
void channel_set_job(channel_T *channel, job_T *job, jobopt_T *options);
void channel_set_options(channel_T *channel, jobopt_T *opt);
void channel_set_req_callback(channel_T *channel, int part, char_u *callback, int id);
void channel_set_req_callback(channel_T *channel, int part, char_u *callback, partial_T *partial, int id);
void channel_write_in(channel_T *channel);
void channel_write_new_lines(buf_T *buf);
char_u *channel_get(channel_T *channel, int part);
@@ -20,14 +20,14 @@ int channel_collapse(channel_T *channel, int part);
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);
int channel_get_id(void);
void channel_read(channel_T *channel, int part, char *func);
char_u *channel_read_block(channel_T *channel, int part, int timeout);
int channel_read_json_block(channel_T *channel, int part, int timeout, int id, typval_T **rettv);
int channel_read_json_block(channel_T *channel, int part, int timeout_arg, int id, typval_T **rettv);
void common_channel_read(typval_T *argvars, typval_T *rettv, int raw);
channel_T *channel_fd2channel(sock_T fd, int *partp);
void channel_handle_events(void);
+5 -2
View File
@@ -59,6 +59,7 @@ void list_append(list_T *l, listitem_T *item);
int list_append_tv(list_T *l, typval_T *tv);
int list_append_dict(list_T *list, dict_T *dict);
int list_append_string(list_T *l, char_u *str, int len);
int list_append_number(list_T *l, varnumber_T n);
int list_insert_tv(list_T *l, typval_T *tv, listitem_T *item);
void list_insert(list_T *l, listitem_T *ni, listitem_T *item);
void vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2);
@@ -82,13 +83,15 @@ long get_dict_number(dict_T *d, char_u *key);
int string2float(char_u *text, float_T *value);
char_u *get_function_name(expand_T *xp, int idx);
char_u *get_expr_name(expand_T *xp, int idx);
int call_func(char_u *funcname, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict);
int call_func(char_u *funcname, int len, typval_T *rettv, int argcount_in, typval_T *argvars_in, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, partial_T *partial, dict_T *selfdict_in);
buf_T *buflist_find_by_name(char_u *name, int curtab_only);
int func_call(char_u *name, typval_T *args, dict_T *selfdict, typval_T *rettv);
int func_call(char_u *name, typval_T *args, partial_T *partial, dict_T *selfdict, typval_T *rettv);
void dict_extend(dict_T *d1, dict_T *d2, char_u *action);
void partial_unref(partial_T *pt);
void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
float_T vim_round(float_T f);
long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit);
char_u *get_callback(typval_T *arg, partial_T **pp);
void set_vim_var_nr(int idx, long val);
long get_vim_var_nr(int idx);
char_u *get_vim_var_str(int idx);
+6 -2
View File
@@ -18,6 +18,10 @@ float_T profile_float(proftime_T *tm);
void profile_setlimit(long msec, proftime_T *tm);
int profile_passed_limit(proftime_T *tm);
void profile_zero(proftime_T *tm);
timer_T *create_timer(long msec, int repeats);
long check_due_timer(void);
timer_T *find_timer(int id);
void stop_timer(timer_T *timer);
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);
@@ -60,9 +64,9 @@ void ex_argdelete(exarg_T *eap);
void ex_listdo(exarg_T *eap);
void ex_compiler(exarg_T *eap);
void ex_runtime(exarg_T *eap);
int source_runtime(char_u *name, int all);
int source_runtime(char_u *name, int flags);
int do_in_path(char_u *path, char_u *name, int flags, void (*callback)(char_u *fname, void *ck), void *cookie);
int do_in_runtimepath(char_u *name, int all, void (*callback)(char_u *fname, void *ck), void *cookie);
int do_in_runtimepath(char_u *name, int flags, void (*callback)(char_u *fname, void *ck), void *cookie);
void ex_packloadall(exarg_T *eap);
void ex_packadd(exarg_T *eap);
void ex_options(exarg_T *eap);

Some files were not shown because too many files have changed in this diff Show More