mirror of
https://github.com/vim/vim
synced 2025-07-16 17:22:00 +00:00
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
3f1a53c434 | |||
b0f42ba60d | |||
ff3be4fe1e | |||
0cb8ac71ae | |||
a10ae5e323 | |||
38623c8512 | |||
7a2b0e55e9 | |||
72cf47a279 | |||
56bc8e299c | |||
b946482190 | |||
9289df5ca9 | |||
69e056915c | |||
39de952577 | |||
18cebf4417 | |||
655a82a8d3 | |||
9b50f36e40 | |||
402c83921e | |||
f25329cb94 | |||
778df2a3cb | |||
85eee130f4 | |||
7ce551f317 | |||
5aa9896b2e | |||
6eddadff13 |
@ -267,6 +267,9 @@ Section "Vim executables and runtime files"
|
||||
SetOutPath $0\pack\dist\opt\swapmouse\plugin
|
||||
File ${VIMRT}\pack\dist\opt\swapmouse\plugin\*.*
|
||||
|
||||
SetOutPath $0\pack\dist\opt\termdebug\plugin
|
||||
File ${VIMRT}\pack\dist\opt\termdebug\plugin\*.*
|
||||
|
||||
SetOutPath $0\plugin
|
||||
File ${VIMRT}\plugin\*.*
|
||||
|
||||
|
@ -73,7 +73,8 @@ Search for "highlight_init".
|
||||
If you think you have a color scheme that is good enough to be used by others,
|
||||
please check the following items:
|
||||
|
||||
- Source the tools/check_colors.vim script to check for common mistakes.
|
||||
- Source the $VIMRUNTIME/colors/tools/check_colors.vim script to check for
|
||||
common mistakes.
|
||||
- Does it work in a color terminal as well as in the GUI?
|
||||
- Is "g:colors_name" set to a meaningful value? In case of doubt you can do
|
||||
it this way:
|
||||
|
@ -1,4 +1,4 @@
|
||||
*autocmd.txt* For Vim version 8.0. Last change: 2018 Apr 30
|
||||
*autocmd.txt* For Vim version 8.0. Last change: 2018 May 03
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
|
@ -1,4 +1,4 @@
|
||||
*change.txt* For Vim version 8.0. Last change: 2018 Apr 17
|
||||
*change.txt* For Vim version 8.0. Last change: 2018 May 06
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -110,7 +110,7 @@ is an error when 'cpoptions' includes the 'E' flag.
|
||||
J Join [count] lines, with a minimum of two lines.
|
||||
Remove the indent and insert up to two spaces (see
|
||||
below). Fails when on the last line of the buffer.
|
||||
If [count] is too big it is reduce to the number of
|
||||
If [count] is too big it is reduced to the number of
|
||||
lines available.
|
||||
|
||||
*v_J*
|
||||
@ -446,7 +446,7 @@ This depends on the 'nrformats' option:
|
||||
|
||||
For decimals a leading negative sign is considered for incrementing/
|
||||
decrementing, for binary, octal and hex values, it won't be considered. To
|
||||
ignore the sign Visually select the number before using CTRL-A or CTRL-X.
|
||||
ignore the sign Visually select the number before using CTRL-A or CTRL-X.
|
||||
|
||||
For numbers with leading zeros (including all octal and hexadecimal numbers),
|
||||
Vim preserves the number of characters in the number when possible. CTRL-A on
|
||||
|
@ -1,4 +1,4 @@
|
||||
*develop.txt* For Vim version 8.0. Last change: 2018 Apr 23
|
||||
*develop.txt* For Vim version 8.0. Last change: 2018 May 02
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -18,7 +18,8 @@ See the file README.txt in the "src" directory for an overview of the source
|
||||
code.
|
||||
|
||||
Vim is open source software. Everybody is encouraged to contribute to help
|
||||
improving Vim. For sending patches a context diff "diff -c" is preferred.
|
||||
improving Vim. For sending patches a unified diff "diff -u" is preferred.
|
||||
You can create a pull request on github, but it's not required.
|
||||
Also see http://vim.wikia.com/wiki/How_to_make_and_submit_a_patch.
|
||||
|
||||
==============================================================================
|
||||
|
@ -1,4 +1,4 @@
|
||||
*gui_x11.txt* For Vim version 8.0. Last change: 2017 Jul 28
|
||||
*gui_x11.txt* For Vim version 8.0. Last change: 2018 May 06
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -53,6 +53,9 @@ When using "gvim -f" and then ":gui", Vim will run in the foreground. The
|
||||
":gui -b".
|
||||
|
||||
"gvim --nofork" does the same as "gvim -f".
|
||||
|
||||
When there are running jobs Vim will not fork, because the processes would no
|
||||
longer be child processes.
|
||||
*E851* *E852*
|
||||
When starting the GUI fails Vim will try to continue running in the terminal.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
*map.txt* For Vim version 8.0. Last change: 2017 Sep 23
|
||||
*map.txt* For Vim version 8.0. Last change: 2018 May 06
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -542,9 +542,9 @@ scenario: >
|
||||
:imap <M-C> foo
|
||||
:set encoding=utf-8
|
||||
The mapping for <M-C> is defined with the latin1 encoding, resulting in a 0xc3
|
||||
byte. If you type the character <EFBFBD> (0xe1 <M-a>) in UTF-8 encoding this is the
|
||||
byte. If you type the character á (0xe1 <M-a>) in UTF-8 encoding this is the
|
||||
two bytes 0xc3 0xa1. You don't want the 0xc3 byte to be mapped then or
|
||||
otherwise it would be impossible to type the <EFBFBD> character.
|
||||
otherwise it would be impossible to type the á character.
|
||||
|
||||
*<Leader>* *mapleader*
|
||||
To define a mapping which uses the "mapleader" variable, the special string
|
||||
|
@ -1,4 +1,4 @@
|
||||
*mlang.txt* For Vim version 8.0. Last change: 2017 Mar 04
|
||||
*mlang.txt* For Vim version 8.0. Last change: 2018 May 06
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -190,8 +190,8 @@ you can do it without restarting Vim: >
|
||||
:source $VIMRUNTIME/menu.vim
|
||||
|
||||
Each part of a menu path is translated separately. The result is that when
|
||||
"Help" is translated to "Hilfe" and "Overview" to "<EFBFBD>berblick" then
|
||||
"Help.Overview" will be translated to "Hilfe.<EFBFBD>berblick".
|
||||
"Help" is translated to "Hilfe" and "Overview" to "Überblick" then
|
||||
"Help.Overview" will be translated to "Hilfe.Überblick".
|
||||
|
||||
==============================================================================
|
||||
3. Scripts *multilang-scripts*
|
||||
|
@ -1,4 +1,4 @@
|
||||
*os_vms.txt* For Vim version 8.0. Last change: 2014 Aug 29
|
||||
*os_vms.txt* For Vim version 8.0. Last change: 2018 May 06
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL
|
||||
@ -702,13 +702,13 @@ In a cluster that contains nodes with different architectures like below:
|
||||
$show cluster
|
||||
View of Cluster from system ID 11655 node: TOR 18-AUG-2008 11:58:31
|
||||
+---------------------------------+
|
||||
<EFBFBD> SYSTEMS <EFBFBD> MEMBERS <EFBFBD>
|
||||
+-----------------------+---------<EFBFBD>
|
||||
<EFBFBD> NODE <EFBFBD> SOFTWARE <EFBFBD> STATUS <EFBFBD>
|
||||
+--------+--------------+---------<EFBFBD>
|
||||
<EFBFBD> TOR <EFBFBD> VMS V7.3-2 <EFBFBD> MEMBER <EFBFBD>
|
||||
<EFBFBD> TITAN2 <EFBFBD> VMS V8.3 <EFBFBD> MEMBER <EFBFBD>
|
||||
<EFBFBD> ODIN <EFBFBD> VMS V7.3-2 <EFBFBD> MEMBER <EFBFBD>
|
||||
| SYSTEMS | MEMBERS |
|
||||
+-----------------------+---------|
|
||||
| NODE | SOFTWARE | STATUS |
|
||||
+--------+--------------+---------|
|
||||
| TOR | VMS V7.3-2 | MEMBER |
|
||||
| TITAN2 | VMS V8.3 | MEMBER |
|
||||
| ODIN | VMS V7.3-2 | MEMBER |
|
||||
+---------------------------------+
|
||||
|
||||
It is convenient to have a common VIM directory but execute different
|
||||
|
@ -1,4 +1,4 @@
|
||||
*quickfix.txt* For Vim version 8.0. Last change: 2018 Apr 28
|
||||
*quickfix.txt* For Vim version 8.0. Last change: 2018 May 01
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -1257,7 +1257,7 @@ or >
|
||||
to indicate the column of the error. This is to be used in a multi-line error
|
||||
message. See |errorformat-javac| for a useful example.
|
||||
|
||||
The "%s" conversion specifies the text to search for to locate the error line.
|
||||
The "%s" conversion specifies the text to search for, to locate the error line.
|
||||
The text is used as a literal string. The anchors "^" and "$" are added to
|
||||
the text to locate the error line exactly matching the search text and the
|
||||
text is prefixed with the "\V" atom to make it "very nomagic". The "%s"
|
||||
|
@ -1,4 +1,4 @@
|
||||
*starting.txt* For Vim version 8.0. Last change: 2018 Mar 14
|
||||
*starting.txt* For Vim version 8.0. Last change: 2018 May 05
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -127,7 +127,8 @@ argument.
|
||||
On VMS all option arguments are assumed to be lowercase, unless preceded with
|
||||
a slash. Thus "-R" means recovery and "-/R" readonly.
|
||||
|
||||
--help *-h* *--help*
|
||||
--help *-h* *--help* *-?*
|
||||
-?
|
||||
-h Give usage (help) message and exit. {not in Vi}
|
||||
See |info-message| about capturing the text.
|
||||
|
||||
|
@ -1408,6 +1408,7 @@ $VIM_POSIX vi_diff.txt /*$VIM_POSIX*
|
||||
--ttyfail starting.txt /*--ttyfail*
|
||||
--version starting.txt /*--version*
|
||||
--windowid starting.txt /*--windowid*
|
||||
-? starting.txt /*-?*
|
||||
-A starting.txt /*-A*
|
||||
-C starting.txt /*-C*
|
||||
-D starting.txt /*-D*
|
||||
@ -5285,6 +5286,7 @@ c_<C-Left> cmdline.txt /*c_<C-Left>*
|
||||
c_<C-R> cmdline.txt /*c_<C-R>*
|
||||
c_<C-R>_<C-A> cmdline.txt /*c_<C-R>_<C-A>*
|
||||
c_<C-R>_<C-F> cmdline.txt /*c_<C-R>_<C-F>*
|
||||
c_<C-R>_<C-L> cmdline.txt /*c_<C-R>_<C-L>*
|
||||
c_<C-R>_<C-O> cmdline.txt /*c_<C-R>_<C-O>*
|
||||
c_<C-R>_<C-P> cmdline.txt /*c_<C-R>_<C-P>*
|
||||
c_<C-R>_<C-R> cmdline.txt /*c_<C-R>_<C-R>*
|
||||
@ -5333,6 +5335,7 @@ c_CTRL-R cmdline.txt /*c_CTRL-R*
|
||||
c_CTRL-R_= cmdline.txt /*c_CTRL-R_=*
|
||||
c_CTRL-R_CTRL-A cmdline.txt /*c_CTRL-R_CTRL-A*
|
||||
c_CTRL-R_CTRL-F cmdline.txt /*c_CTRL-R_CTRL-F*
|
||||
c_CTRL-R_CTRL-L cmdline.txt /*c_CTRL-R_CTRL-L*
|
||||
c_CTRL-R_CTRL-O cmdline.txt /*c_CTRL-R_CTRL-O*
|
||||
c_CTRL-R_CTRL-P cmdline.txt /*c_CTRL-R_CTRL-P*
|
||||
c_CTRL-R_CTRL-R cmdline.txt /*c_CTRL-R_CTRL-R*
|
||||
|
@ -1,4 +1,4 @@
|
||||
*tagsrch.txt* For Vim version 8.0. Last change: 2017 Oct 20
|
||||
*tagsrch.txt* For Vim version 8.0. Last change: 2018 May 04
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -36,12 +36,12 @@ An easy way back is with the CTRL-T command. Also read about the tag stack
|
||||
below.
|
||||
|
||||
*:ta* *:tag* *E426* *E429*
|
||||
:[count]ta[g][!] {ident}
|
||||
Jump to the definition of {ident}, using the
|
||||
information in the tags file(s). Put {ident} in the
|
||||
:[count]ta[g][!] {name}
|
||||
Jump to the definition of {name}, using the
|
||||
information in the tags file(s). Put {name} in the
|
||||
tag stack. See |tag-!| for [!].
|
||||
{ident} can be a regexp pattern, see |tag-regexp|.
|
||||
When there are several matching tags for {ident}, jump
|
||||
{name} can be a regexp pattern, see |tag-regexp|.
|
||||
When there are several matching tags for {name}, jump
|
||||
to the [count] one. When [count] is omitted the
|
||||
first one is jumped to. See |tag-matchlist| for
|
||||
jumping to other matching tags.
|
||||
@ -49,16 +49,16 @@ below.
|
||||
g<LeftMouse> *g<LeftMouse>*
|
||||
<C-LeftMouse> *<C-LeftMouse>* *CTRL-]*
|
||||
CTRL-] Jump to the definition of the keyword under the
|
||||
cursor. Same as ":tag {ident}", where {ident} is the
|
||||
cursor. Same as ":tag {name}", where {name} is the
|
||||
keyword under or after cursor.
|
||||
When there are several matching tags for {ident}, jump
|
||||
When there are several matching tags for {name}, jump
|
||||
to the [count] one. When no [count] is given the
|
||||
first one is jumped to. See |tag-matchlist| for
|
||||
jumping to other matching tags.
|
||||
{Vi: identifier after the cursor}
|
||||
|
||||
*v_CTRL-]*
|
||||
{Visual}CTRL-] Same as ":tag {ident}", where {ident} is the text that
|
||||
{Visual}CTRL-] Same as ":tag {name}", where {name} is the text that
|
||||
is highlighted. {not in Vi}
|
||||
|
||||
*telnet-CTRL-]*
|
||||
@ -82,7 +82,7 @@ When there are multiple matches for a tag, this priority is used:
|
||||
|
||||
Note that when the current file changes, the priority list is mostly not
|
||||
changed, to avoid confusion when using ":tnext". It is changed when using
|
||||
":tag {ident}".
|
||||
":tag {name}".
|
||||
|
||||
The ignore-case matches are not found for a ":tag" command when:
|
||||
- the 'ignorecase' option is off and 'tagcase' is "followic"
|
||||
@ -167,7 +167,7 @@ You can get from main to FuncA by using CTRL-] on the call to FuncA. Then
|
||||
you can CTRL-] to get to FuncC. If you now want to go back to main you can
|
||||
use CTRL-T twice. Then you can CTRL-] to FuncB.
|
||||
|
||||
If you issue a ":ta {ident}" or CTRL-] command, this tag is inserted at the
|
||||
If you issue a ":ta {name}" or CTRL-] command, this tag is inserted at the
|
||||
current position in the stack. If the stack was full (it can hold up to 20
|
||||
entries), the oldest entry is deleted and the older entries shift one
|
||||
position up (their index number is decremented by one). If the last used
|
||||
@ -191,14 +191,14 @@ between them. Note that these commands don't change the tag stack, they keep
|
||||
the same entry.
|
||||
|
||||
*:ts* *:tselect*
|
||||
:ts[elect][!] [ident] List the tags that match [ident], using the
|
||||
:ts[elect][!] [name] List the tags that match [name], using the
|
||||
information in the tags file(s).
|
||||
When [ident] is not given, the last tag name from the
|
||||
When [name] is not given, the last tag name from the
|
||||
tag stack is used.
|
||||
See |tag-!| for [!].
|
||||
With a '>' in the first column is indicated which is
|
||||
the current position in the list (if there is one).
|
||||
[ident] can be a regexp pattern, see |tag-regexp|.
|
||||
[name] can be a regexp pattern, see |tag-regexp|.
|
||||
See |tag-priority| for the priorities used in the
|
||||
listing. {not in Vi}
|
||||
Example output:
|
||||
@ -226,7 +226,7 @@ the same entry.
|
||||
type 'q' and enter the number.
|
||||
|
||||
*:sts* *:stselect*
|
||||
:sts[elect][!] [ident] Does ":tselect[!] [ident]" and splits the window for
|
||||
:sts[elect][!] [name] Does ":tselect[!] [name]" and splits the window for
|
||||
the selected tag. {not in Vi}
|
||||
|
||||
*g]*
|
||||
@ -238,11 +238,11 @@ g] Like CTRL-], but use ":tselect" instead of ":tag".
|
||||
identifier. {not in Vi}
|
||||
|
||||
*:tj* *:tjump*
|
||||
:tj[ump][!] [ident] Like ":tselect", but jump to the tag directly when
|
||||
:tj[ump][!] [name] Like ":tselect", but jump to the tag directly when
|
||||
there is only one match. {not in Vi}
|
||||
|
||||
*:stj* *:stjump*
|
||||
:stj[ump][!] [ident] Does ":tjump[!] [ident]" and splits the window for the
|
||||
:stj[ump][!] [name] Does ":tjump[!] [name]" and splits the window for the
|
||||
selected tag. {not in Vi}
|
||||
|
||||
*g_CTRL-]*
|
||||
@ -277,9 +277,9 @@ g CTRL-] Like CTRL-], but use ":tjump" instead of ":tag".
|
||||
in Vi}
|
||||
|
||||
*:lt* *:ltag*
|
||||
:lt[ag][!] [ident] Jump to tag [ident] and add the matching tags to a new
|
||||
location list for the current window. [ident] can be
|
||||
a regexp pattern, see |tag-regexp|. When [ident] is
|
||||
:lt[ag][!] [name] Jump to tag [name] and add the matching tags to a new
|
||||
location list for the current window. [name] can be
|
||||
a regexp pattern, see |tag-regexp|. When [name] is
|
||||
not given, the last tag name from the tag stack is
|
||||
used. The search pattern to locate the tag line is
|
||||
prefixed with "\V" to escape all the special
|
||||
@ -311,12 +311,12 @@ the same as above, with a "p" prepended.
|
||||
{not available when compiled without the |+quickfix| feature}
|
||||
|
||||
*:pts* *:ptselect*
|
||||
:pts[elect][!] [ident] Does ":tselect[!] [ident]" and shows the new tag in a
|
||||
:pts[elect][!] [name] Does ":tselect[!] [name]" and shows the new tag in a
|
||||
"Preview" window. See |:ptag| for more info.
|
||||
{not in Vi}
|
||||
|
||||
*:ptj* *:ptjump*
|
||||
:ptj[ump][!] [ident] Does ":tjump[!] [ident]" and shows the new tag in a
|
||||
:ptj[ump][!] [name] Does ":tjump[!] [name]" and shows the new tag in a
|
||||
"Preview" window. See |:ptag| for more info.
|
||||
{not in Vi}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
*terminal.txt* For Vim version 8.0. Last change: 2018 Apr 20
|
||||
*terminal.txt* For Vim version 8.0. Last change: 2018 May 04
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -466,6 +466,8 @@ Currently supported commands:
|
||||
Let Vim open a file, like the `:drop` command. If {filename}
|
||||
is already open in a window, switch to that window. Otherwise
|
||||
open a new window to edit {filename}.
|
||||
Note that both the job and Vim may change the current
|
||||
directory, thus it's best to use the full path.
|
||||
|
||||
[options] is only used when opening a new window. If present,
|
||||
it must be a Dict. Similarly to |++opt|, These entries are recognized:
|
||||
|
@ -1,4 +1,4 @@
|
||||
*todo.txt* For Vim version 8.0. Last change: 2018 Apr 30
|
||||
*todo.txt* For Vim version 8.0. Last change: 2018 May 05
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -40,6 +40,10 @@ Terminal emulator window:
|
||||
|
||||
Problem with sudo. #2758
|
||||
|
||||
Looks like an error for inserting register makes ":file other" not work.
|
||||
(Tom M, 2018 Mar 28) Reset did_emsg after inserting a register.
|
||||
Or at the top of the loop? (Apr 4)
|
||||
|
||||
Make assert_functions return non-zero on failure. Make sure they add one
|
||||
entry to v:errors then.
|
||||
Use WaitForAssert() in tests: give error when failed.
|
||||
@ -52,23 +56,19 @@ Also see #2352, want better control over balloon, perhaps set the position.
|
||||
Errors found with random data:
|
||||
heap-buffer-overflow in alist_add (#2472)
|
||||
|
||||
Patch to shorten filenames in quickfix window. (Yegappan, 2018 Apr 28, #2851,
|
||||
closes #2846)
|
||||
|
||||
More warnings from static analysis:
|
||||
https://lgtm.com/projects/g/vim/vim/alerts/?mode=list
|
||||
|
||||
Looks like an error for inserting register makes ":file other" not work.
|
||||
(Tom M, 2018 Mar 28) Reset did_emsg after inserting a register.
|
||||
Or at the top of the loop? (Apr 4)
|
||||
|
||||
Patch to add "module" to quickfix entries. (Marcin Szamotulski, Coot, 2017 Jun
|
||||
8, #1757) Now part of #2322. Or #2327? #1757 was re-opened, include that
|
||||
first.
|
||||
|
||||
When opening foo/x.txt and bar/x.txt get swap file warning. Should check the
|
||||
file name. (Juergen Weigert)
|
||||
|
||||
Script generated by :mksession does not work well if there are windows with
|
||||
modified buffers
|
||||
change "silent only" into "silent only!"
|
||||
change "edit fname" of first buffer to "hide edit fname"
|
||||
skip "badd fname" if "fname" is already in the buffer list
|
||||
remove remark about unloading buffers from documentation
|
||||
|
||||
Compiler warnings (geeknik, 2017 Oct 26):
|
||||
- signed integer overflow in do_sub() (#2249)
|
||||
- signed integer overflow in get_address() (#2248)
|
||||
@ -87,9 +87,6 @@ or asyncmake:
|
||||
Add a ModeChanged autocommand that has an argument indicating the old and new
|
||||
mode. Also used for switching Terminal mode.
|
||||
|
||||
Patch to shorten filenames in quickfix window. (Yegappan Lakshmanan, 2018
|
||||
Apr 27)
|
||||
|
||||
Add an option with file patterns, to be used when unloading a buffer: If there
|
||||
is a match, remove entries for the buffer from marks, jumplist, etc. To be
|
||||
used for git temp files.
|
||||
@ -99,9 +96,28 @@ Cursor in wrong position when line wraps. (#2540)
|
||||
Add an option similar to 'lazyredraw' to skip redrawing while executing a
|
||||
script or function.
|
||||
|
||||
Alternative manpager.vim. (Enno, 2018 Jan 5, #2529)
|
||||
MS-Windows: write may fail if another program is reading the file.
|
||||
If 'readonly' is not set but the file appears to be readonly later, try again
|
||||
(wait a little while).
|
||||
CreateFile() returns ERROR_SHARING_VIOLATION (Linwei, 2018 May 5)
|
||||
|
||||
Patch to add more flags to :ls. (Marcin Szamotulski, #2751)
|
||||
Should add a test for every command line argument. Check coverage for what is
|
||||
missing: --nofork, -A , -b, -h, etc.
|
||||
|
||||
Improve the installer for MS-Windows. There are a few alternatives:
|
||||
- Add silent install option. (Shane Lee, #751)
|
||||
- Installer from Cream (Steve Hall).
|
||||
- Modern UI 2.0 for the Nsis installer. (Guopeng Wen)
|
||||
https://github.com/gpwen/vim-installer-mui2
|
||||
- make it possible to do a silent install, see
|
||||
http://nsis.sourceforge.net/Docs/Chapter4.html#4.12
|
||||
Version from Guopeng Wen does this.
|
||||
- MSI installer: https://github.com/petrkle/vim-msi/
|
||||
- The one on Issue 279.
|
||||
Problem: they all work slightly different (e.g. don't install vimrun.exe).
|
||||
How to test that it works well for all Vim users?
|
||||
|
||||
Alternative manpager.vim. (Enno, 2018 Jan 5, #2529)
|
||||
|
||||
Does setting 'cursorline' cause syntax highlighting to slow down? Perhaps is
|
||||
mess up the cache? (Mike Lee Williams, 2018 Jan 27, #2539)
|
||||
@ -110,6 +126,8 @@ Also: 'foldtext' is evaluated too often. (Daniel Hahler, #2773)
|
||||
When using :packadd files under "later" are not used, which is inconsistent
|
||||
with packages under "start". (xtal8, #1994)
|
||||
|
||||
Patch to support "xxd -ps". (Erik Auerswald, 2018 May 1)
|
||||
|
||||
Column number is wrong when using 'linebreak' and 'wrap'. (Keith Smiley, 2018
|
||||
Jan 15, #2555)
|
||||
|
||||
@ -117,8 +135,9 @@ Jan 15, #2555)
|
||||
|
||||
Check argument of systemlist(). (Pavlov)
|
||||
|
||||
Patch to support 256 colors in Windows console. (Nobuhiro Takasaki, 2018 Apr
|
||||
25, #2821)
|
||||
Can we make ":unlet $VAR" use unsetenv() to delete the env var?
|
||||
What for systems that don't have unsetenv()? (Issue #1116)
|
||||
Patch in #2855, (Yasuhiro Matsumoto)
|
||||
|
||||
Patch to add reg_executing() and reg_recording(). (Hirohito Higashi, #2745)
|
||||
|
||||
@ -1216,9 +1235,6 @@ Idea: For a window in the middle (has window above and below it), use
|
||||
right-mouse-drag on the status line to move a window up/down without changing
|
||||
its height? It's like dragging the status bar above it at the same time.
|
||||
|
||||
Can we make ":unlet $VAR" use unsetenv() to delete the env var?
|
||||
What for systems that don't have unsetenv()? (Issue #1116)
|
||||
|
||||
Patch to add a :domodeline command. (Christian Brabandt, 2014 Oct 21)
|
||||
|
||||
This does not give an error: (Andre Sihera, 2014 Mar 21)
|
||||
@ -1383,19 +1399,6 @@ optional. (2013 Jul 12)
|
||||
|
||||
Dialog is too big on Linux too. (David Fishburn, 2013 Sep 2)
|
||||
|
||||
Improve the installer for MS-Windows. There are a few alternatives:
|
||||
- Add silent install option. (Shane Lee, #751)
|
||||
- Installer from Cream (Steve Hall).
|
||||
- Modern UI 2.0 for the Nsis installer. (Guopeng Wen)
|
||||
https://github.com/gpwen/vim-installer-mui2
|
||||
- make it possible to do a silent install, see
|
||||
http://nsis.sourceforge.net/Docs/Chapter4.html#4.12
|
||||
Version from Guopeng Wen does this.
|
||||
- MSI installer: https://github.com/petrkle/vim-msi/
|
||||
- The one on Issue 279.
|
||||
Problem: they all work slightly different (e.g. don't install vimrun.exe).
|
||||
How to test that it works well for all Vim users?
|
||||
|
||||
Patch to make fold updates much faster. (Christian Brabandt, 2012 Dec)
|
||||
|
||||
- Add regex for 'paragraphs' and 'sections': 'parare' and 'sectre'. Combine
|
||||
|
@ -1,7 +1,7 @@
|
||||
" Vim support file to detect file types
|
||||
"
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2018 Jan 28
|
||||
" Last Change: 2018 May 04
|
||||
|
||||
" Listen very carefully, I will say this only once
|
||||
if exists("did_load_filetypes")
|
||||
@ -429,6 +429,13 @@ au BufNewFile,BufRead control
|
||||
\| setf debcontrol
|
||||
\| endif
|
||||
|
||||
" Debian Copyright
|
||||
au BufNewFile,BufRead */debian/copyright setf debcopyright
|
||||
au BufNewFile,BufRead copyright
|
||||
\ if getline(1) =~ '^Format:'
|
||||
\| setf debcopyright
|
||||
\| endif
|
||||
|
||||
" Debian Sources.list
|
||||
au BufNewFile,BufRead */etc/apt/sources.list setf debsources
|
||||
au BufNewFile,BufRead */etc/apt/sources.list.d/*.list setf debsources
|
||||
|
@ -3,20 +3,20 @@
|
||||
" Maintainer: Debian Vim Maintainers
|
||||
" Former Maintainers: Michael Piefel <piefel@informatik.hu-berlin.de>
|
||||
" Stefano Zacchiroli <zack@debian.org>
|
||||
" Last Change: 2018-01-06
|
||||
" Last Change: 2018-01-28
|
||||
" License: Vim License
|
||||
" URL: https://salsa.debian.org/vim-team/vim-debian/blob/master/ftplugin/debchangelog.vim
|
||||
|
||||
" Bug completion requires apt-listbugs installed for Debian packages or
|
||||
" python-launchpadlib installed for Ubuntu packages
|
||||
|
||||
if exists("b:did_ftplugin")
|
||||
if exists('b:did_ftplugin')
|
||||
finish
|
||||
endif
|
||||
let b:did_ftplugin=1
|
||||
|
||||
" {{{1 Local settings (do on every load)
|
||||
if exists("g:debchangelog_fold_enable")
|
||||
if exists('g:debchangelog_fold_enable')
|
||||
setlocal foldmethod=expr
|
||||
setlocal foldexpr=DebGetChangelogFold(v:lnum)
|
||||
setlocal foldtext=DebChangelogFoldText()
|
||||
@ -28,10 +28,10 @@ setlocal tw=78
|
||||
setlocal comments=f:*
|
||||
|
||||
" Clean unloading
|
||||
let b:undo_ftplugin = "setlocal tw< comments< foldmethod< foldexpr< foldtext<"
|
||||
let b:undo_ftplugin = 'setlocal tw< comments< foldmethod< foldexpr< foldtext<'
|
||||
" }}}1
|
||||
|
||||
if exists("g:did_changelog_ftplugin")
|
||||
if exists('g:did_changelog_ftplugin')
|
||||
finish
|
||||
endif
|
||||
|
||||
@ -44,41 +44,41 @@ let g:did_changelog_ftplugin = 1
|
||||
" Returns full name, either from $DEBFULLNAME or debianfullname.
|
||||
" TODO Is there a way to determine name from anywhere else?
|
||||
function <SID>FullName()
|
||||
if exists("$DEBFULLNAME")
|
||||
if exists('$DEBFULLNAME')
|
||||
return $DEBFULLNAME
|
||||
elseif exists("g:debianfullname")
|
||||
elseif exists('g:debianfullname')
|
||||
return g:debianfullname
|
||||
else
|
||||
return "Your Name"
|
||||
return 'Your Name'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Returns email address, from $DEBEMAIL, $EMAIL or debianemail.
|
||||
function <SID>Email()
|
||||
if exists("$DEBEMAIL")
|
||||
if exists('$DEBEMAIL')
|
||||
return $DEBEMAIL
|
||||
elseif exists("$EMAIL")
|
||||
elseif exists('$EMAIL')
|
||||
return $EMAIL
|
||||
elseif exists("g:debianemail")
|
||||
elseif exists('g:debianemail')
|
||||
return g:debianemail
|
||||
else
|
||||
return "your@email.address"
|
||||
return 'your@email.address'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Returns date in RFC822 format.
|
||||
function <SID>Date()
|
||||
let savelang = v:lc_time
|
||||
execute "language time C"
|
||||
let dateandtime = strftime("%a, %d %b %Y %X %z")
|
||||
execute "language time " . savelang
|
||||
execute 'language time C'
|
||||
let dateandtime = strftime('%a, %d %b %Y %X %z')
|
||||
execute 'language time ' . savelang
|
||||
return dateandtime
|
||||
endfunction
|
||||
|
||||
function <SID>WarnIfNotUnfinalised()
|
||||
if match(getline("."), " -- [[:alpha:]][[:alnum:].]")!=-1
|
||||
if match(getline('.'), ' -- [[:alpha:]][[:alnum:].]')!=-1
|
||||
echohl WarningMsg
|
||||
echo "The entry has not been unfinalised before editing."
|
||||
echo 'The entry has not been unfinalised before editing.'
|
||||
echohl None
|
||||
return 1
|
||||
endif
|
||||
@ -86,10 +86,10 @@ function <SID>WarnIfNotUnfinalised()
|
||||
endfunction
|
||||
|
||||
function <SID>Finalised()
|
||||
let savelinenum = line(".")
|
||||
normal 1G
|
||||
call search("^ -- ")
|
||||
if match(getline("."), " -- [[:alpha:]][[:alnum:].]")!=-1
|
||||
let savelinenum = line('.')
|
||||
1
|
||||
call search('^ -- ')
|
||||
if match(getline('.'), ' -- [[:alpha:]][[:alnum:].]')!=-1
|
||||
let returnvalue = 1
|
||||
else
|
||||
let returnvalue = 0
|
||||
@ -109,54 +109,54 @@ function NewVersion()
|
||||
amenu disable Changelog.Unfinalise
|
||||
amenu enable Changelog.Finalise
|
||||
call append(0, substitute(getline(1), '-\([[:digit:]]\+\))', '-$$\1)', ''))
|
||||
call append(1, "")
|
||||
call append(2, "")
|
||||
call append(3, " -- ")
|
||||
call append(4, "")
|
||||
call Urgency("low")
|
||||
normal 1G0
|
||||
call search(")")
|
||||
normal h
|
||||
normal
|
||||
call append(1, '')
|
||||
call append(2, '')
|
||||
call append(3, ' -- ')
|
||||
call append(4, '')
|
||||
call Urgency('low')
|
||||
normal! 1G0
|
||||
call search(')')
|
||||
normal! h
|
||||
normal!
|
||||
call setline(1, substitute(getline(1), '-\$\$', '-', ''))
|
||||
if exists("g:debchangelog_fold_enable")
|
||||
if exists('g:debchangelog_fold_enable')
|
||||
foldopen
|
||||
endif
|
||||
call AddEntry()
|
||||
endfunction
|
||||
|
||||
function AddEntry()
|
||||
normal 1G
|
||||
call search("^ -- ")
|
||||
normal kk
|
||||
call append(".", " * ")
|
||||
normal jjj
|
||||
1
|
||||
call search('^ -- ')
|
||||
.-2
|
||||
call append('.', ' * ')
|
||||
.+3
|
||||
let warn=<SID>WarnIfNotUnfinalised()
|
||||
normal kk
|
||||
.-2
|
||||
if warn
|
||||
echohl MoreMsg
|
||||
call input("Hit ENTER")
|
||||
call input('Hit ENTER')
|
||||
echohl None
|
||||
endif
|
||||
startinsert!
|
||||
endfunction
|
||||
|
||||
function CloseBug()
|
||||
normal 1G
|
||||
call search("^ -- ")
|
||||
1
|
||||
call search('^ -- ')
|
||||
let warn=<SID>WarnIfNotUnfinalised()
|
||||
normal kk
|
||||
call append(".", " * (closes: #" . input("Bug number to close: ") . ")")
|
||||
normal j^ll
|
||||
.-2
|
||||
call append('.', ' * (closes: #' . input('Bug number to close: ') . ')')
|
||||
normal! j^ll
|
||||
startinsert
|
||||
endfunction
|
||||
|
||||
function Distribution(dist)
|
||||
call setline(1, substitute(getline(1), ') *\%(UNRELEASED\|\l\+\);', ") " . a:dist . ";", ""))
|
||||
call setline(1, substitute(getline(1), ') *\%(UNRELEASED\|\l\+\);', ') ' . a:dist . ';', ''))
|
||||
endfunction
|
||||
|
||||
function Urgency(urg)
|
||||
call setline(1, substitute(getline(1), "urgency=.*$", "urgency=" . a:urg, ""))
|
||||
call setline(1, substitute(getline(1), 'urgency=.*$', 'urgency=' . a:urg, ''))
|
||||
endfunction
|
||||
|
||||
function <SID>UnfinaliseMenu()
|
||||
@ -172,9 +172,9 @@ endfunction
|
||||
|
||||
function Unfinalise()
|
||||
call <SID>UnfinaliseMenu()
|
||||
normal 1G
|
||||
call search("^ -- ")
|
||||
call setline(".", " -- ")
|
||||
1
|
||||
call search('^ -- ')
|
||||
call setline('.', ' -- ')
|
||||
endfunction
|
||||
|
||||
function <SID>FinaliseMenu()
|
||||
@ -190,9 +190,9 @@ endfunction
|
||||
|
||||
function Finalise()
|
||||
call <SID>FinaliseMenu()
|
||||
normal 1G
|
||||
call search("^ -- ")
|
||||
call setline(".", " -- " . <SID>FullName() . " <" . <SID>Email() . "> " . <SID>Date())
|
||||
1
|
||||
call search('^ -- ')
|
||||
call setline('.', ' -- ' . <SID>FullName() . ' <' . <SID>Email() . '> ' . <SID>Date())
|
||||
endfunction
|
||||
|
||||
|
||||
@ -239,7 +239,7 @@ function! s:getAuthor(zonestart, zoneend)
|
||||
let linepos = a:zoneend
|
||||
while linepos >= a:zonestart
|
||||
let line = getline(linepos)
|
||||
if line =~ '^ --'
|
||||
if line =~# '^ --'
|
||||
return substitute(line, '^ --\s*\([^<]\+\)\s*.*', '\1', '')
|
||||
endif
|
||||
let linepos -= 1
|
||||
@ -254,7 +254,7 @@ function! DebGetPkgSrcName(lineno)
|
||||
let pkgname = ''
|
||||
while lineidx > 0
|
||||
let curline = getline(lineidx)
|
||||
if curline =~ '^\S'
|
||||
if curline =~# '^\S'
|
||||
let pkgname = matchlist(curline, '^\(\S\+\).*$')[1]
|
||||
break
|
||||
endif
|
||||
@ -264,7 +264,7 @@ function! DebGetPkgSrcName(lineno)
|
||||
endfunction
|
||||
|
||||
function! DebChangelogFoldText()
|
||||
if v:folddashes == '-' " changelog entry fold
|
||||
if v:folddashes ==# '-' " changelog entry fold
|
||||
return foldtext() . ' -- ' . s:getAuthor(v:foldstart, v:foldend) . ' '
|
||||
endif
|
||||
return foldtext()
|
||||
@ -272,19 +272,19 @@ endfunction
|
||||
|
||||
function! DebGetChangelogFold(lnum)
|
||||
let line = getline(a:lnum)
|
||||
if line =~ '^\w\+'
|
||||
if line =~# '^\w\+'
|
||||
return '>1' " beginning of a changelog entry
|
||||
endif
|
||||
if line =~ '^\s\+\[.*\]'
|
||||
if line =~# '^\s\+\[.*\]'
|
||||
return '>2' " beginning of an author-specific chunk
|
||||
endif
|
||||
if line =~ '^ --'
|
||||
if line =~# '^ --'
|
||||
return '1'
|
||||
endif
|
||||
return '='
|
||||
endfunction
|
||||
|
||||
if exists("g:debchangelog_fold_enable")
|
||||
if exists('g:debchangelog_fold_enable')
|
||||
silent! foldopen! " unfold the entry the cursor is on (usually the first one)
|
||||
endif
|
||||
|
||||
@ -305,13 +305,13 @@ fun! DebCompleteBugs(findstart, base)
|
||||
let try_colidx = col('.') - 1
|
||||
let colidx = -1 " default to no-completion-possible
|
||||
|
||||
while try_colidx > 0 && line[try_colidx - 1] =~ '\s\|\d\|#\|,\|:'
|
||||
while try_colidx > 0 && line[try_colidx - 1] =~# '\s\|\d\|#\|,\|:'
|
||||
let try_colidx = try_colidx - 1
|
||||
if line[try_colidx] == '#' && colidx == -1
|
||||
if line[try_colidx] ==# '#' && colidx == -1
|
||||
" found hash, where we complete from:
|
||||
let colidx = try_colidx
|
||||
elseif line[try_colidx] == ':'
|
||||
if try_colidx > 1 && strpart(line, try_colidx - 2, 3) =~ '\clp:'
|
||||
elseif line[try_colidx] ==# ':'
|
||||
if try_colidx > 1 && strpart(line, try_colidx - 2, 3) =~? '\clp:'
|
||||
let g:debchangelog_complete_mode = 'lp'
|
||||
endif
|
||||
break
|
||||
@ -320,7 +320,7 @@ fun! DebCompleteBugs(findstart, base)
|
||||
return colidx
|
||||
else " return matches:
|
||||
let bug_lines = []
|
||||
if g:debchangelog_complete_mode == 'lp'
|
||||
if g:debchangelog_complete_mode ==? 'lp'
|
||||
if ! has('python')
|
||||
echoerr 'vim must be built with Python support to use LP bug completion'
|
||||
return
|
||||
@ -363,7 +363,7 @@ EOF
|
||||
for line in bug_lines
|
||||
let parts = matchlist(line, '^\s*\(#\S\+\)\s*-\s*\(.*\)$')
|
||||
" filter only those which match a:base:
|
||||
if parts[1] !~ "^" . a:base
|
||||
if parts[1] !~ '^' . a:base
|
||||
continue
|
||||
endif
|
||||
let completion = {}
|
||||
|
@ -2,17 +2,17 @@
|
||||
" Language: Debian control files
|
||||
" Maintainer: Debian Vim Maintainers
|
||||
" Former Maintainer: Pierre Habouzit <madcoder@debian.org>
|
||||
" Last Change: 2018-01-06
|
||||
" Last Change: 2018-01-28
|
||||
" URL: https://salsa.debian.org/vim-team/vim-debian/blob/master/ftplugin/debcontrol.vim
|
||||
|
||||
" Do these settings once per buffer
|
||||
if exists("b:did_ftplugin")
|
||||
if exists('b:did_ftplugin')
|
||||
finish
|
||||
endif
|
||||
let b:did_ftplugin=1
|
||||
|
||||
" {{{1 Local settings (do on every load)
|
||||
if exists("g:debcontrol_fold_enable")
|
||||
if exists('g:debcontrol_fold_enable')
|
||||
setlocal foldmethod=expr
|
||||
setlocal foldexpr=DebControlFold(v:lnum)
|
||||
setlocal foldtext=DebControlFoldText()
|
||||
@ -20,7 +20,7 @@ endif
|
||||
setlocal textwidth=0
|
||||
|
||||
" Clean unloading
|
||||
let b:undo_ftplugin = "setlocal tw< foldmethod< foldexpr< foldtext<"
|
||||
let b:undo_ftplugin = 'setlocal tw< foldmethod< foldexpr< foldtext<'
|
||||
|
||||
" }}}1
|
||||
|
||||
@ -32,7 +32,7 @@ function! s:getField(f, lnum)
|
||||
while line !~ '^'.a:f.':'
|
||||
let fwdsteps += 1
|
||||
let line = getline(a:lnum + fwdsteps)
|
||||
if line == ''
|
||||
if line ==# ''
|
||||
return 'unknown'
|
||||
endif
|
||||
endwhile
|
||||
@ -40,9 +40,9 @@ function! s:getField(f, lnum)
|
||||
endfunction
|
||||
|
||||
function! DebControlFoldText()
|
||||
if v:folddashes == '-' " debcontrol entry fold
|
||||
if v:folddashes ==# '-' " debcontrol entry fold
|
||||
let type = substitute(getline(v:foldstart), ':.*', '', '')
|
||||
if type == 'Source'
|
||||
if type ==# 'Source'
|
||||
let ftext = substitute(foldtext(), ' *Source: *', ' ', '')
|
||||
return ftext . ' -- ' . s:getField('Maintainer', v:foldstart) . ' '
|
||||
endif
|
||||
@ -56,11 +56,11 @@ endfunction
|
||||
function! DebControlFold(l)
|
||||
|
||||
" This is for not merging blank lines around folds to them
|
||||
if getline(a:l) =~ '^Source:'
|
||||
if getline(a:l) =~# '^Source:'
|
||||
return '>1'
|
||||
endif
|
||||
|
||||
if getline(a:l) =~ '^Package:'
|
||||
if getline(a:l) =~# '^Package:'
|
||||
return '>1'
|
||||
endif
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
" Vim filetype plugin file
|
||||
" Language: man
|
||||
" Maintainer: SungHyun Nam <goweol@gmail.com>
|
||||
" Last Change: 2018 Jan 15
|
||||
" Last Change: 2018 May 2
|
||||
|
||||
" To make the ":Man" command available before editing a manual page, source
|
||||
" this script from your startup vimrc file.
|
||||
@ -164,7 +164,7 @@ func <SID>GetPage(...)
|
||||
setl buftype=nofile noswapfile
|
||||
|
||||
setl ma nonu nornu nofen
|
||||
silent exec "norm 1GdG"
|
||||
silent exec "norm! 1GdG"
|
||||
let unsetwidth = 0
|
||||
if empty($MANWIDTH)
|
||||
let $MANWIDTH = winwidth(0)
|
||||
@ -188,10 +188,10 @@ func <SID>GetPage(...)
|
||||
endif
|
||||
" Remove blank lines from top and bottom.
|
||||
while getline(1) =~ '^\s*$'
|
||||
silent keepj norm ggdd
|
||||
silent keepj norm! ggdd
|
||||
endwhile
|
||||
while getline('$') =~ '^\s*$'
|
||||
silent keepj norm Gdd
|
||||
silent keepj norm! Gdd
|
||||
endwhile
|
||||
1
|
||||
setl ft=man nomod
|
||||
@ -208,7 +208,7 @@ func <SID>PopPage()
|
||||
exec "let s:man_tag_col=s:man_tag_col_".s:man_tag_depth
|
||||
exec s:man_tag_buf."b"
|
||||
exec s:man_tag_lin
|
||||
exec "norm ".s:man_tag_col."|"
|
||||
exec "norm! ".s:man_tag_col."|"
|
||||
exec "unlet s:man_tag_buf_".s:man_tag_depth
|
||||
exec "unlet s:man_tag_lin_".s:man_tag_depth
|
||||
exec "unlet s:man_tag_col_".s:man_tag_depth
|
||||
|
@ -1,7 +1,7 @@
|
||||
" These commands create the option window.
|
||||
"
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2018 Feb 27
|
||||
" Last Change: 2018 Apr 18
|
||||
|
||||
" If there already is an option window, jump to that one.
|
||||
let buf = bufnr('option-window')
|
||||
|
@ -1,10 +1,12 @@
|
||||
" Vim syntax file
|
||||
" Language: C#
|
||||
" Maintainer: Anduin Withers <awithers@anduin.com>
|
||||
" Language: C#
|
||||
" Maintainer: Nick Jensen <nickspoon@gmail.com>
|
||||
" Former Maintainer: Anduin Withers <awithers@anduin.com>
|
||||
" Former Maintainer: Johannes Zellner <johannes@zellner.org>
|
||||
" Last Change: Fri Aug 14 13:56:37 PDT 2009
|
||||
" Filenames: *.cs
|
||||
" $Id: cs.vim,v 1.4 2006/05/03 21:20:02 vimboss Exp $
|
||||
" Last Change: 2018-05-02
|
||||
" Filenames: *.cs
|
||||
" License: Vim (see :h license)
|
||||
" Repository: https://github.com/nickspoons/vim-cs
|
||||
"
|
||||
" REFERENCES:
|
||||
" [1] ECMA TC39: C# Language Specification (WD13Oct01.doc)
|
||||
@ -17,11 +19,8 @@ let s:cs_cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
" type
|
||||
syn keyword csType bool byte char decimal double float int long object sbyte short string uint ulong ushort void
|
||||
" storage
|
||||
syn keyword csStorage class delegate enum interface namespace struct
|
||||
" repeat / condition / label
|
||||
syn keyword csType bool byte char decimal double float int long object sbyte short string T uint ulong ushort var void dynamic
|
||||
syn keyword csStorage delegate enum interface namespace struct
|
||||
syn keyword csRepeat break continue do for foreach goto return while
|
||||
syn keyword csConditional else if switch
|
||||
syn keyword csLabel case default
|
||||
@ -29,21 +28,16 @@ syn keyword csLabel case default
|
||||
syn match csOperatorError display +::+
|
||||
" user labels (see [1] 8.6 Statements)
|
||||
syn match csLabel display +^\s*\I\i*\s*:\([^:]\)\@=+
|
||||
" modifier
|
||||
syn keyword csModifier abstract const extern internal override private protected public readonly sealed static virtual volatile
|
||||
" constant
|
||||
syn keyword csConstant false null true
|
||||
" exception
|
||||
syn keyword csException try catch finally throw
|
||||
syn keyword csException try catch finally throw when
|
||||
syn keyword csLinq ascending by descending equals from group in into join let on orderby select where
|
||||
syn keyword csAsync async await
|
||||
|
||||
" TODO:
|
||||
syn keyword csUnspecifiedStatement as base checked event fixed in is lock new operator out params ref sizeof stackalloc this typeof unchecked unsafe using
|
||||
" TODO:
|
||||
syn keyword csUnspecifiedStatement as base checked event fixed get in is lock nameof operator out params ref set sizeof stackalloc this typeof unchecked unsafe using
|
||||
syn keyword csUnsupportedStatement add remove value
|
||||
" TODO:
|
||||
syn keyword csUnspecifiedKeyword explicit implicit
|
||||
|
||||
|
||||
" Contextual Keywords
|
||||
syn match csContextualStatement /\<yield[[:space:]\n]\+\(return\|break\)/me=s+5
|
||||
syn match csContextualStatement /\<partial[[:space:]\n]\+\(class\|struct\|interface\)/me=s+7
|
||||
@ -56,7 +50,7 @@ syn match csContextualStatement /\<where\>[^:]\+:/me=s+5
|
||||
"
|
||||
" TODO: include strings ?
|
||||
"
|
||||
syn keyword csTodo contained TODO FIXME XXX NOTE
|
||||
syn keyword csTodo contained TODO FIXME XXX NOTE HACK
|
||||
syn region csComment start="/\*" end="\*/" contains=@csCommentHook,csTodo,@Spell
|
||||
syn match csComment "//.*$" contains=@csCommentHook,csTodo,@Spell
|
||||
|
||||
@ -89,8 +83,15 @@ syn region csPreCondit
|
||||
\ skip="\\$" end="$" contains=csComment keepend
|
||||
syn region csRegion matchgroup=csPreCondit start="^\s*#\s*region.*$"
|
||||
\ end="^\s*#\s*endregion" transparent fold contains=TOP
|
||||
syn region csSummary start="^\s*/// <summary" end="^\(\s*///\)\@!" transparent fold keepend
|
||||
|
||||
|
||||
syn region csClassType start="\(@\)\@<!class\>"hs=s+6 end="[:\n{]"he=e-1 contains=csClass
|
||||
syn region csNewType start="\(@\)\@<!new\>"hs=s+4 end="[\(\<{\[]"he=e-1 contains=csNew contains=csNewType
|
||||
syn region csIsType start="\v (is|as) "hs=s+4 end="\v[A-Za-z0-9]+" oneline contains=csIsAs
|
||||
syn keyword csNew new contained
|
||||
syn keyword csClass class contained
|
||||
syn keyword csIsAs is as
|
||||
|
||||
" Strings and constants
|
||||
syn match csSpecialError contained "\\."
|
||||
@ -113,7 +114,11 @@ syn match csNumber "\<\d\+\([eE][-+]\=\d\+\)\=[fFdD]\>"
|
||||
|
||||
" The default highlighting.
|
||||
hi def link csType Type
|
||||
hi def link csNewType Type
|
||||
hi def link csClassType Type
|
||||
hi def link csIsType Type
|
||||
hi def link csStorage StorageClass
|
||||
hi def link csClass StorageClass
|
||||
hi def link csRepeat Repeat
|
||||
hi def link csConditional Conditional
|
||||
hi def link csLabel Label
|
||||
@ -123,8 +128,13 @@ hi def link csException Exception
|
||||
hi def link csUnspecifiedStatement Statement
|
||||
hi def link csUnsupportedStatement Statement
|
||||
hi def link csUnspecifiedKeyword Keyword
|
||||
hi def link csNew Statement
|
||||
hi def link csLinq Statement
|
||||
hi def link csIsAs Keyword
|
||||
hi def link csAsync Keyword
|
||||
hi def link csContextualStatement Statement
|
||||
hi def link csOperatorError Error
|
||||
hi def link csInterfaceDeclaration Include
|
||||
|
||||
hi def link csTodo Todo
|
||||
hi def link csComment Comment
|
||||
|
@ -3,11 +3,11 @@
|
||||
" Maintainer: Debian Vim Maintainers
|
||||
" Former Maintainers: Gerfried Fuchs <alfie@ist.org>
|
||||
" Wichert Akkerman <wakkerma@debian.org>
|
||||
" Last Change: 2018 Jan 06
|
||||
" Last Change: 2018 May 03
|
||||
" URL: https://salsa.debian.org/vim-team/vim-debian/blob/master/syntax/debchangelog.vim
|
||||
|
||||
" Standard syntax initialization
|
||||
if exists("b:current_syntax")
|
||||
if exists('b:current_syntax')
|
||||
finish
|
||||
endif
|
||||
|
||||
@ -21,7 +21,7 @@ let s:binNMU='binary-only=yes'
|
||||
syn match debchangelogName contained "^[[:alnum:]][[:alnum:].+-]\+ "
|
||||
exe 'syn match debchangelogFirstKV contained "; \('.s:urgency.'\|'.s:binNMU.'\)"'
|
||||
exe 'syn match debchangelogOtherKV contained ", \('.s:urgency.'\|'.s:binNMU.'\)"'
|
||||
syn match debchangelogTarget contained "\v %(frozen|unstable|sid|%(testing|%(old)=stable)%(-proposed-updates|-security)=|experimental|squeeze-%(backports%(-sloppy)=|volatile|lts|security)|%(wheezy|jessie)%(-backports%(-sloppy)=|-security)=|stretch%(-backports|-security)=|%(devel|precise|trusty|vivid|wily|xenial|yakkety|zesty|artful|bionic)%(-%(security|proposed|updates|backports|commercial|partner))=)+"
|
||||
syn match debchangelogTarget contained "\v %(frozen|unstable|sid|%(testing|%(old)=stable)%(-proposed-updates|-security)=|experimental|squeeze-%(backports%(-sloppy)=|volatile|lts|security)|%(wheezy|jessie)%(-backports%(-sloppy)=|-security)=|stretch%(-backports|-security)=|%(devel|precise|trusty|vivid|wily|xenial|yakkety|zesty|artful|bionic|cosmic)%(-%(security|proposed|updates|backports|commercial|partner))=)+"
|
||||
syn match debchangelogVersion contained "(.\{-})"
|
||||
syn match debchangelogCloses contained "closes:\_s*\(bug\)\=#\=\_s\=\d\+\(,\_s*\(bug\)\=#\=\_s\=\d\+\)*"
|
||||
syn match debchangelogLP contained "\clp:\s\+#\d\+\(,\s*#\d\+\)*"
|
||||
@ -46,6 +46,6 @@ hi def link debchangelogVersion Identifier
|
||||
hi def link debchangelogTarget Identifier
|
||||
hi def link debchangelogEmail Special
|
||||
|
||||
let b:current_syntax = "debchangelog"
|
||||
let b:current_syntax = 'debchangelog'
|
||||
|
||||
" vim: ts=8 sw=2
|
||||
|
@ -3,11 +3,11 @@
|
||||
" Maintainer: Debian Vim Maintainers
|
||||
" Former Maintainers: Gerfried Fuchs <alfie@ist.org>
|
||||
" Wichert Akkerman <wakkerma@debian.org>
|
||||
" Last Change: 2018 Jan 06
|
||||
" Last Change: 2018 Jan 28
|
||||
" URL: https://salsa.debian.org/vim-team/vim-debian/blob/master/syntax/debcontrol.vim
|
||||
|
||||
" Standard syntax initialization
|
||||
if exists("b:current_syntax")
|
||||
if exists('b:current_syntax')
|
||||
finish
|
||||
endif
|
||||
|
||||
@ -135,7 +135,7 @@ hi def link debcontrolR3 Identifier
|
||||
hi def link debcontrolComment Comment
|
||||
hi def link debcontrolElse Special
|
||||
|
||||
let b:current_syntax = "debcontrol"
|
||||
let b:current_syntax = 'debcontrol'
|
||||
|
||||
let &cpo = s:cpo_save
|
||||
unlet s:cpo_save
|
||||
|
33
runtime/syntax/debcopyright.vim
Normal file
33
runtime/syntax/debcopyright.vim
Normal file
@ -0,0 +1,33 @@
|
||||
" Vim syntax file
|
||||
" Language: Debian copyright file
|
||||
" Maintainer: Debian Vim Maintainers
|
||||
" Last Change: 2018 Feb 05
|
||||
" URL: https://salsa.debian.org/vim-team/vim-debian/blob/master/syntax/debcopyright.vim
|
||||
|
||||
" Standard syntax initialization
|
||||
if exists('b:current_syntax')
|
||||
finish
|
||||
endif
|
||||
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
syn case match
|
||||
|
||||
syn match debcopyrightUrl "\vhttps?://[[:alnum:]][-[:alnum:]]*[[:alnum:]]?(\.[[:alnum:]][-[:alnum:]]*[[:alnum:]]?)*\.[[:alpha:]][-[:alnum:]]*[[:alpha:]]?(:\d+)?(/[^[:space:]]*)?$"
|
||||
syn match debcopyrightKey "^\%(Format\|Upstream-Name\|Upstream-Contact\|Disclaimer\|Source\|Comment\|Files\|Copyright\|License\): *"
|
||||
syn match debcopyrightEmail "[_=[:alnum:]\.+-]\+@[[:alnum:]\./\-]\+"
|
||||
syn match debcopyrightEmail "<.\{-}>"
|
||||
syn match debcopyrightComment "^#.*$" contains=@Spell
|
||||
|
||||
hi def link debcopyrightUrl Identifier
|
||||
hi def link debcopyrightKey Keyword
|
||||
hi def link debcopyrightEmail Identifier
|
||||
hi def link debcopyrightComment Comment
|
||||
|
||||
let b:current_syntax = 'debcopyright'
|
||||
|
||||
let &cpo = s:cpo_save
|
||||
unlet s:cpo_save
|
||||
|
||||
" vim: ts=8 sw=2
|
@ -2,11 +2,11 @@
|
||||
" Language: Debian sources.list
|
||||
" Maintainer: Debian Vim Maintainers
|
||||
" Former Maintainer: Matthijs Mohlmann <matthijs@cacholong.nl>
|
||||
" Last Change: 2018 Jan 06
|
||||
" Last Change: 2018 May 03
|
||||
" URL: https://salsa.debian.org/vim-team/vim-debian/blob/master/syntax/debsources.vim
|
||||
|
||||
" Standard syntax initialization
|
||||
if exists("b:current_syntax")
|
||||
if exists('b:current_syntax')
|
||||
finish
|
||||
endif
|
||||
|
||||
@ -25,7 +25,7 @@ let s:supported = [
|
||||
\ 'oldstable', 'stable', 'testing', 'unstable', 'experimental',
|
||||
\ 'wheezy', 'jessie', 'stretch', 'sid', 'rc-buggy',
|
||||
\
|
||||
\ 'trusty', 'xenial', 'zesty', 'artful', 'bionic', 'devel'
|
||||
\ 'trusty', 'xenial', 'artful', 'bionic', 'cosmic', 'devel'
|
||||
\ ]
|
||||
let s:unsupported = [
|
||||
\ 'buzz', 'rex', 'bo', 'hamm', 'slink', 'potato',
|
||||
@ -34,12 +34,12 @@ let s:unsupported = [
|
||||
\ 'warty', 'hoary', 'breezy', 'dapper', 'edgy', 'feisty',
|
||||
\ 'gutsy', 'hardy', 'intrepid', 'jaunty', 'karmic', 'lucid',
|
||||
\ 'maverick', 'natty', 'oneiric', 'precise', 'quantal', 'raring', 'saucy',
|
||||
\ 'utopic', 'vivid', 'wily', 'yakkety'
|
||||
\ 'utopic', 'vivid', 'wily', 'yakkety', 'zesty'
|
||||
\ ]
|
||||
let &cpo=s:cpo
|
||||
|
||||
" Match uri's
|
||||
syn match debsourcesUri +\(https\?://\|ftp://\|[rs]sh://\|debtorrent://\|\(cdrom\|copy\|file\):\)[^' <>"]\++
|
||||
syn match debsourcesUri '\(https\?://\|ftp://\|[rs]sh://\|debtorrent://\|\(cdrom\|copy\|file\):\)[^' <>"]\+'
|
||||
exe 'syn match debsourcesDistrKeyword +\([[:alnum:]_./]*\)\<\('. join(s:supported, '\|'). '\)\>\([-[:alnum:]_./]*\)+'
|
||||
exe 'syn match debsourcesUnsupportedDistrKeyword +\([[:alnum:]_./]*\)\<\('. join(s:unsupported, '\|') .'\)\>\([-[:alnum:]_./]*\)+'
|
||||
|
||||
@ -51,4 +51,4 @@ hi def link debsourcesUnsupportedDistrKeyword WarningMsg
|
||||
hi def link debsourcesComment Comment
|
||||
hi def link debsourcesUri Constant
|
||||
|
||||
let b:current_syntax = "debsources"
|
||||
let b:current_syntax = 'debsources'
|
||||
|
@ -3,7 +3,7 @@
|
||||
" Maintainer: Daniel Kho <daniel.kho@tauhop.com>
|
||||
" Previous Maintainer: Czo <Olivier.Sirol@lip6.fr>
|
||||
" Credits: Stephan Hegel <stephan.hegel@snc.siemens.com.cn>
|
||||
" Last Changed: 2016 Mar 05 by Daniel Kho
|
||||
" Last Changed: 2018 May 06 by Daniel Kho
|
||||
|
||||
" quit when a syntax file was already loaded
|
||||
if exists("b:current_syntax")
|
||||
@ -43,6 +43,8 @@ syn keyword vhdlStatement sequence strong
|
||||
syn keyword vhdlStatement then to transport type
|
||||
syn keyword vhdlStatement unaffected units until use
|
||||
syn keyword vhdlStatement variable
|
||||
" VHDL-2017 interface
|
||||
syn keyword vhdlStatement view
|
||||
syn keyword vhdlStatement vmode vprop vunit
|
||||
syn keyword vhdlStatement wait when while with
|
||||
syn keyword vhdlStatement note warning error failure
|
||||
@ -69,9 +71,7 @@ syn match vhdlType "\<time_vector\>\'\="
|
||||
|
||||
syn match vhdlType "\<character\>\'\="
|
||||
syn match vhdlType "\<string\>\'\="
|
||||
"syn keyword vhdlType severity_level
|
||||
syn keyword vhdlType line
|
||||
syn keyword vhdlType text
|
||||
syn keyword vhdlType line text side width
|
||||
|
||||
" Predefined standard IEEE VHDL types
|
||||
syn match vhdlType "\<std_ulogic\>\'\="
|
||||
@ -124,6 +124,8 @@ syn match vhdlAttribute "\'succ"
|
||||
syn match vhdlAttribute "\'val"
|
||||
syn match vhdlAttribute "\'image"
|
||||
syn match vhdlAttribute "\'value"
|
||||
" VHDL-2017 interface attribute
|
||||
syn match vhdlAttribute "\'converse"
|
||||
|
||||
syn keyword vhdlBoolean true false
|
||||
|
||||
@ -165,6 +167,9 @@ syn match vhdlOperator "=\|\/=\|>\|<\|>="
|
||||
syn match vhdlOperator "<=\|:="
|
||||
syn match vhdlOperator "=>"
|
||||
|
||||
" VHDL-2017 concurrent signal association (spaceship) operator
|
||||
syn match vhdlOperator "<=>"
|
||||
|
||||
" VHDL-2008 conversion, matching equality/non-equality operators
|
||||
syn match vhdlOperator "??\|?=\|?\/=\|?<\|?<=\|?>\|?>="
|
||||
|
||||
@ -183,8 +188,11 @@ syn match vhdlError "\(<\)[&+\-\/\\]\+"
|
||||
syn match vhdlError "[>=&+\-\/\\]\+\(<\)"
|
||||
" Covers most operators
|
||||
" support negative sign after operators. E.g. q<=-b;
|
||||
syn match vhdlError "\(&\|+\|\-\|\*\*\|\/=\|??\|?=\|?\/=\|?<=\|?>=\|>=\|<=\|:=\|=>\)[<>=&+\*\\?:]\+"
|
||||
syn match vhdlError "[<>=&+\-\*\\:]\+\(&\|+\|\*\*\|\/=\|??\|?=\|?\/=\|?<\|?<=\|?>\|?>=\|>=\|<=\|:=\|=>\)"
|
||||
" Supports VHDL-2017 spaceship (concurrent simple signal association).
|
||||
syn match vhdlError "\(<=\)[<=&+\*\\?:]\+"
|
||||
syn match vhdlError "[>=&+\-\*\\:]\+\(=>\)"
|
||||
syn match vhdlError "\(&\|+\|\-\|\*\*\|\/=\|??\|?=\|?\/=\|?<=\|?>=\|>=\|:=\|=>\)[<>=&+\*\\?:]\+"
|
||||
syn match vhdlError "[<>=&+\-\*\\:]\+\(&\|+\|\*\*\|\/=\|??\|?=\|?\/=\|?<\|?<=\|?>\|?>=\|>=\|<=\|:=\)"
|
||||
syn match vhdlError "\(?<\|?>\)[<>&+\*\/\\?:]\+"
|
||||
syn match vhdlError "\(<<\|>>\)[<>&+\*\/\\?:]\+"
|
||||
|
||||
|
@ -1,3 +1,13 @@
|
||||
READ THIS FIRST
|
||||
===============
|
||||
|
||||
ccfilter is a C program to filter the output of a few compilers to a common
|
||||
QuickFix format. It is provided with Vim to make quickfix useful for more
|
||||
compilers.
|
||||
|
||||
ccfilter WILL FAIL with long lines (more than 2047 bytes).
|
||||
|
||||
|
||||
COMPILING AND INSTALLING:
|
||||
=========================
|
||||
|
||||
|
@ -431,7 +431,7 @@ edit(
|
||||
#ifdef FEAT_CONCEAL
|
||||
/* Check if the cursor line needs redrawing before changing State. If
|
||||
* 'concealcursor' is "n" it needs to be redrawn without concealing. */
|
||||
conceal_check_cursur_line();
|
||||
conceal_check_cursor_line();
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_MOUSE
|
||||
@ -6185,6 +6185,8 @@ insertchar(
|
||||
* 'paste' is set)..
|
||||
* Don't do this when there an InsertCharPre autocommand is defined,
|
||||
* because we need to fire the event for every character.
|
||||
* Do the check for InsertCharPre before the call to vpeekc() because the
|
||||
* InsertCharPre autocommand could change the input buffer.
|
||||
*/
|
||||
#ifdef USE_ON_FLY_SCROLL
|
||||
dont_scroll = FALSE; /* allow scrolling here */
|
||||
@ -6194,6 +6196,7 @@ insertchar(
|
||||
#ifdef FEAT_MBYTE
|
||||
&& (!has_mbyte || (*mb_char2len)(c) == 1)
|
||||
#endif
|
||||
&& !has_insertcharpre()
|
||||
&& vpeekc() != NUL
|
||||
&& !(State & REPLACE_FLAG)
|
||||
#ifdef FEAT_CINDENT
|
||||
@ -6202,7 +6205,7 @@ insertchar(
|
||||
#ifdef FEAT_RIGHTLEFT
|
||||
&& !p_ri
|
||||
#endif
|
||||
&& !has_insertcharpre())
|
||||
)
|
||||
{
|
||||
#define INPUT_BUFLEN 100
|
||||
char_u buf[INPUT_BUFLEN + 1];
|
||||
|
23
src/eval.c
23
src/eval.c
@ -6461,6 +6461,29 @@ set_vcount(
|
||||
vimvars[VV_COUNT1].vv_nr = count1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save variables that might be changed as a side effect. Used when executing
|
||||
* a timer callback.
|
||||
*/
|
||||
void
|
||||
save_vimvars(vimvars_save_T *vvsave)
|
||||
{
|
||||
vvsave->vv_prevcount = vimvars[VV_PREVCOUNT].vv_nr;
|
||||
vvsave->vv_count = vimvars[VV_COUNT].vv_nr;
|
||||
vvsave->vv_count1 = vimvars[VV_COUNT1].vv_nr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore variables saved by save_vimvars().
|
||||
*/
|
||||
void
|
||||
restore_vimvars(vimvars_save_T *vvsave)
|
||||
{
|
||||
vimvars[VV_PREVCOUNT].vv_nr = vvsave->vv_prevcount;
|
||||
vimvars[VV_COUNT].vv_nr = vvsave->vv_count;
|
||||
vimvars[VV_COUNT1].vv_nr = vvsave->vv_count1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set string v: variable to a copy of "val".
|
||||
*/
|
||||
|
@ -3313,7 +3313,7 @@ f_feedkeys(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
|
||||
if (!dangerous)
|
||||
++ex_normal_busy;
|
||||
exec_normal(TRUE);
|
||||
exec_normal(TRUE, TRUE);
|
||||
if (!dangerous)
|
||||
--ex_normal_busy;
|
||||
|
||||
|
@ -1206,7 +1206,7 @@ profile_zero(proftime_T *tm)
|
||||
static timer_T *first_timer = NULL;
|
||||
static long last_timer_id = 0;
|
||||
|
||||
static long
|
||||
long
|
||||
proftime_time_left(proftime_T *due, proftime_T *now)
|
||||
{
|
||||
# ifdef WIN3264
|
||||
@ -1336,6 +1336,8 @@ check_due_timer(void)
|
||||
this_due = proftime_time_left(&timer->tr_due, &now);
|
||||
if (this_due <= 1)
|
||||
{
|
||||
/* Save and restore a lot of flags, because the timer fires while
|
||||
* waiting for a character, which might be halfway a command. */
|
||||
int save_timer_busy = timer_busy;
|
||||
int save_vgetc_busy = vgetc_busy;
|
||||
int save_did_emsg = did_emsg;
|
||||
@ -1345,6 +1347,7 @@ check_due_timer(void)
|
||||
int save_did_throw = did_throw;
|
||||
int save_ex_pressedreturn = get_pressedreturn();
|
||||
except_T *save_current_exception = current_exception;
|
||||
vimvars_save_T vvsave;
|
||||
|
||||
/* Create a scope for running the timer callback, ignoring most of
|
||||
* the current scope, such as being inside a try/catch. */
|
||||
@ -1357,6 +1360,7 @@ check_due_timer(void)
|
||||
trylevel = 0;
|
||||
did_throw = FALSE;
|
||||
current_exception = NULL;
|
||||
save_vimvars(&vvsave);
|
||||
|
||||
timer->tr_firing = TRUE;
|
||||
timer_callback(timer);
|
||||
@ -1373,6 +1377,7 @@ check_due_timer(void)
|
||||
trylevel = save_trylevel;
|
||||
did_throw = save_did_throw;
|
||||
current_exception = save_current_exception;
|
||||
restore_vimvars(&vvsave);
|
||||
if (must_redraw != 0)
|
||||
need_update_screen = TRUE;
|
||||
must_redraw = must_redraw > save_must_redraw
|
||||
@ -1424,6 +1429,10 @@ check_due_timer(void)
|
||||
next_due = this_due;
|
||||
}
|
||||
#endif
|
||||
#ifdef FEAT_TERMINAL
|
||||
/* Some terminal windows may need their buffer updated. */
|
||||
next_due = term_check_timers(next_due, &now);
|
||||
#endif
|
||||
|
||||
return current_id != last_timer_id ? 1 : next_due;
|
||||
}
|
||||
|
@ -10323,14 +10323,14 @@ exec_normal_cmd(char_u *cmd, int remap, int silent)
|
||||
{
|
||||
/* Stuff the argument into the typeahead buffer. */
|
||||
ins_typebuf(cmd, remap, 0, TRUE, silent);
|
||||
exec_normal(FALSE);
|
||||
exec_normal(FALSE, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute normal_cmd() until there is no typeahead left.
|
||||
*/
|
||||
void
|
||||
exec_normal(int was_typed)
|
||||
exec_normal(int was_typed, int may_use_terminal_loop UNUSED)
|
||||
{
|
||||
oparg_T oa;
|
||||
|
||||
@ -10341,7 +10341,7 @@ exec_normal(int was_typed)
|
||||
{
|
||||
update_topline_cursor();
|
||||
#ifdef FEAT_TERMINAL
|
||||
if (term_use_loop()
|
||||
if (may_use_terminal_loop && term_use_loop()
|
||||
&& oa.op_type == OP_NOP && oa.regname == NUL
|
||||
&& !VIsual_active)
|
||||
{
|
||||
|
@ -2296,15 +2296,24 @@ gui_mch_get_color(char_u *name)
|
||||
guicolor_T
|
||||
gui_mch_get_rgb_color(int r, int g, int b)
|
||||
{
|
||||
char spec[8]; /* space enough to hold "#RRGGBB" */
|
||||
XColor available;
|
||||
Colormap colormap;
|
||||
|
||||
/* Using XParseColor() is very slow, put rgb in XColor directly.
|
||||
|
||||
char spec[8]; // space enough to hold "#RRGGBB"
|
||||
vim_snprintf(spec, sizeof(spec), "#%.2x%.2x%.2x", r, g, b);
|
||||
colormap = DefaultColormap(gui.dpy, DefaultScreen(gui.dpy));
|
||||
if (XParseColor(gui.dpy, colormap, (char *)spec, &available) != 0
|
||||
&& XAllocColor(gui.dpy, colormap, &available) != 0)
|
||||
return (guicolor_T)available.pixel;
|
||||
*/
|
||||
colormap = DefaultColormap(gui.dpy, DefaultScreen(gui.dpy));
|
||||
vim_memset(&available, 0, sizeof(XColor));
|
||||
available.red = r << 8;
|
||||
available.green = g << 8;
|
||||
available.blue = b << 8;
|
||||
if (XAllocColor(gui.dpy, colormap, &available) != 0)
|
||||
return (guicolor_T)available.pixel;
|
||||
|
||||
return INVALCOLOR;
|
||||
}
|
||||
|
@ -7797,7 +7797,7 @@ n_start_visual_mode(int c)
|
||||
{
|
||||
#ifdef FEAT_CONCEAL
|
||||
/* Check for redraw before changing the state. */
|
||||
conceal_check_cursur_line();
|
||||
conceal_check_cursor_line();
|
||||
#endif
|
||||
|
||||
VIsual_mode = c;
|
||||
@ -7824,7 +7824,7 @@ n_start_visual_mode(int c)
|
||||
#endif
|
||||
#ifdef FEAT_CONCEAL
|
||||
/* Check for redraw after changing the state. */
|
||||
conceal_check_cursur_line();
|
||||
conceal_check_cursor_line();
|
||||
#endif
|
||||
|
||||
if (p_smd && msg_silent == 0)
|
||||
|
@ -6847,7 +6847,6 @@ default_shell(void)
|
||||
mch_access(char *n, int p)
|
||||
{
|
||||
HANDLE hFile;
|
||||
DWORD am;
|
||||
int retval = -1; /* default: fail */
|
||||
#ifdef FEAT_MBYTE
|
||||
WCHAR *wn = NULL;
|
||||
@ -6931,16 +6930,22 @@ mch_access(char *n, int p)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't consider a file read-only if another process has opened it.
|
||||
DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
|
||||
|
||||
/* Trying to open the file for the required access does ACL, read-only
|
||||
* network share, and file attribute checks. */
|
||||
am = ((p & W_OK) ? GENERIC_WRITE : 0)
|
||||
| ((p & R_OK) ? GENERIC_READ : 0);
|
||||
DWORD access_mode = ((p & W_OK) ? GENERIC_WRITE : 0)
|
||||
| ((p & R_OK) ? GENERIC_READ : 0);
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
if (wn != NULL)
|
||||
hFile = CreateFileW(wn, am, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
hFile = CreateFileW(wn, access_mode, share_mode,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
else
|
||||
#endif
|
||||
hFile = CreateFile(n, am, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
hFile = CreateFile(n, access_mode, share_mode,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
goto getout;
|
||||
CloseHandle(hFile);
|
||||
|
@ -67,6 +67,8 @@ list_T *get_vim_var_list(int idx);
|
||||
dict_T *get_vim_var_dict(int idx);
|
||||
void set_vim_var_char(int c);
|
||||
void set_vcount(long count, long count1, int set_prevcount);
|
||||
void save_vimvars(vimvars_save_T *vvsave);
|
||||
void restore_vimvars(vimvars_save_T *vvsave);
|
||||
void set_vim_var_string(int idx, char_u *val, int len);
|
||||
void set_vim_var_list(int idx, list_T *val);
|
||||
void set_vim_var_dict(int idx, dict_T *val);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ex_cmds2.c */
|
||||
int has_watchexpr (void);
|
||||
int has_watchexpr(void);
|
||||
void do_debug(char_u *cmd);
|
||||
void ex_debug(exarg_T *eap);
|
||||
void dbg_check_breakpoint(exarg_T *eap);
|
||||
@ -19,6 +19,7 @@ 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);
|
||||
long proftime_time_left(proftime_T *due, proftime_T *now);
|
||||
timer_T *create_timer(long msec, int repeat);
|
||||
long check_due_timer(void);
|
||||
timer_T *find_timer(long id);
|
||||
|
@ -56,7 +56,7 @@ int save_current_state(save_state_T *sst);
|
||||
void restore_current_state(save_state_T *sst);
|
||||
void ex_normal(exarg_T *eap);
|
||||
void exec_normal_cmd(char_u *cmd, int remap, int silent);
|
||||
void exec_normal(int was_typed);
|
||||
void exec_normal(int was_typed, int may_use_terminal_loop);
|
||||
int find_cmdline_var(char_u *src, int *usedlen);
|
||||
char_u *eval_vars(char_u *src, char_u *srcstart, int *usedlen, linenr_T *lnump, char_u **errormsg, int *escaped);
|
||||
char_u *expand_sfile(char_u *arg);
|
||||
|
@ -9,10 +9,11 @@ void redraw_buf_and_status_later(buf_T *buf, int type);
|
||||
int redraw_asap(int type);
|
||||
void redraw_after_callback(int call_update_screen);
|
||||
void redrawWinline(linenr_T lnum, int invalid);
|
||||
void reset_updating_screen(int may_resize_shell);
|
||||
void update_curbuf(int type);
|
||||
int update_screen(int type_arg);
|
||||
int conceal_cursor_line(win_T *wp);
|
||||
void conceal_check_cursur_line(void);
|
||||
void conceal_check_cursor_line(void);
|
||||
void update_single_line(win_T *wp, linenr_T lnum);
|
||||
void update_debug_sign(buf_T *buf, linenr_T lnum);
|
||||
void updateWindow(win_T *wp);
|
||||
|
@ -9,17 +9,20 @@ void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel);
|
||||
int term_job_running(term_T *term);
|
||||
int term_none_open(term_T *term);
|
||||
int term_try_stop_job(buf_T *buf);
|
||||
int term_check_timers(int next_due_arg, proftime_T *now);
|
||||
int term_in_normal_mode(void);
|
||||
void term_enter_job_mode(void);
|
||||
int send_keys_to_term(term_T *term, int c, int typed);
|
||||
int terminal_is_active(void);
|
||||
cursorentry_T *term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg);
|
||||
void term_win_entered(void);
|
||||
int term_use_loop(void);
|
||||
void term_win_entered(void);
|
||||
int terminal_loop(int blocking);
|
||||
void term_job_ended(job_T *job);
|
||||
void term_channel_closed(channel_T *ch);
|
||||
int term_update_window(win_T *wp);
|
||||
void term_check_channel_closed_recently(void);
|
||||
int term_do_update_window(win_T *wp);
|
||||
void term_update_window(win_T *wp);
|
||||
int term_is_finished(buf_T *buf);
|
||||
int term_show_buffer(buf_T *buf);
|
||||
void term_change_in_curbuf(void);
|
||||
|
1029
src/quickfix.c
1029
src/quickfix.c
File diff suppressed because it is too large
Load Diff
38
src/screen.c
38
src/screen.c
@ -512,6 +512,19 @@ redrawWinline(
|
||||
curwin->w_lines[i].wl_valid = FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
reset_updating_screen(int may_resize_shell UNUSED)
|
||||
{
|
||||
updating_screen = FALSE;
|
||||
#ifdef FEAT_GUI
|
||||
if (may_resize_shell)
|
||||
gui_may_resize_shell();
|
||||
#endif
|
||||
#ifdef FEAT_TERMINAL
|
||||
term_check_channel_closed_recently();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -567,8 +580,12 @@ update_screen(int type_arg)
|
||||
must_redraw = 0;
|
||||
}
|
||||
|
||||
/* Need to update w_lines[]. */
|
||||
if (curwin->w_lines_valid == 0 && type < NOT_VALID)
|
||||
/* May need to update w_lines[]. */
|
||||
if (curwin->w_lines_valid == 0 && type < NOT_VALID
|
||||
#ifdef FEAT_TERMINAL
|
||||
&& !term_do_update_window(curwin)
|
||||
#endif
|
||||
)
|
||||
type = NOT_VALID;
|
||||
|
||||
/* Postpone the redrawing when it's not needed and when being called
|
||||
@ -774,10 +791,7 @@ update_screen(int type_arg)
|
||||
FOR_ALL_WINDOWS(wp)
|
||||
wp->w_buffer->b_mod_set = FALSE;
|
||||
|
||||
updating_screen = FALSE;
|
||||
#ifdef FEAT_GUI
|
||||
gui_may_resize_shell();
|
||||
#endif
|
||||
reset_updating_screen(TRUE);
|
||||
|
||||
/* Clear or redraw the command line. Done last, because scrolling may
|
||||
* mess up the command line. */
|
||||
@ -857,11 +871,9 @@ update_finish(void)
|
||||
end_search_hl();
|
||||
# endif
|
||||
|
||||
updating_screen = FALSE;
|
||||
reset_updating_screen(TRUE);
|
||||
|
||||
# ifdef FEAT_GUI
|
||||
gui_may_resize_shell();
|
||||
|
||||
/* Redraw the cursor and update the scrollbars when all screen updating is
|
||||
* done. */
|
||||
if (gui.in_use)
|
||||
@ -902,7 +914,7 @@ conceal_cursor_line(win_T *wp)
|
||||
* Check if the cursor line needs to be redrawn because of 'concealcursor'.
|
||||
*/
|
||||
void
|
||||
conceal_check_cursur_line(void)
|
||||
conceal_check_cursor_line(void)
|
||||
{
|
||||
if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin))
|
||||
{
|
||||
@ -1172,10 +1184,10 @@ win_update(win_T *wp)
|
||||
}
|
||||
|
||||
#ifdef FEAT_TERMINAL
|
||||
/* If this window contains a terminal, redraw works completely differently.
|
||||
*/
|
||||
if (term_update_window(wp) == OK)
|
||||
// If this window contains a terminal, redraw works completely differently.
|
||||
if (term_do_update_window(wp))
|
||||
{
|
||||
term_update_window(wp);
|
||||
# ifdef FEAT_MENU
|
||||
/* Draw the window toolbar, if there is one. */
|
||||
if (winbar_height(wp) > 0)
|
||||
|
@ -3423,3 +3423,9 @@ typedef struct {
|
||||
int save_opcount;
|
||||
tasave_T tabuf;
|
||||
} save_state_T;
|
||||
|
||||
typedef struct {
|
||||
varnumber_T vv_prevcount;
|
||||
varnumber_T vv_count;
|
||||
varnumber_T vv_count1;
|
||||
} vimvars_save_T;
|
||||
|
287
src/term.c
287
src/term.c
@ -1544,6 +1544,152 @@ static char *(key_names[]) =
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TGETENT
|
||||
static void
|
||||
get_term_entries(int *height, int *width)
|
||||
{
|
||||
static struct {
|
||||
enum SpecialKey dest; /* index in term_strings[] */
|
||||
char *name; /* termcap name for string */
|
||||
} string_names[] =
|
||||
{ {KS_CE, "ce"}, {KS_AL, "al"}, {KS_CAL,"AL"},
|
||||
{KS_DL, "dl"}, {KS_CDL,"DL"}, {KS_CS, "cs"},
|
||||
{KS_CL, "cl"}, {KS_CD, "cd"},
|
||||
{KS_VI, "vi"}, {KS_VE, "ve"}, {KS_MB, "mb"},
|
||||
{KS_ME, "me"}, {KS_MR, "mr"},
|
||||
{KS_MD, "md"}, {KS_SE, "se"}, {KS_SO, "so"},
|
||||
{KS_CZH,"ZH"}, {KS_CZR,"ZR"}, {KS_UE, "ue"},
|
||||
{KS_US, "us"}, {KS_UCE, "Ce"}, {KS_UCS, "Cs"},
|
||||
{KS_STE,"Te"}, {KS_STS,"Ts"},
|
||||
{KS_CM, "cm"}, {KS_SR, "sr"},
|
||||
{KS_CRI,"RI"}, {KS_VB, "vb"}, {KS_KS, "ks"},
|
||||
{KS_KE, "ke"}, {KS_TI, "ti"}, {KS_TE, "te"},
|
||||
{KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
|
||||
{KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_LE, "le"},
|
||||
{KS_ND, "nd"}, {KS_OP, "op"}, {KS_CRV, "RV"},
|
||||
{KS_VS, "vs"}, {KS_CVS, "VS"},
|
||||
{KS_CIS, "IS"}, {KS_CIE, "IE"},
|
||||
{KS_CSC, "SC"}, {KS_CEC, "EC"},
|
||||
{KS_TS, "ts"}, {KS_FS, "fs"},
|
||||
{KS_CWP, "WP"}, {KS_CWS, "WS"},
|
||||
{KS_CSI, "SI"}, {KS_CEI, "EI"},
|
||||
{KS_U7, "u7"}, {KS_RFG, "RF"}, {KS_RBG, "RB"},
|
||||
{KS_8F, "8f"}, {KS_8B, "8b"},
|
||||
{KS_CBE, "BE"}, {KS_CBD, "BD"},
|
||||
{KS_CPS, "PS"}, {KS_CPE, "PE"},
|
||||
{(enum SpecialKey)0, NULL}
|
||||
};
|
||||
int i;
|
||||
char_u *p;
|
||||
static char_u tstrbuf[TBUFSZ];
|
||||
char_u *tp = tstrbuf;
|
||||
|
||||
/*
|
||||
* get output strings
|
||||
*/
|
||||
for (i = 0; string_names[i].name != NULL; ++i)
|
||||
{
|
||||
if (TERM_STR(string_names[i].dest) == NULL
|
||||
|| TERM_STR(string_names[i].dest) == empty_option)
|
||||
TERM_STR(string_names[i].dest) = TGETSTR(string_names[i].name, &tp);
|
||||
}
|
||||
|
||||
/* tgetflag() returns 1 if the flag is present, 0 if not and
|
||||
* possibly -1 if the flag doesn't exist. */
|
||||
if ((T_MS == NULL || T_MS == empty_option) && tgetflag("ms") > 0)
|
||||
T_MS = (char_u *)"y";
|
||||
if ((T_XS == NULL || T_XS == empty_option) && tgetflag("xs") > 0)
|
||||
T_XS = (char_u *)"y";
|
||||
if ((T_XN == NULL || T_XN == empty_option) && tgetflag("xn") > 0)
|
||||
T_XN = (char_u *)"y";
|
||||
if ((T_DB == NULL || T_DB == empty_option) && tgetflag("db") > 0)
|
||||
T_DB = (char_u *)"y";
|
||||
if ((T_DA == NULL || T_DA == empty_option) && tgetflag("da") > 0)
|
||||
T_DA = (char_u *)"y";
|
||||
if ((T_UT == NULL || T_UT == empty_option) && tgetflag("ut") > 0)
|
||||
T_UT = (char_u *)"y";
|
||||
|
||||
/*
|
||||
* get key codes
|
||||
*/
|
||||
for (i = 0; key_names[i] != NULL; ++i)
|
||||
if (find_termcode((char_u *)key_names[i]) == NULL)
|
||||
{
|
||||
p = TGETSTR(key_names[i], &tp);
|
||||
/* if cursor-left == backspace, ignore it (televideo 925) */
|
||||
if (p != NULL
|
||||
&& (*p != Ctrl_H
|
||||
|| key_names[i][0] != 'k'
|
||||
|| key_names[i][1] != 'l'))
|
||||
add_termcode((char_u *)key_names[i], p, FALSE);
|
||||
}
|
||||
|
||||
if (*height == 0)
|
||||
*height = tgetnum("li");
|
||||
if (*width == 0)
|
||||
*width = tgetnum("co");
|
||||
|
||||
/*
|
||||
* Get number of colors (if not done already).
|
||||
*/
|
||||
if (TERM_STR(KS_CCO) == NULL || TERM_STR(KS_CCO) == empty_option)
|
||||
set_color_count(tgetnum("Co"));
|
||||
|
||||
# ifndef hpux
|
||||
BC = (char *)TGETSTR("bc", &tp);
|
||||
UP = (char *)TGETSTR("up", &tp);
|
||||
p = TGETSTR("pc", &tp);
|
||||
if (p)
|
||||
PC = *p;
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
report_term_error(char_u *error_msg, char_u *term)
|
||||
{
|
||||
struct builtin_term *termp;
|
||||
|
||||
mch_errmsg("\r\n");
|
||||
if (error_msg != NULL)
|
||||
{
|
||||
mch_errmsg((char *)error_msg);
|
||||
mch_errmsg("\r\n");
|
||||
}
|
||||
mch_errmsg("'");
|
||||
mch_errmsg((char *)term);
|
||||
mch_errmsg(_("' not known. Available builtin terminals are:"));
|
||||
mch_errmsg("\r\n");
|
||||
for (termp = &(builtin_termcaps[0]); termp->bt_string != NULL; ++termp)
|
||||
{
|
||||
if (termp->bt_entry == (int)KS_NAME)
|
||||
{
|
||||
#ifdef HAVE_TGETENT
|
||||
mch_errmsg(" builtin_");
|
||||
#else
|
||||
mch_errmsg(" ");
|
||||
#endif
|
||||
mch_errmsg(termp->bt_string);
|
||||
mch_errmsg("\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
report_default_term(char_u *term)
|
||||
{
|
||||
mch_errmsg(_("defaulting to '"));
|
||||
mch_errmsg((char *)term);
|
||||
mch_errmsg("'\r\n");
|
||||
if (emsg_silent == 0)
|
||||
{
|
||||
screen_start(); /* don't know where cursor is now */
|
||||
out_flush();
|
||||
if (!is_not_a_term())
|
||||
ui_delay(2000L, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set terminal options for terminal "term".
|
||||
* Return OK if terminal 'term' was found in a termcap, FAIL otherwise.
|
||||
@ -1595,42 +1741,7 @@ set_termname(char_u *term)
|
||||
*/
|
||||
if (try == 1)
|
||||
{
|
||||
char_u *p;
|
||||
static char_u tstrbuf[TBUFSZ];
|
||||
int i;
|
||||
char_u tbuf[TBUFSZ];
|
||||
char_u *tp;
|
||||
static struct {
|
||||
enum SpecialKey dest; /* index in term_strings[] */
|
||||
char *name; /* termcap name for string */
|
||||
} string_names[] =
|
||||
{ {KS_CE, "ce"}, {KS_AL, "al"}, {KS_CAL,"AL"},
|
||||
{KS_DL, "dl"}, {KS_CDL,"DL"}, {KS_CS, "cs"},
|
||||
{KS_CL, "cl"}, {KS_CD, "cd"},
|
||||
{KS_VI, "vi"}, {KS_VE, "ve"}, {KS_MB, "mb"},
|
||||
{KS_ME, "me"}, {KS_MR, "mr"},
|
||||
{KS_MD, "md"}, {KS_SE, "se"}, {KS_SO, "so"},
|
||||
{KS_CZH,"ZH"}, {KS_CZR,"ZR"}, {KS_UE, "ue"},
|
||||
{KS_US, "us"}, {KS_UCE, "Ce"}, {KS_UCS, "Cs"},
|
||||
{KS_STE,"Te"}, {KS_STS,"Ts"},
|
||||
{KS_CM, "cm"}, {KS_SR, "sr"},
|
||||
{KS_CRI,"RI"}, {KS_VB, "vb"}, {KS_KS, "ks"},
|
||||
{KS_KE, "ke"}, {KS_TI, "ti"}, {KS_TE, "te"},
|
||||
{KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
|
||||
{KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_LE, "le"},
|
||||
{KS_ND, "nd"}, {KS_OP, "op"}, {KS_CRV, "RV"},
|
||||
{KS_VS, "vs"}, {KS_CVS, "VS"},
|
||||
{KS_CIS, "IS"}, {KS_CIE, "IE"},
|
||||
{KS_CSC, "SC"}, {KS_CEC, "EC"},
|
||||
{KS_TS, "ts"}, {KS_FS, "fs"},
|
||||
{KS_CWP, "WP"}, {KS_CWS, "WS"},
|
||||
{KS_CSI, "SI"}, {KS_CEI, "EI"},
|
||||
{KS_U7, "u7"}, {KS_RFG, "RF"}, {KS_RBG, "RB"},
|
||||
{KS_8F, "8f"}, {KS_8B, "8b"},
|
||||
{KS_CBE, "BE"}, {KS_CBD, "BD"},
|
||||
{KS_CPS, "PS"}, {KS_CPE, "PE"},
|
||||
{(enum SpecialKey)0, NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
* If the external termcap does not have a matching entry, try the
|
||||
@ -1638,81 +1749,13 @@ set_termname(char_u *term)
|
||||
*/
|
||||
if ((error_msg = tgetent_error(tbuf, term)) == NULL)
|
||||
{
|
||||
tp = tstrbuf;
|
||||
if (!termcap_cleared)
|
||||
{
|
||||
clear_termoptions(); /* clear old options */
|
||||
termcap_cleared = TRUE;
|
||||
}
|
||||
|
||||
/* get output strings */
|
||||
for (i = 0; string_names[i].name != NULL; ++i)
|
||||
{
|
||||
if (TERM_STR(string_names[i].dest) == NULL
|
||||
|| TERM_STR(string_names[i].dest) == empty_option)
|
||||
TERM_STR(string_names[i].dest) =
|
||||
TGETSTR(string_names[i].name, &tp);
|
||||
}
|
||||
|
||||
/* tgetflag() returns 1 if the flag is present, 0 if not and
|
||||
* possibly -1 if the flag doesn't exist. */
|
||||
if ((T_MS == NULL || T_MS == empty_option)
|
||||
&& tgetflag("ms") > 0)
|
||||
T_MS = (char_u *)"y";
|
||||
if ((T_XS == NULL || T_XS == empty_option)
|
||||
&& tgetflag("xs") > 0)
|
||||
T_XS = (char_u *)"y";
|
||||
if ((T_XN == NULL || T_XN == empty_option)
|
||||
&& tgetflag("xn") > 0)
|
||||
T_XN = (char_u *)"y";
|
||||
if ((T_DB == NULL || T_DB == empty_option)
|
||||
&& tgetflag("db") > 0)
|
||||
T_DB = (char_u *)"y";
|
||||
if ((T_DA == NULL || T_DA == empty_option)
|
||||
&& tgetflag("da") > 0)
|
||||
T_DA = (char_u *)"y";
|
||||
if ((T_UT == NULL || T_UT == empty_option)
|
||||
&& tgetflag("ut") > 0)
|
||||
T_UT = (char_u *)"y";
|
||||
|
||||
|
||||
/*
|
||||
* get key codes
|
||||
*/
|
||||
for (i = 0; key_names[i] != NULL; ++i)
|
||||
{
|
||||
if (find_termcode((char_u *)key_names[i]) == NULL)
|
||||
{
|
||||
p = TGETSTR(key_names[i], &tp);
|
||||
/* if cursor-left == backspace, ignore it (televideo
|
||||
* 925) */
|
||||
if (p != NULL
|
||||
&& (*p != Ctrl_H
|
||||
|| key_names[i][0] != 'k'
|
||||
|| key_names[i][1] != 'l'))
|
||||
add_termcode((char_u *)key_names[i], p, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (height == 0)
|
||||
height = tgetnum("li");
|
||||
if (width == 0)
|
||||
width = tgetnum("co");
|
||||
|
||||
/*
|
||||
* Get number of colors (if not done already).
|
||||
*/
|
||||
if (TERM_STR(KS_CCO) == NULL
|
||||
|| TERM_STR(KS_CCO) == empty_option)
|
||||
set_color_count(tgetnum("Co"));
|
||||
|
||||
# ifndef hpux
|
||||
BC = (char *)TGETSTR("bc", &tp);
|
||||
UP = (char *)TGETSTR("up", &tp);
|
||||
p = TGETSTR("pc", &tp);
|
||||
if (p)
|
||||
PC = *p;
|
||||
# endif /* hpux */
|
||||
get_term_entries(&height, &width);
|
||||
}
|
||||
}
|
||||
else /* try == 0 || try == 2 */
|
||||
@ -1748,31 +1791,8 @@ set_termname(char_u *term)
|
||||
if (termcap_cleared) /* found in external termcap */
|
||||
break;
|
||||
#endif
|
||||
report_term_error(error_msg, term);
|
||||
|
||||
mch_errmsg("\r\n");
|
||||
if (error_msg != NULL)
|
||||
{
|
||||
mch_errmsg((char *)error_msg);
|
||||
mch_errmsg("\r\n");
|
||||
}
|
||||
mch_errmsg("'");
|
||||
mch_errmsg((char *)term);
|
||||
mch_errmsg(_("' not known. Available builtin terminals are:"));
|
||||
mch_errmsg("\r\n");
|
||||
for (termp = &(builtin_termcaps[0]); termp->bt_string != NULL;
|
||||
++termp)
|
||||
{
|
||||
if (termp->bt_entry == (int)KS_NAME)
|
||||
{
|
||||
#ifdef HAVE_TGETENT
|
||||
mch_errmsg(" builtin_");
|
||||
#else
|
||||
mch_errmsg(" ");
|
||||
#endif
|
||||
mch_errmsg(termp->bt_string);
|
||||
mch_errmsg("\r\n");
|
||||
}
|
||||
}
|
||||
/* when user typed :set term=xxx, quit here */
|
||||
if (starting != NO_SCREEN)
|
||||
{
|
||||
@ -1781,16 +1801,7 @@ set_termname(char_u *term)
|
||||
return FAIL;
|
||||
}
|
||||
term = DEFAULT_TERM;
|
||||
mch_errmsg(_("defaulting to '"));
|
||||
mch_errmsg((char *)term);
|
||||
mch_errmsg("'\r\n");
|
||||
if (emsg_silent == 0)
|
||||
{
|
||||
screen_start(); /* don't know where cursor is now */
|
||||
out_flush();
|
||||
if (!is_not_a_term())
|
||||
ui_delay(2000L, TRUE);
|
||||
}
|
||||
report_default_term(term);
|
||||
set_string_option_direct((char_u *)"term", -1, term,
|
||||
OPT_FREE, 0);
|
||||
display_errors();
|
||||
|
421
src/terminal.c
421
src/terminal.c
@ -38,19 +38,18 @@
|
||||
* in tl_scrollback are no longer used.
|
||||
*
|
||||
* TODO:
|
||||
* - Win32: Make terminal used for :!cmd in the GUI work better. Allow for
|
||||
* redirection. Probably in call to channel_set_pipes().
|
||||
* - Win32: Redirecting output does not work, Test_terminal_redir_file()
|
||||
* - Win32: Termdebug doesn't work, because gdb does not support mi2. This
|
||||
* plugin: https://github.com/cpiger/NeoDebug runs gdb as a job, redirecting
|
||||
* input and output. Command I/O is in gdb window.
|
||||
* - Win32: Redirecting input does not work, half of Test_terminal_redir_file()
|
||||
* is disabled.
|
||||
* - handle_moverect() scrolls one line at a time. Postpone scrolling, count
|
||||
* the number of lines, until a redraw happens. Then if scrolling many lines
|
||||
* a redraw is faster.
|
||||
* - Copy text in the vterm to the Vim buffer once in a while, so that
|
||||
* completion works.
|
||||
* - Win32: Redirecting output works but includes escape sequences.
|
||||
* - Win32: Make terminal used for :!cmd in the GUI work better. Allow for
|
||||
* redirection.
|
||||
* - When the job only outputs lines, we could handle resizing the terminal
|
||||
* better: store lines separated by line breaks, instead of screen lines,
|
||||
* then when the window is resized redraw those lines.
|
||||
* - Redrawing is slow with Athena and Motif. Also other GUI? (Ramel Eshed)
|
||||
* - Redrawing is slow with Athena and Motif. (Ramel Eshed)
|
||||
* - For the GUI fill termios with default values, perhaps like pangoterm:
|
||||
* http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134
|
||||
* - When 'encoding' is not utf-8, or the job is using another encoding, setup
|
||||
@ -102,13 +101,10 @@ struct terminal_S {
|
||||
/* Set when setting the size of a vterm, reset after redrawing. */
|
||||
int tl_vterm_size_changed;
|
||||
|
||||
/* used when tl_job is NULL and only a pty was created */
|
||||
int tl_tty_fd;
|
||||
char_u *tl_tty_in;
|
||||
char_u *tl_tty_out;
|
||||
|
||||
int tl_normal_mode; /* TRUE: Terminal-Normal mode */
|
||||
int tl_channel_closed;
|
||||
int tl_channel_recently_closed; // still need to handle tl_finish
|
||||
|
||||
int tl_finish;
|
||||
#define TL_FINISH_UNSET NUL
|
||||
#define TL_FINISH_CLOSE 'c' /* ++close or :terminal without argument */
|
||||
@ -120,6 +116,8 @@ struct terminal_S {
|
||||
#ifdef WIN3264
|
||||
void *tl_winpty_config;
|
||||
void *tl_winpty;
|
||||
|
||||
FILE *tl_out_fd;
|
||||
#endif
|
||||
#if defined(FEAT_SESSION)
|
||||
char_u *tl_command;
|
||||
@ -136,6 +134,12 @@ struct terminal_S {
|
||||
/* Range of screen rows to update. Zero based. */
|
||||
int tl_dirty_row_start; /* MAX_ROW if nothing dirty */
|
||||
int tl_dirty_row_end; /* row below last one to update */
|
||||
int tl_dirty_snapshot; /* text updated after making snapshot */
|
||||
#ifdef FEAT_TIMERS
|
||||
int tl_timer_set;
|
||||
proftime_T tl_timer_due;
|
||||
#endif
|
||||
int tl_postponed_scroll; /* to be scrolled up */
|
||||
|
||||
garray_T tl_scrollback;
|
||||
int tl_scrollback_scrolled;
|
||||
@ -170,7 +174,7 @@ static term_T *in_terminal_loop = NULL;
|
||||
/*
|
||||
* Functions with separate implementation for MS-Windows and Unix-like systems.
|
||||
*/
|
||||
static int term_and_job_init(term_T *term, typval_T *argvar, char **argv, jobopt_T *opt);
|
||||
static int term_and_job_init(term_T *term, typval_T *argvar, char **argv, jobopt_T *opt, jobopt_T *orig_opt);
|
||||
static int create_pty_only(term_T *term, jobopt_T *opt);
|
||||
static void term_report_winsize(term_T *term, int rows, int cols);
|
||||
static void term_free_vterm(term_T *term);
|
||||
@ -284,7 +288,11 @@ init_job_options(jobopt_T *opt)
|
||||
static void
|
||||
setup_job_options(jobopt_T *opt, int rows, int cols)
|
||||
{
|
||||
#ifndef WIN3264
|
||||
/* Win32: Redirecting the job output won't work, thus always connect stdout
|
||||
* here. */
|
||||
if (!(opt->jo_set & JO_OUT_IO))
|
||||
#endif
|
||||
{
|
||||
/* Connect stdout to the terminal. */
|
||||
opt->jo_io[PART_OUT] = JIO_BUFFER;
|
||||
@ -293,7 +301,11 @@ setup_job_options(jobopt_T *opt, int rows, int cols)
|
||||
opt->jo_set |= JO_OUT_IO + JO_OUT_BUF + JO_OUT_MODIFIABLE;
|
||||
}
|
||||
|
||||
#ifndef WIN3264
|
||||
/* Win32: Redirecting the job output won't work, thus always connect stderr
|
||||
* here. */
|
||||
if (!(opt->jo_set & JO_ERR_IO))
|
||||
#endif
|
||||
{
|
||||
/* Connect stderr to the terminal. */
|
||||
opt->jo_io[PART_ERR] = JIO_BUFFER;
|
||||
@ -351,6 +363,7 @@ term_start(
|
||||
int res;
|
||||
buf_T *newbuf;
|
||||
int vertical = opt->jo_vertical || (cmdmod.split & WSP_VERT);
|
||||
jobopt_T orig_opt; // only partly filled
|
||||
|
||||
if (check_restricted() || check_secure())
|
||||
return NULL;
|
||||
@ -518,6 +531,9 @@ term_start(
|
||||
curbuf->b_p_ma = FALSE;
|
||||
|
||||
set_term_and_win_size(term);
|
||||
#ifdef WIN3264
|
||||
mch_memmove(orig_opt.jo_io, opt->jo_io, sizeof(orig_opt.jo_io));
|
||||
#endif
|
||||
setup_job_options(opt, term->tl_rows, term->tl_cols);
|
||||
|
||||
if (flags & TERM_START_NOJOB)
|
||||
@ -583,7 +599,7 @@ term_start(
|
||||
&& STRCMP(argvar->vval.v_string, "NONE") == 0)
|
||||
res = create_pty_only(term, opt);
|
||||
else
|
||||
res = term_and_job_init(term, argvar, argv, opt);
|
||||
res = term_and_job_init(term, argvar, argv, opt, &orig_opt);
|
||||
|
||||
newbuf = curbuf;
|
||||
if (res == OK)
|
||||
@ -824,6 +840,10 @@ free_terminal(buf_T *buf)
|
||||
vim_free(term->tl_status_text);
|
||||
vim_free(term->tl_opencmd);
|
||||
vim_free(term->tl_eof_chars);
|
||||
#ifdef WIN3264
|
||||
if (term->tl_out_fd != NULL)
|
||||
fclose(term->tl_out_fd);
|
||||
#endif
|
||||
if (desired_cursor_color == term->tl_cursor_color)
|
||||
desired_cursor_color = (char_u *)"";
|
||||
vim_free(term->tl_cursor_color);
|
||||
@ -919,6 +939,17 @@ write_to_term(buf_T *buffer, char_u *msg, channel_T *channel)
|
||||
size_t len = STRLEN(msg);
|
||||
term_T *term = buffer->b_term;
|
||||
|
||||
#ifdef WIN3264
|
||||
/* Win32: Cannot redirect output of the job, intercept it here and write to
|
||||
* the file. */
|
||||
if (term->tl_out_fd != NULL)
|
||||
{
|
||||
ch_log(channel, "Writing %d bytes to output file", (int)len);
|
||||
fwrite(msg, len, 1, term->tl_out_fd);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (term->tl_vterm == NULL)
|
||||
{
|
||||
ch_log(channel, "NOT writing %d bytes to terminal", (int)len);
|
||||
@ -945,7 +976,10 @@ write_to_term(buf_T *buffer, char_u *msg, channel_T *channel)
|
||||
if (buffer == curbuf)
|
||||
{
|
||||
update_screen(0);
|
||||
update_cursor(term, TRUE);
|
||||
/* update_screen() can be slow, check the terminal wasn't closed
|
||||
* already */
|
||||
if (buffer == curbuf && curbuf->b_term != NULL)
|
||||
update_cursor(curbuf->b_term, TRUE);
|
||||
}
|
||||
else
|
||||
redraw_after_callback(TRUE);
|
||||
@ -1417,6 +1451,32 @@ add_empty_scrollback(term_T *term, cellattr_T *fill_attr, int lnum)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the terminal contents from the scrollback and the buffer.
|
||||
* Used before adding a new scrollback line or updating the buffer for lines
|
||||
* displayed in the terminal.
|
||||
*/
|
||||
static void
|
||||
cleanup_scrollback(term_T *term)
|
||||
{
|
||||
sb_line_T *line;
|
||||
garray_T *gap;
|
||||
|
||||
curbuf = term->tl_buffer;
|
||||
gap = &term->tl_scrollback;
|
||||
while (curbuf->b_ml.ml_line_count > term->tl_scrollback_scrolled
|
||||
&& gap->ga_len > 0)
|
||||
{
|
||||
ml_delete(curbuf->b_ml.ml_line_count, FALSE);
|
||||
line = (sb_line_T *)gap->ga_data + gap->ga_len - 1;
|
||||
vim_free(line->sb_cells);
|
||||
--gap->ga_len;
|
||||
}
|
||||
curbuf = curwin->w_buffer;
|
||||
if (curbuf == term->tl_buffer)
|
||||
check_cursor();
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the current lines of the terminal to scrollback and to the buffer.
|
||||
* Called after the job has ended and when switching to Terminal-Normal mode.
|
||||
@ -1435,9 +1495,22 @@ move_terminal_to_buffer(term_T *term)
|
||||
|
||||
if (term->tl_vterm == NULL)
|
||||
return;
|
||||
|
||||
/* Nothing to do if the buffer already has the lines and nothing was
|
||||
* changed. */
|
||||
if (!term->tl_dirty_snapshot && term->tl_buffer->b_ml.ml_line_count
|
||||
> term->tl_scrollback_scrolled)
|
||||
return;
|
||||
|
||||
ch_log(term->tl_job == NULL ? NULL : term->tl_job->jv_channel,
|
||||
"Adding terminal window snapshot to buffer");
|
||||
|
||||
/* First remove the lines that were appended before, they might be
|
||||
* outdated. */
|
||||
cleanup_scrollback(term);
|
||||
|
||||
screen = vterm_obtain_screen(term->tl_vterm);
|
||||
fill_attr = new_fill_attr = term->tl_default_color;
|
||||
|
||||
for (pos.row = 0; pos.row < term->tl_rows; ++pos.row)
|
||||
{
|
||||
len = 0;
|
||||
@ -1524,6 +1597,11 @@ move_terminal_to_buffer(term_T *term)
|
||||
}
|
||||
}
|
||||
|
||||
term->tl_dirty_snapshot = FALSE;
|
||||
#ifdef FEAT_TIMERS
|
||||
term->tl_timer_set = FALSE;
|
||||
#endif
|
||||
|
||||
/* Obtain the current background color. */
|
||||
vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
|
||||
&term->tl_default_color.fg, &term->tl_default_color.bg);
|
||||
@ -1547,6 +1625,38 @@ move_terminal_to_buffer(term_T *term)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(FEAT_TIMERS) || defined(PROTO)
|
||||
/*
|
||||
* Check if any terminal timer expired. If so, copy text from the terminal to
|
||||
* the buffer.
|
||||
* Return the time until the next timer will expire.
|
||||
*/
|
||||
int
|
||||
term_check_timers(int next_due_arg, proftime_T *now)
|
||||
{
|
||||
term_T *term;
|
||||
int next_due = next_due_arg;
|
||||
|
||||
for (term = first_term; term != NULL; term = term->tl_next)
|
||||
{
|
||||
if (term->tl_timer_set && !term->tl_normal_mode)
|
||||
{
|
||||
long this_due = proftime_time_left(&term->tl_timer_due, now);
|
||||
|
||||
if (this_due <= 1)
|
||||
{
|
||||
term->tl_timer_set = FALSE;
|
||||
move_terminal_to_buffer(term);
|
||||
}
|
||||
else if (next_due == -1 || next_due > this_due)
|
||||
next_due = this_due;
|
||||
}
|
||||
}
|
||||
|
||||
return next_due;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
set_terminal_mode(term_T *term, int normal_mode)
|
||||
{
|
||||
@ -1614,20 +1724,6 @@ term_in_normal_mode(void)
|
||||
term_enter_job_mode()
|
||||
{
|
||||
term_T *term = curbuf->b_term;
|
||||
sb_line_T *line;
|
||||
garray_T *gap;
|
||||
|
||||
/* Remove the terminal contents from the scrollback and the buffer. */
|
||||
gap = &term->tl_scrollback;
|
||||
while (curbuf->b_ml.ml_line_count > term->tl_scrollback_scrolled
|
||||
&& gap->ga_len > 0)
|
||||
{
|
||||
ml_delete(curbuf->b_ml.ml_line_count, FALSE);
|
||||
line = (sb_line_T *)gap->ga_data + gap->ga_len - 1;
|
||||
vim_free(line->sb_cells);
|
||||
--gap->ga_len;
|
||||
}
|
||||
check_cursor();
|
||||
|
||||
set_terminal_mode(term, FALSE);
|
||||
|
||||
@ -2015,6 +2111,10 @@ terminal_loop(int blocking)
|
||||
while (must_redraw != 0)
|
||||
if (update_screen(0) == FAIL)
|
||||
break;
|
||||
if (!term_use_loop_check(TRUE))
|
||||
/* job finished while redrawing */
|
||||
break;
|
||||
|
||||
update_cursor(curbuf->b_term, FALSE);
|
||||
restore_cursor = TRUE;
|
||||
|
||||
@ -2150,6 +2250,12 @@ theend:
|
||||
in_terminal_loop = NULL;
|
||||
if (restore_cursor)
|
||||
prepare_restore_cursor_props();
|
||||
|
||||
/* Move a snapshot of the screen contents to the buffer, so that completion
|
||||
* works in other buffers. */
|
||||
if (curbuf->b_term != NULL)
|
||||
move_terminal_to_buffer(curbuf->b_term);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2366,6 +2472,20 @@ cell2attr(VTermScreenCellAttrs cellattrs, VTermColor cellfg, VTermColor cellbg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
set_dirty_snapshot(term_T *term)
|
||||
{
|
||||
term->tl_dirty_snapshot = TRUE;
|
||||
#ifdef FEAT_TIMERS
|
||||
if (!term->tl_normal_mode)
|
||||
{
|
||||
/* Update the snapshot after 100 msec of not getting updates. */
|
||||
profile_setlimit(100L, &term->tl_timer_due);
|
||||
term->tl_timer_set = TRUE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
handle_damage(VTermRect rect, void *user)
|
||||
{
|
||||
@ -2373,44 +2493,57 @@ handle_damage(VTermRect rect, void *user)
|
||||
|
||||
term->tl_dirty_row_start = MIN(term->tl_dirty_row_start, rect.start_row);
|
||||
term->tl_dirty_row_end = MAX(term->tl_dirty_row_end, rect.end_row);
|
||||
redraw_buf_later(term->tl_buffer, NOT_VALID);
|
||||
set_dirty_snapshot(term);
|
||||
redraw_buf_later(term->tl_buffer, SOME_VALID);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
term_scroll_up(term_T *term, int start_row, int count)
|
||||
{
|
||||
win_T *wp;
|
||||
VTermColor fg, bg;
|
||||
VTermScreenCellAttrs attr;
|
||||
int clear_attr;
|
||||
|
||||
/* Set the color to clear lines with. */
|
||||
vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
|
||||
&fg, &bg);
|
||||
vim_memset(&attr, 0, sizeof(attr));
|
||||
clear_attr = cell2attr(attr, fg, bg);
|
||||
|
||||
FOR_ALL_WINDOWS(wp)
|
||||
{
|
||||
if (wp->w_buffer == term->tl_buffer)
|
||||
win_del_lines(wp, start_row, count, FALSE, FALSE, clear_attr);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
handle_moverect(VTermRect dest, VTermRect src, void *user)
|
||||
{
|
||||
term_T *term = (term_T *)user;
|
||||
int count = src.start_row - dest.start_row;
|
||||
|
||||
/* Scrolling up is done much more efficiently by deleting lines instead of
|
||||
* redrawing the text. */
|
||||
* redrawing the text. But avoid doing this multiple times, postpone until
|
||||
* the redraw happens. */
|
||||
if (dest.start_col == src.start_col
|
||||
&& dest.end_col == src.end_col
|
||||
&& dest.start_row < src.start_row)
|
||||
{
|
||||
win_T *wp;
|
||||
VTermColor fg, bg;
|
||||
VTermScreenCellAttrs attr;
|
||||
int clear_attr;
|
||||
|
||||
/* Set the color to clear lines with. */
|
||||
vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
|
||||
&fg, &bg);
|
||||
vim_memset(&attr, 0, sizeof(attr));
|
||||
clear_attr = cell2attr(attr, fg, bg);
|
||||
|
||||
FOR_ALL_WINDOWS(wp)
|
||||
{
|
||||
if (wp->w_buffer == term->tl_buffer)
|
||||
win_del_lines(wp, dest.start_row,
|
||||
src.start_row - dest.start_row, FALSE, FALSE,
|
||||
clear_attr);
|
||||
}
|
||||
if (dest.start_row == 0)
|
||||
term->tl_postponed_scroll += count;
|
||||
else
|
||||
term_scroll_up(term, dest.start_row, count);
|
||||
}
|
||||
|
||||
term->tl_dirty_row_start = MIN(term->tl_dirty_row_start, dest.start_row);
|
||||
term->tl_dirty_row_end = MIN(term->tl_dirty_row_end, dest.end_row);
|
||||
set_dirty_snapshot(term);
|
||||
|
||||
/* Note sure if the scrolling will work correctly, let's do a complete
|
||||
* redraw later. */
|
||||
redraw_buf_later(term->tl_buffer, NOT_VALID);
|
||||
return 1;
|
||||
}
|
||||
@ -2559,6 +2692,10 @@ handle_pushline(int cols, const VTermScreenCell *cells, void *user)
|
||||
{
|
||||
term_T *term = (term_T *)user;
|
||||
|
||||
/* First remove the lines that were appended before, the pushed line goes
|
||||
* above it. */
|
||||
cleanup_scrollback(term);
|
||||
|
||||
/* If the number of lines that are stored goes over 'termscrollback' then
|
||||
* delete the first 10%. */
|
||||
if (term->tl_scrollback.ga_len >= term->tl_buffer->b_p_twsl)
|
||||
@ -2647,6 +2784,53 @@ static VTermScreenCallbacks screen_callbacks = {
|
||||
NULL /* sb_popline */
|
||||
};
|
||||
|
||||
/*
|
||||
* Do the work after the channel of a terminal was closed.
|
||||
* Must be called only when updating_screen is FALSE.
|
||||
* Returns TRUE when a buffer was closed (list of terminals may have changed).
|
||||
*/
|
||||
static int
|
||||
term_after_channel_closed(term_T *term)
|
||||
{
|
||||
/* Unless in Terminal-Normal mode: clear the vterm. */
|
||||
if (!term->tl_normal_mode)
|
||||
{
|
||||
int fnum = term->tl_buffer->b_fnum;
|
||||
|
||||
cleanup_vterm(term);
|
||||
|
||||
if (term->tl_finish == TL_FINISH_CLOSE)
|
||||
{
|
||||
aco_save_T aco;
|
||||
|
||||
/* ++close or term_finish == "close" */
|
||||
ch_log(NULL, "terminal job finished, closing window");
|
||||
aucmd_prepbuf(&aco, term->tl_buffer);
|
||||
do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE);
|
||||
aucmd_restbuf(&aco);
|
||||
return TRUE;
|
||||
}
|
||||
if (term->tl_finish == TL_FINISH_OPEN
|
||||
&& term->tl_buffer->b_nwindows == 0)
|
||||
{
|
||||
char buf[50];
|
||||
|
||||
/* TODO: use term_opencmd */
|
||||
ch_log(NULL, "terminal job finished, opening window");
|
||||
vim_snprintf(buf, sizeof(buf),
|
||||
term->tl_opencmd == NULL
|
||||
? "botright sbuf %d"
|
||||
: (char *)term->tl_opencmd, fnum);
|
||||
do_cmdline_cmd((char_u *)buf);
|
||||
}
|
||||
else
|
||||
ch_log(NULL, "terminal job finished");
|
||||
}
|
||||
|
||||
redraw_buf_and_status_later(term->tl_buffer, NOT_VALID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when a channel has been closed.
|
||||
* If this was a channel for a terminal window then finish it up.
|
||||
@ -2655,9 +2839,12 @@ static VTermScreenCallbacks screen_callbacks = {
|
||||
term_channel_closed(channel_T *ch)
|
||||
{
|
||||
term_T *term;
|
||||
term_T *next_term;
|
||||
int did_one = FALSE;
|
||||
|
||||
for (term = first_term; term != NULL; term = term->tl_next)
|
||||
for (term = first_term; term != NULL; term = next_term)
|
||||
{
|
||||
next_term = term->tl_next;
|
||||
if (term->tl_job == ch->ch_job)
|
||||
{
|
||||
term->tl_channel_closed = TRUE;
|
||||
@ -2665,44 +2852,27 @@ term_channel_closed(channel_T *ch)
|
||||
|
||||
VIM_CLEAR(term->tl_title);
|
||||
VIM_CLEAR(term->tl_status_text);
|
||||
|
||||
/* Unless in Terminal-Normal mode: clear the vterm. */
|
||||
if (!term->tl_normal_mode)
|
||||
#ifdef WIN3264
|
||||
if (term->tl_out_fd != NULL)
|
||||
{
|
||||
int fnum = term->tl_buffer->b_fnum;
|
||||
fclose(term->tl_out_fd);
|
||||
term->tl_out_fd = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
cleanup_vterm(term);
|
||||
|
||||
if (term->tl_finish == TL_FINISH_CLOSE)
|
||||
{
|
||||
aco_save_T aco;
|
||||
|
||||
/* ++close or term_finish == "close" */
|
||||
ch_log(NULL, "terminal job finished, closing window");
|
||||
aucmd_prepbuf(&aco, term->tl_buffer);
|
||||
do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE);
|
||||
aucmd_restbuf(&aco);
|
||||
break;
|
||||
}
|
||||
if (term->tl_finish == TL_FINISH_OPEN
|
||||
&& term->tl_buffer->b_nwindows == 0)
|
||||
{
|
||||
char buf[50];
|
||||
|
||||
/* TODO: use term_opencmd */
|
||||
ch_log(NULL, "terminal job finished, opening window");
|
||||
vim_snprintf(buf, sizeof(buf),
|
||||
term->tl_opencmd == NULL
|
||||
? "botright sbuf %d"
|
||||
: (char *)term->tl_opencmd, fnum);
|
||||
do_cmdline_cmd((char_u *)buf);
|
||||
}
|
||||
else
|
||||
ch_log(NULL, "terminal job finished");
|
||||
if (updating_screen)
|
||||
{
|
||||
/* Cannot open or close windows now. Can happen when
|
||||
* 'lazyredraw' is set. */
|
||||
term->tl_channel_recently_closed = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
redraw_buf_and_status_later(term->tl_buffer, NOT_VALID);
|
||||
if (term_after_channel_closed(term))
|
||||
next_term = first_term;
|
||||
}
|
||||
}
|
||||
|
||||
if (did_one)
|
||||
{
|
||||
redraw_statuslines();
|
||||
@ -2721,6 +2891,29 @@ term_channel_closed(channel_T *ch)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* To be called after resetting updating_screen: handle any terminal where the
|
||||
* channel was closed.
|
||||
*/
|
||||
void
|
||||
term_check_channel_closed_recently()
|
||||
{
|
||||
term_T *term;
|
||||
term_T *next_term;
|
||||
|
||||
for (term = first_term; term != NULL; term = next_term)
|
||||
{
|
||||
next_term = term->tl_next;
|
||||
if (term->tl_channel_recently_closed)
|
||||
{
|
||||
term->tl_channel_recently_closed = FALSE;
|
||||
if (term_after_channel_closed(term))
|
||||
// start over, the list may have changed
|
||||
next_term = first_term;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill one screen line from a line of the terminal.
|
||||
* Advances "pos" to past the last column.
|
||||
@ -2857,11 +3050,22 @@ update_system_term(term_T *term)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Called to update a window that contains an active terminal.
|
||||
* Returns FAIL when there is no terminal running in this window or in
|
||||
* Return TRUE if window "wp" is to be redrawn with term_update_window().
|
||||
* Returns FALSE when there is no terminal running in this window or it is in
|
||||
* Terminal-Normal mode.
|
||||
*/
|
||||
int
|
||||
term_do_update_window(win_T *wp)
|
||||
{
|
||||
term_T *term = wp->w_buffer->b_term;
|
||||
|
||||
return term != NULL && term->tl_vterm != NULL && !term->tl_normal_mode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to update a window that contains an active terminal.
|
||||
*/
|
||||
void
|
||||
term_update_window(win_T *wp)
|
||||
{
|
||||
term_T *term = wp->w_buffer->b_term;
|
||||
@ -2874,17 +3078,23 @@ term_update_window(win_T *wp)
|
||||
int minsize;
|
||||
win_T *twp;
|
||||
|
||||
if (term == NULL || term->tl_vterm == NULL || term->tl_normal_mode)
|
||||
return FAIL;
|
||||
|
||||
vterm = term->tl_vterm;
|
||||
screen = vterm_obtain_screen(vterm);
|
||||
state = vterm_obtain_state(vterm);
|
||||
|
||||
if (wp->w_redr_type >= SOME_VALID)
|
||||
/* We use NOT_VALID on a resize or scroll, redraw everything then. With
|
||||
* SOME_VALID only redraw what was marked dirty. */
|
||||
if (wp->w_redr_type > SOME_VALID)
|
||||
{
|
||||
term->tl_dirty_row_start = 0;
|
||||
term->tl_dirty_row_end = MAX_ROW;
|
||||
|
||||
if (term->tl_postponed_scroll > 0
|
||||
&& term->tl_postponed_scroll < term->tl_rows / 3)
|
||||
/* Scrolling is usually faster than redrawing, when there are only
|
||||
* a few lines to scroll. */
|
||||
term_scroll_up(term, 0, term->tl_postponed_scroll);
|
||||
term->tl_postponed_scroll = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2943,8 +3153,6 @@ term_update_window(win_T *wp)
|
||||
}
|
||||
term->tl_dirty_row_start = MAX_ROW;
|
||||
term->tl_dirty_row_end = 0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4701,7 +4909,7 @@ f_term_gettitle(typval_T *argvars, typval_T *rettv)
|
||||
f_term_gettty(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
buf_T *buf = term_get_buf(argvars, "term_gettty()");
|
||||
char_u *p;
|
||||
char_u *p = NULL;
|
||||
int num = 0;
|
||||
|
||||
rettv->v_type = VAR_STRING;
|
||||
@ -4715,14 +4923,10 @@ f_term_gettty(typval_T *argvars, typval_T *rettv)
|
||||
case 0:
|
||||
if (buf->b_term->tl_job != NULL)
|
||||
p = buf->b_term->tl_job->jv_tty_out;
|
||||
else
|
||||
p = buf->b_term->tl_tty_out;
|
||||
break;
|
||||
case 1:
|
||||
if (buf->b_term->tl_job != NULL)
|
||||
p = buf->b_term->tl_job->jv_tty_in;
|
||||
else
|
||||
p = buf->b_term->tl_tty_in;
|
||||
break;
|
||||
default:
|
||||
EMSG2(_(e_invarg2), get_tv_string(&argvars[1]));
|
||||
@ -5214,7 +5418,8 @@ term_and_job_init(
|
||||
term_T *term,
|
||||
typval_T *argvar,
|
||||
char **argv UNUSED,
|
||||
jobopt_T *opt)
|
||||
jobopt_T *opt,
|
||||
jobopt_T *orig_opt)
|
||||
{
|
||||
WCHAR *cmd_wchar = NULL;
|
||||
WCHAR *cwd_wchar = NULL;
|
||||
@ -5368,6 +5573,19 @@ term_and_job_init(
|
||||
++job->jv_refcount;
|
||||
term->tl_job = job;
|
||||
|
||||
/* Redirecting stdout and stderr doesn't work at the job level. Instead
|
||||
* open the file here and handle it in. opt->jo_io was changed in
|
||||
* setup_job_options(), use the original flags here. */
|
||||
if (orig_opt->jo_io[PART_OUT] == JIO_FILE)
|
||||
{
|
||||
char_u *fname = opt->jo_io_name[PART_OUT];
|
||||
|
||||
ch_log(channel, "Opening output file %s", fname);
|
||||
term->tl_out_fd = mch_fopen((char *)fname, WRITEBIN);
|
||||
if (term->tl_out_fd == NULL)
|
||||
EMSG2(_(e_notopen), fname);
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
failed:
|
||||
@ -5521,7 +5739,8 @@ term_and_job_init(
|
||||
term_T *term,
|
||||
typval_T *argvar,
|
||||
char **argv,
|
||||
jobopt_T *opt)
|
||||
jobopt_T *opt,
|
||||
jobopt_T *orig_opt UNUSED)
|
||||
{
|
||||
create_vterm(term, term->tl_rows, term->tl_cols);
|
||||
|
||||
|
@ -470,4 +470,25 @@ func Test_verbosefile()
|
||||
call delete('Xlog')
|
||||
endfunc
|
||||
|
||||
func Test_setcmdpos()
|
||||
func InsertTextAtPos(text, pos)
|
||||
call assert_equal(0, setcmdpos(a:pos))
|
||||
return a:text
|
||||
endfunc
|
||||
|
||||
" setcmdpos() with position in the middle of the command line.
|
||||
call feedkeys(":\"12\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt')
|
||||
call assert_equal('"1ab2', @:)
|
||||
|
||||
call feedkeys(":\"12\<C-R>\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt')
|
||||
call assert_equal('"1b2a', @:)
|
||||
|
||||
" setcmdpos() with position beyond the end of the command line.
|
||||
call feedkeys(":\"12\<C-B>\<C-R>=InsertTextAtPos('a', 10)\<CR>b\<CR>", 'xt')
|
||||
call assert_equal('"12ab', @:)
|
||||
|
||||
" setcmdpos() returns 1 when not editing the command line.
|
||||
call assert_equal(1, setcmdpos(3))
|
||||
endfunc
|
||||
|
||||
set cpo&
|
||||
|
@ -284,7 +284,7 @@ func Test_set_ttytype()
|
||||
" in travis on some builds. Why? Catch both for now
|
||||
try
|
||||
set ttytype=
|
||||
call assert_report('set ttype= did not fail')
|
||||
call assert_report('set ttytype= did not fail')
|
||||
catch /E529\|E522/
|
||||
endtry
|
||||
|
||||
@ -292,7 +292,7 @@ func Test_set_ttytype()
|
||||
" check for failure of finding the entry and for missing 'cm' entry.
|
||||
try
|
||||
set ttytype=xxx
|
||||
call assert_report('set ttype=xxx did not fail')
|
||||
call assert_report('set ttytype=xxx did not fail')
|
||||
catch /E522\|E437/
|
||||
endtry
|
||||
|
||||
|
@ -831,4 +831,34 @@ func Test_popup_complete_backwards_ctrl_p()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
fun! Test_complete_o_tab()
|
||||
let s:o_char_pressed = 0
|
||||
|
||||
fun! s:act_on_text_changed()
|
||||
if s:o_char_pressed
|
||||
let s:o_char_pressed = 0
|
||||
call feedkeys("\<c-x>\<c-n>", 'i')
|
||||
endif
|
||||
endf
|
||||
|
||||
set completeopt=menu,noselect
|
||||
new
|
||||
imap <expr> <buffer> <tab> pumvisible() ? "\<c-p>" : "X"
|
||||
autocmd! InsertCharPre <buffer> let s:o_char_pressed = (v:char ==# 'o')
|
||||
autocmd! TextChangedI <buffer> call <sid>act_on_text_changed()
|
||||
call setline(1, ['hoard', 'hoax', 'hoarse', ''])
|
||||
let l:expected = ['hoard', 'hoax', 'hoarse', 'hoax', 'hoax']
|
||||
call cursor(4,1)
|
||||
call test_override("char_avail", 1)
|
||||
call feedkeys("Ahoa\<tab>\<tab>\<c-y>\<esc>", 'tx')
|
||||
call feedkeys("oho\<tab>\<tab>\<c-y>\<esc>", 'tx')
|
||||
call assert_equal(l:expected, getline(1,'$'))
|
||||
|
||||
call test_override("char_avail", 0)
|
||||
bwipe!
|
||||
set completeopt&
|
||||
delfunc s:act_on_text_changed
|
||||
endf
|
||||
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -25,3 +25,41 @@ func Test_yank_shows_register()
|
||||
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_display_registers()
|
||||
e file1
|
||||
e file2
|
||||
call setline(1, ['foo', 'bar'])
|
||||
/bar
|
||||
exe 'norm! y2l"axx'
|
||||
call feedkeys("i\<C-R>=2*4\n\<esc>")
|
||||
call feedkeys(":ls\n", 'xt')
|
||||
|
||||
let a = execute('display')
|
||||
let b = execute('registers')
|
||||
|
||||
call assert_equal(a, b)
|
||||
call assert_match('^\n--- Registers ---\n'
|
||||
\ . '"" a\n'
|
||||
\ . '"0 ba\n'
|
||||
\ . '"1 b\n'
|
||||
\ . '"a b\n'
|
||||
\ . '.*'
|
||||
\ . '"- a\n'
|
||||
\ . '.*'
|
||||
\ . '": ls\n'
|
||||
\ . '"% file2\n'
|
||||
\ . '"# file1\n'
|
||||
\ . '"/ bar\n'
|
||||
\ . '"= 2\*4', a)
|
||||
|
||||
let a = execute('registers a')
|
||||
call assert_match('^\n--- Registers ---\n'
|
||||
\ . '"a b', a)
|
||||
|
||||
let a = execute('registers :')
|
||||
call assert_match('^\n--- Registers ---\n'
|
||||
\ . '": ls', a)
|
||||
|
||||
bwipe!
|
||||
endfunc
|
||||
|
@ -675,18 +675,15 @@ func Test_terminal_wrong_options()
|
||||
endfunc
|
||||
|
||||
func Test_terminal_redir_file()
|
||||
" TODO: this should work on MS-Window
|
||||
if has('unix')
|
||||
let cmd = Get_cat_123_cmd()
|
||||
let buf = term_start(cmd, {'out_io': 'file', 'out_name': 'Xfile'})
|
||||
call term_wait(buf)
|
||||
call WaitForAssert({-> assert_notequal(0, len(readfile("Xfile")))})
|
||||
call assert_match('123', readfile('Xfile')[0])
|
||||
let g:job = term_getjob(buf)
|
||||
call WaitForAssert({-> assert_equal("dead", job_status(g:job))})
|
||||
call delete('Xfile')
|
||||
bwipe
|
||||
endif
|
||||
let cmd = Get_cat_123_cmd()
|
||||
let buf = term_start(cmd, {'out_io': 'file', 'out_name': 'Xfile'})
|
||||
call term_wait(buf)
|
||||
call WaitForAssert({-> assert_notequal(0, len(readfile("Xfile")))})
|
||||
call assert_match('123', readfile('Xfile')[0])
|
||||
let g:job = term_getjob(buf)
|
||||
call WaitForAssert({-> assert_equal("dead", job_status(g:job))})
|
||||
call delete('Xfile')
|
||||
bwipe
|
||||
|
||||
if has('unix')
|
||||
call writefile(['one line'], 'Xfile')
|
||||
|
@ -5,6 +5,7 @@ if !has('timers')
|
||||
endif
|
||||
|
||||
source shared.vim
|
||||
source screendump.vim
|
||||
|
||||
func MyHandler(timer)
|
||||
let g:val += 1
|
||||
@ -260,4 +261,35 @@ func Test_ex_mode()
|
||||
call timer_stop(timer)
|
||||
endfunc
|
||||
|
||||
func Test_restore_count()
|
||||
if !CanRunVimInTerminal()
|
||||
return
|
||||
endif
|
||||
" Check that v:count is saved and restored, not changed by a timer.
|
||||
call writefile([
|
||||
\ 'nnoremap <expr><silent> L v:count ? v:count . "l" : "l"',
|
||||
\ 'func Doit(id)',
|
||||
\ ' normal 3j',
|
||||
\ 'endfunc',
|
||||
\ 'call timer_start(100, "Doit")',
|
||||
\ ], 'Xtrcscript')
|
||||
call writefile([
|
||||
\ '1-1234',
|
||||
\ '2-1234',
|
||||
\ '3-1234',
|
||||
\ ], 'Xtrctext')
|
||||
let buf = RunVimInTerminal('-S Xtrcscript Xtrctext', {})
|
||||
|
||||
" Wait for the timer to move the cursor to the third line.
|
||||
call WaitForAssert({-> assert_equal(3, term_getcursor(buf)[0])})
|
||||
call assert_equal(1, term_getcursor(buf)[1])
|
||||
" Now check that v:count has not been set to 3
|
||||
call term_sendkeys(buf, 'L')
|
||||
call WaitForAssert({-> assert_equal(2, term_getcursor(buf)[1])})
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xtrcscript')
|
||||
call delete('Xtrctext')
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -17,7 +17,7 @@ func Test_window_cmd_ls0_with_split()
|
||||
endfunc
|
||||
|
||||
func Test_window_cmd_cmdwin_with_vsp()
|
||||
let efmt='Expected 0 but got %d (in ls=%d, %s window)'
|
||||
let efmt = 'Expected 0 but got %d (in ls=%d, %s window)'
|
||||
for v in range(0, 2)
|
||||
exec "set ls=" . v
|
||||
vsplit
|
||||
@ -444,21 +444,21 @@ func Test_window_contents()
|
||||
|
||||
exe "norm! \<C-W>t\<C-W>=1Gzt\<C-W>w\<C-W>+"
|
||||
redraw
|
||||
let s3=GetScreenStr(1)
|
||||
let s3 = GetScreenStr(1)
|
||||
wincmd p
|
||||
call assert_equal(1, line("w0"))
|
||||
call assert_equal('1 ', s3)
|
||||
|
||||
exe "norm! \<C-W>t\<C-W>=50Gzt\<C-W>w\<C-W>+"
|
||||
redraw
|
||||
let s3=GetScreenStr(1)
|
||||
let s3 = GetScreenStr(1)
|
||||
wincmd p
|
||||
call assert_equal(50, line("w0"))
|
||||
call assert_equal('50 ', s3)
|
||||
|
||||
exe "norm! \<C-W>t\<C-W>=59Gzt\<C-W>w\<C-W>+"
|
||||
redraw
|
||||
let s3=GetScreenStr(1)
|
||||
let s3 = GetScreenStr(1)
|
||||
wincmd p
|
||||
call assert_equal(59, line("w0"))
|
||||
call assert_equal('59 ', s3)
|
||||
@ -507,4 +507,19 @@ func Test_visual_cleared_after_window_split()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_winrestcmd()
|
||||
2split
|
||||
3vsplit
|
||||
let a = winrestcmd()
|
||||
call assert_equal(2, winheight(0))
|
||||
call assert_equal(3, winwidth(0))
|
||||
wincmd =
|
||||
call assert_notequal(2, winheight(0))
|
||||
call assert_notequal(3, winwidth(0))
|
||||
exe a
|
||||
call assert_equal(2, winheight(0))
|
||||
call assert_equal(3, winwidth(0))
|
||||
only
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
7
src/ui.c
7
src/ui.c
@ -415,7 +415,10 @@ ui_breakcheck_force(int force)
|
||||
#endif
|
||||
mch_breakcheck(force);
|
||||
|
||||
updating_screen = save_us;
|
||||
if (save_us)
|
||||
updating_screen = save_us;
|
||||
else
|
||||
reset_updating_screen(FALSE);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -1971,7 +1974,7 @@ ui_cursor_shape_forced(int forced)
|
||||
# endif
|
||||
|
||||
# ifdef FEAT_CONCEAL
|
||||
conceal_check_cursur_line();
|
||||
conceal_check_cursor_line();
|
||||
# endif
|
||||
}
|
||||
|
||||
|
@ -761,6 +761,50 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1818,
|
||||
/**/
|
||||
1817,
|
||||
/**/
|
||||
1816,
|
||||
/**/
|
||||
1815,
|
||||
/**/
|
||||
1814,
|
||||
/**/
|
||||
1813,
|
||||
/**/
|
||||
1812,
|
||||
/**/
|
||||
1811,
|
||||
/**/
|
||||
1810,
|
||||
/**/
|
||||
1809,
|
||||
/**/
|
||||
1808,
|
||||
/**/
|
||||
1807,
|
||||
/**/
|
||||
1806,
|
||||
/**/
|
||||
1805,
|
||||
/**/
|
||||
1804,
|
||||
/**/
|
||||
1803,
|
||||
/**/
|
||||
1802,
|
||||
/**/
|
||||
1801,
|
||||
/**/
|
||||
1800,
|
||||
/**/
|
||||
1799,
|
||||
/**/
|
||||
1798,
|
||||
/**/
|
||||
1797,
|
||||
/**/
|
||||
1796,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user