mirror of
https://github.com/zoriya/vim.git
synced 2025-12-16 20:25:19 +00:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ad022a9b8 | ||
|
|
24820691e6 | ||
|
|
22044dc317 | ||
|
|
af903e5d49 | ||
|
|
a7c54cfcf8 | ||
|
|
97ce419201 | ||
|
|
76bb7196f5 | ||
|
|
2f0584910c | ||
|
|
46359e198f | ||
|
|
8b9e20afb0 | ||
|
|
1a2ab991a6 | ||
|
|
c5aa55db7e | ||
|
|
a45ff6caba | ||
|
|
3660a10c73 | ||
|
|
1ed2276fd5 | ||
|
|
f38c86eb6b | ||
|
|
bdb8139098 | ||
|
|
1355aad2b9 | ||
|
|
17471e84a7 | ||
|
|
c8c75796a6 | ||
|
|
e0aa23f7e3 | ||
|
|
a3571ebef5 | ||
|
|
c41838aa01 | ||
|
|
2877d334ad | ||
|
|
d7ccc4d81d | ||
|
|
fb1db0e355 | ||
|
|
be5d998d0e |
4
Filelist
4
Filelist
@@ -119,7 +119,6 @@ SRC_ALL = \
|
||||
src/testdir/test[0-9]*a.ok \
|
||||
src/testdir/test_[a-z]*.ok \
|
||||
src/testdir/test49.vim \
|
||||
src/testdir/test60.vim \
|
||||
src/testdir/test83-tags? \
|
||||
src/testdir/test77a.com \
|
||||
src/testdir/test_*.vim \
|
||||
@@ -138,7 +137,7 @@ SRC_ALL = \
|
||||
src/testdir/samples/*.txt \
|
||||
src/testdir/samples/test000 \
|
||||
src/testdir/if_ver*.vim \
|
||||
src/testdir/xterm_ramp.vim \
|
||||
src/testdir/color_ramp.vim \
|
||||
src/proto.h \
|
||||
src/proto/arabic.pro \
|
||||
src/proto/beval.pro \
|
||||
@@ -585,6 +584,7 @@ RT_ALL = \
|
||||
runtime/doc/*.txt \
|
||||
runtime/doc/Makefile \
|
||||
runtime/doc/doctags.c \
|
||||
runtime/doc/test_urls.vim \
|
||||
runtime/doc/vim.1 \
|
||||
runtime/doc/evim.1 \
|
||||
runtime/doc/vimdiff.1 \
|
||||
|
||||
@@ -16,6 +16,7 @@ matrix:
|
||||
|
||||
before_build:
|
||||
- '"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 /release'
|
||||
- 'set INCLUDE=%INCLUDE%C:\Program Files (x86)\Windows Kits\8.1\Include\um'
|
||||
|
||||
build_script:
|
||||
- src/appveyor.bat
|
||||
|
||||
@@ -375,6 +375,10 @@ tags.ref tags.html: tags
|
||||
perlhtml: tags $(DOCS)
|
||||
./vim2html.pl tags $(DOCS)
|
||||
|
||||
# Check URLs in the help with "curl".
|
||||
test_urls:
|
||||
vim -S test_urls.vim
|
||||
|
||||
clean:
|
||||
-rm doctags *.html tags.ref
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*eval.txt* For Vim version 8.0. Last change: 2017 Nov 19
|
||||
*eval.txt* For Vim version 8.0. Last change: 2017 Nov 24
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -2452,6 +2452,7 @@ win_getid([{win} [, {tab}]]) Number get window ID for {win} in {tab}
|
||||
win_gotoid({expr}) Number go to window with ID {expr}
|
||||
win_id2tabwin({expr}) List get tab and window nr from window ID
|
||||
win_id2win({expr}) Number get window nr from window ID
|
||||
win_screenpos({nr}) List get screen position of window {nr}
|
||||
winbufnr({nr}) Number buffer number of window {nr}
|
||||
wincol() Number window column of the cursor
|
||||
winheight({nr}) Number height of window {nr}
|
||||
@@ -4662,11 +4663,11 @@ getqflist([{what}]) *getqflist()*
|
||||
following string items are supported in {what}:
|
||||
context get the context stored with |setqflist()|
|
||||
efm errorformat to use when parsing "lines". If
|
||||
not present, then the 'erroformat' option
|
||||
not present, then the 'errorformat' option
|
||||
value is used.
|
||||
id get information for the quickfix list with
|
||||
|quickfix-ID|; zero means the id for the
|
||||
current list or the list specifed by "nr"
|
||||
current list or the list specified by "nr"
|
||||
idx index of the current entry in the list
|
||||
items quickfix list entries
|
||||
lines use 'errorformat' to extract items from a list
|
||||
@@ -7695,8 +7696,9 @@ submatch({nr} [, {list}]) *submatch()* *E935*
|
||||
When substitute() is used recursively only the submatches in
|
||||
the current (deepest) call can be obtained.
|
||||
|
||||
Example: >
|
||||
Examples: >
|
||||
:s/\d\+/\=submatch(0) + 1/
|
||||
:echo substitute(text, '\d\+', '\=submatch(0) + 1', '')
|
||||
< This finds the first number in the line and adds one to it.
|
||||
A line break is included as a newline character.
|
||||
|
||||
@@ -8632,6 +8634,14 @@ win_id2win({expr}) *win_id2win()*
|
||||
Return the window number of window with ID {expr}.
|
||||
Return 0 if the window cannot be found in the current tabpage.
|
||||
|
||||
win_screenpos({nr}) *win_screenpos()*
|
||||
Return the screen position of window {nr} as a list with two
|
||||
numbers: [row, col]. The first window always has position
|
||||
[1, 1].
|
||||
{nr} can be the window number or the |window-ID|.
|
||||
Return [0, 0] if the window cannot be found in the current
|
||||
tabpage.
|
||||
|
||||
*winbufnr()*
|
||||
winbufnr({nr}) The result is a Number, which is the number of the buffer
|
||||
associated with window {nr}. {nr} can be the window number or
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*if_cscop.txt* For Vim version 8.0. Last change: 2017 Jun 14
|
||||
*if_cscop.txt* For Vim version 8.0. Last change: 2017 Nov 23
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Andy Kahn
|
||||
@@ -468,36 +468,18 @@ license or OS distribution), then you can download it for free from:
|
||||
http://cscope.sourceforge.net/
|
||||
This is released by SCO under the BSD license.
|
||||
|
||||
If you want a newer version of cscope, you will probably have to buy it.
|
||||
According to the (old) nvi documentation:
|
||||
|
||||
You can buy version 13.3 source with an unrestricted license
|
||||
for $400 from AT&T Software Solutions by calling +1-800-462-8146.
|
||||
|
||||
Also you can download cscope 13.x and mlcscope 14.x (multi-lingual cscope
|
||||
which supports C, C++, Java, lex, yacc, breakpoint listing, Ingres, and SDL)
|
||||
from World-Wide Exptools Open Source packages page:
|
||||
http://www.bell-labs.com/project/wwexptools/packages.html
|
||||
|
||||
In Solaris 2.x, if you have the C compiler license, you will also have
|
||||
cscope. Both are usually located under /opt/SUNWspro/bin
|
||||
|
||||
SGI developers can also get it. Search for Cscope on this page:
|
||||
http://freeware.sgi.com/index-by-alpha.html
|
||||
https://toolbox.sgi.com/toolbox/utilities/cscope/
|
||||
The second one is for those who have a password for the SGI toolbox.
|
||||
|
||||
There is source to an older version of a cscope clone (called "cs") available
|
||||
on the net. Due to various reasons, this is not supported with Vim.
|
||||
|
||||
The cscope interface/support for Vim was originally written by
|
||||
Andy Kahn <ackahn@netapp.com>. The original structure (as well as a tiny
|
||||
bit of code) was adapted from the cscope interface in nvi. Please report
|
||||
any problems, suggestions, patches, et al., you have for the usage of
|
||||
cscope within Vim to him.
|
||||
bit of code) was adapted from the cscope interface in nvi.
|
||||
*cscope-win32*
|
||||
For a cscope version for Win32 see:
|
||||
http://code.google.com/p/cscope-win32/
|
||||
For a cscope version for Win32 see (seems abandonded):
|
||||
https://code.google.com/archive/p/cscope-win32/
|
||||
|
||||
Win32 support was added by Sergey Khorev <sergey.khorev@gmail.com>. Contact
|
||||
him if you have Win32-specific issues.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*if_perl.txt* For Vim version 8.0. Last change: 2015 Oct 16
|
||||
*if_perl.txt* For Vim version 8.0. Last change: 2017 Nov 24
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Sven Verdoolaege
|
||||
@@ -112,7 +112,7 @@ possible.
|
||||
Here is an overview of the functions that are available to Perl: >
|
||||
|
||||
:perl VIM::Msg("Text") # displays a message
|
||||
:perl VIM::Msg("Error", "ErrorMsg") # displays an error message
|
||||
:perl VIM::Msg("Wrong!", "ErrorMsg") # displays an error message
|
||||
:perl VIM::Msg("remark", "Comment") # displays a highlighted message
|
||||
:perl VIM::SetOption("ai") # sets a vim option
|
||||
:perl $nbuf = VIM::Buffers() # returns the number of buffers
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*insert.txt* For Vim version 8.0. Last change: 2017 May 30
|
||||
*insert.txt* For Vim version 8.0. Last change: 2017 Nov 23
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -1296,7 +1296,8 @@ it here: http://ctags.sourceforge.net/ Version 5.6 or later is recommended.
|
||||
For version 5.5.4 you should add a patch that adds the "typename:" field:
|
||||
ftp://ftp.vim.org/pub/vim/unstable/patches/ctags-5.5.4.patch
|
||||
A compiled .exe for MS-Windows can be found at:
|
||||
http://georgevreilly.com/vim/ctags.html
|
||||
http://ctags.sourceforge.net/
|
||||
https://github.com/universal-ctags/ctags-win32
|
||||
|
||||
If you want to complete system functions you can do something like this. Use
|
||||
ctags to generate a tags file for all the system header files: >
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*mbyte.txt* For Vim version 8.0. Last change: 2016 Jul 21
|
||||
*mbyte.txt* For Vim version 8.0. Last change: 2017 Nov 30
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar et al.
|
||||
@@ -1257,8 +1257,8 @@ Combining forms:
|
||||
==============================================================================
|
||||
10. Input with imactivatefunc() *mbyte-func*
|
||||
|
||||
Vim has |imactivatefunc()| and |imstatusfunc()|. This is useful to
|
||||
activate/deativate input method from Vim in any way, also with an external
|
||||
Vim has the 'imactivatefunc' and 'imstatusfunc' options. These are useful to
|
||||
activate/deativate the input method from Vim in any way, also with an external
|
||||
command. For example, fcitx provide fcitx-remote command: >
|
||||
|
||||
set iminsert=2
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*options.txt* For Vim version 8.0. Last change: 2017 Nov 18
|
||||
*options.txt* For Vim version 8.0. Last change: 2017 Nov 26
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -2634,6 +2634,9 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
vertical Start diff mode with vertical splits (unless
|
||||
explicitly specified otherwise).
|
||||
|
||||
hiddenoff Do not use diff mode for a buffer when it
|
||||
becomes hidden.
|
||||
|
||||
foldcolumn:{n} Set the 'foldcolumn' option to {n} when
|
||||
starting diff mode. Without this 2 is used.
|
||||
|
||||
@@ -4258,7 +4261,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
{not in Vi}
|
||||
{only available when compiled with |+mbyte|}
|
||||
This option specifies a function that will be called to
|
||||
activate/inactivate Input Method.
|
||||
activate or deactivate the Input Method.
|
||||
It is not used in the GUI.
|
||||
|
||||
Example: >
|
||||
function ImActivateFunc(active)
|
||||
@@ -4374,6 +4378,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
{only available when compiled with |+mbyte|}
|
||||
This option specifies a function that is called to obtain the status
|
||||
of Input Method. It must return a positive number when IME is active.
|
||||
It is not used in the GUI.
|
||||
|
||||
Example: >
|
||||
function ImStatusFunc()
|
||||
@@ -4462,8 +4467,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
match may not be found. This is to avoid that Vim hangs while you
|
||||
are typing the pattern.
|
||||
The highlighting can be set with the 'i' flag in 'highlight'.
|
||||
When 'hlsearch' is on, all matched strings are highlighted too while typing
|
||||
a search command. See also: 'hlsearch'.
|
||||
When 'hlsearch' is on, all matched strings are highlighted too while
|
||||
typing a search command. See also: 'hlsearch'.
|
||||
If you don't want turn 'hlsearch' on, but want to highlight all matches
|
||||
while searching, you can turn on and off 'hlsearch' with autocmd.
|
||||
Example: >
|
||||
@@ -6152,11 +6157,34 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
|
||||
Example: >
|
||||
set encoding=utf-8
|
||||
set gfn=Ricty_Diminished:h12:cSHIFTJIS
|
||||
set gfn=Ricty_Diminished:h12
|
||||
set rop=type:directx
|
||||
<
|
||||
If select a raster font (Courier, Terminal or FixedSys) to
|
||||
'guifont', it fallbacks to be drawn by GDI automatically.
|
||||
If select a raster font (Courier, Terminal or FixedSys which
|
||||
have ".fon" extension in file name) to 'guifont', it will be
|
||||
drawn by GDI as a fallback. This fallback will cause
|
||||
significant slow down on drawing.
|
||||
|
||||
NOTE: It is known that some fonts and options combination
|
||||
causes trouble on drawing glyphs.
|
||||
|
||||
- 'rendmode:5' and 'renmode:6' will not work with some
|
||||
special made fonts (True-Type fonts which includes only
|
||||
bitmap glyphs).
|
||||
- 'taamode:3' will not work with some vector fonts.
|
||||
|
||||
NOTE: With this option, you can display colored emoji
|
||||
(emoticon) in Windows 8.1 or later. To display colored emoji,
|
||||
there are some conditions which you should notice.
|
||||
|
||||
- If your font includes non-colored emoji already, it will
|
||||
be used.
|
||||
- If your font doesn't have emoji, the system chooses an
|
||||
alternative symbol font. On Windows 10, "Segoe UI Emoji"
|
||||
will be used.
|
||||
- When this alternative font didn't have fixed width glyph,
|
||||
emoji might be rendered beyond the bounding box of drawing
|
||||
cell.
|
||||
|
||||
Other render types are currently not supported.
|
||||
|
||||
@@ -8230,7 +8258,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
number, more intelligent detection process runs.
|
||||
The "xterm2" value will be set if the xterm version is reported to be
|
||||
from 95 to 276. The "sgr" value will be set if the xterm version is
|
||||
277 or highter and when Vim detects Mac Terminal.app or Iterm2.
|
||||
277 or higher and when Vim detects Mac Terminal.app or iTerm2.
|
||||
If you do not want 'ttymouse' to be set to "xterm2" or "sgr"
|
||||
automatically, set t_RV to an empty string: >
|
||||
:set t_RV=
|
||||
|
||||
@@ -7346,6 +7346,7 @@ mbyte-encoding mbyte.txt /*mbyte-encoding*
|
||||
mbyte-first mbyte.txt /*mbyte-first*
|
||||
mbyte-fonts-MSwin mbyte.txt /*mbyte-fonts-MSwin*
|
||||
mbyte-fonts-X11 mbyte.txt /*mbyte-fonts-X11*
|
||||
mbyte-func mbyte.txt /*mbyte-func*
|
||||
mbyte-keymap mbyte.txt /*mbyte-keymap*
|
||||
mbyte-locale mbyte.txt /*mbyte-locale*
|
||||
mbyte-options mbyte.txt /*mbyte-options*
|
||||
|
||||
68
runtime/doc/test_urls.vim
Normal file
68
runtime/doc/test_urls.vim
Normal file
@@ -0,0 +1,68 @@
|
||||
" Test for URLs in help documents.
|
||||
"
|
||||
" Opens a new window with all found URLS followed by return code from curl
|
||||
" (anything other than 0 means unreachable)
|
||||
"
|
||||
" Written by Christian Brabandt.
|
||||
|
||||
func Test_check_URLs()
|
||||
if has("win32")
|
||||
echoerr "Doesn't work on MS-Windows"
|
||||
return
|
||||
endif
|
||||
if executable('curl')
|
||||
" Note: does not follow redirects!
|
||||
let s:command = 'curl --silent --fail --output /dev/null --head '
|
||||
elseif executable('wget')
|
||||
" Note: only allow a couple of redirects
|
||||
let s:command = 'wget --quiet -S --spider --max-redirect=2 --timeout=5 --tries=2 -O /dev/null '
|
||||
else
|
||||
echoerr 'Only works when "curl" or "wget" is available'
|
||||
return
|
||||
endif
|
||||
|
||||
let pat='\(https\?\|ftp\)://[^\t* ]\+'
|
||||
exe 'helpgrep' pat
|
||||
helpclose
|
||||
|
||||
let urls = map(getqflist(), 'v:val.text')
|
||||
" do not use submatch(1)!
|
||||
let urls = map(urls, {key, val -> matchstr(val, pat)})
|
||||
" remove examples like user@host (invalid urls)
|
||||
let urls = filter(urls, 'v:val !~ "@"')
|
||||
" Remove example URLs which are invalid
|
||||
let urls = filter(urls, {key, val -> val !~ '\<\(\(my\|some\)\?host\|machine\|hostname\|file\)\>'})
|
||||
new
|
||||
put =urls
|
||||
" remove some more invalid items
|
||||
" empty lines
|
||||
v/./d
|
||||
" remove # anchors
|
||||
%s/#.*$//e
|
||||
" remove trailing stuff (parenthesis, dot, comma, quotes), but only for HTTP
|
||||
" links
|
||||
g/^h/s#[.,)'"/>][:.]\?$##
|
||||
g#^[hf]t\?tp:/\(/\?\.*\)$#d
|
||||
silent! g/ftp://,$/d
|
||||
silent! g/=$/d
|
||||
let a = getline(1,'$')
|
||||
let a = uniq(sort(a))
|
||||
%d
|
||||
call setline(1, a)
|
||||
|
||||
" Do the testing.
|
||||
set nomore
|
||||
%s/.*/\=TestURL(submatch(0))/
|
||||
|
||||
" highlight the failures
|
||||
/.* \([0-9]*[1-9]\|[0-9]\{2,}\)$
|
||||
endfunc
|
||||
|
||||
func TestURL(url)
|
||||
" Relies on the return code to determine whether a page is valid
|
||||
echom printf("Testing URL: %d/%d %s", line('.'), line('$'), a:url)
|
||||
call system(s:command . shellescape(a:url))
|
||||
return printf("%s %d", a:url, v:shell_error)
|
||||
endfunc
|
||||
|
||||
call Test_check_URLs()
|
||||
@@ -1,4 +1,4 @@
|
||||
*todo.txt* For Vim version 8.0. Last change: 2017 Nov 21
|
||||
*todo.txt* For Vim version 8.0. Last change: 2017 Nov 29
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -35,6 +35,13 @@ entered there will not be repeated below, unless there is extra information.
|
||||
*known-bugs*
|
||||
-------------------- Known bugs and current work -----------------------
|
||||
|
||||
Motif testgui:
|
||||
From test_options.vim:
|
||||
Found errors in Test_set_values():
|
||||
Caught exception in Test_set_values(): Vim(set):E596: Invalid font(s): guifont=fixedsys @ /home/mool/vim/vim80/src/testdir/opt_test.vim, line 1153
|
||||
|
||||
WinBar: balloon shows up for next line
|
||||
|
||||
No maintainer for Vietnamese translations.
|
||||
No maintainer for Simplified Chinese translations.
|
||||
|
||||
@@ -150,8 +157,17 @@ Compiler warnings (geeknik, 2017 Oct 26):
|
||||
- signed integer overflow in nfa_regatom() (#2251)
|
||||
- undefined left shift in get_string_tv() (#2250)
|
||||
|
||||
Patch to use imactivatefunc() also without +xim feature. (Yasuhiro Matsumoto,
|
||||
2017 Nov 19, #2349)
|
||||
patch for: fix SHIFT-Insert on Windows command prompt (Yasuhiro Matsumoto,
|
||||
#2381)
|
||||
|
||||
Patch for profile log truncating halfway a character. (ichizok, 2017 Nov 28,
|
||||
#2385)
|
||||
|
||||
WinBar: Maximizing window causes window size to be wrong. (Lifepillar, 2017
|
||||
Nov 29, #2356)
|
||||
|
||||
CTRL-A does not work with empty line. (Alex, #2387)
|
||||
Patch by Hirohito Higashi, 2017 Nov 29.
|
||||
|
||||
'hlsearch' shows empty matches, which means highlighting everything.
|
||||
Don't do that. For "foo\|" or "\v"
|
||||
@@ -171,12 +187,6 @@ With foldmethod=syntax and nofoldenable comment highlighting isn't removed.
|
||||
Using 'wildignore' also applies to literally entered file name. Also with
|
||||
:drop (remote commands).
|
||||
|
||||
Race condition between stat() and open() in write_viminfo(). Use open() in the
|
||||
loop and try another name instead of using a temp file. (Simon Ruderich)
|
||||
The first one, when viminfo is new, should just fail if it creating with
|
||||
O_EXCL fails.
|
||||
Also use umask instead of mch_fopen() after vim_tempname().
|
||||
|
||||
"gvim --remote" from a directory with non-word characters changes the current
|
||||
directory (Paulo Marcel Coelho Arabic, 2017 Oct 30, #2266)
|
||||
Also see #1689.
|
||||
@@ -184,6 +194,9 @@ Also see #1689.
|
||||
ml_get error when using a Python. (Yggdroot, 2017 Jun 1, #1737)
|
||||
Lemonboy can reproduce (2017 Jun 5)
|
||||
|
||||
Patch to fix E806. (Dominique, 2017 Nov 22, #2368)
|
||||
Kazunobu Kuriyama: caused by XtSetLanguageProc().
|
||||
|
||||
Invalid range error when using BufWinLeave for closing terminal.
|
||||
(Gabriel Barta, 2017 Nov 15, #2339)
|
||||
|
||||
@@ -208,7 +221,7 @@ Patch to fix cmdline abbreviation after '<,'>. (Christian Brabandt, 2017 Nov
|
||||
|
||||
Patch to add TextDeletePost and TextYankPost events. (Philippe Vaucher, 2011
|
||||
May 24) Update May 26.
|
||||
Now in patch by Lemonboy, #2333 (who is Lemonboy?)
|
||||
Now in patch by Lemonboy, #2333
|
||||
|
||||
Default install on MS-Windows should source defaults.vim.
|
||||
Ask whether to use Windows or Vim key behavior?
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*version8.txt* For Vim version 8.0. Last change: 2017 Apr 23
|
||||
*version8.txt* For Vim version 8.0. Last change: 2017 Nov 24
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -15582,7 +15582,7 @@ Files: src/json.c, src/testdir/test_json.vim
|
||||
|
||||
Patch 8.0.0181
|
||||
Problem: When 'cursorbind' and 'cursorcolumn' are both on, the column
|
||||
highlignt in non-current windows is wrong.
|
||||
highlight in non-current windows is wrong.
|
||||
Solution: Add validate_cursor(). (Masanori Misono, closes #1372)
|
||||
Files: src/move.c
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
" Vim support file to detect file types
|
||||
"
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2017 Nov 21
|
||||
" Last Change: 2017 Nov 23
|
||||
|
||||
" Listen very carefully, I will say this only once
|
||||
if exists("did_load_filetypes")
|
||||
@@ -1878,8 +1878,8 @@ au BufNewFile,BufRead *.yy,*.yxx,*.y++ setf yacc
|
||||
" Yacc or racc
|
||||
au BufNewFile,BufRead *.y call dist#ft#FTy()
|
||||
|
||||
" Yaml
|
||||
au BufNewFile,BufRead *.yaml,*.yml setf yaml
|
||||
" Yaml or Raml
|
||||
au BufNewFile,BufRead *.yaml,*.yml,*.raml setf yaml
|
||||
|
||||
" yum conf (close enough to dosini)
|
||||
au BufNewFile,BufRead */etc/yum.conf setf dosini
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
" Language: Zsh shell script
|
||||
" Maintainer: Christian Brabandt <cb@256bit.org>
|
||||
" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
|
||||
" Latest Revision: 2015-05-29
|
||||
" Latest Revision: 2017-11-22
|
||||
" License: Vim (see :h license)
|
||||
" Repository: https://github.com/chrisbra/vim-zsh
|
||||
|
||||
@@ -18,9 +18,7 @@ let b:undo_ftplugin = "setl com< cms< fo<"
|
||||
|
||||
setlocal comments=:# commentstring=#\ %s formatoptions-=t formatoptions+=croql
|
||||
|
||||
let b:match_words =
|
||||
\ &matchpairs
|
||||
\ . ',\<if\>:\<elif\>:\<else\>:\<fi\>'
|
||||
let b:match_words = ',\<if\>:\<elif\>:\<else\>:\<fi\>'
|
||||
\ . ',\<case\>:^\s*([^)]*):\<esac\>'
|
||||
\ . ',\<\%(select\|while\|until\|repeat\|for\%(each\)\=\)\>:\<done\>'
|
||||
let b:match_skip = 's:comment\|string\|heredoc\|subst'
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
" Language: Zsh shell script
|
||||
" Maintainer: Christian Brabandt <cb@256bit.org>
|
||||
" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
|
||||
" Latest Revision: 2017-07-11
|
||||
" Latest Revision: 2017-11-22
|
||||
" License: Vim (see :h license)
|
||||
" Repository: https://github.com/chrisbra/vim-zsh
|
||||
|
||||
@@ -324,9 +324,9 @@ syn match zshOption /
|
||||
\ \%(\%(\<no_\?\)\?vi\>\)\|
|
||||
\ \%(\%(\<no_\?\)\?warncreateglobal\>\)\|\%(\%(no_\?\)\?warn_create_global\>\)\|
|
||||
\ \%(\%(\<no_\?\)\?xtrace\>\)\|
|
||||
\ \%(\%(\<no_\?\)\?zle\>\)/ nextgroup=zshOption skipwhite contained
|
||||
\ \%(\%(\<no_\?\)\?zle\>\)/ nextgroup=zshOption,zshComment skipwhite contained
|
||||
|
||||
syn keyword zshTypes float integer local typeset declare private
|
||||
syn keyword zshTypes float integer local typeset declare private readonly
|
||||
|
||||
" XXX: this may be too much
|
||||
" syn match zshSwitches '\s\zs--\=[a-zA-Z0-9-]\+'
|
||||
|
||||
@@ -50,7 +50,7 @@ get_beval_info(
|
||||
}
|
||||
#endif
|
||||
wp = mouse_find_win(&row, &col);
|
||||
if (wp != NULL && row < wp->w_height && col < wp->w_width)
|
||||
if (wp != NULL && row >= 0 && row < wp->w_height && col < wp->w_width)
|
||||
{
|
||||
/* Found a window and the cursor is in the text. Now find the line
|
||||
* number. */
|
||||
|
||||
@@ -593,6 +593,11 @@ aucmd_abort:
|
||||
if (buf->b_nwindows > 0)
|
||||
--buf->b_nwindows;
|
||||
|
||||
#ifdef FEAT_DIFF
|
||||
if (diffopt_hiddenoff() && !unload_buf && buf->b_nwindows == 0)
|
||||
diff_buf_delete(buf); /* Clear 'diff' for hidden buffer. */
|
||||
#endif
|
||||
|
||||
/* Return when a window is displaying the buffer or when it's not
|
||||
* unloaded. */
|
||||
if (buf->b_nwindows > 0 || !unload_buf)
|
||||
|
||||
15
src/diff.c
15
src/diff.c
@@ -23,6 +23,7 @@ static int diff_busy = FALSE; /* ex_diffgetput() is busy */
|
||||
#define DIFF_IWHITE 4 /* ignore change in white space */
|
||||
#define DIFF_HORIZONTAL 8 /* horizontal splits */
|
||||
#define DIFF_VERTICAL 16 /* vertical splits */
|
||||
#define DIFF_HIDDEN_OFF 32 /* diffoff when hidden */
|
||||
static int diff_flags = DIFF_FILLER;
|
||||
|
||||
#define LBUFLEN 50 /* length of line in diff file */
|
||||
@@ -1924,6 +1925,11 @@ diffopt_changed(void)
|
||||
p += 11;
|
||||
diff_foldcolumn_new = getdigits(&p);
|
||||
}
|
||||
else if (STRNCMP(p, "hiddenoff", 9) == 0)
|
||||
{
|
||||
p += 9;
|
||||
diff_flags_new |= DIFF_HIDDEN_OFF;
|
||||
}
|
||||
if (*p != ',' && *p != NUL)
|
||||
return FAIL;
|
||||
if (*p == ',')
|
||||
@@ -1961,6 +1967,15 @@ diffopt_horizontal(void)
|
||||
return (diff_flags & DIFF_HORIZONTAL) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if 'diffopt' contains "hiddenoff".
|
||||
*/
|
||||
int
|
||||
diffopt_hiddenoff(void)
|
||||
{
|
||||
return (diff_flags & DIFF_HIDDEN_OFF) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the difference within a changed line.
|
||||
* Returns TRUE if the line was added, no other buffer has it.
|
||||
|
||||
@@ -781,7 +781,7 @@ edit(
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get a character for Insert mode. Ignore K_IGNORE.
|
||||
* Get a character for Insert mode. Ignore K_IGNORE and K_NOP.
|
||||
*/
|
||||
if (c != K_CURSORHOLD)
|
||||
lastc = c; /* remember the previous char for CTRL-D */
|
||||
@@ -798,7 +798,7 @@ edit(
|
||||
do
|
||||
{
|
||||
c = safe_vgetc();
|
||||
} while (c == K_IGNORE);
|
||||
} while (c == K_IGNORE || c == K_NOP);
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
/* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */
|
||||
|
||||
@@ -441,6 +441,7 @@ static void f_win_getid(typval_T *argvars, typval_T *rettv);
|
||||
static void f_win_gotoid(typval_T *argvars, typval_T *rettv);
|
||||
static void f_win_id2tabwin(typval_T *argvars, typval_T *rettv);
|
||||
static void f_win_id2win(typval_T *argvars, typval_T *rettv);
|
||||
static void f_win_screenpos(typval_T *argvars, typval_T *rettv);
|
||||
static void f_winbufnr(typval_T *argvars, typval_T *rettv);
|
||||
static void f_wincol(typval_T *argvars, typval_T *rettv);
|
||||
static void f_winheight(typval_T *argvars, typval_T *rettv);
|
||||
@@ -899,6 +900,7 @@ static struct fst
|
||||
{"win_gotoid", 1, 1, f_win_gotoid},
|
||||
{"win_id2tabwin", 1, 1, f_win_id2tabwin},
|
||||
{"win_id2win", 1, 1, f_win_id2win},
|
||||
{"win_screenpos", 1, 1, f_win_screenpos},
|
||||
{"winbufnr", 1, 1, f_winbufnr},
|
||||
{"wincol", 0, 0, f_wincol},
|
||||
{"winheight", 1, 1, f_winheight},
|
||||
@@ -5378,6 +5380,22 @@ f_win_id2win(typval_T *argvars, typval_T *rettv)
|
||||
rettv->vval.v_number = win_id2win(argvars);
|
||||
}
|
||||
|
||||
/*
|
||||
* "win_screenpos()" function
|
||||
*/
|
||||
static void
|
||||
f_win_screenpos(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
win_T *wp;
|
||||
|
||||
if (rettv_list_alloc(rettv) == FAIL)
|
||||
return;
|
||||
|
||||
wp = find_win_by_nr(&argvars[0], NULL);
|
||||
list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_winrow + 1);
|
||||
list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_wincol + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* "getwinposx()" function
|
||||
*/
|
||||
|
||||
231
src/ex_cmds.c
231
src/ex_cmds.c
@@ -1825,7 +1825,6 @@ write_viminfo(char_u *file, int forceit)
|
||||
FILE *fp_out = NULL; /* output viminfo file */
|
||||
char_u *tempname = NULL; /* name of temp viminfo file */
|
||||
stat_T st_new; /* mch_stat() of potential new file */
|
||||
char_u *wp;
|
||||
#if defined(UNIX) || defined(VMS)
|
||||
mode_t umask_save;
|
||||
#endif
|
||||
@@ -1847,27 +1846,29 @@ write_viminfo(char_u *file, int forceit)
|
||||
fp_in = mch_fopen((char *)fname, READBIN);
|
||||
if (fp_in == NULL)
|
||||
{
|
||||
int fd;
|
||||
|
||||
/* if it does exist, but we can't read it, don't try writing */
|
||||
if (mch_stat((char *)fname, &st_new) == 0)
|
||||
goto end;
|
||||
#if defined(UNIX) || defined(VMS)
|
||||
/*
|
||||
* For Unix we create the .viminfo non-accessible for others,
|
||||
* because it may contain text from non-accessible documents.
|
||||
*/
|
||||
umask_save = umask(077);
|
||||
#endif
|
||||
fp_out = mch_fopen((char *)fname, WRITEBIN);
|
||||
#if defined(UNIX) || defined(VMS)
|
||||
(void)umask(umask_save);
|
||||
#endif
|
||||
|
||||
/* Create the new .viminfo non-accessible for others, because it may
|
||||
* contain text from non-accessible documents. It is up to the user to
|
||||
* widen access (e.g. to a group). This may also fail if there is a
|
||||
* race condition, then just give up. */
|
||||
fd = mch_open((char *)fname,
|
||||
O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, 0600);
|
||||
if (fd < 0)
|
||||
goto end;
|
||||
fp_out = fdopen(fd, WRITEBIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* There is an existing viminfo file. Create a temporary file to
|
||||
* write the new viminfo into, in the same directory as the
|
||||
* existing viminfo file, which will be renamed later.
|
||||
* existing viminfo file, which will be renamed once all writing is
|
||||
* successful.
|
||||
*/
|
||||
#ifdef UNIX
|
||||
/*
|
||||
@@ -1901,12 +1902,18 @@ write_viminfo(char_u *file, int forceit)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make tempname.
|
||||
* Make tempname, find one that does not exist yet.
|
||||
* Beware of a race condition: If someone logs out and all Vim
|
||||
* instances exit at the same time a temp file might be created between
|
||||
* stat() and open(). Use mch_open() with O_EXCL to avoid that.
|
||||
* May try twice: Once normal and once with shortname set, just in
|
||||
* case somebody puts his viminfo file in an 8.3 filesystem.
|
||||
*/
|
||||
for (;;)
|
||||
{
|
||||
int next_char = 'z';
|
||||
char_u *wp;
|
||||
|
||||
tempname = buf_modname(
|
||||
#ifdef UNIX
|
||||
shortname,
|
||||
@@ -1924,126 +1931,128 @@ write_viminfo(char_u *file, int forceit)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Check if tempfile already exists. Never overwrite an
|
||||
* existing file!
|
||||
* Try a series of names. Change one character, just before
|
||||
* the extension. This should also work for an 8.3
|
||||
* file name, when after adding the extension it still is
|
||||
* the same file as the original.
|
||||
*/
|
||||
if (mch_stat((char *)tempname, &st_new) == 0)
|
||||
wp = tempname + STRLEN(tempname) - 5;
|
||||
if (wp < gettail(tempname)) /* empty file name? */
|
||||
wp = gettail(tempname);
|
||||
for (;;)
|
||||
{
|
||||
/*
|
||||
* Check if tempfile already exists. Never overwrite an
|
||||
* existing file!
|
||||
*/
|
||||
if (mch_stat((char *)tempname, &st_new) == 0)
|
||||
{
|
||||
#ifdef UNIX
|
||||
/*
|
||||
* Check if tempfile is same as original file. May happen
|
||||
* when modname() gave the same file back. E.g. silly
|
||||
* link, or file name-length reached. Try again with
|
||||
* shortname set.
|
||||
*/
|
||||
if (!shortname && st_new.st_dev == st_old.st_dev
|
||||
&& st_new.st_ino == st_old.st_ino)
|
||||
{
|
||||
vim_free(tempname);
|
||||
tempname = NULL;
|
||||
shortname = TRUE;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Try another name. Change one character, just before
|
||||
* the extension. This should also work for an 8.3
|
||||
* file name, when after adding the extension it still is
|
||||
* the same file as the original.
|
||||
*/
|
||||
wp = tempname + STRLEN(tempname) - 5;
|
||||
if (wp < gettail(tempname)) /* empty file name? */
|
||||
wp = gettail(tempname);
|
||||
for (*wp = 'z'; mch_stat((char *)tempname, &st_new) == 0;
|
||||
--*wp)
|
||||
{
|
||||
/*
|
||||
* They all exist? Must be something wrong! Don't
|
||||
* write the viminfo file then.
|
||||
* Check if tempfile is same as original file. May happen
|
||||
* when modname() gave the same file back. E.g. silly
|
||||
* link, or file name-length reached. Try again with
|
||||
* shortname set.
|
||||
*/
|
||||
if (*wp == 'a')
|
||||
if (!shortname && st_new.st_dev == st_old.st_dev
|
||||
&& st_new.st_ino == st_old.st_ino)
|
||||
{
|
||||
EMSG2(_("E929: Too many viminfo temp files, like %s!"),
|
||||
tempname);
|
||||
vim_free(tempname);
|
||||
tempname = NULL;
|
||||
shortname = TRUE;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Try creating the file exclusively. This may fail if
|
||||
* another Vim tries to do it at the same time. */
|
||||
#ifdef VMS
|
||||
/* fdopen() fails for some reason */
|
||||
umask_save = umask(077);
|
||||
fp_out = mch_fopen((char *)tempname, WRITEBIN);
|
||||
(void)umask(umask_save);
|
||||
#else
|
||||
int fd;
|
||||
|
||||
/* Use mch_open() to be able to use O_NOFOLLOW and set file
|
||||
* protection:
|
||||
* Unix: same as original file, but strip s-bit. Reset
|
||||
* umask to avoid it getting in the way.
|
||||
* Others: r&w for user only. */
|
||||
# ifdef UNIX
|
||||
umask_save = umask(0);
|
||||
fd = mch_open((char *)tempname,
|
||||
O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW,
|
||||
(int)((st_old.st_mode & 0777) | 0600));
|
||||
(void)umask(umask_save);
|
||||
# else
|
||||
fd = mch_open((char *)tempname,
|
||||
O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, 0600);
|
||||
# endif
|
||||
if (fd < 0)
|
||||
{
|
||||
fp_out = NULL;
|
||||
# ifdef EEXIST
|
||||
/* Avoid trying lots of names while the problem is lack
|
||||
* of premission, only retry if the file already
|
||||
* exists. */
|
||||
if (errno != EEXIST)
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
else
|
||||
fp_out = fdopen(fd, WRITEBIN);
|
||||
#endif /* VMS */
|
||||
if (fp_out != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Assume file exists, try again with another name. */
|
||||
if (next_char == 'a' - 1)
|
||||
{
|
||||
/* They all exist? Must be something wrong! Don't write
|
||||
* the viminfo file then. */
|
||||
EMSG2(_("E929: Too many viminfo temp files, like %s!"),
|
||||
tempname);
|
||||
break;
|
||||
}
|
||||
*wp = next_char;
|
||||
--next_char;
|
||||
}
|
||||
break;
|
||||
|
||||
if (tempname != NULL)
|
||||
break;
|
||||
/* continue if shortname was set */
|
||||
}
|
||||
|
||||
if (tempname != NULL)
|
||||
{
|
||||
#ifdef VMS
|
||||
/* fdopen() fails for some reason */
|
||||
umask_save = umask(077);
|
||||
fp_out = mch_fopen((char *)tempname, WRITEBIN);
|
||||
(void)umask(umask_save);
|
||||
#else
|
||||
int fd;
|
||||
|
||||
/* Use mch_open() to be able to use O_NOFOLLOW and set file
|
||||
* protection:
|
||||
* Unix: same as original file, but strip s-bit. Reset umask to
|
||||
* avoid it getting in the way.
|
||||
* Others: r&w for user only. */
|
||||
# ifdef UNIX
|
||||
umask_save = umask(0);
|
||||
fd = mch_open((char *)tempname,
|
||||
O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW,
|
||||
(int)((st_old.st_mode & 0777) | 0600));
|
||||
(void)umask(umask_save);
|
||||
# else
|
||||
fd = mch_open((char *)tempname,
|
||||
O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, 0600);
|
||||
# endif
|
||||
if (fd < 0)
|
||||
fp_out = NULL;
|
||||
else
|
||||
fp_out = fdopen(fd, WRITEBIN);
|
||||
#endif /* VMS */
|
||||
|
||||
/*
|
||||
* If we can't create in the same directory, try creating a
|
||||
* "normal" temp file. This is just an attempt, renaming the temp
|
||||
* file might fail as well.
|
||||
*/
|
||||
if (fp_out == NULL)
|
||||
{
|
||||
vim_free(tempname);
|
||||
if ((tempname = vim_tempname('o', TRUE)) != NULL)
|
||||
fp_out = mch_fopen((char *)tempname, WRITEBIN);
|
||||
}
|
||||
|
||||
#if defined(UNIX) && defined(HAVE_FCHOWN)
|
||||
if (tempname != NULL && fp_out != NULL)
|
||||
{
|
||||
stat_T tmp_st;
|
||||
|
||||
/*
|
||||
* Make sure the original owner can read/write the tempfile and
|
||||
* otherwise preserve permissions, making sure the group matches.
|
||||
*/
|
||||
if (fp_out != NULL)
|
||||
if (mch_stat((char *)tempname, &tmp_st) >= 0)
|
||||
{
|
||||
stat_T tmp_st;
|
||||
|
||||
if (mch_stat((char *)tempname, &tmp_st) >= 0)
|
||||
{
|
||||
if (st_old.st_uid != tmp_st.st_uid)
|
||||
/* Changing the owner might fail, in which case the
|
||||
* file will now owned by the current user, oh well. */
|
||||
ignored = fchown(fileno(fp_out), st_old.st_uid, -1);
|
||||
if (st_old.st_gid != tmp_st.st_gid
|
||||
&& fchown(fileno(fp_out), -1, st_old.st_gid) == -1)
|
||||
/* can't set the group to what it should be, remove
|
||||
* group permissions */
|
||||
(void)mch_setperm(tempname, 0600);
|
||||
}
|
||||
else
|
||||
/* can't stat the file, set conservative permissions */
|
||||
if (st_old.st_uid != tmp_st.st_uid)
|
||||
/* Changing the owner might fail, in which case the
|
||||
* file will now owned by the current user, oh well. */
|
||||
ignored = fchown(fileno(fp_out), st_old.st_uid, -1);
|
||||
if (st_old.st_gid != tmp_st.st_gid
|
||||
&& fchown(fileno(fp_out), -1, st_old.st_gid) == -1)
|
||||
/* can't set the group to what it should be, remove
|
||||
* group permissions */
|
||||
(void)mch_setperm(tempname, 0600);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
/* can't stat the file, set conservative permissions */
|
||||
(void)mch_setperm(tempname, 0600);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -417,12 +417,12 @@ getcmdline(
|
||||
|
||||
cursorcmd(); /* set the cursor on the right spot */
|
||||
|
||||
/* Get a character. Ignore K_IGNORE, it should not do anything, such
|
||||
* as stop completion. */
|
||||
/* Get a character. Ignore K_IGNORE and K_NOP, they should not do
|
||||
* anything, such as stop completion. */
|
||||
do
|
||||
{
|
||||
c = safe_vgetc();
|
||||
} while (c == K_IGNORE);
|
||||
} while (c == K_IGNORE || c == K_NOP);
|
||||
|
||||
if (KeyTyped)
|
||||
{
|
||||
|
||||
@@ -635,7 +635,8 @@
|
||||
/* #define FEAT_MBYTE_IME */
|
||||
# endif
|
||||
|
||||
#if defined(FEAT_MBYTE_IME) && !defined(FEAT_MBYTE)
|
||||
/* Input methods are only useful with +multi_byte. */
|
||||
#if (defined(FEAT_MBYTE_IME) || defined(FEAT_XIM)) && !defined(FEAT_MBYTE)
|
||||
# define FEAT_MBYTE
|
||||
#endif
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*
|
||||
* Contributors:
|
||||
* - Ken Takata
|
||||
* - Yasuhiro Matsumoto
|
||||
*
|
||||
* Copyright (C) 2013 MURAOKA Taro <koron.kaoriya@gmail.com>
|
||||
* THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE.
|
||||
@@ -23,7 +24,21 @@
|
||||
#include <math.h>
|
||||
#include <d2d1.h>
|
||||
#include <d2d1helper.h>
|
||||
#include <dwrite.h>
|
||||
|
||||
// Disable these macros to compile with old VC and newer SDK (V8.1 or later).
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1700)
|
||||
# define _COM_Outptr_ __out
|
||||
# define _In_reads_(s)
|
||||
# define _In_reads_opt_(s)
|
||||
# define _Maybenull_
|
||||
# define _Out_writes_(s)
|
||||
# define _Out_writes_opt_(s)
|
||||
# define _Out_writes_to_(x, y)
|
||||
# define _Out_writes_to_opt_(x, y)
|
||||
# define _Outptr_
|
||||
#endif
|
||||
|
||||
#include <dwrite_2.h>
|
||||
|
||||
#include "gui_dwrite.h"
|
||||
|
||||
@@ -79,16 +94,6 @@ template <class T> inline void SafeRelease(T **ppT)
|
||||
}
|
||||
}
|
||||
|
||||
struct GdiTextRendererContext
|
||||
{
|
||||
// const fields.
|
||||
COLORREF color;
|
||||
FLOAT cellWidth;
|
||||
|
||||
// working fields.
|
||||
FLOAT offsetX;
|
||||
};
|
||||
|
||||
static DWRITE_PIXEL_GEOMETRY
|
||||
ToPixelGeometry(int value)
|
||||
{
|
||||
@@ -184,17 +189,151 @@ ToInt(DWRITE_RENDERING_MODE value)
|
||||
}
|
||||
}
|
||||
|
||||
class FontCache {
|
||||
public:
|
||||
struct Item {
|
||||
HFONT hFont;
|
||||
IDWriteTextFormat* pTextFormat;
|
||||
DWRITE_FONT_WEIGHT fontWeight;
|
||||
DWRITE_FONT_STYLE fontStyle;
|
||||
Item() : hFont(NULL), pTextFormat(NULL) {}
|
||||
};
|
||||
|
||||
private:
|
||||
int mSize;
|
||||
Item *mItems;
|
||||
|
||||
public:
|
||||
FontCache(int size = 2) :
|
||||
mSize(size),
|
||||
mItems(new Item[size])
|
||||
{
|
||||
}
|
||||
|
||||
~FontCache()
|
||||
{
|
||||
for (int i = 0; i < mSize; ++i)
|
||||
SafeRelease(&mItems[i].pTextFormat);
|
||||
delete[] mItems;
|
||||
}
|
||||
|
||||
bool get(HFONT hFont, Item &item)
|
||||
{
|
||||
int n = find(hFont);
|
||||
if (n < 0)
|
||||
return false;
|
||||
item = mItems[n];
|
||||
slide(n);
|
||||
return true;
|
||||
}
|
||||
|
||||
void put(const Item& item)
|
||||
{
|
||||
int n = find(item.hFont);
|
||||
if (n < 0)
|
||||
n = mSize - 1;
|
||||
if (mItems[n].pTextFormat != item.pTextFormat)
|
||||
{
|
||||
SafeRelease(&mItems[n].pTextFormat);
|
||||
item.pTextFormat->AddRef();
|
||||
}
|
||||
mItems[n] = item;
|
||||
slide(n);
|
||||
}
|
||||
|
||||
private:
|
||||
int find(HFONT hFont)
|
||||
{
|
||||
for (int i = 0; i < mSize; ++i)
|
||||
{
|
||||
if (mItems[i].hFont == hFont)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void slide(int nextTop)
|
||||
{
|
||||
if (nextTop == 0)
|
||||
return;
|
||||
Item tmp = mItems[nextTop];
|
||||
for (int i = nextTop - 1; i >= 0; --i)
|
||||
mItems[i + 1] = mItems[i];
|
||||
mItems[0] = tmp;
|
||||
}
|
||||
};
|
||||
|
||||
struct DWriteContext {
|
||||
HDC mHDC;
|
||||
bool mDrawing;
|
||||
bool mFallbackDC;
|
||||
|
||||
ID2D1Factory *mD2D1Factory;
|
||||
|
||||
ID2D1DCRenderTarget *mRT;
|
||||
ID2D1SolidColorBrush *mBrush;
|
||||
|
||||
IDWriteFactory *mDWriteFactory;
|
||||
IDWriteFactory2 *mDWriteFactory2;
|
||||
|
||||
IDWriteGdiInterop *mGdiInterop;
|
||||
IDWriteRenderingParams *mRenderingParams;
|
||||
|
||||
FontCache mFontCache;
|
||||
IDWriteTextFormat *mTextFormat;
|
||||
DWRITE_FONT_WEIGHT mFontWeight;
|
||||
DWRITE_FONT_STYLE mFontStyle;
|
||||
|
||||
D2D1_TEXT_ANTIALIAS_MODE mTextAntialiasMode;
|
||||
|
||||
// METHODS
|
||||
|
||||
DWriteContext();
|
||||
|
||||
virtual ~DWriteContext();
|
||||
|
||||
HRESULT CreateTextFormatFromLOGFONT(const LOGFONTW &logFont,
|
||||
IDWriteTextFormat **ppTextFormat);
|
||||
|
||||
HRESULT SetFontByLOGFONT(const LOGFONTW &logFont);
|
||||
|
||||
void SetFont(HFONT hFont);
|
||||
|
||||
void BindDC(HDC hdc, RECT *rect);
|
||||
|
||||
void AssureDrawing();
|
||||
|
||||
ID2D1Brush* SolidBrush(COLORREF color);
|
||||
|
||||
void DrawText(const WCHAR* text, int len,
|
||||
int x, int y, int w, int h, int cellWidth, COLORREF color,
|
||||
UINT fuOptions, CONST RECT *lprc, CONST INT * lpDx);
|
||||
|
||||
void FillRect(RECT *rc, COLORREF color);
|
||||
|
||||
void Flush();
|
||||
|
||||
void SetRenderingParams(
|
||||
const DWriteRenderingParams *params);
|
||||
|
||||
DWriteRenderingParams *GetRenderingParams(
|
||||
DWriteRenderingParams *params);
|
||||
};
|
||||
|
||||
class AdjustedGlyphRun : public DWRITE_GLYPH_RUN
|
||||
{
|
||||
private:
|
||||
FLOAT &mAccum;
|
||||
FLOAT mDelta;
|
||||
FLOAT *mAdjustedAdvances;
|
||||
|
||||
public:
|
||||
AdjustedGlyphRun(
|
||||
const DWRITE_GLYPH_RUN *glyphRun,
|
||||
FLOAT cellWidth) :
|
||||
FLOAT cellWidth,
|
||||
FLOAT &accum) :
|
||||
DWRITE_GLYPH_RUN(*glyphRun),
|
||||
mAccum(accum),
|
||||
mDelta(0.0f),
|
||||
mAdjustedAdvances(new FLOAT[glyphRun->glyphCount])
|
||||
{
|
||||
@@ -209,45 +348,44 @@ public:
|
||||
glyphAdvances = mAdjustedAdvances;
|
||||
}
|
||||
|
||||
~AdjustedGlyphRun(void)
|
||||
~AdjustedGlyphRun()
|
||||
{
|
||||
mAccum += mDelta;
|
||||
delete[] mAdjustedAdvances;
|
||||
}
|
||||
|
||||
FLOAT getDelta(void) const
|
||||
{
|
||||
return mDelta;
|
||||
}
|
||||
|
||||
static FLOAT adjustToCell(FLOAT value, FLOAT cellWidth)
|
||||
{
|
||||
int cellCount = (int)floor(value / cellWidth + 0.5f);
|
||||
int cellCount = int(floor(value / cellWidth + 0.5f));
|
||||
if (cellCount < 1)
|
||||
cellCount = 1;
|
||||
return cellCount * cellWidth;
|
||||
}
|
||||
};
|
||||
|
||||
class GdiTextRenderer FINAL : public IDWriteTextRenderer
|
||||
struct TextRendererContext {
|
||||
// const fields.
|
||||
COLORREF color;
|
||||
FLOAT cellWidth;
|
||||
|
||||
// working fields.
|
||||
FLOAT offsetX;
|
||||
};
|
||||
|
||||
class TextRenderer FINAL : public IDWriteTextRenderer
|
||||
{
|
||||
public:
|
||||
GdiTextRenderer(
|
||||
IDWriteBitmapRenderTarget* bitmapRenderTarget,
|
||||
IDWriteRenderingParams* renderingParams) :
|
||||
TextRenderer(
|
||||
DWriteContext* pDWC) :
|
||||
cRefCount_(0),
|
||||
pRenderTarget_(bitmapRenderTarget),
|
||||
pRenderingParams_(renderingParams)
|
||||
pDWC_(pDWC)
|
||||
{
|
||||
pRenderTarget_->AddRef();
|
||||
pRenderingParams_->AddRef();
|
||||
AddRef();
|
||||
}
|
||||
|
||||
// add "virtual" to avoid a compiler warning
|
||||
virtual ~GdiTextRenderer()
|
||||
virtual ~TextRenderer()
|
||||
{
|
||||
SafeRelease(&pRenderTarget_);
|
||||
SafeRelease(&pRenderingParams_);
|
||||
}
|
||||
|
||||
IFACEMETHOD(IsPixelSnappingDisabled)(
|
||||
@@ -263,7 +401,8 @@ public:
|
||||
__out DWRITE_MATRIX* transform)
|
||||
{
|
||||
// forward the render target's transform
|
||||
pRenderTarget_->GetCurrentTransform(transform);
|
||||
pDWC_->mRT->GetTransform(
|
||||
reinterpret_cast<D2D1_MATRIX_3X2_F*>(transform));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -271,43 +410,12 @@ public:
|
||||
__maybenull void* clientDrawingContext,
|
||||
__out FLOAT* pixelsPerDip)
|
||||
{
|
||||
*pixelsPerDip = pRenderTarget_->GetPixelsPerDip();
|
||||
float dpiX, unused;
|
||||
pDWC_->mRT->GetDpi(&dpiX, &unused);
|
||||
*pixelsPerDip = dpiX / 96.0f;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHOD(DrawGlyphRun)(
|
||||
__maybenull void* clientDrawingContext,
|
||||
FLOAT baselineOriginX,
|
||||
FLOAT baselineOriginY,
|
||||
DWRITE_MEASURING_MODE measuringMode,
|
||||
__in DWRITE_GLYPH_RUN const* glyphRun,
|
||||
__in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
|
||||
IUnknown* clientDrawingEffect)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
GdiTextRendererContext *context =
|
||||
reinterpret_cast<GdiTextRendererContext*>(clientDrawingContext);
|
||||
|
||||
AdjustedGlyphRun adjustedGlyphRun(glyphRun, context->cellWidth);
|
||||
|
||||
// Pass on the drawing call to the render target to do the real work.
|
||||
RECT dirtyRect = {0};
|
||||
|
||||
hr = pRenderTarget_->DrawGlyphRun(
|
||||
baselineOriginX + context->offsetX,
|
||||
baselineOriginY,
|
||||
measuringMode,
|
||||
&adjustedGlyphRun,
|
||||
pRenderingParams_,
|
||||
context->color,
|
||||
&dirtyRect);
|
||||
|
||||
context->offsetX += adjustedGlyphRun.getDelta();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
IFACEMETHOD(DrawUnderline)(
|
||||
__maybenull void* clientDrawingContext,
|
||||
FLOAT baselineOriginX,
|
||||
@@ -340,6 +448,69 @@ public:
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
IFACEMETHOD(DrawGlyphRun)(
|
||||
__maybenull void* clientDrawingContext,
|
||||
FLOAT baselineOriginX,
|
||||
FLOAT baselineOriginY,
|
||||
DWRITE_MEASURING_MODE measuringMode,
|
||||
__in DWRITE_GLYPH_RUN const* glyphRun,
|
||||
__in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
|
||||
IUnknown* clientDrawingEffect)
|
||||
{
|
||||
TextRendererContext *context =
|
||||
reinterpret_cast<TextRendererContext*>(clientDrawingContext);
|
||||
|
||||
AdjustedGlyphRun adjustedGlyphRun(glyphRun, context->cellWidth,
|
||||
context->offsetX);
|
||||
|
||||
if (pDWC_->mDWriteFactory2 != NULL)
|
||||
{
|
||||
IDWriteColorGlyphRunEnumerator *enumerator = NULL;
|
||||
HRESULT hr = pDWC_->mDWriteFactory2->TranslateColorGlyphRun(
|
||||
baselineOriginX + context->offsetX,
|
||||
baselineOriginY,
|
||||
&adjustedGlyphRun,
|
||||
NULL,
|
||||
DWRITE_MEASURING_MODE_GDI_NATURAL,
|
||||
NULL,
|
||||
0,
|
||||
&enumerator);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// Draw by IDWriteFactory2 for color emoji
|
||||
BOOL hasRun = TRUE;
|
||||
enumerator->MoveNext(&hasRun);
|
||||
while (hasRun)
|
||||
{
|
||||
const DWRITE_COLOR_GLYPH_RUN* colorGlyphRun;
|
||||
enumerator->GetCurrentRun(&colorGlyphRun);
|
||||
|
||||
pDWC_->mBrush->SetColor(colorGlyphRun->runColor);
|
||||
pDWC_->mRT->DrawGlyphRun(
|
||||
D2D1::Point2F(
|
||||
colorGlyphRun->baselineOriginX,
|
||||
colorGlyphRun->baselineOriginY),
|
||||
&colorGlyphRun->glyphRun,
|
||||
pDWC_->mBrush,
|
||||
DWRITE_MEASURING_MODE_NATURAL);
|
||||
enumerator->MoveNext(&hasRun);
|
||||
}
|
||||
SafeRelease(&enumerator);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw by IDWriteFactory (without color emoji)
|
||||
pDWC_->mRT->DrawGlyphRun(
|
||||
D2D1::Point2F(
|
||||
baselineOriginX + context->offsetX,
|
||||
baselineOriginY),
|
||||
&adjustedGlyphRun,
|
||||
pDWC_->SolidBrush(context->color),
|
||||
DWRITE_MEASURING_MODE_NATURAL);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
public:
|
||||
IFACEMETHOD_(unsigned long, AddRef) ()
|
||||
{
|
||||
@@ -385,80 +556,28 @@ public:
|
||||
|
||||
private:
|
||||
long cRefCount_;
|
||||
IDWriteBitmapRenderTarget* pRenderTarget_;
|
||||
IDWriteRenderingParams* pRenderingParams_;
|
||||
};
|
||||
|
||||
struct DWriteContext {
|
||||
FLOAT mDpiScaleX;
|
||||
FLOAT mDpiScaleY;
|
||||
bool mDrawing;
|
||||
|
||||
ID2D1Factory *mD2D1Factory;
|
||||
|
||||
ID2D1DCRenderTarget *mRT;
|
||||
ID2D1SolidColorBrush *mBrush;
|
||||
|
||||
IDWriteFactory *mDWriteFactory;
|
||||
IDWriteGdiInterop *mGdiInterop;
|
||||
IDWriteRenderingParams *mRenderingParams;
|
||||
IDWriteTextFormat *mTextFormat;
|
||||
|
||||
HFONT mLastHFont;
|
||||
DWRITE_FONT_WEIGHT mFontWeight;
|
||||
DWRITE_FONT_STYLE mFontStyle;
|
||||
|
||||
D2D1_TEXT_ANTIALIAS_MODE mTextAntialiasMode;
|
||||
|
||||
// METHODS
|
||||
|
||||
DWriteContext();
|
||||
|
||||
virtual ~DWriteContext();
|
||||
|
||||
HRESULT SetLOGFONT(const LOGFONTW &logFont, float fontSize);
|
||||
|
||||
void SetFont(HFONT hFont);
|
||||
|
||||
void SetFont(const LOGFONTW &logFont);
|
||||
|
||||
void DrawText(HDC hdc, const WCHAR* text, int len,
|
||||
int x, int y, int w, int h, int cellWidth, COLORREF color);
|
||||
|
||||
float PixelsToDipsX(int x);
|
||||
|
||||
float PixelsToDipsY(int y);
|
||||
|
||||
void SetRenderingParams(
|
||||
const DWriteRenderingParams *params);
|
||||
|
||||
DWriteRenderingParams *GetRenderingParams(
|
||||
DWriteRenderingParams *params);
|
||||
DWriteContext* pDWC_;
|
||||
};
|
||||
|
||||
DWriteContext::DWriteContext() :
|
||||
mDpiScaleX(1.f),
|
||||
mDpiScaleY(1.f),
|
||||
mHDC(NULL),
|
||||
mDrawing(false),
|
||||
mFallbackDC(false),
|
||||
mD2D1Factory(NULL),
|
||||
mRT(NULL),
|
||||
mBrush(NULL),
|
||||
mDWriteFactory(NULL),
|
||||
mDWriteFactory2(NULL),
|
||||
mGdiInterop(NULL),
|
||||
mRenderingParams(NULL),
|
||||
mFontCache(8),
|
||||
mTextFormat(NULL),
|
||||
mLastHFont(NULL),
|
||||
mFontWeight(DWRITE_FONT_WEIGHT_NORMAL),
|
||||
mFontStyle(DWRITE_FONT_STYLE_NORMAL),
|
||||
mTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_DEFAULT)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
HDC screen = ::GetDC(0);
|
||||
mDpiScaleX = ::GetDeviceCaps(screen, LOGPIXELSX) / 96.0f;
|
||||
mDpiScaleY = ::GetDeviceCaps(screen, LOGPIXELSY) / 96.0f;
|
||||
::ReleaseDC(0, screen);
|
||||
|
||||
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||
__uuidof(ID2D1Factory), NULL,
|
||||
reinterpret_cast<void**>(&mD2D1Factory));
|
||||
@@ -495,6 +614,15 @@ DWriteContext::DWriteContext() :
|
||||
mDWriteFactory);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
DWriteCreateFactory(
|
||||
DWRITE_FACTORY_TYPE_SHARED,
|
||||
__uuidof(IDWriteFactory2),
|
||||
reinterpret_cast<IUnknown**>(&mDWriteFactory2));
|
||||
_RPT1(_CRT_WARN, "IDWriteFactory2: %s\n", SUCCEEDED(hr) ? "available" : "not available");
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = mDWriteFactory->GetGdiInterop(&mGdiInterop);
|
||||
@@ -515,20 +643,24 @@ DWriteContext::~DWriteContext()
|
||||
SafeRelease(&mRenderingParams);
|
||||
SafeRelease(&mGdiInterop);
|
||||
SafeRelease(&mDWriteFactory);
|
||||
SafeRelease(&mDWriteFactory2);
|
||||
SafeRelease(&mBrush);
|
||||
SafeRelease(&mRT);
|
||||
SafeRelease(&mD2D1Factory);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
DWriteContext::SetLOGFONT(const LOGFONTW &logFont, float fontSize)
|
||||
DWriteContext::CreateTextFormatFromLOGFONT(const LOGFONTW &logFont,
|
||||
IDWriteTextFormat **ppTextFormat)
|
||||
{
|
||||
// Most of this function is copy from: http://msdn.microsoft.com/en-us/library/windows/desktop/dd941783(v=vs.85).aspx
|
||||
// Most of this function is copied from: https://github.com/Microsoft/Windows-classic-samples/blob/master/Samples/Win7Samples/multimedia/DirectWrite/RenderTest/TextHelpers.cpp
|
||||
HRESULT hr = S_OK;
|
||||
IDWriteTextFormat *pTextFormat = NULL;
|
||||
|
||||
IDWriteFont *font = NULL;
|
||||
IDWriteFontFamily *fontFamily = NULL;
|
||||
IDWriteLocalizedStrings *localizedFamilyNames = NULL;
|
||||
float fontSize = 0;
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
@@ -561,33 +693,30 @@ DWriteContext::SetLOGFONT(const LOGFONTW &logFont, float fontSize)
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// If no font size was passed in use the lfHeight of the LOGFONT.
|
||||
if (fontSize == 0)
|
||||
// Use lfHeight of the LOGFONT as font size.
|
||||
fontSize = float(logFont.lfHeight);
|
||||
|
||||
if (fontSize < 0)
|
||||
{
|
||||
// Convert from pixels to DIPs.
|
||||
fontSize = PixelsToDipsY(logFont.lfHeight);
|
||||
if (fontSize < 0)
|
||||
{
|
||||
// Negative lfHeight represents the size of the em unit.
|
||||
fontSize = -fontSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Positive lfHeight represents the cell height (ascent +
|
||||
// descent).
|
||||
DWRITE_FONT_METRICS fontMetrics;
|
||||
font->GetMetrics(&fontMetrics);
|
||||
// Negative lfHeight represents the size of the em unit.
|
||||
fontSize = -fontSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Positive lfHeight represents the cell height (ascent +
|
||||
// descent).
|
||||
DWRITE_FONT_METRICS fontMetrics;
|
||||
font->GetMetrics(&fontMetrics);
|
||||
|
||||
// Convert the cell height (ascent + descent) from design units
|
||||
// to ems.
|
||||
float cellHeight = static_cast<float>(
|
||||
fontMetrics.ascent + fontMetrics.descent)
|
||||
/ fontMetrics.designUnitsPerEm;
|
||||
// Convert the cell height (ascent + descent) from design units
|
||||
// to ems.
|
||||
float cellHeight = static_cast<float>(
|
||||
fontMetrics.ascent + fontMetrics.descent)
|
||||
/ fontMetrics.designUnitsPerEm;
|
||||
|
||||
// Divide the font size by the cell height to get the font em
|
||||
// size.
|
||||
fontSize /= cellHeight;
|
||||
}
|
||||
// Divide the font size by the cell height to get the font em
|
||||
// size.
|
||||
fontSize /= cellHeight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -612,123 +741,165 @@ DWriteContext::SetLOGFONT(const LOGFONTW &logFont, float fontSize)
|
||||
font->GetStretch(),
|
||||
fontSize,
|
||||
localeName,
|
||||
&mTextFormat);
|
||||
&pTextFormat);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
mFontWeight = static_cast<DWRITE_FONT_WEIGHT>(logFont.lfWeight);
|
||||
mFontStyle = logFont.lfItalic ? DWRITE_FONT_STYLE_ITALIC
|
||||
: DWRITE_FONT_STYLE_NORMAL;
|
||||
}
|
||||
hr = pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = pTextFormat->SetParagraphAlignment(
|
||||
DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = pTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
|
||||
|
||||
SafeRelease(&localizedFamilyNames);
|
||||
SafeRelease(&fontFamily);
|
||||
SafeRelease(&font);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
*ppTextFormat = pTextFormat;
|
||||
else
|
||||
SafeRelease(&pTextFormat);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
DWriteContext::SetFontByLOGFONT(const LOGFONTW &logFont)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
IDWriteTextFormat *pTextFormat = NULL;
|
||||
|
||||
hr = CreateTextFormatFromLOGFONT(logFont, &pTextFormat);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
SafeRelease(&mTextFormat);
|
||||
mTextFormat = pTextFormat;
|
||||
mFontWeight = static_cast<DWRITE_FONT_WEIGHT>(logFont.lfWeight);
|
||||
mFontStyle = logFont.lfItalic ? DWRITE_FONT_STYLE_ITALIC
|
||||
: DWRITE_FONT_STYLE_NORMAL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext::SetFont(HFONT hFont)
|
||||
{
|
||||
if (mLastHFont != hFont)
|
||||
FontCache::Item item;
|
||||
if (mFontCache.get(hFont, item))
|
||||
{
|
||||
LOGFONTW lf;
|
||||
if (GetObjectW(hFont, sizeof(lf), &lf))
|
||||
if (item.pTextFormat != NULL)
|
||||
{
|
||||
SetFont(lf);
|
||||
mLastHFont = hFont;
|
||||
item.pTextFormat->AddRef();
|
||||
SafeRelease(&mTextFormat);
|
||||
mTextFormat = item.pTextFormat;
|
||||
mFontWeight = item.fontWeight;
|
||||
mFontStyle = item.fontStyle;
|
||||
mFallbackDC = false;
|
||||
}
|
||||
else
|
||||
mFallbackDC = true;
|
||||
return;
|
||||
}
|
||||
|
||||
HRESULT hr = E_FAIL;
|
||||
LOGFONTW lf;
|
||||
if (GetObjectW(hFont, sizeof(lf), &lf))
|
||||
hr = SetFontByLOGFONT(lf);
|
||||
|
||||
item.hFont = hFont;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
item.pTextFormat = mTextFormat;
|
||||
item.fontWeight = mFontWeight;
|
||||
item.fontStyle = mFontStyle;
|
||||
}
|
||||
mFontCache.put(item);
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext::SetFont(const LOGFONTW &logFont)
|
||||
DWriteContext::BindDC(HDC hdc, RECT *rect)
|
||||
{
|
||||
SafeRelease(&mTextFormat);
|
||||
mLastHFont = NULL;
|
||||
|
||||
HRESULT hr = SetLOGFONT(logFont, 0.f);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = mTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = mTextFormat->SetParagraphAlignment(
|
||||
DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = mTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
|
||||
Flush();
|
||||
mRT->BindDC(hdc, rect);
|
||||
mRT->SetTransform(D2D1::IdentityMatrix());
|
||||
mHDC = hdc;
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext::DrawText(HDC hdc, const WCHAR* text, int len,
|
||||
int x, int y, int w, int h, int cellWidth, COLORREF color)
|
||||
DWriteContext::AssureDrawing()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
IDWriteBitmapRenderTarget *bmpRT = NULL;
|
||||
if (mDrawing == false)
|
||||
{
|
||||
mRT->BeginDraw();
|
||||
mDrawing = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip when any fonts are not set.
|
||||
if (mTextFormat == NULL)
|
||||
ID2D1Brush*
|
||||
DWriteContext::SolidBrush(COLORREF color)
|
||||
{
|
||||
mBrush->SetColor(D2D1::ColorF(UINT32(GetRValue(color)) << 16 |
|
||||
UINT32(GetGValue(color)) << 8 | UINT32(GetBValue(color))));
|
||||
return mBrush;
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext::DrawText(const WCHAR* text, int len,
|
||||
int x, int y, int w, int h, int cellWidth, COLORREF color,
|
||||
UINT fuOptions, CONST RECT *lprc, CONST INT * lpDx)
|
||||
{
|
||||
if (mFallbackDC)
|
||||
{
|
||||
Flush();
|
||||
ExtTextOutW(mHDC, x, y, fuOptions, lprc, text, len, lpDx);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check possibility of zero divided error.
|
||||
if (cellWidth == 0 || mDpiScaleX == 0.0f || mDpiScaleY == 0.0f)
|
||||
return;
|
||||
AssureDrawing();
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = mGdiInterop->CreateBitmapRenderTarget(hdc, w, h, &bmpRT);
|
||||
HRESULT hr;
|
||||
IDWriteTextLayout *textLayout = NULL;
|
||||
|
||||
hr = mDWriteFactory->CreateTextLayout(text, len, mTextFormat,
|
||||
FLOAT(w), FLOAT(h), &textLayout);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
IDWriteTextLayout *textLayout = NULL;
|
||||
DWRITE_TEXT_RANGE textRange = { 0, UINT32(len) };
|
||||
textLayout->SetFontWeight(mFontWeight, textRange);
|
||||
textLayout->SetFontStyle(mFontStyle, textRange);
|
||||
|
||||
HDC memdc = bmpRT->GetMemoryDC();
|
||||
BitBlt(memdc, 0, 0, w, h, hdc, x, y, SRCCOPY);
|
||||
|
||||
hr = mDWriteFactory->CreateGdiCompatibleTextLayout(
|
||||
text, len, mTextFormat, PixelsToDipsX(w),
|
||||
PixelsToDipsY(h), mDpiScaleX, NULL, TRUE, &textLayout);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
DWRITE_TEXT_RANGE textRange = { 0, (UINT32)len };
|
||||
textLayout->SetFontWeight(mFontWeight, textRange);
|
||||
textLayout->SetFontStyle(mFontStyle, textRange);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
GdiTextRenderer *renderer = new GdiTextRenderer(bmpRT,
|
||||
mRenderingParams);
|
||||
GdiTextRendererContext data = {
|
||||
color,
|
||||
PixelsToDipsX(cellWidth),
|
||||
0.0f
|
||||
};
|
||||
textLayout->Draw(&data, renderer, 0, 0);
|
||||
SafeRelease(&renderer);
|
||||
}
|
||||
|
||||
BitBlt(hdc, x, y, w, h, memdc, 0, 0, SRCCOPY);
|
||||
|
||||
SafeRelease(&textLayout);
|
||||
TextRenderer renderer(this);
|
||||
TextRendererContext context = { color, FLOAT(cellWidth), 0.0f };
|
||||
textLayout->Draw(&context, &renderer, FLOAT(x), FLOAT(y));
|
||||
}
|
||||
|
||||
SafeRelease(&bmpRT);
|
||||
SafeRelease(&textLayout);
|
||||
}
|
||||
|
||||
float
|
||||
DWriteContext::PixelsToDipsX(int x)
|
||||
void
|
||||
DWriteContext::FillRect(RECT *rc, COLORREF color)
|
||||
{
|
||||
return x / mDpiScaleX;
|
||||
AssureDrawing();
|
||||
mRT->FillRectangle(
|
||||
D2D1::RectF(FLOAT(rc->left), FLOAT(rc->top),
|
||||
FLOAT(rc->right), FLOAT(rc->bottom)),
|
||||
SolidBrush(color));
|
||||
}
|
||||
|
||||
float
|
||||
DWriteContext::PixelsToDipsY(int y)
|
||||
void
|
||||
DWriteContext::Flush()
|
||||
{
|
||||
return y / mDpiScaleY;
|
||||
if (mDrawing)
|
||||
{
|
||||
mRT->EndDraw();
|
||||
mDrawing = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -757,6 +928,10 @@ DWriteContext::SetRenderingParams(
|
||||
SafeRelease(&mRenderingParams);
|
||||
mRenderingParams = renderingParams;
|
||||
mTextAntialiasMode = textAntialiasMode;
|
||||
|
||||
Flush();
|
||||
mRT->SetTextRenderingParams(mRenderingParams);
|
||||
mRT->SetTextAntialiasMode(mTextAntialiasMode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -824,40 +999,23 @@ DWriteContext_Open(void)
|
||||
return new DWriteContext();
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext_BeginDraw(DWriteContext *ctx)
|
||||
{
|
||||
if (ctx != NULL && ctx->mRT != NULL)
|
||||
{
|
||||
ctx->mRT->BeginDraw();
|
||||
ctx->mRT->SetTransform(D2D1::IdentityMatrix());
|
||||
ctx->mDrawing = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext_BindDC(DWriteContext *ctx, HDC hdc, RECT *rect)
|
||||
{
|
||||
if (ctx != NULL && ctx->mRT != NULL)
|
||||
{
|
||||
ctx->mRT->BindDC(hdc, rect);
|
||||
ctx->mRT->SetTextAntialiasMode(ctx->mTextAntialiasMode);
|
||||
}
|
||||
if (ctx != NULL)
|
||||
ctx->BindDC(hdc, rect);
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext_SetFont(DWriteContext *ctx, HFONT hFont)
|
||||
{
|
||||
if (ctx != NULL)
|
||||
{
|
||||
ctx->SetFont(hFont);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext_DrawText(
|
||||
DWriteContext *ctx,
|
||||
HDC hdc,
|
||||
const WCHAR* text,
|
||||
int len,
|
||||
int x,
|
||||
@@ -865,20 +1023,28 @@ DWriteContext_DrawText(
|
||||
int w,
|
||||
int h,
|
||||
int cellWidth,
|
||||
COLORREF color)
|
||||
COLORREF color,
|
||||
UINT fuOptions,
|
||||
CONST RECT *lprc,
|
||||
CONST INT * lpDx)
|
||||
{
|
||||
if (ctx != NULL)
|
||||
ctx->DrawText(hdc, text, len, x, y, w, h, cellWidth, color);
|
||||
ctx->DrawText(text, len, x, y, w, h, cellWidth, color,
|
||||
fuOptions, lprc, lpDx);
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext_EndDraw(DWriteContext *ctx)
|
||||
DWriteContext_FillRect(DWriteContext *ctx, RECT *rc, COLORREF color)
|
||||
{
|
||||
if (ctx != NULL && ctx->mRT != NULL)
|
||||
{
|
||||
ctx->mRT->EndDraw();
|
||||
ctx->mDrawing = false;
|
||||
}
|
||||
if (ctx != NULL)
|
||||
ctx->FillRect(rc, color);
|
||||
}
|
||||
|
||||
void
|
||||
DWriteContext_Flush(DWriteContext *ctx)
|
||||
{
|
||||
if (ctx != NULL)
|
||||
ctx->Flush();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*
|
||||
* Contributors:
|
||||
* - Ken Takata
|
||||
* - Yasuhiro Matsumoto
|
||||
*
|
||||
* Copyright (C) 2013 MURAOKA Taro <koron.kaoriya@gmail.com>
|
||||
* THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE.
|
||||
@@ -54,12 +55,10 @@ void DWrite_Init(void);
|
||||
void DWrite_Final(void);
|
||||
|
||||
DWriteContext *DWriteContext_Open(void);
|
||||
void DWriteContext_BeginDraw(DWriteContext *ctx);
|
||||
void DWriteContext_BindDC(DWriteContext *ctx, HDC hdc, RECT *rect);
|
||||
void DWriteContext_SetFont(DWriteContext *ctx, HFONT hFont);
|
||||
void DWriteContext_DrawText(
|
||||
DWriteContext *ctx,
|
||||
HDC hdc,
|
||||
const WCHAR* text,
|
||||
int len,
|
||||
int x,
|
||||
@@ -67,8 +66,12 @@ void DWriteContext_DrawText(
|
||||
int w,
|
||||
int h,
|
||||
int cellWidth,
|
||||
COLORREF color);
|
||||
void DWriteContext_EndDraw(DWriteContext *ctx);
|
||||
COLORREF color,
|
||||
UINT fuOptions,
|
||||
CONST RECT *lprc,
|
||||
CONST INT * lpDx);
|
||||
void DWriteContext_FillRect(DWriteContext *ctx, RECT *rc, COLORREF color);
|
||||
void DWriteContext_Flush(DWriteContext *ctx);
|
||||
void DWriteContext_Close(DWriteContext *ctx);
|
||||
|
||||
void DWriteContext_SetRenderingParams(
|
||||
|
||||
184
src/gui_w32.c
184
src/gui_w32.c
@@ -34,28 +34,14 @@ static DWriteContext *s_dwc = NULL;
|
||||
static int s_directx_enabled = 0;
|
||||
static int s_directx_load_attempted = 0;
|
||||
# define IS_ENABLE_DIRECTX() (s_directx_enabled && s_dwc != NULL)
|
||||
static int directx_enabled(void);
|
||||
static void directx_binddc(void);
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_MENU
|
||||
static int gui_mswin_get_menu_height(int fix_window);
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_DIRECTX) || defined(PROTO)
|
||||
int
|
||||
directx_enabled(void)
|
||||
{
|
||||
if (s_dwc != NULL)
|
||||
return 1;
|
||||
else if (s_directx_load_attempted)
|
||||
return 0;
|
||||
/* load DirectX */
|
||||
DWrite_Init();
|
||||
s_directx_load_attempted = 1;
|
||||
s_dwc = DWriteContext_Open();
|
||||
return s_dwc != NULL ? 1 : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_RENDER_OPTIONS) || defined(PROTO)
|
||||
int
|
||||
gui_mch_set_rendering_options(char_u *s)
|
||||
@@ -369,6 +355,34 @@ static int allow_scrollbar = FALSE;
|
||||
# define MyTranslateMessage(x) TranslateMessage(x)
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
static int
|
||||
directx_enabled(void)
|
||||
{
|
||||
if (s_dwc != NULL)
|
||||
return 1;
|
||||
else if (s_directx_load_attempted)
|
||||
return 0;
|
||||
/* load DirectX */
|
||||
DWrite_Init();
|
||||
s_directx_load_attempted = 1;
|
||||
s_dwc = DWriteContext_Open();
|
||||
directx_binddc();
|
||||
return s_dwc != NULL ? 1 : 0;
|
||||
}
|
||||
|
||||
static void
|
||||
directx_binddc(void)
|
||||
{
|
||||
if (s_textArea != NULL)
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(s_textArea, &rect);
|
||||
DWriteContext_BindDC(s_dwc, s_hdc, &rect);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_MBYTE) || defined(GLOBAL_IME)
|
||||
/* use of WindowProc depends on wide_WindowProc */
|
||||
# define MyWindowProc vim_WindowProc
|
||||
@@ -484,9 +498,11 @@ static void TrackUserActivity(UINT uMsg);
|
||||
*
|
||||
* These LOGFONT used for IME.
|
||||
*/
|
||||
#ifdef FEAT_MBYTE
|
||||
#if defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME)
|
||||
/* holds LOGFONT for 'guifontwide' if available, otherwise 'guifont' */
|
||||
static LOGFONT norm_logfont;
|
||||
#endif
|
||||
#ifdef FEAT_MBYTE_IME
|
||||
/* holds LOGFONT for 'guifont' always. */
|
||||
static LOGFONT sub_logfont;
|
||||
#endif
|
||||
@@ -589,6 +605,10 @@ _OnBlinkTimer(
|
||||
blink_timer = (UINT) SetTimer(NULL, 0, (UINT)blink_ontime,
|
||||
(TIMERPROC)_OnBlinkTimer);
|
||||
}
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_Flush(s_dwc);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1000,6 +1020,19 @@ _OnMouseMoveOrRelease(
|
||||
_OnMouseEvent(button, x, y, FALSE, keyFlags);
|
||||
}
|
||||
|
||||
static void
|
||||
_OnSizeTextArea(
|
||||
HWND hwnd UNUSED,
|
||||
UINT state UNUSED,
|
||||
int cx UNUSED,
|
||||
int cy UNUSED)
|
||||
{
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
directx_binddc();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FEAT_MENU
|
||||
/*
|
||||
* Find the vimmenu_T with the given id
|
||||
@@ -1234,6 +1267,7 @@ _TextAreaWndProc(
|
||||
HANDLE_MSG(hwnd, WM_XBUTTONDBLCLK,_OnMouseButtonDown);
|
||||
HANDLE_MSG(hwnd, WM_XBUTTONDOWN,_OnMouseButtonDown);
|
||||
HANDLE_MSG(hwnd, WM_XBUTTONUP, _OnMouseMoveOrRelease);
|
||||
HANDLE_MSG(hwnd, WM_SIZE, _OnSizeTextArea);
|
||||
|
||||
#ifdef FEAT_BEVAL_GUI
|
||||
case WM_NOTIFY: Handle_WM_Notify(hwnd, (LPNMHDR)lParam);
|
||||
@@ -1633,6 +1667,11 @@ gui_mch_invert_rectangle(
|
||||
{
|
||||
RECT rc;
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_Flush(s_dwc);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Note: InvertRect() excludes right and bottom of rectangle.
|
||||
*/
|
||||
@@ -1661,6 +1700,11 @@ gui_mch_draw_hollow_cursor(guicolor_T color)
|
||||
HBRUSH hbr;
|
||||
RECT rc;
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_Flush(s_dwc);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Note: FrameRect() excludes right and bottom of rectangle.
|
||||
*/
|
||||
@@ -1701,6 +1745,12 @@ gui_mch_draw_part_cursor(
|
||||
rc.top = FILL_Y(gui.row) + gui.char_height - h;
|
||||
rc.right = rc.left + w;
|
||||
rc.bottom = rc.top + h;
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_Flush(s_dwc);
|
||||
#endif
|
||||
|
||||
hbr = CreateSolidBrush(color);
|
||||
FillRect(s_hdc, &rc, hbr);
|
||||
DeleteBrush(hbr);
|
||||
@@ -2856,10 +2906,6 @@ _OnPaint(
|
||||
|
||||
out_flush(); /* make sure all output has been processed */
|
||||
(void)BeginPaint(hwnd, &ps);
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_BeginDraw(s_dwc);
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
/* prevent multi-byte characters from misprinting on an invalid
|
||||
@@ -2876,19 +2922,11 @@ _OnPaint(
|
||||
|
||||
if (!IsRectEmpty(&ps.rcPaint))
|
||||
{
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_BindDC(s_dwc, s_hdc, &ps.rcPaint);
|
||||
#endif
|
||||
gui_redraw(ps.rcPaint.left, ps.rcPaint.top,
|
||||
ps.rcPaint.right - ps.rcPaint.left + 1,
|
||||
ps.rcPaint.bottom - ps.rcPaint.top + 1);
|
||||
}
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_EndDraw(s_dwc);
|
||||
#endif
|
||||
EndPaint(hwnd, &ps);
|
||||
}
|
||||
}
|
||||
@@ -3010,6 +3048,11 @@ gui_mch_flash(int msec)
|
||||
{
|
||||
RECT rc;
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_Flush(s_dwc);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Note: InvertRect() excludes right and bottom of rectangle.
|
||||
*/
|
||||
@@ -3082,6 +3125,12 @@ gui_mch_delete_lines(
|
||||
|
||||
intel_gpu_workaround();
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
// Commit drawing queue before ScrollWindowEx.
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_Flush(s_dwc);
|
||||
#endif
|
||||
|
||||
rc.left = FILL_X(gui.scroll_region_left);
|
||||
rc.right = FILL_X(gui.scroll_region_right + 1);
|
||||
rc.top = FILL_Y(row);
|
||||
@@ -3115,6 +3164,12 @@ gui_mch_insert_lines(
|
||||
|
||||
intel_gpu_workaround();
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
// Commit drawing queue before ScrollWindowEx.
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_Flush(s_dwc);
|
||||
#endif
|
||||
|
||||
rc.left = FILL_X(gui.scroll_region_left);
|
||||
rc.right = FILL_X(gui.scroll_region_right + 1);
|
||||
rc.top = FILL_Y(row);
|
||||
@@ -3308,6 +3363,8 @@ gui_mch_init_font(char_u *font_name, int fontset UNUSED)
|
||||
font_name = (char_u *)lf.lfFaceName;
|
||||
#if defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME)
|
||||
norm_logfont = lf;
|
||||
#endif
|
||||
#ifdef FEAT_MBYTE_IME
|
||||
sub_logfont = lf;
|
||||
#endif
|
||||
#ifdef FEAT_MBYTE_IME
|
||||
@@ -5741,15 +5798,15 @@ gui_mch_set_sp_color(guicolor_T color)
|
||||
gui.currSpColor = color;
|
||||
}
|
||||
|
||||
#if defined(FEAT_MBYTE) && defined(FEAT_MBYTE_IME)
|
||||
#ifdef FEAT_MBYTE_IME
|
||||
/*
|
||||
* Multi-byte handling, originally by Sung-Hoon Baek.
|
||||
* First static functions (no prototypes generated).
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
# include <ime.h> /* Apparently not needed for Cygwin, MingW or Borland. */
|
||||
#endif
|
||||
#include <imm.h>
|
||||
# ifdef _MSC_VER
|
||||
# include <ime.h> /* Apparently not needed for Cygwin, MingW or Borland. */
|
||||
# endif
|
||||
# include <imm.h>
|
||||
|
||||
/*
|
||||
* handle WM_IME_NOTIFY message
|
||||
@@ -5901,7 +5958,7 @@ GetResultStr(HWND hwnd, int GCS, int *lenp)
|
||||
#endif
|
||||
|
||||
/* For global functions we need prototypes. */
|
||||
#if (defined(FEAT_MBYTE) && defined(FEAT_MBYTE_IME)) || defined(PROTO)
|
||||
#if defined(FEAT_MBYTE_IME) || defined(PROTO)
|
||||
|
||||
/*
|
||||
* set font to IM.
|
||||
@@ -6026,7 +6083,7 @@ im_get_status(void)
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* FEAT_MBYTE && FEAT_MBYTE_IME */
|
||||
#endif /* FEAT_MBYTE_IME */
|
||||
|
||||
#if defined(FEAT_MBYTE) && !defined(FEAT_MBYTE_IME) && defined(GLOBAL_IME)
|
||||
/* Win32 with GLOBAL IME */
|
||||
@@ -6145,9 +6202,6 @@ gui_mch_draw_string(
|
||||
#endif
|
||||
HPEN hpen, old_pen;
|
||||
int y;
|
||||
#ifdef FEAT_DIRECTX
|
||||
int font_is_ttf_or_vector = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Italic and bold text seems to have an extra row of pixels at the bottom
|
||||
@@ -6208,6 +6262,11 @@ gui_mch_draw_string(
|
||||
hbr = hbr_cache[brush_lru];
|
||||
brush_lru = !brush_lru;
|
||||
}
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_FillRect(s_dwc, &rc, gui.currBgColor);
|
||||
#endif
|
||||
FillRect(s_hdc, &rc, hbr);
|
||||
|
||||
SetBkMode(s_hdc, TRANSPARENT);
|
||||
@@ -6227,16 +6286,7 @@ gui_mch_draw_string(
|
||||
|
||||
#ifdef FEAT_DIRECTX
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
{
|
||||
TEXTMETRIC tm;
|
||||
|
||||
GetTextMetrics(s_hdc, &tm);
|
||||
if (tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR))
|
||||
{
|
||||
font_is_ttf_or_vector = 1;
|
||||
DWriteContext_SetFont(s_dwc, (HFONT)gui.currFont);
|
||||
}
|
||||
}
|
||||
DWriteContext_SetFont(s_dwc, (HFONT)gui.currFont);
|
||||
#endif
|
||||
|
||||
if (pad_size != Columns || padding == NULL || padding[0] != gui.char_width)
|
||||
@@ -6347,12 +6397,13 @@ gui_mch_draw_string(
|
||||
++clen;
|
||||
}
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX() && font_is_ttf_or_vector)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
{
|
||||
/* Add one to "cells" for italics. */
|
||||
DWriteContext_DrawText(s_dwc, s_hdc, unicodebuf, wlen,
|
||||
DWriteContext_DrawText(s_dwc, unicodebuf, wlen,
|
||||
TEXT_X(col), TEXT_Y(row), FILL_X(cells + 1), FILL_Y(1),
|
||||
gui.char_width, gui.currFgColor);
|
||||
gui.char_width, gui.currFgColor,
|
||||
foptions, pcliprect, unicodepdy);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -6411,6 +6462,12 @@ gui_mch_draw_string(
|
||||
foptions, pcliprect, (char *)text, len, padding);
|
||||
}
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX() &&
|
||||
(flags & (DRAW_UNDERL | DRAW_STRIKE | DRAW_UNDERC | DRAW_CURSOR)))
|
||||
DWriteContext_Flush(s_dwc);
|
||||
#endif
|
||||
|
||||
/* Underline */
|
||||
if (flags & DRAW_UNDERL)
|
||||
{
|
||||
@@ -6473,6 +6530,11 @@ gui_mch_flush(void)
|
||||
BOOL __stdcall GdiFlush(void);
|
||||
# endif
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_Flush(s_dwc);
|
||||
#endif
|
||||
|
||||
GdiFlush();
|
||||
}
|
||||
|
||||
@@ -6481,6 +6543,14 @@ clear_rect(RECT *rcp)
|
||||
{
|
||||
HBRUSH hbr;
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
{
|
||||
DWriteContext_FillRect(s_dwc, rcp, gui.back_pixel);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
hbr = CreateSolidBrush(gui.back_pixel);
|
||||
FillRect(s_hdc, rcp, hbr);
|
||||
DeleteBrush(hbr);
|
||||
@@ -8386,6 +8456,11 @@ gui_mch_drawsign(int row, int col, int typenr)
|
||||
if (!gui.in_use || (sign = (signicon_t *)sign_get_image(typenr)) == NULL)
|
||||
return;
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_Flush(s_dwc);
|
||||
#endif
|
||||
|
||||
x = TEXT_X(col);
|
||||
y = TEXT_Y(row);
|
||||
w = gui.char_width * 2;
|
||||
@@ -8865,6 +8940,11 @@ netbeans_draw_multisign_indicator(int row)
|
||||
x = 0;
|
||||
y = TEXT_Y(row);
|
||||
|
||||
#if defined(FEAT_DIRECTX)
|
||||
if (IS_ENABLE_DIRECTX())
|
||||
DWriteContext_Flush(s_dwc);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < gui.char_height - 3; i++)
|
||||
SetPixel(s_hdc, x+2, y++, gui.currFgColor);
|
||||
|
||||
|
||||
@@ -79,8 +79,16 @@ INLINE void vterm_rect_move(VTermRect *rect, int row_delta, int col_delta)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The ansi_index is used for the lower 16 colors, which can be set to any
|
||||
* color. */
|
||||
#define VTERM_ANSI_INDEX_DEFAULT 0 /* color cleared */
|
||||
#define VTERM_ANSI_INDEX_MIN 1
|
||||
#define VTERM_ANSI_INDEX_MAX 16
|
||||
#define VTERM_ANSI_INDEX_NONE 255 /* non-ANSI color, use red/green/blue */
|
||||
|
||||
typedef struct {
|
||||
uint8_t red, green, blue;
|
||||
uint8_t ansi_index;
|
||||
} VTermColor;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -3,25 +3,25 @@
|
||||
#include <stdio.h>
|
||||
|
||||
static const VTermColor ansi_colors[] = {
|
||||
/* R G B */
|
||||
{ 0, 0, 0 }, /* black */
|
||||
{ 224, 0, 0 }, /* red */
|
||||
{ 0, 224, 0 }, /* green */
|
||||
{ 224, 224, 0 }, /* yellow */
|
||||
{ 0, 0, 224 }, /* blue */
|
||||
{ 224, 0, 224 }, /* magenta */
|
||||
{ 0, 224, 224 }, /* cyan */
|
||||
{ 224, 224, 224 }, /* white == light grey */
|
||||
/* R G B index */
|
||||
{ 0, 0, 0, 1 }, /* black */
|
||||
{ 224, 0, 0, 2 }, /* red */
|
||||
{ 0, 224, 0, 3 }, /* green */
|
||||
{ 224, 224, 0, 4 }, /* yellow */
|
||||
{ 0, 0, 224, 5 }, /* blue */
|
||||
{ 224, 0, 224, 6 }, /* magenta */
|
||||
{ 0, 224, 224, 7 }, /* cyan */
|
||||
{ 224, 224, 224, 8 }, /* white == light grey */
|
||||
|
||||
/* high intensity */
|
||||
{ 128, 128, 128 }, /* black */
|
||||
{ 255, 64, 64 }, /* red */
|
||||
{ 64, 255, 64 }, /* green */
|
||||
{ 255, 255, 64 }, /* yellow */
|
||||
{ 64, 64, 255 }, /* blue */
|
||||
{ 255, 64, 255 }, /* magenta */
|
||||
{ 64, 255, 255 }, /* cyan */
|
||||
{ 255, 255, 255 }, /* white for real */
|
||||
{ 128, 128, 128, 9 }, /* black */
|
||||
{ 255, 64, 64, 10 }, /* red */
|
||||
{ 64, 255, 64, 11 }, /* green */
|
||||
{ 255, 255, 64, 12 }, /* yellow */
|
||||
{ 64, 64, 255, 13 }, /* blue */
|
||||
{ 255, 64, 255, 14 }, /* magenta */
|
||||
{ 64, 255, 255, 15 }, /* cyan */
|
||||
{ 255, 255, 255, 16 }, /* white for real */
|
||||
};
|
||||
|
||||
static int ramp6[] = {
|
||||
@@ -57,6 +57,7 @@ static int lookup_colour_palette(const VTermState *state, long index, VTermColor
|
||||
col->blue = ramp6[index % 6];
|
||||
col->green = ramp6[index/6 % 6];
|
||||
col->red = ramp6[index/6/6 % 6];
|
||||
col->ansi_index = VTERM_ANSI_INDEX_NONE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -67,6 +68,7 @@ static int lookup_colour_palette(const VTermState *state, long index, VTermColor
|
||||
col->blue = ramp24[index];
|
||||
col->green = ramp24[index];
|
||||
col->red = ramp24[index];
|
||||
col->ansi_index = VTERM_ANSI_INDEX_NONE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -84,6 +86,7 @@ static int lookup_colour(const VTermState *state, int palette, const long args[]
|
||||
col->red = (uint8_t)CSI_ARG(args[0]);
|
||||
col->green = (uint8_t)CSI_ARG(args[1]);
|
||||
col->blue = (uint8_t)CSI_ARG(args[2]);
|
||||
col->ansi_index = VTERM_ANSI_INDEX_NONE;
|
||||
|
||||
return 3;
|
||||
|
||||
@@ -152,7 +155,9 @@ INTERNAL void vterm_state_newpen(VTermState *state)
|
||||
|
||||
/* 90% grey so that pure white is brighter */
|
||||
state->default_fg.red = state->default_fg.green = state->default_fg.blue = 240;
|
||||
state->default_fg.ansi_index = VTERM_ANSI_INDEX_DEFAULT;
|
||||
state->default_bg.red = state->default_bg.green = state->default_bg.blue = 0;
|
||||
state->default_bg.ansi_index = VTERM_ANSI_INDEX_DEFAULT;
|
||||
|
||||
for(col = 0; col < 16; col++)
|
||||
state->colors[col] = ansi_colors[col];
|
||||
@@ -214,7 +219,10 @@ void vterm_state_set_default_colors(VTermState *state, const VTermColor *default
|
||||
void vterm_state_set_palette_color(VTermState *state, int index, const VTermColor *col)
|
||||
{
|
||||
if(index >= 0 && index < 16)
|
||||
{
|
||||
state->colors[index] = *col;
|
||||
state->colors[index].ansi_index = index + VTERM_ANSI_INDEX_MIN;
|
||||
}
|
||||
}
|
||||
|
||||
void vterm_state_set_bold_highbright(VTermState *state, int bold_is_highbright)
|
||||
|
||||
31
src/mbyte.c
31
src/mbyte.c
@@ -4782,7 +4782,15 @@ iconv_end(void)
|
||||
|
||||
#endif /* FEAT_MBYTE */
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
#ifdef FEAT_GUI
|
||||
# define USE_IMACTIVATEFUNC (!gui.in_use && *p_imaf != NUL)
|
||||
# define USE_IMSTATUSFUNC (!gui.in_use && *p_imsf != NUL)
|
||||
#else
|
||||
# define USE_IMACTIVATEFUNC (*p_imaf != NUL)
|
||||
# define USE_IMSTATUSFUNC (*p_imsf != NUL)
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_EVAL) && defined(FEAT_MBYTE)
|
||||
static void
|
||||
call_imactivatefunc(int active)
|
||||
{
|
||||
@@ -5689,7 +5697,7 @@ im_synthesize_keypress(unsigned int keyval, unsigned int state)
|
||||
xim_reset(void)
|
||||
{
|
||||
#ifdef FEAT_EVAL
|
||||
if (p_imaf[0] != NUL)
|
||||
if (USE_IMACTIVATEFUNC)
|
||||
call_imactivatefunc(im_is_active);
|
||||
else
|
||||
#endif
|
||||
@@ -5868,7 +5876,7 @@ xim_queue_key_press_event(GdkEventKey *event, int down)
|
||||
im_get_status(void)
|
||||
{
|
||||
# ifdef FEAT_EVAL
|
||||
if (p_imsf[0] != NUL)
|
||||
if (USE_IMSTATUSFUNC)
|
||||
return call_imstatusfunc();
|
||||
# endif
|
||||
return im_is_active;
|
||||
@@ -5908,21 +5916,19 @@ im_set_active(int active_arg)
|
||||
/* If 'imdisable' is set, XIM is never active. */
|
||||
if (p_imdisable)
|
||||
active = FALSE;
|
||||
# if !defined(FEAT_GUI_GTK)
|
||||
else if (input_style & XIMPreeditPosition)
|
||||
/* There is a problem in switching XIM off when preediting is used,
|
||||
* and it is not clear how this can be solved. For now, keep XIM on
|
||||
* all the time, like it was done in Vim 5.8. */
|
||||
active = TRUE;
|
||||
# endif
|
||||
|
||||
# if defined(FEAT_EVAL)
|
||||
if (p_imaf[0] != NUL)
|
||||
if (USE_IMACTIVATEFUNC)
|
||||
{
|
||||
if (active != im_get_status())
|
||||
{
|
||||
call_imactivatefunc(active);
|
||||
im_is_active = active;
|
||||
xim_has_focus = active;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -6328,7 +6334,8 @@ xim_real_init(Window x11_window, Display *x11_display)
|
||||
}
|
||||
else
|
||||
{
|
||||
EMSG(_(e_xim));
|
||||
if (!is_not_a_term())
|
||||
EMSG(_(e_xim));
|
||||
XCloseIM(xim);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -6348,7 +6355,7 @@ xim_real_init(Window x11_window, Display *x11_display)
|
||||
im_get_status(void)
|
||||
{
|
||||
# ifdef FEAT_EVAL
|
||||
if (p_imsf[0] != NUL)
|
||||
if (USE_IMSTATUSFUNC)
|
||||
return call_imstatusfunc();
|
||||
# endif
|
||||
return xim_has_focus;
|
||||
@@ -6479,8 +6486,8 @@ static int im_was_set_active = FALSE;
|
||||
int
|
||||
im_get_status()
|
||||
{
|
||||
# ifdef FEAT_EVAL
|
||||
if (p_imsf[0] != NUL)
|
||||
# if defined(FEAT_MBYTE) && defined(FEAT_EVAL)
|
||||
if (USE_IMSTATUSFUNC)
|
||||
return call_imstatusfunc();
|
||||
# endif
|
||||
return im_was_set_active;
|
||||
@@ -6492,7 +6499,7 @@ im_set_active(int active_arg)
|
||||
# if defined(FEAT_MBYTE) && defined(FEAT_EVAL)
|
||||
int active = !p_imdisable && active_arg;
|
||||
|
||||
if (p_imaf[0] != NUL && active != im_get_status())
|
||||
if (USE_IMACTIVATEFUNC && active != im_get_status())
|
||||
{
|
||||
call_imactivatefunc(active);
|
||||
im_was_set_active = active;
|
||||
|
||||
@@ -1139,7 +1139,7 @@ ml_recover(void)
|
||||
attr = HL_ATTR(HLF_E);
|
||||
|
||||
/*
|
||||
* If the file name ends in ".s[uvw][a-z]" we assume this is the swap file.
|
||||
* If the file name ends in ".s[a-w][a-z]" we assume this is the swap file.
|
||||
* Otherwise a search is done to find the swap file(s).
|
||||
*/
|
||||
fname = curbuf->b_fname;
|
||||
@@ -1153,7 +1153,8 @@ ml_recover(void)
|
||||
STRNICMP(fname + len - 4, ".s", 2)
|
||||
#endif
|
||||
== 0
|
||||
&& vim_strchr((char_u *)"UVWuvw", fname[len - 2]) != NULL
|
||||
&& vim_strchr((char_u *)"abcdefghijklmnopqrstuvw",
|
||||
TOLOWER_ASC(fname[len - 2])) != NULL
|
||||
&& ASCII_ISALPHA(fname[len - 1]))
|
||||
{
|
||||
directly = TRUE;
|
||||
|
||||
@@ -6369,8 +6369,13 @@ did_set_string_option(
|
||||
* display output conversion. */
|
||||
if (((varp == &p_enc && *p_tenc != NUL) || varp == &p_tenc))
|
||||
{
|
||||
convert_setup(&input_conv, p_tenc, p_enc);
|
||||
convert_setup(&output_conv, p_enc, p_tenc);
|
||||
if (convert_setup(&input_conv, p_tenc, p_enc) == FAIL
|
||||
|| convert_setup(&output_conv, p_enc, p_tenc) == FAIL)
|
||||
{
|
||||
EMSG3(_("E950: Cannot convert between %s and %s"),
|
||||
p_tenc, p_enc);
|
||||
errmsg = e_invarg;
|
||||
}
|
||||
}
|
||||
|
||||
# if defined(WIN3264) && defined(FEAT_MBYTE)
|
||||
|
||||
@@ -1789,7 +1789,6 @@ mch_inchar(
|
||||
#endif
|
||||
{
|
||||
int n = 1;
|
||||
int conv = FALSE;
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
if (ch2 == NUL)
|
||||
@@ -1822,28 +1821,6 @@ mch_inchar(
|
||||
n += 2;
|
||||
}
|
||||
|
||||
if (conv)
|
||||
{
|
||||
char_u *p = typeahead + typeaheadlen;
|
||||
|
||||
if (*p != K_NUL)
|
||||
{
|
||||
char_u *e = typeahead + TYPEAHEADLEN;
|
||||
|
||||
while (*p && p < e)
|
||||
{
|
||||
if (*p == K_NUL)
|
||||
{
|
||||
++p;
|
||||
mch_memmove(p + 1, p, ((size_t)(e - p)) - 1);
|
||||
*p = 3;
|
||||
++n;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Use the ALT key to set the 8th bit of the character
|
||||
* when it's one byte, the 8th bit isn't set yet and not
|
||||
* using a double-byte encoding (would become a lead
|
||||
|
||||
@@ -836,7 +836,7 @@ split_message(char_u *mesg, pumitem_T **array)
|
||||
item->bytelen = p - item->start;
|
||||
if (item->cells > max_cells)
|
||||
max_cells = item->cells;
|
||||
long_item_count += item->cells / BALLOON_MIN_WIDTH;
|
||||
long_item_count += (item->cells - 1) / BALLOON_MIN_WIDTH;
|
||||
}
|
||||
|
||||
height = 2 + ga.ga_len;
|
||||
|
||||
@@ -16,6 +16,7 @@ int diff_check_fill(win_T *wp, linenr_T lnum);
|
||||
void diff_set_topline(win_T *fromwin, win_T *towin);
|
||||
int diffopt_changed(void);
|
||||
int diffopt_horizontal(void);
|
||||
int diffopt_hiddenoff(void);
|
||||
int diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp);
|
||||
int diff_infold(win_T *wp, linenr_T lnum);
|
||||
void nv_diffgetput(int put, long count);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/* gui_w32.c */
|
||||
int directx_enabled(void);
|
||||
int gui_mch_set_rendering_options(char_u *s);
|
||||
int gui_mch_is_blinking(void);
|
||||
int gui_mch_is_blink_off(void);
|
||||
|
||||
@@ -20,6 +20,7 @@ void term_change_in_curbuf(void);
|
||||
int term_get_attr(buf_T *buf, linenr_T lnum, int col);
|
||||
char_u *term_get_status_text(term_T *term);
|
||||
int set_ref_in_term(int copyID);
|
||||
void set_terminal_default_colors(int cterm_fg, int cterm_bg);
|
||||
void f_term_getaltscreen(typval_T *argvars, typval_T *rettv);
|
||||
void f_term_getattr(typval_T *argvars, typval_T *rettv);
|
||||
void f_term_getcursor(typval_T *argvars, typval_T *rettv);
|
||||
|
||||
@@ -4055,6 +4055,7 @@ ex_cfile(exarg_T *eap)
|
||||
#ifdef FEAT_AUTOCMD
|
||||
char_u *au_name = NULL;
|
||||
#endif
|
||||
int res;
|
||||
|
||||
if (eap->cmdidx == CMD_lfile || eap->cmdidx == CMD_lgetfile
|
||||
|| eap->cmdidx == CMD_laddfile)
|
||||
@@ -4102,28 +4103,18 @@ ex_cfile(exarg_T *eap)
|
||||
* :caddfile adds to an existing quickfix list. If there is no
|
||||
* quickfix list then a new list is created.
|
||||
*/
|
||||
if (qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile
|
||||
&& eap->cmdidx != CMD_laddfile),
|
||||
*eap->cmdlinep, enc) > 0
|
||||
&& (eap->cmdidx == CMD_cfile
|
||||
|| eap->cmdidx == CMD_lfile))
|
||||
{
|
||||
res = qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile
|
||||
&& eap->cmdidx != CMD_laddfile), *eap->cmdlinep, enc);
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (au_name != NULL)
|
||||
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, NULL, FALSE, curbuf);
|
||||
if (au_name != NULL)
|
||||
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, NULL, FALSE, curbuf);
|
||||
#endif
|
||||
if (res > 0 && (eap->cmdidx == CMD_cfile || eap->cmdidx == CMD_lfile))
|
||||
{
|
||||
if (wp != NULL)
|
||||
qi = GET_LOC_LIST(wp);
|
||||
qf_jump(qi, 0, 0, eap->forceit); /* display first error */
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (au_name != NULL)
|
||||
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, NULL, FALSE, curbuf);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5450,6 +5441,7 @@ ex_cbuffer(exarg_T *eap)
|
||||
#ifdef FEAT_AUTOCMD
|
||||
char_u *au_name = NULL;
|
||||
#endif
|
||||
int res;
|
||||
|
||||
if (eap->cmdidx == CMD_lbuffer || eap->cmdidx == CMD_lgetbuffer
|
||||
|| eap->cmdidx == CMD_laddbuffer)
|
||||
@@ -5509,20 +5501,19 @@ ex_cbuffer(exarg_T *eap)
|
||||
qf_title = IObuff;
|
||||
}
|
||||
|
||||
if (qf_init_ext(qi, qi->qf_curlist, NULL, buf, NULL, p_efm,
|
||||
res = qf_init_ext(qi, qi->qf_curlist, NULL, buf, NULL, p_efm,
|
||||
(eap->cmdidx != CMD_caddbuffer
|
||||
&& eap->cmdidx != CMD_laddbuffer),
|
||||
eap->line1, eap->line2,
|
||||
qf_title, NULL) > 0)
|
||||
{
|
||||
qf_title, NULL);
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (au_name != NULL)
|
||||
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
|
||||
curbuf->b_fname, TRUE, curbuf);
|
||||
if (au_name != NULL)
|
||||
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
|
||||
curbuf->b_fname, TRUE, curbuf);
|
||||
#endif
|
||||
if (eap->cmdidx == CMD_cbuffer || eap->cmdidx == CMD_lbuffer)
|
||||
qf_jump(qi, 0, 0, eap->forceit); /* display first error */
|
||||
}
|
||||
if (res > 0 && (eap->cmdidx == CMD_cbuffer ||
|
||||
eap->cmdidx == CMD_lbuffer))
|
||||
qf_jump(qi, 0, 0, eap->forceit); /* display first error */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5540,6 +5531,7 @@ ex_cexpr(exarg_T *eap)
|
||||
#ifdef FEAT_AUTOCMD
|
||||
char_u *au_name = NULL;
|
||||
#endif
|
||||
int res;
|
||||
|
||||
if (eap->cmdidx == CMD_lexpr || eap->cmdidx == CMD_lgetexpr
|
||||
|| eap->cmdidx == CMD_laddexpr)
|
||||
@@ -5578,20 +5570,19 @@ ex_cexpr(exarg_T *eap)
|
||||
if ((tv->v_type == VAR_STRING && tv->vval.v_string != NULL)
|
||||
|| (tv->v_type == VAR_LIST && tv->vval.v_list != NULL))
|
||||
{
|
||||
if (qf_init_ext(qi, qi->qf_curlist, NULL, NULL, tv, p_efm,
|
||||
res = qf_init_ext(qi, qi->qf_curlist, NULL, NULL, tv, p_efm,
|
||||
(eap->cmdidx != CMD_caddexpr
|
||||
&& eap->cmdidx != CMD_laddexpr),
|
||||
(linenr_T)0, (linenr_T)0, *eap->cmdlinep,
|
||||
NULL) > 0)
|
||||
{
|
||||
NULL);
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (au_name != NULL)
|
||||
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
|
||||
curbuf->b_fname, TRUE, curbuf);
|
||||
if (au_name != NULL)
|
||||
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
|
||||
curbuf->b_fname, TRUE, curbuf);
|
||||
#endif
|
||||
if (eap->cmdidx == CMD_cexpr || eap->cmdidx == CMD_lexpr)
|
||||
qf_jump(qi, 0, 0, eap->forceit); /* display first error */
|
||||
}
|
||||
if (res > 0 && (eap->cmdidx == CMD_cexpr ||
|
||||
eap->cmdidx == CMD_lexpr))
|
||||
qf_jump(qi, 0, 0, eap->forceit); /* display first error */
|
||||
}
|
||||
else
|
||||
EMSG(_("E777: String or List expected"));
|
||||
|
||||
17
src/screen.c
17
src/screen.c
@@ -8058,8 +8058,11 @@ screen_start_highlight(int attr)
|
||||
out_str(T_ME);
|
||||
if ((attr & HL_STANDOUT) && T_SO != NULL) /* standout */
|
||||
out_str(T_SO);
|
||||
if ((attr & (HL_UNDERLINE | HL_UNDERCURL)) && T_US != NULL)
|
||||
/* underline or undercurl */
|
||||
if ((attr & HL_UNDERCURL) && T_UCS != NULL) /* undercurl */
|
||||
out_str(T_UCS);
|
||||
if (((attr & HL_UNDERLINE) /* underline or undercurl */
|
||||
|| ((attr & HL_UNDERCURL) && T_UCS == NULL))
|
||||
&& T_US != NULL)
|
||||
out_str(T_US);
|
||||
if ((attr & HL_ITALIC) && T_CZH != NULL) /* italic */
|
||||
out_str(T_CZH);
|
||||
@@ -8177,7 +8180,15 @@ screen_stop_highlight(void)
|
||||
else
|
||||
out_str(T_SE);
|
||||
}
|
||||
if (screen_attr & (HL_UNDERLINE | HL_UNDERCURL))
|
||||
if ((screen_attr & HL_UNDERCURL) && T_UCE != NULL)
|
||||
{
|
||||
if (STRCMP(T_UCE, T_ME) == 0)
|
||||
do_ME = TRUE;
|
||||
else
|
||||
out_str(T_UCE);
|
||||
}
|
||||
if ((screen_attr & HL_UNDERLINE)
|
||||
|| ((screen_attr & HL_UNDERCURL) && T_UCE == NULL))
|
||||
{
|
||||
if (STRCMP(T_UE, T_ME) == 0)
|
||||
do_ME = TRUE;
|
||||
|
||||
12
src/syntax.c
12
src/syntax.c
@@ -7391,6 +7391,9 @@ do_highlight(
|
||||
int error = FALSE;
|
||||
int color;
|
||||
int is_normal_group = FALSE; /* "Normal" group */
|
||||
#ifdef FEAT_TERMINAL
|
||||
int is_terminal_group = FALSE; /* "Terminal" group */
|
||||
#endif
|
||||
#ifdef FEAT_GUI_X11
|
||||
int is_menu_group = FALSE; /* "Menu" group */
|
||||
int is_scrollbar_group = FALSE; /* "Scrollbar" group */
|
||||
@@ -7616,6 +7619,10 @@ do_highlight(
|
||||
|
||||
if (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0)
|
||||
is_normal_group = TRUE;
|
||||
#ifdef FEAT_TERMINAL
|
||||
else if (STRCMP(HL_TABLE()[idx].sg_name_u, "TERMINAL") == 0)
|
||||
is_terminal_group = TRUE;
|
||||
#endif
|
||||
#ifdef FEAT_GUI_X11
|
||||
else if (STRCMP(HL_TABLE()[idx].sg_name_u, "MENU") == 0)
|
||||
is_menu_group = TRUE;
|
||||
@@ -8239,6 +8246,11 @@ do_highlight(
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef FEAT_TERMINAL
|
||||
else if (is_terminal_group)
|
||||
set_terminal_default_colors(
|
||||
HL_TABLE()[idx].sg_cterm_fg, HL_TABLE()[idx].sg_cterm_bg);
|
||||
#endif
|
||||
#ifdef FEAT_GUI_X11
|
||||
# ifdef FEAT_MENU
|
||||
else if (is_menu_group)
|
||||
|
||||
168
src/terminal.c
168
src/terminal.c
@@ -38,6 +38,8 @@
|
||||
* in tl_scrollback are no longer used.
|
||||
*
|
||||
* TODO:
|
||||
* - When using 'termguicolors' still use the 16 ANSI colors as-is. Helps for
|
||||
* a job that uses 16 colors while Vim is using > 256.
|
||||
* - in GUI vertical split causes problems. Cursor is flickering. (Hirohito
|
||||
* Higashi, 2017 Sep 19)
|
||||
* - Shift-Tab does not work.
|
||||
@@ -48,7 +50,6 @@
|
||||
* - When closing gvim with an active terminal buffer, the dialog suggests
|
||||
* saving the buffer. Should say something else. (Manas Thakur, #2215)
|
||||
* Also: #2223
|
||||
* - implement term_setsize()
|
||||
* - Termdebug does not work when Vim build with mzscheme. gdb hangs.
|
||||
* - MS-Windows GUI: WinBar has tearoff item
|
||||
* - Adding WinBar to terminal window doesn't display, text isn't shifted down.
|
||||
@@ -57,6 +58,7 @@
|
||||
* - What to store in a session file? Shell at the prompt would be OK to
|
||||
* restore, but others may not. Open the window and let the user start the
|
||||
* command?
|
||||
* - implement term_setsize()
|
||||
* - add test for giving error for invalid 'termsize' value.
|
||||
* - support minimal size when 'termsize' is "rows*cols".
|
||||
* - support minimal size when 'termsize' is empty?
|
||||
@@ -186,6 +188,9 @@ static void term_free_vterm(term_T *term);
|
||||
* backspace key. */
|
||||
static int term_backspace_char = BS;
|
||||
|
||||
/* "Terminal" highlight group colors. */
|
||||
static int term_default_cterm_fg = -1;
|
||||
static int term_default_cterm_bg = -1;
|
||||
|
||||
/**************************************
|
||||
* 1. Generic code for all systems.
|
||||
@@ -1707,7 +1712,7 @@ may_toggle_cursor(term_T *term)
|
||||
|
||||
/*
|
||||
* Reverse engineer the RGB value into a cterm color index.
|
||||
* First color is 1. Return 0 if no match found.
|
||||
* First color is 1. Return 0 if no match found (default color).
|
||||
*/
|
||||
static int
|
||||
color2index(VTermColor *color, int fg, int *boldp)
|
||||
@@ -1716,78 +1721,34 @@ color2index(VTermColor *color, int fg, int *boldp)
|
||||
int blue = color->blue;
|
||||
int green = color->green;
|
||||
|
||||
/* The argument for lookup_color() is for the color_names[] table. */
|
||||
if (red == 0)
|
||||
if (color->ansi_index != VTERM_ANSI_INDEX_NONE)
|
||||
{
|
||||
if (green == 0)
|
||||
/* First 16 colors and default: use the ANSI index, because these
|
||||
* colors can be redefined. */
|
||||
if (t_colors >= 16)
|
||||
return color->ansi_index;
|
||||
switch (color->ansi_index)
|
||||
{
|
||||
if (blue == 0)
|
||||
return lookup_color(0, fg, boldp) + 1; /* black */
|
||||
if (blue == 224)
|
||||
return lookup_color(1, fg, boldp) + 1; /* dark blue */
|
||||
}
|
||||
else if (green == 224)
|
||||
{
|
||||
if (blue == 0)
|
||||
return lookup_color(2, fg, boldp) + 1; /* dark green */
|
||||
if (blue == 224)
|
||||
return lookup_color(3, fg, boldp) + 1; /* dark cyan */
|
||||
}
|
||||
}
|
||||
else if (red == 224)
|
||||
{
|
||||
if (green == 0)
|
||||
{
|
||||
if (blue == 0)
|
||||
return lookup_color(4, fg, boldp) + 1; /* dark red */
|
||||
if (blue == 224)
|
||||
return lookup_color(5, fg, boldp) + 1; /* dark magenta */
|
||||
}
|
||||
else if (green == 224)
|
||||
{
|
||||
if (blue == 0)
|
||||
return lookup_color(6, fg, boldp) + 1; /* dark yellow / brown */
|
||||
if (blue == 224)
|
||||
return lookup_color(8, fg, boldp) + 1; /* white / light grey */
|
||||
}
|
||||
}
|
||||
else if (red == 128)
|
||||
{
|
||||
if (green == 128 && blue == 128)
|
||||
return lookup_color(12, fg, boldp) + 1; /* dark grey */
|
||||
}
|
||||
else if (red == 255)
|
||||
{
|
||||
if (green == 64)
|
||||
{
|
||||
if (blue == 64)
|
||||
return lookup_color(20, fg, boldp) + 1; /* light red */
|
||||
if (blue == 255)
|
||||
return lookup_color(22, fg, boldp) + 1; /* light magenta */
|
||||
}
|
||||
else if (green == 255)
|
||||
{
|
||||
if (blue == 64)
|
||||
return lookup_color(24, fg, boldp) + 1; /* yellow */
|
||||
if (blue == 255)
|
||||
return lookup_color(26, fg, boldp) + 1; /* white */
|
||||
}
|
||||
}
|
||||
else if (red == 64)
|
||||
{
|
||||
if (green == 64)
|
||||
{
|
||||
if (blue == 255)
|
||||
return lookup_color(14, fg, boldp) + 1; /* light blue */
|
||||
}
|
||||
else if (green == 255)
|
||||
{
|
||||
if (blue == 64)
|
||||
return lookup_color(16, fg, boldp) + 1; /* light green */
|
||||
if (blue == 255)
|
||||
return lookup_color(18, fg, boldp) + 1; /* light cyan */
|
||||
case 0: return 0;
|
||||
case 1: return lookup_color( 0, fg, boldp) + 1;
|
||||
case 2: return lookup_color( 4, fg, boldp) + 1; /* dark red */
|
||||
case 3: return lookup_color( 2, fg, boldp) + 1; /* dark green */
|
||||
case 4: return lookup_color( 6, fg, boldp) + 1; /* brown */
|
||||
case 5: return lookup_color( 1, fg, boldp) + 1; /* dark blue*/
|
||||
case 6: return lookup_color( 5, fg, boldp) + 1; /* dark magenta */
|
||||
case 7: return lookup_color( 3, fg, boldp) + 1; /* dark cyan */
|
||||
case 8: return lookup_color( 8, fg, boldp) + 1; /* light grey */
|
||||
case 9: return lookup_color(12, fg, boldp) + 1; /* dark grey */
|
||||
case 10: return lookup_color(20, fg, boldp) + 1; /* red */
|
||||
case 11: return lookup_color(16, fg, boldp) + 1; /* green */
|
||||
case 12: return lookup_color(24, fg, boldp) + 1; /* yellow */
|
||||
case 13: return lookup_color(14, fg, boldp) + 1; /* blue */
|
||||
case 14: return lookup_color(22, fg, boldp) + 1; /* magenta */
|
||||
case 15: return lookup_color(18, fg, boldp) + 1; /* cyan */
|
||||
case 16: return lookup_color(26, fg, boldp) + 1; /* white */
|
||||
}
|
||||
}
|
||||
|
||||
if (t_colors >= 256)
|
||||
{
|
||||
if (red == blue && red == green)
|
||||
@@ -1875,6 +1836,15 @@ cell2attr(VTermScreenCellAttrs cellattrs, VTermColor cellfg, VTermColor cellbg)
|
||||
int fg = color2index(&cellfg, TRUE, &bold);
|
||||
int bg = color2index(&cellbg, FALSE, &bold);
|
||||
|
||||
/* Use the "Terminal" highlighting for the default colors. */
|
||||
if ((fg == 0 || bg == 0) && t_colors >= 16)
|
||||
{
|
||||
if (fg == 0 && term_default_cterm_fg >= 0)
|
||||
fg = term_default_cterm_fg + 1;
|
||||
if (bg == 0 && term_default_cterm_bg >= 0)
|
||||
bg = term_default_cterm_bg + 1;
|
||||
}
|
||||
|
||||
/* with 8 colors set the bold attribute to get a bright foreground */
|
||||
if (bold == TRUE)
|
||||
attr |= HL_BOLD;
|
||||
@@ -2447,23 +2417,23 @@ term_get_attr(buf_T *buf, linenr_T lnum, int col)
|
||||
}
|
||||
|
||||
static VTermColor ansi_table[16] = {
|
||||
{ 0, 0, 0}, /* black */
|
||||
{224, 0, 0}, /* dark red */
|
||||
{ 0, 224, 0}, /* dark green */
|
||||
{224, 224, 0}, /* dark yellow / brown */
|
||||
{ 0, 0, 224}, /* dark blue */
|
||||
{224, 0, 224}, /* dark magenta */
|
||||
{ 0, 224, 224}, /* dark cyan */
|
||||
{224, 224, 224}, /* light grey */
|
||||
{ 0, 0, 0, 1}, /* black */
|
||||
{224, 0, 0, 2}, /* dark red */
|
||||
{ 0, 224, 0, 3}, /* dark green */
|
||||
{224, 224, 0, 4}, /* dark yellow / brown */
|
||||
{ 0, 0, 224, 5}, /* dark blue */
|
||||
{224, 0, 224, 6}, /* dark magenta */
|
||||
{ 0, 224, 224, 7}, /* dark cyan */
|
||||
{224, 224, 224, 8}, /* light grey */
|
||||
|
||||
{128, 128, 128}, /* dark grey */
|
||||
{255, 64, 64}, /* light red */
|
||||
{ 64, 255, 64}, /* light green */
|
||||
{255, 255, 64}, /* yellow */
|
||||
{ 64, 64, 255}, /* light blue */
|
||||
{255, 64, 255}, /* light magenta */
|
||||
{ 64, 255, 255}, /* light cyan */
|
||||
{255, 255, 255}, /* white */
|
||||
{128, 128, 128, 9}, /* dark grey */
|
||||
{255, 64, 64, 10}, /* light red */
|
||||
{ 64, 255, 64, 11}, /* light green */
|
||||
{255, 255, 64, 12}, /* yellow */
|
||||
{ 64, 64, 255, 13}, /* light blue */
|
||||
{255, 64, 255, 14}, /* light magenta */
|
||||
{ 64, 255, 255, 15}, /* light cyan */
|
||||
{255, 255, 255, 16}, /* white */
|
||||
};
|
||||
|
||||
static int cube_value[] = {
|
||||
@@ -2495,6 +2465,7 @@ cterm_color2rgb(int nr, VTermColor *rgb)
|
||||
rgb->blue = cube_value[idx % 6];
|
||||
rgb->green = cube_value[idx / 6 % 6];
|
||||
rgb->red = cube_value[idx / 36 % 6];
|
||||
rgb->ansi_index = VTERM_ANSI_INDEX_NONE;
|
||||
}
|
||||
else if (nr < 256)
|
||||
{
|
||||
@@ -2503,6 +2474,7 @@ cterm_color2rgb(int nr, VTermColor *rgb)
|
||||
rgb->blue = grey_ramp[idx];
|
||||
rgb->green = grey_ramp[idx];
|
||||
rgb->red = grey_ramp[idx];
|
||||
rgb->ansi_index = VTERM_ANSI_INDEX_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2545,11 +2517,12 @@ create_vterm(term_T *term, int rows, int cols)
|
||||
}
|
||||
fg->red = fg->green = fg->blue = fgval;
|
||||
bg->red = bg->green = bg->blue = bgval;
|
||||
fg->ansi_index = bg->ansi_index = VTERM_ANSI_INDEX_DEFAULT;
|
||||
|
||||
/* The "Terminal" highlight group overrules the defaults. */
|
||||
id = syn_name2id((char_u *)"Terminal");
|
||||
|
||||
/* Use the actual color for the GUI and when 'guitermcolors' is set. */
|
||||
/* Use the actual color for the GUI and when 'termguicolors' is set. */
|
||||
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
if (0
|
||||
# ifdef FEAT_GUI
|
||||
@@ -2607,13 +2580,10 @@ create_vterm(term_T *term, int rows, int cols)
|
||||
#endif
|
||||
if (id != 0 && t_colors >= 16)
|
||||
{
|
||||
int cterm_fg, cterm_bg;
|
||||
|
||||
syn_id2cterm_bg(id, &cterm_fg, &cterm_bg);
|
||||
if (cterm_fg >= 0)
|
||||
cterm_color2rgb(cterm_fg, fg);
|
||||
if (cterm_bg >= 0)
|
||||
cterm_color2rgb(cterm_bg, bg);
|
||||
if (term_default_cterm_fg >= 0)
|
||||
cterm_color2rgb(term_default_cterm_fg, fg);
|
||||
if (term_default_cterm_bg >= 0)
|
||||
cterm_color2rgb(term_default_cterm_bg, bg);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2729,6 +2699,16 @@ set_ref_in_term(int copyID)
|
||||
return abort;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cache "Terminal" highlight group colors.
|
||||
*/
|
||||
void
|
||||
set_terminal_default_colors(int cterm_fg, int cterm_bg)
|
||||
{
|
||||
term_default_cterm_fg = cterm_fg - 1;
|
||||
term_default_cterm_bg = cterm_bg - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the buffer from the first argument in "argvars".
|
||||
* Returns NULL when the buffer is not for a terminal window.
|
||||
|
||||
@@ -11,7 +11,8 @@ endfor
|
||||
for nr in range(8, 15)
|
||||
let s .= "\033[10" . (nr - 8) . "m "
|
||||
endfor
|
||||
let s .= "\033[107m|"
|
||||
" Add | in original color pair to see white background.
|
||||
let s .= "\033[m|"
|
||||
call setline(2, s)
|
||||
|
||||
" 6 x 6 x 6 color cube
|
||||
@@ -22,7 +23,7 @@ for high in range(0, 5)
|
||||
let nr = low + high * 36
|
||||
let s .= "\033[48;5;" . (nr + 16) . "m "
|
||||
endfor
|
||||
let s .= "\033[107m|"
|
||||
let s .= "\033[m|"
|
||||
call setline(high + 4, s)
|
||||
endfor
|
||||
|
||||
@@ -32,9 +33,9 @@ let s = ''
|
||||
for nr in range(0, 23)
|
||||
let s .= "\033[48;5;" . (nr + 232) . "m "
|
||||
endfor
|
||||
let s .= "\033[107m|"
|
||||
let s .= "\033[m|"
|
||||
call setline(11, s)
|
||||
|
||||
set binary
|
||||
write! <sfile>:h/xterm_ramp.txt
|
||||
write! <sfile>:h/color_ramp.txt
|
||||
quit
|
||||
@@ -19,6 +19,9 @@ let script = [
|
||||
/#define p_term
|
||||
let end = line('.')
|
||||
|
||||
" font name that works everywhere (hopefully)
|
||||
let fontname = has('win32') ? 'fixedsys' : 'fixed'
|
||||
|
||||
" Two lists with values: values that work and values that fail.
|
||||
" When not listed, "othernum" or "otherstring" is used.
|
||||
let test_values = {
|
||||
@@ -93,8 +96,9 @@ let test_values = {
|
||||
\ 'foldmarker': [['((,))'], ['', 'xxx']],
|
||||
\ 'formatoptions': [['', 'vt', 'v,t'], ['xxx']],
|
||||
\ 'guicursor': [['', 'n:block-Cursor'], ['xxx']],
|
||||
\ 'guifont': [['', 'fixedsys'], []],
|
||||
\ 'guifontwide': [['', 'fixedsys'], []],
|
||||
\ 'guifont': [['', fontname], []],
|
||||
\ 'guifontwide': [['', fontname], []],
|
||||
\ 'guifontset': [['', fontname], []],
|
||||
\ 'helplang': [['', 'de', 'de,it'], ['xxx']],
|
||||
\ 'highlight': [['', 'e:Error'], ['xxx']],
|
||||
\ 'imactivatekey': [['', 'S-space'], ['xxx']],
|
||||
@@ -126,6 +130,7 @@ let test_values = {
|
||||
\ 'tagcase': [['smart', 'match'], ['', 'xxx', 'smart,match']],
|
||||
\ 'term': [[], []],
|
||||
\ 'termsize': [['', '24x80', '0x80', '32x0', '0x0'], ['xxx', '80', '8ax9', '24x80b']],
|
||||
\ 'termencoding': [has('gui_gtk') ? [] : ['', 'utf-8'], ['xxx']],
|
||||
\ 'toolbar': [['', 'icons', 'text'], ['xxx']],
|
||||
\ 'toolbariconsize': [['', 'tiny', 'huge'], ['xxx']],
|
||||
\ 'ttymouse': [['', 'xterm'], ['xxx']],
|
||||
@@ -189,8 +194,11 @@ while 1
|
||||
call add(script, "endif")
|
||||
endif
|
||||
|
||||
call add(script, 'set ' . name . '&')
|
||||
call add(script, 'set ' . shortname . '&')
|
||||
" cannot change 'termencoding' in GTK
|
||||
if name != 'termencoding' || !has('gui_gtk')
|
||||
call add(script, 'set ' . name . '&')
|
||||
call add(script, 'set ' . shortname . '&')
|
||||
endif
|
||||
if name == 'verbosefile'
|
||||
call add(script, 'call delete("xxx")')
|
||||
endif
|
||||
|
||||
@@ -251,6 +251,7 @@ let s:flaky = [
|
||||
\ 'Test_exit_callback_interval()',
|
||||
\ 'Test_nb_basic()',
|
||||
\ 'Test_oneshot()',
|
||||
\ 'Test_paused()',
|
||||
\ 'Test_pipe_through_sort_all()',
|
||||
\ 'Test_pipe_through_sort_some()',
|
||||
\ 'Test_quoteplus()',
|
||||
@@ -259,6 +260,7 @@ let s:flaky = [
|
||||
\ 'Test_terminal_composing_unicode()',
|
||||
\ 'Test_terminal_noblock()',
|
||||
\ 'Test_terminal_redir_file()',
|
||||
\ 'Test_terminal_tmap()',
|
||||
\ 'Test_with_partial_callback()',
|
||||
\ ]
|
||||
|
||||
|
||||
@@ -1694,19 +1694,23 @@ func Test_cwd()
|
||||
let g:envstr = ''
|
||||
if has('win32')
|
||||
let expect = $TEMP
|
||||
call job_start(['cmd', '/c', 'echo %CD%'], {'callback': {ch,msg->execute(":let g:envstr .= msg")}, 'cwd': expect})
|
||||
let job = job_start(['cmd', '/c', 'echo %CD%'], {'callback': {ch,msg->execute(":let g:envstr .= msg")}, 'cwd': expect})
|
||||
else
|
||||
let expect = $HOME
|
||||
call job_start(['pwd'], {'callback': {ch,msg->execute(":let g:envstr .= msg")}, 'cwd': expect})
|
||||
let job = job_start(['pwd'], {'callback': {ch,msg->execute(":let g:envstr .= msg")}, 'cwd': expect})
|
||||
endif
|
||||
call WaitFor('"" != g:envstr')
|
||||
let expect = substitute(expect, '[/\\]$', '', '')
|
||||
let g:envstr = substitute(g:envstr, '[/\\]$', '', '')
|
||||
if $CI != '' && stridx(g:envstr, '/private/') == 0
|
||||
let g:envstr = g:envstr[8:]
|
||||
endif
|
||||
call assert_equal(expect, g:envstr)
|
||||
unlet g:envstr
|
||||
try
|
||||
call WaitFor('"" != g:envstr')
|
||||
let expect = substitute(expect, '[/\\]$', '', '')
|
||||
let g:envstr = substitute(g:envstr, '[/\\]$', '', '')
|
||||
if $CI != '' && stridx(g:envstr, '/private/') == 0
|
||||
let g:envstr = g:envstr[8:]
|
||||
endif
|
||||
call assert_equal(expect, g:envstr)
|
||||
finally
|
||||
call job_stop(job)
|
||||
unlet g:envstr
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
function Ch_test_close_lambda(port)
|
||||
@@ -1731,7 +1735,7 @@ endfunc
|
||||
func s:test_list_args(cmd, out, remove_lf)
|
||||
try
|
||||
let g:out = ''
|
||||
call job_start([s:python, '-c', a:cmd], {'callback': {ch, msg -> execute('let g:out .= msg')}, 'out_mode': 'raw'})
|
||||
let job = job_start([s:python, '-c', a:cmd], {'callback': {ch, msg -> execute('let g:out .= msg')}, 'out_mode': 'raw'})
|
||||
call WaitFor('"" != g:out')
|
||||
if has('win32')
|
||||
let g:out = substitute(g:out, '\r', '', 'g')
|
||||
@@ -1741,6 +1745,7 @@ func s:test_list_args(cmd, out, remove_lf)
|
||||
endif
|
||||
call assert_equal(a:out, g:out)
|
||||
finally
|
||||
call job_stop(job)
|
||||
unlet g:out
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
@@ -375,6 +375,29 @@ func Test_diffopt_vertical()
|
||||
%bwipe
|
||||
endfunc
|
||||
|
||||
func Test_diffopt_hiddenoff()
|
||||
set diffopt=filler,foldcolumn:0,hiddenoff
|
||||
e! one
|
||||
call setline(1, ['Two', 'Three'])
|
||||
redraw
|
||||
let normattr = screenattr(1, 1)
|
||||
diffthis
|
||||
botright vert new two
|
||||
call setline(1, ['One', 'Four'])
|
||||
diffthis
|
||||
redraw
|
||||
call assert_notequal(normattr, screenattr(1, 1))
|
||||
set hidden
|
||||
close
|
||||
redraw
|
||||
" should not diffing with hidden buffer two while 'hiddenoff' is enabled
|
||||
call assert_equal(normattr, screenattr(1, 1))
|
||||
|
||||
bwipe!
|
||||
bwipe!
|
||||
set hidden& diffopt&
|
||||
endfunc
|
||||
|
||||
func Test_diffoff_hidden()
|
||||
set diffopt=filler,foldcolumn:0
|
||||
e! one
|
||||
|
||||
@@ -24,6 +24,8 @@ func Test_iminsert2()
|
||||
set iminsert=0
|
||||
set imactivatefunc=
|
||||
set imstatusfunc=
|
||||
call assert_equal(1, s:imactivatefunc_called)
|
||||
call assert_equal(1, s:imstatusfunc_called)
|
||||
|
||||
let expected = has('gui_running') ? 0 : 1
|
||||
call assert_equal(expected, s:imactivatefunc_called)
|
||||
call assert_equal(expected, s:imstatusfunc_called)
|
||||
endfunc
|
||||
|
||||
@@ -707,6 +707,10 @@ func Test_balloon_split()
|
||||
if !exists('*balloon_split')
|
||||
return
|
||||
endif
|
||||
call assert_equal([
|
||||
\ 'tempname: 0x555555e380a0 "/home/mool/.viminfz.tmp"',
|
||||
\ ], balloon_split(
|
||||
\ 'tempname: 0x555555e380a0 "/home/mool/.viminfz.tmp"'))
|
||||
call assert_equal([
|
||||
\ 'one two three four one two three four one two thre',
|
||||
\ 'e four',
|
||||
|
||||
@@ -1966,26 +1966,136 @@ func Test_Autocmd()
|
||||
cexpr "F1:10:Line 10"
|
||||
caddexpr "F1:20:Line 20"
|
||||
cgetexpr "F1:30:Line 30"
|
||||
enew! | call append(0, "F2:10:Line 10")
|
||||
cbuffer!
|
||||
enew! | call append(0, "F2:20:Line 20")
|
||||
cgetbuffer
|
||||
enew! | call append(0, "F2:30:Line 30")
|
||||
caddbuffer
|
||||
|
||||
cexpr ""
|
||||
caddexpr ""
|
||||
cgetexpr ""
|
||||
silent! cexpr non_existing_func()
|
||||
silent! caddexpr non_existing_func()
|
||||
silent! cgetexpr non_existing_func()
|
||||
let l = ['precexpr',
|
||||
\ 'postcexpr',
|
||||
\ 'precaddexpr',
|
||||
\ 'postcaddexpr',
|
||||
\ 'precgetexpr',
|
||||
\ 'postcgetexpr',
|
||||
\ 'precbuffer',
|
||||
\ 'precexpr',
|
||||
\ 'postcexpr',
|
||||
\ 'precaddexpr',
|
||||
\ 'postcaddexpr',
|
||||
\ 'precgetexpr',
|
||||
\ 'postcgetexpr',
|
||||
\ 'precexpr',
|
||||
\ 'precaddexpr',
|
||||
\ 'precgetexpr']
|
||||
call assert_equal(l, g:acmds)
|
||||
|
||||
let g:acmds = []
|
||||
enew! | call append(0, "F2:10:Line 10")
|
||||
cbuffer!
|
||||
enew! | call append(0, "F2:20:Line 20")
|
||||
cgetbuffer
|
||||
enew! | call append(0, "F2:30:Line 30")
|
||||
caddbuffer
|
||||
new
|
||||
let bnum = bufnr('%')
|
||||
bunload
|
||||
exe 'silent! cbuffer! ' . bnum
|
||||
exe 'silent! cgetbuffer ' . bnum
|
||||
exe 'silent! caddbuffer ' . bnum
|
||||
enew!
|
||||
let l = ['precbuffer',
|
||||
\ 'postcbuffer',
|
||||
\ 'precgetbuffer',
|
||||
\ 'postcgetbuffer',
|
||||
\ 'precaddbuffer',
|
||||
\ 'postcaddbuffer']
|
||||
\ 'postcaddbuffer',
|
||||
\ 'precbuffer',
|
||||
\ 'precgetbuffer',
|
||||
\ 'precaddbuffer']
|
||||
call assert_equal(l, g:acmds)
|
||||
|
||||
call writefile(['Xtest:1:Line1'], 'Xtest')
|
||||
call writefile([], 'Xempty')
|
||||
let g:acmds = []
|
||||
cfile Xtest
|
||||
caddfile Xtest
|
||||
cgetfile Xtest
|
||||
cfile Xempty
|
||||
caddfile Xempty
|
||||
cgetfile Xempty
|
||||
silent! cfile do_not_exist
|
||||
silent! caddfile do_not_exist
|
||||
silent! cgetfile do_not_exist
|
||||
let l = ['precfile',
|
||||
\ 'postcfile',
|
||||
\ 'precaddfile',
|
||||
\ 'postcaddfile',
|
||||
\ 'precgetfile',
|
||||
\ 'postcgetfile',
|
||||
\ 'precfile',
|
||||
\ 'postcfile',
|
||||
\ 'precaddfile',
|
||||
\ 'postcaddfile',
|
||||
\ 'precgetfile',
|
||||
\ 'postcgetfile',
|
||||
\ 'precfile',
|
||||
\ 'postcfile',
|
||||
\ 'precaddfile',
|
||||
\ 'postcaddfile',
|
||||
\ 'precgetfile',
|
||||
\ 'postcgetfile']
|
||||
call assert_equal(l, g:acmds)
|
||||
|
||||
let g:acmds = []
|
||||
helpgrep quickfix
|
||||
silent! helpgrep non_existing_help_topic
|
||||
vimgrep test Xtest
|
||||
vimgrepadd test Xtest
|
||||
silent! vimgrep non_existing_test Xtest
|
||||
silent! vimgrepadd non_existing_test Xtest
|
||||
set makeprg=
|
||||
silent! make
|
||||
set makeprg&
|
||||
let l = ['prehelpgrep',
|
||||
\ 'posthelpgrep',
|
||||
\ 'prehelpgrep',
|
||||
\ 'posthelpgrep',
|
||||
\ 'previmgrep',
|
||||
\ 'postvimgrep',
|
||||
\ 'previmgrepadd',
|
||||
\ 'postvimgrepadd',
|
||||
\ 'previmgrep',
|
||||
\ 'postvimgrep',
|
||||
\ 'previmgrepadd',
|
||||
\ 'postvimgrepadd',
|
||||
\ 'premake',
|
||||
\ 'postmake']
|
||||
call assert_equal(l, g:acmds)
|
||||
|
||||
if has('unix')
|
||||
" Run this test only on Unix-like systems. The grepprg may not be set on
|
||||
" non-Unix systems.
|
||||
" The following lines are used for the grep test. Don't remove.
|
||||
" Grep_Autocmd_Text: Match 1
|
||||
" GrepAdd_Autocmd_Text: Match 2
|
||||
let g:acmds = []
|
||||
silent grep Grep_Autocmd_Text test_quickfix.vim
|
||||
silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
|
||||
silent grep abc123def Xtest
|
||||
silent grepadd abc123def Xtest
|
||||
let l = ['pregrep',
|
||||
\ 'postgrep',
|
||||
\ 'pregrepadd',
|
||||
\ 'postgrepadd',
|
||||
\ 'pregrep',
|
||||
\ 'postgrep',
|
||||
\ 'pregrepadd',
|
||||
\ 'postgrepadd']
|
||||
call assert_equal(l, g:acmds)
|
||||
endif
|
||||
|
||||
call delete('Xtest')
|
||||
call delete('Xempty')
|
||||
endfunc
|
||||
|
||||
func Test_Autocmd_Exception()
|
||||
|
||||
@@ -362,6 +362,19 @@ func Test_equalalways_on_close()
|
||||
set equalalways&
|
||||
endfunc
|
||||
|
||||
func Test_win_screenpos()
|
||||
call assert_equal(1, winnr('$'))
|
||||
split
|
||||
vsplit
|
||||
10wincmd _
|
||||
30wincmd |
|
||||
call assert_equal([1, 1], win_screenpos(1))
|
||||
call assert_equal([1, 32], win_screenpos(2))
|
||||
call assert_equal([12, 1], win_screenpos(3))
|
||||
call assert_equal([0, 0], win_screenpos(4))
|
||||
only
|
||||
endfunc
|
||||
|
||||
func Test_window_jump_tag()
|
||||
help
|
||||
/iccf
|
||||
|
||||
@@ -771,6 +771,58 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1366,
|
||||
/**/
|
||||
1365,
|
||||
/**/
|
||||
1364,
|
||||
/**/
|
||||
1363,
|
||||
/**/
|
||||
1362,
|
||||
/**/
|
||||
1361,
|
||||
/**/
|
||||
1360,
|
||||
/**/
|
||||
1359,
|
||||
/**/
|
||||
1358,
|
||||
/**/
|
||||
1357,
|
||||
/**/
|
||||
1356,
|
||||
/**/
|
||||
1355,
|
||||
/**/
|
||||
1354,
|
||||
/**/
|
||||
1353,
|
||||
/**/
|
||||
1352,
|
||||
/**/
|
||||
1351,
|
||||
/**/
|
||||
1350,
|
||||
/**/
|
||||
1349,
|
||||
/**/
|
||||
1348,
|
||||
/**/
|
||||
1347,
|
||||
/**/
|
||||
1346,
|
||||
/**/
|
||||
1345,
|
||||
/**/
|
||||
1344,
|
||||
/**/
|
||||
1343,
|
||||
/**/
|
||||
1342,
|
||||
/**/
|
||||
1341,
|
||||
/**/
|
||||
1340,
|
||||
/**/
|
||||
|
||||
@@ -2485,7 +2485,8 @@ typedef enum {
|
||||
#define FNE_INCL_BR 1 /* include [] in name */
|
||||
#define FNE_CHECK_START 2 /* check name starts with valid character */
|
||||
|
||||
#if (defined(SUN_SYSTEM) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) \
|
||||
/* BSD is supposed to cover FreeBSD and similar systems. */
|
||||
#if (defined(SUN_SYSTEM) || defined(BSD) || defined(__FreeBSD_kernel__)) \
|
||||
&& defined(S_ISCHR)
|
||||
# define OPEN_CHR_FILES
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user