mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-02 11:19:22 +02:00
Compare commits
277 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8cd984a56b | |||
| 650cb7ac61 | |||
| ae400c2dbb | |||
| 507a68ef81 | |||
| 271ef88821 | |||
| 9a248b819d | |||
| 6aeca470b5 | |||
| 936863de98 | |||
| d96b64262d | |||
| 200d3e5957 | |||
| 4ca28fccbd | |||
| 9c08729d42 | |||
| 8e0d50c1ed | |||
| 865619bc65 | |||
| 3b1a4d48f0 | |||
| 6c124f1604 | |||
| 44c21d0863 | |||
| ad1b34005d | |||
| 107a1cf7cc | |||
| cbe2f307b1 | |||
| 5213b783d7 | |||
| c6babee370 | |||
| b4b97fe905 | |||
| cd37d01770 | |||
| d8b193e98b | |||
| 629579e8a0 | |||
| 9d6d075726 | |||
| 7d6909d353 | |||
| b75c36581f | |||
| ae253a2dad | |||
| 21cced3fc6 | |||
| 29745cf124 | |||
| 699de3c049 | |||
| 5560396666 | |||
| 8570b5df1f | |||
| 7391be3977 | |||
| 7068f9086c | |||
| af2e8b9e3b | |||
| 7d87f83e26 | |||
| eb6512ab82 | |||
| c2d5277fc9 | |||
| e9d2694dce | |||
| 36154dd8c0 | |||
| 0d778b28a4 | |||
| fa7096a6ee | |||
| cc2b9e2245 | |||
| 2cd4c80953 | |||
| 8303ab1b1a | |||
| 3ef707c468 | |||
| b3ec0ad87a | |||
| 4486bb71fb | |||
| 176ab5d393 | |||
| aff8366139 | |||
| d05fb395d1 | |||
| e764e25045 | |||
| bd178a9659 | |||
| 5a5cd60221 | |||
| 7c3e218035 | |||
| 760e36dc8b | |||
| 941e7a992d | |||
| 7108d56061 | |||
| d5a9cdd9c8 | |||
| 60ed6e1213 | |||
| d628c3711d | |||
| 3344f11140 | |||
| f047b3aa3e | |||
| 31ad5d0472 | |||
| edbdca29e1 | |||
| 5433ca7d4c | |||
| 816ac0a441 | |||
| 90e4752df4 | |||
| 0978ebc1c6 | |||
| f486bb41d6 | |||
| 44227b9a93 | |||
| ad02696d27 | |||
| 87658a916a | |||
| 66299b9ed5 | |||
| fc072b7b61 | |||
| fef8272db2 | |||
| b04c78a6a0 | |||
| 99b7765c18 | |||
| c8e331a5f5 | |||
| 03f0a92f69 | |||
| ca96b60e9a | |||
| ea811731f0 | |||
| 11b068fc25 | |||
| 097577c351 | |||
| 250b62c9a8 | |||
| 54fea5fe67 | |||
| e63aad92b1 | |||
| 8ac99eed90 | |||
| 25b4e351c9 | |||
| 20da24a60c | |||
| 0873fb8f49 | |||
| 839717064f | |||
| cee529f197 | |||
| a3935654b8 | |||
| ff7ca495c1 | |||
| 335f08054d | |||
| fa0d5e0ba9 | |||
| 1f4d8dd8e1 | |||
| b465ee5bbe | |||
| 919b11d301 | |||
| f5cfc6a148 | |||
| 915fba8a25 | |||
| 6b64a62626 | |||
| 0ee0fbc2d4 | |||
| 8db81befc3 | |||
| 47b763090e | |||
| 99b962f986 | |||
| e6b7f4ff3b | |||
| 11f7764bd6 | |||
| 3f2fbccc21 | |||
| 84602997b6 | |||
| 19a1e1db6b | |||
| 0949ad4f8b | |||
| 8f5131b2d7 | |||
| 682e144672 | |||
| a05172e1db | |||
| 9b0f42ed24 | |||
| 7b900cf55a | |||
| 82c9ce9eeb | |||
| 104a7e6484 | |||
| 1e2844207d | |||
| b39439f386 | |||
| 185e34337d | |||
| e711158eed | |||
| f43ffacda1 | |||
| 160f5fa78f | |||
| 7ebc297d1d | |||
| 3a9b07d2d2 | |||
| 86d424677a | |||
| 1666886eaa | |||
| 7f3a4e21e7 | |||
| 49b3032c6d | |||
| 153c893e9e | |||
| e07aeca8c3 | |||
| 788aadad0a | |||
| 396732e9af | |||
| 1c74207cd6 | |||
| eb9ece5bf1 | |||
| 204e14b994 | |||
| 2e8bea32db | |||
| e70fb38670 | |||
| 3d56969f47 | |||
| 294d03baf6 | |||
| ac96dc67ba | |||
| 0413dcf3f1 | |||
| 40263195cb | |||
| dd76f85f0b | |||
| e93e9c4201 | |||
| a4a14b39ac | |||
| 49eeb133ac | |||
| 28de969ae3 | |||
| 6961a51e9a | |||
| f679af784b | |||
| fd8e8e0b4f | |||
| cd5ca1918d | |||
| 27d4ee55ae | |||
| 23e38c4298 | |||
| 0486075221 | |||
| 7a010c4a46 | |||
| 9aeade7147 | |||
| 5663536b1f | |||
| 95f42c734a | |||
| e1ece272fa | |||
| 73b5d1837c | |||
| 790f685006 | |||
| a680267d49 | |||
| 5f1547b288 | |||
| 9d9a5983f5 | |||
| 16e57e6189 | |||
| 5d45d4a4d2 | |||
| 0546647038 | |||
| c9ad0b6d4d | |||
| 25306ee0c5 | |||
| 2e024248fa | |||
| 85879328b0 | |||
| 9c530a8030 | |||
| 9105eb1fd0 | |||
| c49868a11f | |||
| 795860de7c | |||
| 90a729a8e4 | |||
| 1a328483b7 | |||
| 5e09d64d77 | |||
| 4591403b7e | |||
| e90f76c1aa | |||
| 8745e4380e | |||
| cd7a1f6539 | |||
| bb21f9f120 | |||
| 38c7ababf6 | |||
| 5aea857883 | |||
| 322b4eec7e | |||
| 886d3d7aed | |||
| b2f7a2f021 | |||
| 4374e9787e | |||
| 080a7c2c6c | |||
| ffef064005 | |||
| d23a68d047 | |||
| c973e12d3e | |||
| 5e0543116b | |||
| d9f633dbb3 | |||
| 32cb07dd61 | |||
| 40ae005819 | |||
| c4e8fcc338 | |||
| 9dbb79f942 | |||
| 031479c46b | |||
| 843a3a41bf | |||
| 01973d329c | |||
| bcfeb7c895 | |||
| 46b250b75f | |||
| 9b06b0a4b2 | |||
| 80b36e7995 | |||
| d29599b7ea | |||
| a63fc2427e | |||
| 393e47945b | |||
| 5100db4427 | |||
| 19ee857237 | |||
| 781ac5b687 | |||
| 9b52c915d9 | |||
| 7a68824771 | |||
| c2aed127ca | |||
| 12b3ecfdcd | |||
| 4143f69655 | |||
| 7a720947c8 | |||
| 9393a4151c | |||
| 95a678d204 | |||
| 68cec2f91b | |||
| 5ed292ebfb | |||
| 6d70e1a179 | |||
| 355d2ec231 | |||
| c6ceb6c969 | |||
| 60c1c58967 | |||
| ba43ddb524 | |||
| 2a032c05b7 | |||
| 8d8aecf662 | |||
| 380d7b2cbf | |||
| 30a12fc740 | |||
| 43050b40f8 | |||
| d5dfed9cfc | |||
| 0e2e98e570 | |||
| d0a875e3af | |||
| b770256474 | |||
| e14b8cd599 | |||
| 938149499b | |||
| 9245af7148 | |||
| a874eae869 | |||
| cca95bae41 | |||
| 243fcce65c | |||
| b8c8a68a5c | |||
| 8502d5f2b2 | |||
| da857362b0 | |||
| 4c50d72cdf | |||
| 9af39a7cb2 | |||
| d4038f59f4 | |||
| 9150d82be1 | |||
| 87694dc1bf | |||
| 22704e2bb4 | |||
| 95676cfcd4 | |||
| 1e901456a5 | |||
| 899f9a6260 | |||
| 6b989afdb1 | |||
| 4f48c32bc3 | |||
| c2ea4b240d | |||
| f81158c840 | |||
| 3950b3a6b1 | |||
| ae65cb89b3 | |||
| f90e3c31ab | |||
| 014700ca55 | |||
| f86423097b | |||
| a4cdb9b1c4 | |||
| 03a1a0ea74 | |||
| 4e1a1cad93 | |||
| 9dc3e9172c | |||
| 2e69b16f67 | |||
| 3142e74a3a | |||
| c5b2d1b5b4 |
@@ -3,6 +3,14 @@
|
||||
src/MacVim/MacVim.xcodeproj/*.mode1
|
||||
src/MacVim/MacVim.xcodeproj/*.mode1v3
|
||||
src/MacVim/MacVim.xcodeproj/*.pbxuser
|
||||
src/MacVim/icons/*.pyc
|
||||
src/MacVim/icons/*.ttf
|
||||
src/MacVim/icons/*.reg
|
||||
src/MacVim/icons/*.zip
|
||||
src/MacVim/icons/*.txt
|
||||
src/MacVim/icons/*.so
|
||||
src/MacVim/icons/*.egg-info
|
||||
src/MacVim/icons/build
|
||||
src/MacVim/icons/makeicns/*.o
|
||||
src/MacVim/icons/makeicns/makeicns
|
||||
src/MacVim/PSMTabBarControl/PSMTabBarControl.xcodeproj/*.mode1
|
||||
|
||||
@@ -683,9 +683,7 @@ LANG_GEN = \
|
||||
runtime/spell/??/main.aap \
|
||||
runtime/spell/yi/README.txt \
|
||||
runtime/spell/main.aap \
|
||||
runtime/spell/cleanadd.vim \
|
||||
runtime/spell/*.vim \
|
||||
runtime/spell/fixdup \
|
||||
|
||||
# generic language files, binary
|
||||
LANG_GEN_BIN = \
|
||||
|
||||
+10
-2
@@ -335,6 +335,8 @@ BufDelete Before deleting a buffer from the buffer list.
|
||||
NOTE: When this autocommand is executed, the
|
||||
current buffer "%" may be different from the
|
||||
buffer being deleted "<afile>" and "<abuf>".
|
||||
Don't change to another buffer, it will cause
|
||||
problems.
|
||||
*BufEnter*
|
||||
BufEnter After entering a buffer. Useful for setting
|
||||
options for a file type. Also executed when
|
||||
@@ -397,6 +399,8 @@ BufUnload Before unloading a buffer. This is when the
|
||||
NOTE: When this autocommand is executed, the
|
||||
current buffer "%" may be different from the
|
||||
buffer being unloaded "<afile>".
|
||||
Don't change to another buffer, it will cause
|
||||
problems.
|
||||
*BufWinEnter*
|
||||
BufWinEnter After a buffer is displayed in a window. This
|
||||
can be when the buffer is loaded (after
|
||||
@@ -428,6 +432,8 @@ BufWipeout Before completely deleting a buffer. The
|
||||
NOTE: When this autocommand is executed, the
|
||||
current buffer "%" may be different from the
|
||||
buffer being deleted "<afile>".
|
||||
Don't change to another buffer, it will cause
|
||||
problems.
|
||||
*BufWrite* *BufWritePre*
|
||||
BufWrite or BufWritePre Before writing the whole buffer to a file.
|
||||
*BufWriteCmd*
|
||||
@@ -748,8 +754,10 @@ SwapExists Detected an existing swap file when starting
|
||||
'a' abort, like hitting CTRL-C
|
||||
When set to an empty string the user will be
|
||||
asked, as if there was no SwapExists autocmd.
|
||||
Note: Do not try to change the buffer, the
|
||||
results are unpredictable.
|
||||
*E812*
|
||||
It is not allowed to change to another buffer,
|
||||
change a buffer name or change directory
|
||||
here.
|
||||
*Syntax*
|
||||
Syntax When the 'syntax' option has been set. The
|
||||
pattern is matched against the syntax name.
|
||||
|
||||
@@ -441,13 +441,20 @@ between files with almost the same name. If there are multiple matches,
|
||||
those files with an extension that is in the 'suffixes' option are ignored.
|
||||
The default is ".bak,~,.o,.h,.info,.swp,.obj", which means that files ending
|
||||
in ".bak", "~", ".o", ".h", ".info", ".swp" and ".obj" are sometimes ignored.
|
||||
It is impossible to ignore suffixes with two dots. Examples:
|
||||
|
||||
An empty entry, two consecutive commas, match a file name that does not
|
||||
contain a ".", thus has no suffix. This is useful to ignore "prog" and prefer
|
||||
"prog.c".
|
||||
|
||||
Examples:
|
||||
|
||||
pattern: files: match: ~
|
||||
test* test.c test.h test.o test.c
|
||||
test* test.h test.o test.h and test.o
|
||||
test* test.i test.h test.c test.i and test.c
|
||||
|
||||
It is impossible to ignore suffixes with two dots.
|
||||
|
||||
If there is more than one matching file (after ignoring the ones matching
|
||||
the 'suffixes' option) the first file name is inserted. You can see that
|
||||
there is only one match when you type 'wildchar' twice and the completed
|
||||
|
||||
@@ -2414,6 +2414,7 @@ cursor({list})
|
||||
When 'virtualedit' is used {off} specifies the offset in
|
||||
screen columns from the start of the character. E.g., a
|
||||
position within a <Tab> or after the last character.
|
||||
Returns 0 when the position could be set, -1 otherwise.
|
||||
|
||||
|
||||
deepcopy({expr}[, {noref}]) *deepcopy()* *E698*
|
||||
@@ -4516,6 +4517,7 @@ rename({from}, {to}) *rename()*
|
||||
should also work to move files across file systems. The
|
||||
result is a Number, which is 0 if the file was renamed
|
||||
successfully, and non-zero when the renaming failed.
|
||||
NOTE: If {to} exists it is overwritten without warning.
|
||||
This function is not available in the |sandbox|.
|
||||
|
||||
repeat({expr}, {count}) *repeat()*
|
||||
|
||||
+46
-6
@@ -1,4 +1,4 @@
|
||||
*gui_mac.txt* For Vim version 7.2. Last change: 2009 Jan 08
|
||||
*gui_mac.txt* For Vim version 7.2. Last change: 2009 Aug 8
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bjorn Winckler
|
||||
@@ -17,8 +17,9 @@ The MacVim Graphical User Interface *macvim* *gui-macvim*
|
||||
8. System services |macvim-services|
|
||||
9. mvim:// URL handler |macvim-url-handler|
|
||||
10. Keyboard shortcuts |macvim-shortcuts|
|
||||
11. Known bugs/missing features |macvim-todo|
|
||||
12. Hints |macvim-hints|
|
||||
11. International |macvim-international|
|
||||
12. Known bugs/missing features |macvim-todo|
|
||||
13. Hints |macvim-hints|
|
||||
|
||||
Other relevant documentation:
|
||||
|gui.txt| For generic items of the GUI.
|
||||
@@ -117,6 +118,11 @@ really bad once you start using tabs. For example, dropping two files, then
|
||||
dropping two more, and switching back to the first tab would cause weird
|
||||
strings like "((3) of 2)" to appear in the window title.
|
||||
|
||||
*macvim-tablabel*
|
||||
Tab labels only show the tail of the file name to make the tabs more readable
|
||||
when editing files in deeply nested folders. Add the line "set guitablabel="
|
||||
to your .gvimrc file to revert back to the default Vim tab label.
|
||||
|
||||
*macvim-options*
|
||||
These are the non-standard options that MacVim supports:
|
||||
'antialias' 'fullscreen' 'fuoptions'
|
||||
@@ -345,7 +351,7 @@ The color scheme uses the the system "Highlight Color", which can be changed in
|
||||
the "Appearance" pane of the System Preferences. It also changes the
|
||||
highlight color when a window becomes inactive.
|
||||
|
||||
If you have any comments regarding this colors cheme (is it better or worse
|
||||
If you have any comments regarding this color scheme (is it better or worse
|
||||
than the default?) then post them to |vim_mac|.
|
||||
|
||||
==============================================================================
|
||||
@@ -568,12 +574,15 @@ Cmd-. Interrupt Vim. Unlike Ctrl-C which is sent as normal
|
||||
interpreted) this sends a SIGINT signal to the Vim
|
||||
process. Use this shortcut if the Vim process appears
|
||||
to have locked up and is not responding to key presses.
|
||||
This Cmd-key combination cannot be unmapped.
|
||||
|
||||
*Cmd-`* *<D-`>*
|
||||
Cmd-` Cycle to the next window. On an American keyboard the
|
||||
`-key is located under the Esc-key. On European
|
||||
keyboards this key is often adjacent to the left
|
||||
Shift-key and it may be not even be marked with "`".
|
||||
This Cmd-key combination can only be unmapped via the
|
||||
"Keyboard & Mouse" System Preferences.
|
||||
|
||||
*Cmd-Left* *<D-Left>*
|
||||
Cmd-Left Move cursor to the beginning of the line
|
||||
@@ -617,7 +626,28 @@ See |macvim-shift-movement| if you want Shift to select text when used in
|
||||
conjunction with the above Cmd/Alt movement shortcuts.
|
||||
|
||||
==============================================================================
|
||||
11. Known bugs/missing features *macvim-todo*
|
||||
11. International *macvim-international*
|
||||
|
||||
When editing non-English text it may be convenient to keep separate keyboard
|
||||
layouts for normal and insert mode. This is supported via the 'imd' option on
|
||||
Mac OS X 10.5 or later (on 10.4 the 'imd' option support is not as useful as
|
||||
it only switches between Roman and non-Roman input sources and it has been
|
||||
known not to work very reliably).
|
||||
|
||||
For example: When 'noimd' is enabled (i.e. IM is enabled) the input source is
|
||||
saved when toggling between normal and insert mode, so you can use a US layout
|
||||
in normal mode then switch to insert mode and choose a Swedish layout. When
|
||||
you go back to normal mode the US layout will be selected and when you enter
|
||||
insert mode the Swedish layout is selected. This also works when searching
|
||||
for text etc. see 'imc', 'imi', 'ims'.
|
||||
|
||||
Note that the layout used in normal mode is the layout used when 'noimd' is
|
||||
set (i.e when IM is enabled). If you find that MacVim switches to the
|
||||
wrong layout when going back to normal mode, then select the layout you want
|
||||
to use in normal mode and type ":set imd" followed by ":set noimd".
|
||||
|
||||
==============================================================================
|
||||
12. Known bugs/missing features *macvim-todo*
|
||||
|
||||
This list is by no means exhaustive, it only enumerates some of the more
|
||||
prominent bugs/missing features.
|
||||
@@ -640,7 +670,7 @@ might be simple to implement, but unless somebody asks for a particular
|
||||
feature then there is little incentive to add it.
|
||||
|
||||
==============================================================================
|
||||
12. Hints *macvim-hints*
|
||||
13. Hints *macvim-hints*
|
||||
|
||||
In this section some general (not necessarily MacVim specific) hints are
|
||||
given.
|
||||
@@ -745,6 +775,16 @@ this makes Caps Lock "drop" key presses. To work around this problem go into
|
||||
the "Keyboard & Mouse" System Preference and remap Caps Lock to Ctrl first
|
||||
(click the "Modifier Keys..." button).
|
||||
|
||||
Scenario: ~
|
||||
You have problems creating custom mappings involving the Cmd key.
|
||||
Solution: ~
|
||||
To bind to a key involving Cmd you use the "<D-..>" syntax. Many Cmd-key
|
||||
mappings are already used by the menus so if your mapping doesn't work then
|
||||
the solution is usually to first unmap the menu binding (see |macvim-menus|,
|
||||
in particular read the end of that section). Also see the section on
|
||||
|macvim-shortcuts| for some Cmd-key combinations which are not used by the
|
||||
menus but still need to be freed up before they can be used in custom bindings.
|
||||
|
||||
Scenario: ~
|
||||
You can't find the information on MacVim you thought should be in this manual
|
||||
page.
|
||||
|
||||
@@ -63,7 +63,8 @@ already running vim will never fork in MacVim.
|
||||
"gvim --nofork" does the same as "gvim -f".
|
||||
|
||||
If you want the GUI to run in the foreground always, include the 'f'
|
||||
flag in 'guioptions'. |-f|.
|
||||
flag in 'guioptions'. |-f|. MacVim does not support this flag in
|
||||
'guioptions'.
|
||||
|
||||
==============================================================================
|
||||
2. GUI Resources *gui-resources* *.Xdefaults*
|
||||
|
||||
+16
-10
@@ -1,4 +1,4 @@
|
||||
*if_cscop.txt* For Vim version 7.2. Last change: 2005 Mar 29
|
||||
*if_cscop.txt* For Vim version 7.2. Last change: 2009 Mar 18
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Andy Kahn
|
||||
@@ -131,11 +131,22 @@ The available subcommands are:
|
||||
7 or f: Find this file
|
||||
8 or i: Find files #including this file
|
||||
|
||||
For all types, except 4 and 6, leading white space for {name} is
|
||||
removed. For 4 and 6 there is exactly one space between {querytype}
|
||||
and {name}. Further white space is included in {name}.
|
||||
|
||||
EXAMPLES >
|
||||
:cscope find c vim_free
|
||||
:cscope find 3 vim_free
|
||||
:cscope find 3 vim_free
|
||||
<
|
||||
These two examples perform the same query. >
|
||||
These two examples perform the same query: functions calling
|
||||
"vim_free". >
|
||||
|
||||
:cscope find t initOnce
|
||||
:cscope find t initOnce
|
||||
<
|
||||
The first one searches for the text "initOnce", the second one for
|
||||
" initOnce". >
|
||||
|
||||
:cscope find 0 DEFAULT_TERM
|
||||
<
|
||||
@@ -344,13 +355,8 @@ cscope version for Win32 see:
|
||||
The DJGPP-built version from http://cscope.sourceforge.net is known to not
|
||||
work with Vim.
|
||||
|
||||
There are a couple of hard-coded limitations:
|
||||
|
||||
1. The maximum number of cscope connections allowed is 8. Do you
|
||||
really need more?
|
||||
|
||||
2. Doing a |:tjump| when |:cstag| searches the tag files is not
|
||||
configurable (e.g., you can't do a tselect instead).
|
||||
Hard-coded limitation: doing a |:tjump| when |:cstag| searches the tag files
|
||||
is not configurable (e.g., you can't do a tselect instead).
|
||||
|
||||
==============================================================================
|
||||
6. Suggested usage *cscope-suggestions*
|
||||
|
||||
+39
-58
@@ -1,4 +1,4 @@
|
||||
*if_mzsch.txt* For Vim version 7.2. Last change: 2008 Jun 28
|
||||
*if_mzsch.txt* For Vim version 7.2. Last change: 2009 Jun 24
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Sergey Khorev
|
||||
@@ -42,10 +42,6 @@ Note: On FreeBSD you should use the "drscheme" port.
|
||||
|
||||
*:mzfile* *:mzf*
|
||||
:[range]mzf[ile] {file} Execute the MzScheme script in {file}. {not in Vi}
|
||||
All statements are executed in the namespace of the
|
||||
buffer that was current during :mzfile start.
|
||||
If you want to access other namespaces, use
|
||||
'parameterize'.
|
||||
|
||||
All of these commands do essentially the same thing - they execute a piece of
|
||||
MzScheme code, with the "current range" set to the given line
|
||||
@@ -54,8 +50,6 @@ range.
|
||||
In the case of :mzscheme, the code to execute is in the command-line.
|
||||
In the case of :mzfile, the code to execute is the contents of the given file.
|
||||
|
||||
Each buffer has its own MzScheme namespace. Global namespace is bound to
|
||||
the "global-namespace" value from the 'vimext' module.
|
||||
MzScheme interface defines exception exn:vim, derived from exn.
|
||||
It is raised for various Vim errors.
|
||||
|
||||
@@ -79,40 +73,8 @@ To avoid clashes with MzScheme, consider using prefix when requiring module,
|
||||
e.g.: >
|
||||
:mzscheme (require (prefix vim- vimext))
|
||||
<
|
||||
All the examples below assume this naming scheme. Note that you need to do
|
||||
this again for every buffer.
|
||||
All the examples below assume this naming scheme.
|
||||
|
||||
The auto-instantiation can be achieved with autocommands, e.g. you can put
|
||||
something like this in your .vimrc (EOFs should not have indentation): >
|
||||
function s:MzRequire()
|
||||
if has("mzscheme")
|
||||
:mz << EOF
|
||||
(require (prefix vim- vimext))
|
||||
(let ((buf (vim-get-buff-by-name (vim-eval "expand(\"<afile>\")"))))
|
||||
(when (and buf (not (eq? buf (vim-curr-buff))))
|
||||
(parameterize ((current-namespace (vim-get-buff-namespace buf)))
|
||||
(namespace-attach-module vim-global-namespace 'vimext)
|
||||
(namespace-require '(prefix vim vimext)))))
|
||||
EOF
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function s:MzStartup()
|
||||
if has("mzscheme")
|
||||
au BufNew,BufNewFile,BufAdd,BufReadPre * :call s:MzRequire()
|
||||
:mz << EOF
|
||||
(current-library-collection-paths
|
||||
(cons
|
||||
(build-path (find-system-path 'addon-dir) (version) "collects")
|
||||
(current-library-collection-paths)))
|
||||
EOF
|
||||
endif
|
||||
endfunction
|
||||
|
||||
call s:MzStartup()
|
||||
<
|
||||
|
||||
The global namespace just instantiated this module with the prefix "vimext:".
|
||||
*mzscheme-sandbox*
|
||||
When executed in the |sandbox|, access to some filesystem and Vim interface
|
||||
procedures is restricted.
|
||||
@@ -121,15 +83,20 @@ procedures is restricted.
|
||||
2. Examples *mzscheme-examples*
|
||||
>
|
||||
:mzscheme (display "Hello")
|
||||
:mz (display (string-append "Using MzScheme version " (version)))
|
||||
:mzscheme (require (prefix vim- vimext)) ; for MzScheme < 4.x
|
||||
:mzscheme (require (prefix-in vim- 'vimext)) ; MzScheme 4.x
|
||||
:mzscheme (vim-set-buff-line 10 "This is line #10")
|
||||
<
|
||||
Inline script usage: >
|
||||
function! <SID>SetFirstLine()
|
||||
:mz << EOF
|
||||
(display "!!!")
|
||||
(require (prefix vim- vimext))
|
||||
; for newer versions (require (prefix-in vim- 'vimext))
|
||||
(vim-set-buff-line 1 "This is line #1")
|
||||
(vim-beep)
|
||||
EOF
|
||||
EOF
|
||||
endfunction
|
||||
|
||||
nmap <F9> :call <SID>SetFirstLine() <CR>
|
||||
@@ -137,17 +104,33 @@ Inline script usage: >
|
||||
File execution: >
|
||||
:mzfile supascript.scm
|
||||
<
|
||||
Accessing the current buffer namespace from an MzScheme program running in
|
||||
another buffer within |:mzfile|-executed script : >
|
||||
; Move to the window below
|
||||
(vim-command "wincmd j")
|
||||
; execute in the context of buffer, to which window belongs
|
||||
; assume that buffer has 'textstring' defined
|
||||
(parameterize ((current-namespace
|
||||
(vim-get-buff-namespace (vim-curr-buff))))
|
||||
(eval '(vim-set-buff-line 1 textstring)))
|
||||
Vim exception handling: >
|
||||
:mz << EOF
|
||||
(require (prefix vim- vimext))
|
||||
; for newer versions (require (prefix-in vim- 'vimext))
|
||||
(with-handlers
|
||||
([exn:vim? (lambda (e) (display (exn-message e)))])
|
||||
(vim-eval "nonsense-string"))
|
||||
EOF
|
||||
<
|
||||
Auto-instantiation of vimext module (can be placed in your |vimrc|): >
|
||||
function! MzRequire()
|
||||
:redir => l:mzversion
|
||||
:mz (version)
|
||||
:redir END
|
||||
if strpart(l:mzversion, 1, 1) < "4"
|
||||
" MzScheme versions < 4.x:
|
||||
:mz (require (prefix vim- vimext))
|
||||
else
|
||||
" newer versions:
|
||||
:mz (require (prefix-in vim- 'vimext))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
if has("mzscheme")
|
||||
silent call MzRequire()
|
||||
endif
|
||||
<
|
||||
==============================================================================
|
||||
3. Threads *mzscheme-threads*
|
||||
|
||||
@@ -168,11 +151,11 @@ interface.
|
||||
Common
|
||||
------
|
||||
(command {command-string}) Perform the vim ":Ex" style command.
|
||||
(eval {expr-string}) Evaluate the vim expression to a string.
|
||||
A |List| is turned into a string by
|
||||
joining the items and inserting line
|
||||
breaks.
|
||||
NOTE clashes with MzScheme eval
|
||||
(eval {expr-string}) Evaluate the vim expression into
|
||||
respective MzScheme object: |Lists| are
|
||||
represented as Scheme lists,
|
||||
|Dictionaries| as hash tables.
|
||||
NOTE the name clashes with MzScheme eval
|
||||
(range-start) Start/End of the range passed with
|
||||
(range-end) the Scheme command.
|
||||
(beep) beep
|
||||
@@ -186,7 +169,6 @@ Common
|
||||
be set. The symbol 'global can be passed
|
||||
as {buffer-or-window}. Then |:setglobal|
|
||||
will be used.
|
||||
global-namespace The MzScheme main namespace.
|
||||
|
||||
Buffers *mzscheme-buffer*
|
||||
-------
|
||||
@@ -228,7 +210,6 @@ Buffers *mzscheme-buffer*
|
||||
if there is no such buffer.
|
||||
(get-buff-by-num {buffernum}) Get a buffer by its number (return #f if
|
||||
there is no buffer with this number).
|
||||
(get-buff-namespace [buffer]) Get buffer namespace.
|
||||
|
||||
Windows *mzscheme-window*
|
||||
------
|
||||
@@ -250,7 +231,7 @@ Windows *mzscheme-window*
|
||||
(set-cursor (line . col) [window]) Set cursor position.
|
||||
|
||||
==============================================================================
|
||||
5. Dynamic loading *mzscheme-dynamic*
|
||||
5. Dynamic loading *mzscheme-dynamic* *E815*
|
||||
|
||||
On MS-Windows the MzScheme libraries can be loaded dynamically. The |:version|
|
||||
output then includes |+mzscheme/dyn|.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*netbeans.txt* For Vim version 7.2. Last change: 2008 Jun 28
|
||||
*netbeans.txt* For Vim version 7.2. Last change: 2009 Jan 06
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Gordon Prieur et al.
|
||||
@@ -722,8 +722,10 @@ keyAtPos keyName lnum/col
|
||||
of the cursor.
|
||||
New in version 2.1.
|
||||
|
||||
killed A file was closed by the user. Only for files that have been
|
||||
assigned a number by the IDE.
|
||||
killed A file was deleted or wiped out by the user and the buffer
|
||||
annotations have been removed. The bufID number for this
|
||||
buffer has become invalid. Only for files that have been
|
||||
assigned a bufID number by the IDE.
|
||||
|
||||
newDotAndMark off off
|
||||
Reports the position of the cursor being at "off" bytes into
|
||||
|
||||
+14
-6
@@ -1448,6 +1448,14 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
autoselectml Like "autoselect", but for the modeless selection
|
||||
only. Compare to the 'A' flag in 'guioptions'.
|
||||
|
||||
html When the clipboard contains HTML, use this when
|
||||
pasting. When putting text on the clipboard, mark it
|
||||
as HTML. This works to copy rendered HTML from
|
||||
Firefox, paste it as raw HTML in Vim, select the HTML
|
||||
in Vim and paste it in a rich edit box in Firefox.
|
||||
Only supported for GTK version 2 and later.
|
||||
Only available with the |+multi_byte| feature.
|
||||
|
||||
exclude:{pattern}
|
||||
Defines a pattern that is matched against the name of
|
||||
the terminal 'term'. If there is a match, no
|
||||
@@ -3490,6 +3498,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
foreground. |gui-fork|
|
||||
Note: Set this option in the vimrc file. The forking may have
|
||||
happened already when the |gvimrc| file is read.
|
||||
MacVim does not support this flag due to limitations with
|
||||
forking on Mac OS X.
|
||||
*'go-i'*
|
||||
'i' Use a Vim icon. For GTK with KDE it is used in the left-upper
|
||||
corner of the window. It's black&white on non-GTK, because of
|
||||
@@ -3871,11 +3881,12 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
global
|
||||
{not in Vi}
|
||||
{only available when compiled with the |+xim|
|
||||
|+multi_byte_ime| or |global-ime| feature}
|
||||
|+multi_byte_ime| or |global-ime| feature, always
|
||||
available in MacVim}
|
||||
When set the Input Method is never used. This is useful to disable
|
||||
the IM when it doesn't work properly.
|
||||
Currently this option is on by default for SGI/IRIX and MacVim. This
|
||||
may change in later releases.
|
||||
Currently this option is on by default for SGI/IRIX. This may change
|
||||
in later releases.
|
||||
|
||||
*'iminsert'* *'imi'*
|
||||
'iminsert' 'imi' number (default 0, 2 when an input method is supported)
|
||||
@@ -4273,9 +4284,6 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
be able to execute Normal mode commands.
|
||||
This is the opposite of the 'keymap' option, where characters are
|
||||
mapped in Insert mode.
|
||||
This only works for 8-bit characters. The value of 'langmap' may be
|
||||
specified with multi-byte characters (e.g., UTF-8), but only the lower
|
||||
8 bits of each character will be used.
|
||||
|
||||
Example (for Greek, in UTF-8): *greek* >
|
||||
:set langmap=ΑA,ΒB,ΨC,ΔD,ΕE,ΦF,ΓG,ΗH,ΙI,ΞJ,ΚK,ΛL,ΜM,ΝN,ΟO,ΠP,QQ,ΡR,ΣS,ΤT,ΘU,ΩV,WW,ΧX,ΥY,ΖZ,αa,βb,ψc,δd,εe,φf,γg,ηh,ιi,ξj,κk,λl,μm,νn,οo,πp,qq,ρr,σs,τt,θu,ωv,ςw,χx,υy,ζz
|
||||
|
||||
@@ -511,6 +511,17 @@ N *+X11* Unix only: can restore window title |X11|
|
||||
messages though. Use ":silent" in the command itself
|
||||
to avoid that: ":silent menu .... :silent command".
|
||||
|
||||
*:uns* *:unsilent*
|
||||
:uns[ilent] {command} Execute {command} not silently. Only makes a
|
||||
difference when |:silent| was used to get to this
|
||||
command.
|
||||
Use this for giving a message even when |:silent| was
|
||||
used. In this example |:silent| is used to avoid the
|
||||
message about reading the file and |:unsilent| to be
|
||||
able to list the first line of each file. >
|
||||
:silent argdo unsilent echo expand('%') . ": " . getline(1)
|
||||
<
|
||||
|
||||
*:verb* *:verbose*
|
||||
:[count]verb[ose] {command}
|
||||
Execute {command} with 'verbose' set to [count]. If
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
" Vim script to fix duplicate words in a .dic file vim: set ft=vim:
|
||||
"
|
||||
" Usage: Edit the .dic file and source this script.
|
||||
|
||||
let deleted = 0
|
||||
|
||||
" Start below the word count.
|
||||
let lnum = 2
|
||||
while lnum <= line('$')
|
||||
let word = getline(lnum)
|
||||
if word !~ '/'
|
||||
if search('^' . word . '/', 'w') != 0
|
||||
let deleted += 1
|
||||
exe lnum . "d"
|
||||
continue " don't increment lnum, it's already at the next word
|
||||
endif
|
||||
endif
|
||||
let lnum += 1
|
||||
endwhile
|
||||
|
||||
if deleted == 0
|
||||
echomsg "No duplicate words found"
|
||||
elseif deleted == 1
|
||||
echomsg "Deleted 1 duplicate word"
|
||||
else
|
||||
echomsg printf("Deleted %d duplicate words", deleted)
|
||||
endif
|
||||
+464
-461
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf350
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf430
|
||||
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\vieww9000\viewh8400\viewkind0
|
||||
@@ -31,6 +31,7 @@ Matt Tolton\
|
||||
Kaoru Yoshida\
|
||||
Ron Olson\
|
||||
Jonathon Mah\
|
||||
Kazuki Sakamoto\
|
||||
|
||||
\i0 \
|
||||
...and many others who have helped by reporting bugs etc.\
|
||||
@@ -40,8 +41,6 @@ Thank you to {\field{\*\fldinst{HYPERLINK "http://www.positivespinmedia.com"}}{\
|
||||
\
|
||||
Toolbar icons by {\field{\*\fldinst{HYPERLINK "http://www.mattballdesign.com/"}}{\fldrslt Matt Ball}} (free Developer Icons), {\field{\*\fldinst{HYPERLINK "http://www.jonasraskdesign.com/"}}{\fldrslt Jonas Rask}} (Danish Royalty Free icon set), and {\field{\*\fldinst{HYPERLINK "http://www.everaldo.com"}}{\fldrslt Everaldo Coelho}} (Crystal Project Icons, released under LGPL license).\
|
||||
\
|
||||
Vim icons made by {\field{\*\fldinst{HYPERLINK "http://www.cs.princeton.edu/~mtwebb/vim_icon/vim_icons.html"}}{\fldrslt Matthew Webb}}.\
|
||||
\
|
||||
The default font in MacVim, DejaVu Sans Mono, is based on the Bitstream Vera\'99 and Arev fonts. Bitstream Vera\'99 is \'a9 2003 by Bitstream, Inc. Arev is \'a9 2006 by Tavmjong Bah. The DejaVu changes to these fonts are in the public domain.\
|
||||
\
|
||||
Thanks to Andy Matuschak for {\field{\*\fldinst{HYPERLINK "http://sparkle.andymatuschak.org/"}}{\fldrslt Sparkle}}.\
|
||||
@@ -52,4 +51,6 @@ Thanks to Allan Odgaard for making the "Edit in TextMate" input manager source c
|
||||
\
|
||||
Thanks to Rainer Brockerhoff for RBSplitView.\
|
||||
\
|
||||
Thanks to Chad Weider for CTGradient.}
|
||||
Thanks to Chad Weider for CTGradient.\
|
||||
\
|
||||
Thanks to Damien Guard for {\field{\*\fldinst{HYPERLINK "http://damieng.com/blog/2008/05/26/envy-code-r-preview-7-coding-font-released"}}{\fldrslt Envy Code R}} (used in MacVim's 16x16 document icons).}
|
||||
+1349
-7
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,532 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<!-- These keys are needed to prevent Cocoa from inserting them as
|
||||
normal text (missing from StandardKeyBinding.dict below).
|
||||
-->
|
||||
<key>$</key>
|
||||
<string>deleteBackward:</string>
|
||||
<key>$
|
||||
</key>
|
||||
<string>insertNewline:</string>
|
||||
<key>^~
|
||||
</key>
|
||||
<string>insertNewline:</string>
|
||||
<key>$</key>
|
||||
<string>insertNewline:</string>
|
||||
<key>^~</key>
|
||||
<string>insertNewline:</string>
|
||||
<key>^</key>
|
||||
<string>cancelOperation:</string>
|
||||
<key>$</key>
|
||||
<string>cancelOperation:</string>
|
||||
<key>^~</key>
|
||||
<string>cancelOperation:</string>
|
||||
<key>^~ </key>
|
||||
<string>insertTab:</string>
|
||||
<key>~</key>
|
||||
<string>insertBackTab:</string>
|
||||
<key>^~</key>
|
||||
<string>insertBackTab:</string>
|
||||
<key>^ </key>
|
||||
<string>keySpace:</string>
|
||||
<key>~ </key>
|
||||
<string>keySpace:</string>
|
||||
<key>$ </key>
|
||||
<string>keySpace:</string>
|
||||
<key>^~ </key>
|
||||
<string>keySpace:</string>
|
||||
|
||||
<!-- The following keys involving Command (@) are here to make sure
|
||||
interpretKeyEvents: does not block Command+Alt+.. and
|
||||
Command+Ctrl+.. key events. -->
|
||||
<key>@~</key>
|
||||
<string>noop:</string>
|
||||
<key>@^</key>
|
||||
<string>noop:</string>
|
||||
<key>@^~</key>
|
||||
<string>noop:</string>
|
||||
|
||||
|
||||
<!-- These keys are used to convert certain keys so that we don't have
|
||||
to do it manually.
|
||||
-->
|
||||
<!-- Turn Ctrl-2 into Ctrl-@ -->
|
||||
<key>^2</key>
|
||||
<string>keyCtrlAt:</string>
|
||||
<!-- Turn Ctrl-6 into Ctrl-^ -->
|
||||
<key>^6</key>
|
||||
<string>keyCtrlHat:</string>
|
||||
|
||||
|
||||
<!-- These are copied from AppKit.framework/StandardKeyBinding.dict
|
||||
-->
|
||||
<key></key>
|
||||
<string>insertNewline:</string>
|
||||
<key></key>
|
||||
<string>deleteBackward:</string>
|
||||
<key> </key>
|
||||
<string>insertTab:</string>
|
||||
<key>
|
||||
</key>
|
||||
<string>insertNewline:</string>
|
||||
<key>
|
||||
</key>
|
||||
<string>insertNewline:</string>
|
||||
<key></key>
|
||||
<string>insertBacktab:</string>
|
||||
<key></key>
|
||||
<string>cancelOperation:</string>
|
||||
<key>$</key>
|
||||
<string>moveUpAndModifySelection:</string>
|
||||
<key>$</key>
|
||||
<string>moveDownAndModifySelection:</string>
|
||||
<key>$</key>
|
||||
<string>moveLeftAndModifySelection:</string>
|
||||
<key>$</key>
|
||||
<string>moveRightAndModifySelection:</string>
|
||||
<key>$</key>
|
||||
<string>moveToBeginningOfDocumentAndModifySelection:</string>
|
||||
<key>$</key>
|
||||
<string>moveToEndOfDocumentAndModifySelection:</string>
|
||||
<key>$</key>
|
||||
<string>pageUpAndModifySelection:</string>
|
||||
<key>$</key>
|
||||
<string>pageDownAndModifySelection:</string>
|
||||
<key>@</key>
|
||||
<string>noop:</string>
|
||||
<key>@ </key>
|
||||
<string>cycleToNextInputScript:</string>
|
||||
<key>@.</key>
|
||||
<string>cancelOperation:</string>
|
||||
<key>@^ </key>
|
||||
<string>togglePlatformInputSystem:</string>
|
||||
<key>@~ </key>
|
||||
<string>cycleToNextInputKeyboardLayout:</string>
|
||||
<key>^</key>
|
||||
<string>noop:</string>
|
||||
<key>^</key>
|
||||
<string>insertLineBreak:</string>
|
||||
<key>^ </key>
|
||||
<string>selectNextKeyView:</string>
|
||||
<key>^
|
||||
</key>
|
||||
<string>insertLineBreak:</string>
|
||||
<key>^
|
||||
</key>
|
||||
<string>insertLineBreak:</string>
|
||||
<key>^</key>
|
||||
<string>selectPreviousKeyView:</string>
|
||||
<key>^"</key>
|
||||
<string>insertDoubleQuoteIgnoringSubstitution:</string>
|
||||
<key>^'</key>
|
||||
<string>insertSingleQuoteIgnoringSubstitution:</string>
|
||||
<key>^A</key>
|
||||
<string>moveToBeginningOfParagraphAndModifySelection:</string>
|
||||
<key>^B</key>
|
||||
<string>moveBackwardAndModifySelection:</string>
|
||||
<key>^E</key>
|
||||
<string>moveToEndOfParagraphAndModifySelection:</string>
|
||||
<key>^F</key>
|
||||
<string>moveForwardAndModifySelection:</string>
|
||||
<key>^N</key>
|
||||
<string>moveDownAndModifySelection:</string>
|
||||
<key>^P</key>
|
||||
<string>moveUpAndModifySelection:</string>
|
||||
<key>^V</key>
|
||||
<string>pageDownAndModifySelection:</string>
|
||||
<key>^a</key>
|
||||
<string>moveToBeginningOfParagraph:</string>
|
||||
<key>^b</key>
|
||||
<string>moveBackward:</string>
|
||||
<key>^d</key>
|
||||
<string>deleteForward:</string>
|
||||
<key>^e</key>
|
||||
<string>moveToEndOfParagraph:</string>
|
||||
<key>^f</key>
|
||||
<string>moveForward:</string>
|
||||
<key>^h</key>
|
||||
<string>deleteBackward:</string>
|
||||
<key>^k</key>
|
||||
<string>deleteToEndOfParagraph:</string>
|
||||
<key>^l</key>
|
||||
<string>centerSelectionInVisibleArea:</string>
|
||||
<key>^n</key>
|
||||
<string>moveDown:</string>
|
||||
<key>^o</key>
|
||||
<array>
|
||||
<string>insertNewlineIgnoringFieldEditor:</string>
|
||||
<string>moveBackward:</string>
|
||||
</array>
|
||||
<key>^p</key>
|
||||
<string>moveUp:</string>
|
||||
<key>^t</key>
|
||||
<string>transpose:</string>
|
||||
<key>^v</key>
|
||||
<string>pageDown:</string>
|
||||
<key>^y</key>
|
||||
<string>yank:</string>
|
||||
<key>^~</key>
|
||||
<string>deleteWordBackward:</string>
|
||||
<key>^</key>
|
||||
<string>deleteBackwardByDecomposingPreviousCharacter:</string>
|
||||
<key>~</key>
|
||||
<string>insertNewlineIgnoringFieldEditor:</string>
|
||||
<key>~</key>
|
||||
<string>deleteWordBackward:</string>
|
||||
<key>~ </key>
|
||||
<string>insertTabIgnoringFieldEditor:</string>
|
||||
<key>~
|
||||
</key>
|
||||
<string>insertNewlineIgnoringFieldEditor:</string>
|
||||
<key>~
|
||||
</key>
|
||||
<string>insertNewlineIgnoringFieldEditor:</string>
|
||||
<key>~</key>
|
||||
<string>complete:</string>
|
||||
<key>~^B</key>
|
||||
<string>moveWordBackwardAndModifySelection:</string>
|
||||
<key>~^F</key>
|
||||
<string>moveWordForwardAndModifySelection:</string>
|
||||
<key>~^b</key>
|
||||
<string>moveWordBackward:</string>
|
||||
<key>~^f</key>
|
||||
<string>moveWordForward:</string>
|
||||
<key>~</key>
|
||||
<string>deleteWordBackward:</string>
|
||||
<key></key>
|
||||
<string>deleteBackward:</string>
|
||||
<key></key>
|
||||
<string>moveUp:</string>
|
||||
<key></key>
|
||||
<string>moveDown:</string>
|
||||
<key></key>
|
||||
<string>moveLeft:</string>
|
||||
<key></key>
|
||||
<string>moveRight:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>complete:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>deleteForward:</string>
|
||||
<key></key>
|
||||
<string>scrollToBeginningOfDocument:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>scrollToEndOfDocument:</string>
|
||||
<key></key>
|
||||
<string>scrollPageUp:</string>
|
||||
<key></key>
|
||||
<string>scrollPageDown:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key>@</key>
|
||||
<string>moveToBeginningOfDocument:</string>
|
||||
<key>@</key>
|
||||
<string>moveToEndOfDocument:</string>
|
||||
<key>@</key>
|
||||
<string>moveToBeginningOfLine:</string>
|
||||
<key>@</key>
|
||||
<string>moveToEndOfLine:</string>
|
||||
<key>@$</key>
|
||||
<string>moveToBeginningOfDocumentAndModifySelection:</string>
|
||||
<key>@$</key>
|
||||
<string>moveToEndOfDocumentAndModifySelection:</string>
|
||||
<key>@$</key>
|
||||
<string>moveToBeginningOfLineAndModifySelection:</string>
|
||||
<key>@$</key>
|
||||
<string>moveToEndOfLineAndModifySelection:</string>
|
||||
<key>@^</key>
|
||||
<string>changeBaseWritingDirectionToRTL:</string>
|
||||
<key>@^</key>
|
||||
<string>changeBaseWritingDirectionToLTR:</string>
|
||||
<key>@</key>
|
||||
<string>deleteToBeginningOfLine:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key></key>
|
||||
<string>noop:</string>
|
||||
<key>^</key>
|
||||
<string>scrollPageUp:</string>
|
||||
<key>^</key>
|
||||
<string>scrollPageDown:</string>
|
||||
<key>^</key>
|
||||
<string>moveToBeginningOfLine:</string>
|
||||
<key>^</key>
|
||||
<string>moveToEndOfLine:</string>
|
||||
<key>^$</key>
|
||||
<string>moveToBeginningOfLineAndModifySelection:</string>
|
||||
<key>^$</key>
|
||||
<string>moveToEndOfLineAndModifySelection:</string>
|
||||
<key>~</key>
|
||||
<array>
|
||||
<string>moveBackward:</string>
|
||||
<string>moveToBeginningOfParagraph:</string>
|
||||
</array>
|
||||
<key>~</key>
|
||||
<array>
|
||||
<string>moveForward:</string>
|
||||
<string>moveToEndOfParagraph:</string>
|
||||
</array>
|
||||
<key>~</key>
|
||||
<string>moveWordLeft:</string>
|
||||
<key>~</key>
|
||||
<string>moveWordRight:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~$</key>
|
||||
<string>moveParagraphBackwardAndModifySelection:</string>
|
||||
<key>~$</key>
|
||||
<string>moveParagraphForwardAndModifySelection:</string>
|
||||
<key>~$</key>
|
||||
<string>moveWordLeftAndModifySelection:</string>
|
||||
<key>~$</key>
|
||||
<string>moveWordRightAndModifySelection:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>deleteWordForward:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>pageUp:</string>
|
||||
<key>~</key>
|
||||
<string>pageDown:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
<string>noop:</string>
|
||||
<key>~</key>
|
||||
@@ -29,6 +29,8 @@
|
||||
int preloadPid;
|
||||
BOOL shouldActivateWhenNextWindowOpens;
|
||||
int numChildProcesses;
|
||||
NSMutableDictionary *inputQueues;
|
||||
int processingFlag;
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
FSEventStreamRef fsEventStream;
|
||||
|
||||
+382
-152
@@ -82,6 +82,13 @@ typedef struct
|
||||
#pragma options align=reset
|
||||
|
||||
|
||||
// This is a private AppKit API gleaned from class-dump.
|
||||
@interface NSKeyBindingManager : NSObject
|
||||
+ (id)sharedKeyBindingManager;
|
||||
- (id)dictionary;
|
||||
- (void)setDictionary:(id)arg1;
|
||||
@end
|
||||
|
||||
|
||||
@interface MMAppController (MMServices)
|
||||
- (void)openSelection:(NSPasteboard *)pboard userData:(NSString *)userData
|
||||
@@ -125,6 +132,8 @@ typedef struct
|
||||
- (void)loadDefaultFont;
|
||||
- (int)executeInLoginShell:(NSString *)path arguments:(NSArray *)args;
|
||||
- (void)reapChildProcesses:(id)sender;
|
||||
- (void)processInputQueues:(id)sender;
|
||||
- (void)addVimController:(MMVimController *)vc;
|
||||
|
||||
#ifdef MM_ENABLE_PLUGINS
|
||||
- (void)removePlugInMenu;
|
||||
@@ -151,6 +160,22 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
static BOOL initDone = NO;
|
||||
if (initDone) return;
|
||||
initDone = YES;
|
||||
|
||||
ASLInit();
|
||||
|
||||
// HACK! The following user default must be reset, else Ctrl-q (or
|
||||
// whichever key is specified by the default) will be blocked by the input
|
||||
// manager (interpretKeyEvents: swallows that key). (We can't use
|
||||
// NSUserDefaults since it only allows us to write to the registration
|
||||
// domain and this preference has "higher precedence" than that so such a
|
||||
// change would have no effect.)
|
||||
CFPreferencesSetAppValue(CFSTR("NSQuotedKeystrokeBinding"),
|
||||
CFSTR(""),
|
||||
kCFPreferencesCurrentApplication);
|
||||
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithBool:NO], MMNoWindowKey,
|
||||
[NSNumber numberWithInt:64], MMTabMinWidthKey,
|
||||
@@ -184,6 +209,9 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
[NSNumber numberWithInt:0], MMPreloadCacheSizeKey,
|
||||
[NSNumber numberWithInt:0], MMLastWindowClosedBehaviorKey,
|
||||
[NSNumber numberWithBool:YES], MMLoadDefaultFontKey,
|
||||
#ifdef INCLUDE_OLD_IM_CODE
|
||||
[NSNumber numberWithBool:YES], MMUseInlineImKey,
|
||||
#endif // INCLUDE_OLD_IM_CODE
|
||||
nil];
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
|
||||
@@ -208,6 +236,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
cachedVimControllers = [NSMutableArray new];
|
||||
preloadPid = -1;
|
||||
pidArguments = [NSMutableDictionary new];
|
||||
inputQueues = [NSMutableDictionary new];
|
||||
|
||||
#ifdef MM_ENABLE_PLUGINS
|
||||
NSString *plugInTitle = NSLocalizedString(@"Plug-In",
|
||||
@@ -234,10 +263,8 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
// updated in MMBackend.m.
|
||||
NSString *name = [NSString stringWithFormat:@"%@-connection",
|
||||
[[NSBundle mainBundle] bundlePath]];
|
||||
//NSLog(@"Registering connection with name '%@'", name);
|
||||
if (![connection registerName:name]) {
|
||||
NSLog(@"FATAL ERROR: Failed to register connection with name '%@'",
|
||||
name);
|
||||
ASLogCrit(@"Failed to register connection with name '%@'", name);
|
||||
[connection release]; connection = nil;
|
||||
}
|
||||
|
||||
@@ -246,9 +273,10 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
//NSLog(@"MMAppController dealloc");
|
||||
ASLogDebug(@"");
|
||||
|
||||
[connection release]; connection = nil;
|
||||
[inputQueues release]; inputQueues = nil;
|
||||
[pidArguments release]; pidArguments = nil;
|
||||
[vimControllers release]; vimControllers = nil;
|
||||
[cachedVimControllers release]; cachedVimControllers = nil;
|
||||
@@ -317,6 +345,40 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
andSelector:@selector(handleGetURLEvent:replyEvent:)
|
||||
forEventClass:kInternetEventClass
|
||||
andEventID:kAEGetURL];
|
||||
|
||||
// Disable the default Cocoa "Key Bindings" since they interfere with the
|
||||
// way Vim handles keyboard input. Cocoa reads bindings from
|
||||
// /System/Library/Frameworks/AppKit.framework/Resources/
|
||||
// StandardKeyBinding.dict
|
||||
// and
|
||||
// ~/Library/KeyBindings/DefaultKeyBinding.dict
|
||||
// To avoid having the user accidentally break keyboard handling (by
|
||||
// modifying the latter in some unexpected way) in MacVim we load our own
|
||||
// key binding dictionary from Resource/KeyBinding.plist. We can't disable
|
||||
// the bindings completely since it would break keyboard handling in
|
||||
// dialogs so the our custom dictionary contains all the entries from the
|
||||
// former location.
|
||||
//
|
||||
// It is possible to disable key bindings completely by not calling
|
||||
// interpretKeyEvents: in keyDown: but this also disables key bindings used
|
||||
// by certain input methods. E.g. Ctrl-Shift-; would no longer work in
|
||||
// the Kotoeri input manager.
|
||||
//
|
||||
// To solve this problem we access a private API and set the key binding
|
||||
// dictionary to our own custom dictionary here. At this time Cocoa will
|
||||
// have already read the above mentioned dictionaries so it (hopefully)
|
||||
// won't try to change the key binding dictionary again after this point.
|
||||
NSKeyBindingManager *mgr = [NSKeyBindingManager sharedKeyBindingManager];
|
||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
||||
NSString *path = [mainBundle pathForResource:@"KeyBinding"
|
||||
ofType:@"plist"];
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
|
||||
if (mgr && dict) {
|
||||
[mgr setDictionary:dict];
|
||||
} else {
|
||||
ASLogNotice(@"Failed to override the Cocoa key bindings. Keyboard "
|
||||
"input may behave strangely as a result (path=%@).", path);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||
@@ -330,6 +392,8 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
[self scheduleVimControllerPreloadAfterDelay:2];
|
||||
[self startWatchingVimDir];
|
||||
}
|
||||
|
||||
ASLogInfo(@"MacVim finished launching");
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender
|
||||
@@ -341,14 +405,17 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
// The user default MMUntitledWindow can be set to control whether an
|
||||
// untitled window should open on 'Open' and 'Reopen' events.
|
||||
int untitledWindowFlag = [ud integerForKey:MMUntitledWindowKey];
|
||||
if ([desc eventID] == kAEOpenApplication
|
||||
&& (untitledWindowFlag & MMUntitledWindowOnOpen) == 0)
|
||||
|
||||
BOOL isAppOpenEvent = [desc eventID] == kAEOpenApplication;
|
||||
if (isAppOpenEvent && (untitledWindowFlag & MMUntitledWindowOnOpen) == 0)
|
||||
return NO;
|
||||
else if ([desc eventID] == kAEReopenApplication
|
||||
|
||||
BOOL isAppReopenEvent = [desc eventID] == kAEReopenApplication;
|
||||
if (isAppReopenEvent
|
||||
&& (untitledWindowFlag & MMUntitledWindowOnReopen) == 0)
|
||||
return NO;
|
||||
|
||||
// When a process is started from the command line, the 'Open' event will
|
||||
// When a process is started from the command line, the 'Open' event may
|
||||
// contain a parameter to surpress the opening of an untitled window.
|
||||
desc = [desc paramDescriptorForKeyword:keyAEPropData];
|
||||
desc = [desc paramDescriptorForKeyword:keyMMUntitledWindow];
|
||||
@@ -361,18 +428,25 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
return NO;
|
||||
|
||||
// NOTE! This way it possible to start the app with the command-line
|
||||
// argument '-nowindow yes' and no window will be opened by default.
|
||||
return ![ud boolForKey:MMNoWindowKey];
|
||||
// argument '-nowindow yes' and no window will be opened by default but
|
||||
// this argument will only be heeded when the application is opening.
|
||||
if (isAppOpenEvent && [ud boolForKey:MMNoWindowKey] == YES)
|
||||
return NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender
|
||||
{
|
||||
ASLogDebug(@"Opening untitled window...");
|
||||
[self newWindow:self];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
|
||||
{
|
||||
ASLogInfo(@"Opening files %@", filenames);
|
||||
|
||||
// Extract ODB/Xcode/Spotlight parameters from the current Apple event,
|
||||
// sort the filenames, and then let openFiles:withArguments: do the heavy
|
||||
// lifting.
|
||||
@@ -506,20 +580,20 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
e = [vimControllers objectEnumerator];
|
||||
id vc;
|
||||
while ((vc = [e nextObject])) {
|
||||
//NSLog(@"Terminate pid=%d", [vc pid]);
|
||||
ASLogDebug(@"Terminate pid=%d", [vc pid]);
|
||||
[vc sendMessage:TerminateNowMsgID data:nil];
|
||||
}
|
||||
|
||||
e = [cachedVimControllers objectEnumerator];
|
||||
while ((vc = [e nextObject])) {
|
||||
//NSLog(@"Terminate pid=%d (cached)", [vc pid]);
|
||||
ASLogDebug(@"Terminate pid=%d (cached)", [vc pid]);
|
||||
[vc sendMessage:TerminateNowMsgID data:nil];
|
||||
}
|
||||
|
||||
// If a Vim process is being preloaded as we quit we have to forcibly
|
||||
// kill it since we have not established a connection yet.
|
||||
if (preloadPid > 0) {
|
||||
//NSLog(@"INCOMPLETE preloaded process: preloadPid=%d", preloadPid);
|
||||
ASLogDebug(@"Kill incomplete preloaded process pid=%d", preloadPid);
|
||||
kill(preloadPid, SIGKILL);
|
||||
}
|
||||
|
||||
@@ -527,7 +601,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
e = [[pidArguments allKeys] objectEnumerator];
|
||||
NSNumber *pidKey;
|
||||
while ((pidKey = [e nextObject])) {
|
||||
//NSLog(@"INCOMPLETE process: pid=%d", [pidKey intValue]);
|
||||
ASLogDebug(@"Kill incomplete process pid=%d", [pidKey intValue]);
|
||||
kill([pidKey intValue], SIGKILL);
|
||||
}
|
||||
|
||||
@@ -540,6 +614,8 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)notification
|
||||
{
|
||||
ASLogInfo(@"Terminating MacVim...");
|
||||
|
||||
[self stopWatchingVimDir];
|
||||
|
||||
#ifdef MM_ENABLE_PLUGINS
|
||||
@@ -574,7 +650,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
if (numChildProcesses <= 0)
|
||||
break;
|
||||
|
||||
//NSLog(@"%d processes still left, sleep a bit...", numChildProcesses);
|
||||
ASLogDebug(@"%d processes still left, hold on...", numChildProcesses);
|
||||
|
||||
// Run in NSConnectionReplyMode while waiting instead of calling e.g.
|
||||
// usleep(). Otherwise incoming messages may clog up the DO queues and
|
||||
@@ -589,8 +665,9 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
; // do nothing
|
||||
}
|
||||
|
||||
if (numChildProcesses > 0)
|
||||
NSLog(@"%d ZOMBIES left behind", numChildProcesses);
|
||||
if (numChildProcesses > 0) {
|
||||
ASLogNotice(@"%d zombies left behind", numChildProcesses);
|
||||
}
|
||||
}
|
||||
|
||||
+ (MMAppController *)sharedInstance
|
||||
@@ -613,9 +690,14 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (void)removeVimController:(id)controller
|
||||
{
|
||||
ASLogDebug(@"Remove Vim controller pid=%d id=%d (processingFlag=%d)",
|
||||
[controller pid], [controller identifier], processingFlag);
|
||||
|
||||
int idx = [vimControllers indexOfObject:controller];
|
||||
if (NSNotFound == idx)
|
||||
if (NSNotFound == idx) {
|
||||
ASLogDebug(@"Controller not found, probably due to duplicate removal");
|
||||
return;
|
||||
}
|
||||
|
||||
[controller cleanup];
|
||||
|
||||
@@ -669,21 +751,26 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
[win setFrameTopLeftPoint:topLeft];
|
||||
|
||||
NSPoint screenOrigin = [[win screen] frame].origin;
|
||||
if ([win frame].origin.y < screenOrigin.y) {
|
||||
// Try to avoid shifting the new window downwards if it means that
|
||||
// the bottom of the window will be off the screen. E.g. if the
|
||||
// user has set windows to open maximized in the vertical direction
|
||||
// then the new window will cascade horizontally only.
|
||||
topLeft.y = oldTopLeft.y;
|
||||
[win setFrameTopLeftPoint:topLeft];
|
||||
}
|
||||
if ([win screen]) {
|
||||
NSPoint screenOrigin = [[win screen] frame].origin;
|
||||
if ([win frame].origin.y < screenOrigin.y) {
|
||||
// Try to avoid shifting the new window downwards if it means
|
||||
// that the bottom of the window will be off the screen. E.g.
|
||||
// if the user has set windows to open maximized in the
|
||||
// vertical direction then the new window will cascade
|
||||
// horizontally only.
|
||||
topLeft.y = oldTopLeft.y;
|
||||
[win setFrameTopLeftPoint:topLeft];
|
||||
}
|
||||
|
||||
if ([win frame].origin.y < screenOrigin.y) {
|
||||
// Move the window to the top of the screen if the bottom of the
|
||||
// window is still obscured.
|
||||
topLeft.y = NSMaxY([[win screen] frame]);
|
||||
[win setFrameTopLeftPoint:topLeft];
|
||||
if ([win frame].origin.y < screenOrigin.y) {
|
||||
// Move the window to the top of the screen if the bottom of
|
||||
// the window is still obscured.
|
||||
topLeft.y = NSMaxY([[win screen] frame]);
|
||||
[win setFrameTopLeftPoint:topLeft];
|
||||
}
|
||||
} else {
|
||||
ASLogNotice(@"Window not on screen, don't constrain position");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -803,6 +890,8 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
NSMutableDictionary *arguments = (args ? [[args mutableCopy] autorelease]
|
||||
: [NSMutableDictionary dictionary]);
|
||||
|
||||
filenames = normalizeFilenames(filenames);
|
||||
|
||||
//
|
||||
// a) Filter out any already open files
|
||||
//
|
||||
@@ -830,6 +919,17 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
firstController = vc;
|
||||
}
|
||||
|
||||
// The meaning of "layout" is defined by the WIN_* defines in main.c.
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
int layout = [ud integerForKey:MMOpenLayoutKey];
|
||||
BOOL splitVert = [ud boolForKey:MMVerticalSplitKey];
|
||||
BOOL openInCurrentWindow = [ud boolForKey:MMOpenInCurrentWindowKey];
|
||||
|
||||
if (splitVert && MMLayoutHorizontalSplit == layout)
|
||||
layout = MMLayoutVerticalSplit;
|
||||
if (layout < 0 || (layout > MMLayoutTabs && openInCurrentWindow))
|
||||
layout = MMLayoutTabs;
|
||||
|
||||
if ([filenames count] == 0) {
|
||||
// Raise the window containing the first file that was already open,
|
||||
// and make sure that the tab containing that file is selected. Only
|
||||
@@ -837,10 +937,18 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
// the window with 'firstFile' will be raised, other times it might be
|
||||
// the window that will open with the files in the 'filenames' array.
|
||||
firstFile = [firstFile stringByEscapingSpecialFilenameCharacters];
|
||||
|
||||
NSString *bufCmd = @"tab sb";
|
||||
switch (layout) {
|
||||
case MMLayoutHorizontalSplit: bufCmd = @"sb"; break;
|
||||
case MMLayoutVerticalSplit: bufCmd = @"vert sb"; break;
|
||||
case MMLayoutArglist: bufCmd = @"b"; break;
|
||||
}
|
||||
|
||||
NSString *input = [NSString stringWithFormat:@"<C-\\><C-N>"
|
||||
":let oldswb=&swb|let &swb=\"useopen,usetab\"|"
|
||||
"tab sb %@|let &swb=oldswb|unl oldswb|"
|
||||
"cal foreground()<CR>", firstFile];
|
||||
"%@ %@|let &swb=oldswb|unl oldswb|"
|
||||
"cal foreground()<CR>", bufCmd, firstFile];
|
||||
|
||||
[firstController addVimInput:input];
|
||||
|
||||
@@ -857,23 +965,13 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
//
|
||||
// b) Open any remaining files
|
||||
//
|
||||
MMVimController *vc;
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
BOOL openInCurrentWindow = [ud boolForKey:MMOpenInCurrentWindowKey];
|
||||
|
||||
// The meaning of "layout" is defined by the WIN_* defines in main.c.
|
||||
int layout = [ud integerForKey:MMOpenLayoutKey];
|
||||
BOOL splitVert = [ud boolForKey:MMVerticalSplitKey];
|
||||
if (splitVert && MMLayoutHorizontalSplit == layout)
|
||||
layout = MMLayoutVerticalSplit;
|
||||
if (layout < 0 || (layout > MMLayoutTabs && openInCurrentWindow))
|
||||
layout = MMLayoutTabs;
|
||||
|
||||
[arguments setObject:[NSNumber numberWithInt:layout] forKey:@"layout"];
|
||||
[arguments setObject:filenames forKey:@"filenames"];
|
||||
// (Indicate that files should be opened from now on.)
|
||||
[arguments setObject:[NSNumber numberWithBool:NO] forKey:@"dontOpen"];
|
||||
|
||||
MMVimController *vc;
|
||||
if (openInCurrentWindow && (vc = [self topmostVimController])) {
|
||||
// Open files in an already open window.
|
||||
[[[vc windowController] window] makeKeyAndOrderFront:self];
|
||||
@@ -944,6 +1042,8 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (IBAction)newWindow:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Open new window");
|
||||
|
||||
// A cached controller requires no loading times and results in the new
|
||||
// window popping up instantaneously. If the cache is empty it may take
|
||||
// 1-2 seconds to start a new Vim process.
|
||||
@@ -963,6 +1063,8 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (IBAction)fileOpen:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Show file open panel");
|
||||
|
||||
NSString *dir = nil;
|
||||
BOOL trackPwd = [[NSUserDefaults standardUserDefaults]
|
||||
boolForKey:MMDialogsTrackPwdKey];
|
||||
@@ -973,7 +1075,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
[panel setAllowsMultipleSelection:YES];
|
||||
[panel setAccessoryView:openPanelAccessoryView()];
|
||||
[panel setAccessoryView:showHiddenFilesView()];
|
||||
|
||||
int result = [panel runModalForDirectory:dir file:nil types:nil];
|
||||
if (NSOKButton == result)
|
||||
@@ -982,6 +1084,8 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (IBAction)selectNextWindow:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Select next window");
|
||||
|
||||
unsigned i, count = [vimControllers count];
|
||||
if (!count) return;
|
||||
|
||||
@@ -1002,6 +1106,8 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (IBAction)selectPreviousWindow:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Select previous window");
|
||||
|
||||
unsigned i, count = [vimControllers count];
|
||||
if (!count) return;
|
||||
|
||||
@@ -1025,17 +1131,20 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (IBAction)orderFrontPreferencePanel:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Show preferences panel");
|
||||
[[MMPreferenceController sharedPrefsWindowController] showWindow:self];
|
||||
}
|
||||
|
||||
- (IBAction)openWebsite:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Open MacVim website");
|
||||
[[NSWorkspace sharedWorkspace] openURL:
|
||||
[NSURL URLWithString:MMWebsiteString]];
|
||||
}
|
||||
|
||||
- (IBAction)showVimHelp:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Open window with Vim help");
|
||||
// Open a new window with the help window maximized.
|
||||
[self launchVimProcessWithArguments:[NSArray arrayWithObjects:
|
||||
@"-c", @":h gui_mac", @"-c", @":res", nil]];
|
||||
@@ -1043,11 +1152,13 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (IBAction)zoomAll:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Zoom all windows");
|
||||
[NSApp makeWindowsPerform:@selector(performZoom:) inOrder:YES];
|
||||
}
|
||||
|
||||
- (IBAction)atsuiButtonClicked:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Toggle ATSUI renderer");
|
||||
// This action is called when the user clicks the "use ATSUI renderer"
|
||||
// button in the advanced preferences pane.
|
||||
[self rebuildPreloadCache];
|
||||
@@ -1055,6 +1166,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (IBAction)loginShellButtonClicked:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Toggle login shell option");
|
||||
// This action is called when the user clicks the "use login shell" button
|
||||
// in the advanced preferences pane.
|
||||
[self rebuildPreloadCache];
|
||||
@@ -1062,6 +1174,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (IBAction)quickstartButtonClicked:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Toggle Quickstart option");
|
||||
if ([self maxPreloadCacheSize] > 0) {
|
||||
[self scheduleVimControllerPreloadAfterDelay:1.0];
|
||||
[self startWatchingVimDir];
|
||||
@@ -1072,78 +1185,6 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
}
|
||||
}
|
||||
|
||||
- (byref id <MMFrontendProtocol>)
|
||||
connectBackend:(byref in id <MMBackendProtocol>)backend
|
||||
pid:(int)pid
|
||||
{
|
||||
//NSLog(@"Connect backend (pid=%d)", pid);
|
||||
NSNumber *pidKey = [NSNumber numberWithInt:pid];
|
||||
MMVimController *vc = nil;
|
||||
|
||||
@try {
|
||||
[(NSDistantObject*)backend
|
||||
setProtocolForProxy:@protocol(MMBackendProtocol)];
|
||||
|
||||
vc = [[[MMVimController alloc] initWithBackend:backend pid:pid]
|
||||
autorelease];
|
||||
|
||||
if (preloadPid == pid) {
|
||||
// This backend was preloaded, so add it to the cache and schedule
|
||||
// another vim process to be preloaded.
|
||||
preloadPid = -1;
|
||||
[vc setIsPreloading:YES];
|
||||
[cachedVimControllers addObject:vc];
|
||||
[self scheduleVimControllerPreloadAfterDelay:1];
|
||||
|
||||
return vc;
|
||||
}
|
||||
|
||||
[vimControllers addObject:vc];
|
||||
|
||||
id args = [pidArguments objectForKey:pidKey];
|
||||
if (args && [NSNull null] != args)
|
||||
[vc passArguments:args];
|
||||
|
||||
// HACK! MacVim does not get activated if it is launched from the
|
||||
// terminal, so we forcibly activate here unless it is an untitled
|
||||
// window opening. Untitled windows are treated differently, else
|
||||
// MacVim would steal the focus if another app was activated while the
|
||||
// untitled window was loading.
|
||||
if (!args || args != [NSNull null])
|
||||
[self activateWhenNextWindowOpens];
|
||||
|
||||
if (args)
|
||||
[pidArguments removeObjectForKey:pidKey];
|
||||
|
||||
return vc;
|
||||
}
|
||||
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught in %s: \"%@\"", _cmd, e);
|
||||
|
||||
if (vc)
|
||||
[vimControllers removeObject:vc];
|
||||
|
||||
[pidArguments removeObjectForKey:pidKey];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSArray *)serverList
|
||||
{
|
||||
NSMutableArray *array = [NSMutableArray array];
|
||||
|
||||
unsigned i, count = [vimControllers count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
MMVimController *controller = [vimControllers objectAtIndex:i];
|
||||
if ([controller serverName])
|
||||
[array addObject:[controller serverName]];
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
- (MMVimController *)keyVimController
|
||||
{
|
||||
NSWindow *keyWindow = [NSApp keyWindow];
|
||||
@@ -1159,6 +1200,78 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (unsigned)connectBackend:(byref in id <MMBackendProtocol>)proxy pid:(int)pid
|
||||
{
|
||||
ASLogDebug(@"pid=%d", pid);
|
||||
|
||||
[(NSDistantObject*)proxy setProtocolForProxy:@protocol(MMBackendProtocol)];
|
||||
|
||||
// NOTE: Allocate the vim controller now but don't add it to the list of
|
||||
// controllers since this is a distributed object call and as such can
|
||||
// arrive at unpredictable times (e.g. while iterating the list of vim
|
||||
// controllers).
|
||||
// (What if input arrives before the vim controller is added to the list of
|
||||
// controllers? This should not be a problem since the input isn't
|
||||
// processed immediately (see processInput:forIdentifier:).)
|
||||
MMVimController *vc = [[MMVimController alloc] initWithBackend:proxy
|
||||
pid:pid];
|
||||
[self performSelector:@selector(addVimController:)
|
||||
withObject:vc
|
||||
afterDelay:0];
|
||||
|
||||
[vc release];
|
||||
|
||||
return [vc identifier];
|
||||
}
|
||||
|
||||
- (oneway void)processInput:(in bycopy NSArray *)queue
|
||||
forIdentifier:(unsigned)identifier
|
||||
{
|
||||
// NOTE: Input is not handled immediately since this is a distributed
|
||||
// object call and as such can arrive at unpredictable times. Instead,
|
||||
// queue the input and process it when the run loop is updated.
|
||||
|
||||
if (!(queue && identifier)) {
|
||||
ASLogWarn(@"Bad input for identifier=%d", identifier);
|
||||
return;
|
||||
}
|
||||
|
||||
ASLogDebug(@"QUEUE for identifier=%d: <<< %@>>>", identifier,
|
||||
debugStringForMessageQueue(queue));
|
||||
|
||||
NSNumber *key = [NSNumber numberWithUnsignedInt:identifier];
|
||||
NSArray *q = [inputQueues objectForKey:key];
|
||||
if (q) {
|
||||
q = [q arrayByAddingObjectsFromArray:queue];
|
||||
[inputQueues setObject:q forKey:key];
|
||||
} else {
|
||||
[inputQueues setObject:queue forKey:key];
|
||||
}
|
||||
|
||||
// NOTE: We must use "event tracking mode" as well as "default mode",
|
||||
// otherwise the input queue will not be processed e.g. during live
|
||||
// resizing.
|
||||
[self performSelector:@selector(processInputQueues:)
|
||||
withObject:nil
|
||||
afterDelay:0
|
||||
inModes:[NSArray arrayWithObjects:NSDefaultRunLoopMode,
|
||||
NSEventTrackingRunLoopMode, nil]];
|
||||
}
|
||||
|
||||
- (NSArray *)serverList
|
||||
{
|
||||
NSMutableArray *array = [NSMutableArray array];
|
||||
|
||||
unsigned i, count = [vimControllers count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
MMVimController *controller = [vimControllers objectAtIndex:i];
|
||||
if ([controller serverName])
|
||||
[array addObject:[controller serverName]];
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
@end // MMAppController
|
||||
|
||||
|
||||
@@ -1170,11 +1283,12 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
error:(NSString **)error
|
||||
{
|
||||
if (![[pboard types] containsObject:NSStringPboardType]) {
|
||||
NSLog(@"WARNING: Pasteboard contains no object of type "
|
||||
"NSStringPboardType");
|
||||
ASLogNotice(@"Pasteboard contains no NSStringPboardType");
|
||||
return;
|
||||
}
|
||||
|
||||
ASLogInfo(@"Open new window containing current selection");
|
||||
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
BOOL openInCurrentWindow = [ud boolForKey:MMOpenInCurrentWindowKey];
|
||||
MMVimController *vc;
|
||||
@@ -1197,8 +1311,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
error:(NSString **)error
|
||||
{
|
||||
if (![[pboard types] containsObject:NSStringPboardType]) {
|
||||
NSLog(@"WARNING: Pasteboard contains no object of type "
|
||||
"NSStringPboardType");
|
||||
ASLogNotice(@"Pasteboard contains no NSStringPboardType");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1208,6 +1321,8 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
string = [string stringByStandardizingPath];
|
||||
|
||||
ASLogInfo(@"Open new window with selected file: %@", string);
|
||||
|
||||
NSArray *filenames = [self filterFilesAndNotify:
|
||||
[NSArray arrayWithObject:string]];
|
||||
if ([filenames count] == 0)
|
||||
@@ -1228,8 +1343,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
error:(NSString **)error
|
||||
{
|
||||
if (![[pboard types] containsObject:NSStringPboardType]) {
|
||||
NSLog(@"WARNING: Pasteboard contains no object of type "
|
||||
"NSStringPboardType");
|
||||
ASLogNotice(@"Pasteboard contains no NSStringPboardType");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1238,10 +1352,12 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
BOOL dirIndicator;
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:path
|
||||
isDirectory:&dirIndicator]) {
|
||||
NSLog(@"Invalid path. Cannot open new document at: %@", path);
|
||||
ASLogNotice(@"Invalid path. Cannot open new document at: %@", path);
|
||||
return;
|
||||
}
|
||||
|
||||
ASLogInfo(@"Open new file at path=%@", path);
|
||||
|
||||
if (!dirIndicator)
|
||||
path = [path stringByDeletingLastPathComponent];
|
||||
|
||||
@@ -1292,7 +1408,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
NSString *path = [[NSBundle mainBundle] pathForAuxiliaryExecutable:@"Vim"];
|
||||
|
||||
if (!path) {
|
||||
NSLog(@"ERROR: Vim executable could not be found inside app bundle!");
|
||||
ASLogCrit(@"Vim executable could not be found inside app bundle!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1315,13 +1431,24 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
}
|
||||
|
||||
if (-1 != pid) {
|
||||
// Add a null argument to the pidArguments dictionary. This is later
|
||||
// used to detect that a process without arguments is being launched.
|
||||
[pidArguments setObject:[NSNull null]
|
||||
forKey:[NSNumber numberWithInt:pid]];
|
||||
// The 'pidArguments' dictionary keeps arguments to be passed to the
|
||||
// process when it connects (this is in contrast to arguments which are
|
||||
// passed on the command line, like '-f' and '-g').
|
||||
// If this method is called with nil arguments we take this as a hint
|
||||
// that this is an "untitled window" being launched and add a null
|
||||
// object to the 'pidArguments' dictionary. This way we can detect if
|
||||
// an untitled window is being launched by looking for null objects in
|
||||
// this dictionary.
|
||||
// If this method is called with non-nil arguments then it is assumed
|
||||
// that the caller takes care of adding items to 'pidArguments' as
|
||||
// necessary (only some arguments are passed on connect, e.g. files to
|
||||
// open).
|
||||
if (!args)
|
||||
[pidArguments setObject:[NSNull null]
|
||||
forKey:[NSNumber numberWithInt:pid]];
|
||||
} else {
|
||||
NSLog(@"WARNING: %s%@ failed (useLoginShell=%d)", _cmd, args,
|
||||
useLoginShell);
|
||||
ASLogWarn(@"Failed to launch Vim process: args=%@, useLoginShell=%d",
|
||||
args, useLoginShell);
|
||||
}
|
||||
|
||||
return pid;
|
||||
@@ -1429,8 +1556,8 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
#if 0
|
||||
// Xcode sends this event to query MacVim which open files have been
|
||||
// modified.
|
||||
NSLog(@"reply:%@", reply);
|
||||
NSLog(@"event:%@", event);
|
||||
ASLogDebug(@"reply:%@", reply);
|
||||
ASLogDebug(@"event:%@", event);
|
||||
|
||||
NSEnumerator *e = [vimControllers objectEnumerator];
|
||||
id vc;
|
||||
@@ -1541,10 +1668,8 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
- (int)findLaunchingProcessWithoutArguments
|
||||
{
|
||||
NSArray *keys = [pidArguments allKeysForObject:[NSNull null]];
|
||||
if ([keys count] > 0) {
|
||||
//NSLog(@"found launching process without arguments");
|
||||
if ([keys count] > 0)
|
||||
return [[keys objectAtIndex:0] intValue];
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -1859,12 +1984,12 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (void)activateWhenNextWindowOpens
|
||||
{
|
||||
ASLogDebug(@"Activate MacVim when next window opens");
|
||||
shouldActivateWhenNextWindowOpens = YES;
|
||||
}
|
||||
|
||||
- (void)startWatchingVimDir
|
||||
{
|
||||
//NSLog(@"%s", _cmd);
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
if (fsEventStream)
|
||||
return;
|
||||
@@ -1883,13 +2008,12 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
kCFRunLoopDefaultMode);
|
||||
|
||||
FSEventStreamStart(fsEventStream);
|
||||
//NSLog(@"Started FS event stream");
|
||||
ASLogDebug(@"Started FS event stream");
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)stopWatchingVimDir
|
||||
{
|
||||
//NSLog(@"%s", _cmd);
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
if (NULL == FSEventStreamStop)
|
||||
return; // FSEvent functions are weakly linked
|
||||
@@ -1899,7 +2023,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
FSEventStreamInvalidate(fsEventStream);
|
||||
FSEventStreamRelease(fsEventStream);
|
||||
fsEventStream = NULL;
|
||||
//NSLog(@"Stopped FS event stream");
|
||||
ASLogDebug(@"Stopped FS event stream");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1907,7 +2031,6 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (void)handleFSEvent
|
||||
{
|
||||
//NSLog(@"%s", _cmd);
|
||||
[self clearPreloadCacheWithCount:-1];
|
||||
|
||||
// Several FS events may arrive in quick succession so make sure to cancel
|
||||
@@ -1921,8 +2044,12 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
// It is possible to set a user default to avoid loading the default font
|
||||
// (this cuts down on startup time).
|
||||
if (![[NSUserDefaults standardUserDefaults] boolForKey:MMLoadDefaultFontKey]
|
||||
|| fontContainerRef)
|
||||
|| fontContainerRef) {
|
||||
ASLogInfo(@"Skip loading of the default font...");
|
||||
return;
|
||||
}
|
||||
|
||||
ASLogInfo(@"Loading the default font...");
|
||||
|
||||
// Load all fonts in the Resouces folder of the app bundle.
|
||||
NSString *fontsFolder = [[NSBundle mainBundle] resourcePath];
|
||||
@@ -1957,9 +2084,10 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
}
|
||||
}
|
||||
|
||||
if (!fontContainerRef)
|
||||
NSLog(@"WARNING: Failed to activate the default font (the app bundle "
|
||||
"may be incomplete)");
|
||||
if (!fontContainerRef) {
|
||||
ASLogNotice(@"Failed to activate the default font (the app bundle "
|
||||
"may be incomplete)");
|
||||
}
|
||||
}
|
||||
|
||||
- (int)executeInLoginShell:(NSString *)path arguments:(NSArray *)args
|
||||
@@ -1981,8 +2109,6 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
if (!shell)
|
||||
shell = @"/bin/bash";
|
||||
|
||||
//NSLog(@"shell = %@", shell);
|
||||
|
||||
// Bash needs the '-l' flag to launch a login shell. The user may add
|
||||
// flags by setting a user default.
|
||||
NSString *shellArgument = [ud stringForKey:MMLoginShellArgumentKey];
|
||||
@@ -1993,8 +2119,6 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
shellArgument = nil;
|
||||
}
|
||||
|
||||
//NSLog(@"shellArgument = %@", shellArgument);
|
||||
|
||||
// Build input string to pipe to the login shell.
|
||||
NSMutableString *input = [NSMutableString stringWithFormat:
|
||||
@"exec \"%@\"", path];
|
||||
@@ -2059,7 +2183,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
if (close(ds[1]) == -1) return -1;
|
||||
|
||||
++numChildProcesses;
|
||||
//NSLog(@"new process pid=%d (count=%d)", pid, numChildProcesses);
|
||||
ASLogDebug(@"new process pid=%d (count=%d)", pid, numChildProcesses);
|
||||
}
|
||||
|
||||
return pid;
|
||||
@@ -2078,9 +2202,115 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
if (pid <= 0)
|
||||
break;
|
||||
|
||||
//NSLog(@"WAIT for pid=%d complete", pid);
|
||||
ASLogDebug(@"Wait for pid=%d complete", pid);
|
||||
--numChildProcesses;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)processInputQueues:(id)sender
|
||||
{
|
||||
// NOTE: Because we use distributed objects it is quite possible for this
|
||||
// function to be re-entered. This can cause all sorts of unexpected
|
||||
// problems so we guard against it here so that the rest of the code does
|
||||
// not need to worry about it.
|
||||
|
||||
// The processing flag is > 0 if this function is already on the call
|
||||
// stack; < 0 if this function was also re-entered.
|
||||
if (processingFlag != 0) {
|
||||
ASLogDebug(@"BUSY!");
|
||||
processingFlag = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: Be _very_ careful that no exceptions can be raised between here
|
||||
// and the point at which 'processingFlag' is reset. Otherwise the above
|
||||
// test could end up always failing and no input queues would ever be
|
||||
// processed!
|
||||
processingFlag = 1;
|
||||
|
||||
// NOTE: New input may arrive while we're busy processing; we deal with
|
||||
// this by putting the current queue aside and creating a new input queue
|
||||
// for future input.
|
||||
NSDictionary *queues = inputQueues;
|
||||
inputQueues = [NSMutableDictionary new];
|
||||
|
||||
// Pass each input queue on to the vim controller with matching
|
||||
// identifier (and note that it could be cached).
|
||||
NSEnumerator *e = [queues keyEnumerator];
|
||||
NSNumber *key;
|
||||
while ((key = [e nextObject])) {
|
||||
unsigned ukey = [key unsignedIntValue];
|
||||
int i = 0, count = [vimControllers count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
MMVimController *vc = [vimControllers objectAtIndex:i];
|
||||
if (ukey == [vc identifier]) {
|
||||
[vc processInputQueue:[queues objectForKey:key]]; // !exceptions
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < count) continue;
|
||||
|
||||
count = [cachedVimControllers count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
MMVimController *vc = [cachedVimControllers objectAtIndex:i];
|
||||
if (ukey == [vc identifier]) {
|
||||
[vc processInputQueue:[queues objectForKey:key]]; // !exceptions
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == count) {
|
||||
ASLogWarn(@"No Vim controller for identifier=%d", ukey);
|
||||
}
|
||||
}
|
||||
|
||||
[queues release];
|
||||
|
||||
// If new input arrived while we were processing it would have been
|
||||
// blocked so we have to schedule it to be processed again.
|
||||
if (processingFlag < 0)
|
||||
[self performSelector:@selector(processInputQueues:)
|
||||
withObject:nil
|
||||
afterDelay:0
|
||||
inModes:[NSArray arrayWithObjects:NSDefaultRunLoopMode,
|
||||
NSEventTrackingRunLoopMode, nil]];
|
||||
|
||||
processingFlag = 0;
|
||||
}
|
||||
|
||||
- (void)addVimController:(MMVimController *)vc
|
||||
{
|
||||
ASLogDebug(@"Add Vim controller pid=%d id=%d", [vc pid], [vc identifier]);
|
||||
|
||||
int pid = [vc pid];
|
||||
NSNumber *pidKey = [NSNumber numberWithInt:pid];
|
||||
|
||||
if (preloadPid == pid) {
|
||||
// This controller was preloaded, so add it to the cache and
|
||||
// schedule another vim process to be preloaded.
|
||||
preloadPid = -1;
|
||||
[vc setIsPreloading:YES];
|
||||
[cachedVimControllers addObject:vc];
|
||||
[self scheduleVimControllerPreloadAfterDelay:1];
|
||||
} else {
|
||||
[vimControllers addObject:vc];
|
||||
|
||||
id args = [pidArguments objectForKey:pidKey];
|
||||
if (args && [NSNull null] != args)
|
||||
[vc passArguments:args];
|
||||
|
||||
// HACK! MacVim does not get activated if it is launched from the
|
||||
// terminal, so we forcibly activate here unless it is an untitled
|
||||
// window opening. Untitled windows are treated differently, else
|
||||
// MacVim would steal the focus if another app was activated while the
|
||||
// untitled window was loading.
|
||||
if (!args || args != [NSNull null])
|
||||
[self activateWhenNextWindowOpens];
|
||||
|
||||
if (args)
|
||||
[pidArguments removeObjectForKey:pidKey];
|
||||
}
|
||||
}
|
||||
|
||||
@end // MMAppController (Private)
|
||||
|
||||
@@ -68,6 +68,8 @@ enum { MMMaxCellsPerChar = 2 };
|
||||
- (void)setPreEditRow:(int)row column:(int)col;
|
||||
- (void)setMouseShape:(int)shape;
|
||||
- (void)setAntialias:(BOOL)state;
|
||||
- (void)setImControl:(BOOL)enable;
|
||||
- (void)activateIm:(BOOL)enable;
|
||||
- (BOOL)convertPoint:(NSPoint)point toRow:(int *)row column:(int *)column;
|
||||
- (NSPoint)pointForRow:(int)row column:(int)col;
|
||||
- (NSRect)rectForRow:(int)row column:(int)col numRows:(int)nr
|
||||
|
||||
@@ -139,7 +139,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
LOG_DEALLOC
|
||||
ASLogDebug(@"");
|
||||
|
||||
[self disposeAtsuStyles];
|
||||
[font release]; font = nil;
|
||||
@@ -324,6 +324,16 @@ defaultLineHeightForFont(NSFont *font)
|
||||
antialias = state;
|
||||
}
|
||||
|
||||
- (void)setImControl:(BOOL)enable
|
||||
{
|
||||
[helper setImControl:enable];
|
||||
}
|
||||
|
||||
- (void)activateIm:(BOOL)enable
|
||||
{
|
||||
[helper activateIm:enable];
|
||||
}
|
||||
|
||||
- (void)keyDown:(NSEvent *)event
|
||||
{
|
||||
[helper keyDown:event];
|
||||
@@ -508,7 +518,8 @@ defaultLineHeightForFont(NSFont *font)
|
||||
NSPoint pt = { insetSize.width, insetSize.height };
|
||||
[contentImage compositeToPoint:pt operation:NSCompositeCopy];
|
||||
|
||||
if ([self hasMarkedText]) {
|
||||
#ifdef INCLUDE_OLD_IM_CODE
|
||||
if ([self hasMarkedText] && ![helper useInlineIm]) {
|
||||
int len = [[helper markedText] length];
|
||||
int rows = 0;
|
||||
int cols = maxColumns - [helper preEditColumn];
|
||||
@@ -564,6 +575,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
shape:MMInsertionPointVertical
|
||||
fraction:25];
|
||||
}
|
||||
#endif // INCLUDE_OLD_IM_CODE
|
||||
}
|
||||
|
||||
- (BOOL) wantsDefaultClipping
|
||||
@@ -583,7 +595,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
[self resizeContentImage];
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@"====> BEGIN %s", _cmd);
|
||||
ASLogDebug(@"====> BEGIN %s", _cmd);
|
||||
#endif
|
||||
[self beginDrawing];
|
||||
|
||||
@@ -594,7 +606,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
|
||||
if (ClearAllDrawType == type) {
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Clear all");
|
||||
ASLogDebug(@" Clear all");
|
||||
#endif
|
||||
[self clearAll];
|
||||
} else if (ClearBlockDrawType == type) {
|
||||
@@ -605,8 +617,8 @@ defaultLineHeightForFont(NSFont *font)
|
||||
int col2 = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Clear block (%d,%d) -> (%d,%d)", row1, col1,
|
||||
row2,col2);
|
||||
ASLogDebug(@" Clear block (%d,%d) -> (%d,%d)", row1, col1,
|
||||
row2,col2);
|
||||
#endif
|
||||
[self clearBlockFromRow:row1 column:col1
|
||||
toRow:row2 column:col2
|
||||
@@ -620,7 +632,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
int right = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Delete %d line(s) from %d", count, row);
|
||||
ASLogDebug(@" Delete %d line(s) from %d", count, row);
|
||||
#endif
|
||||
[self deleteLinesFromRow:row lineCount:count
|
||||
scrollBottom:bot left:left right:right
|
||||
@@ -642,8 +654,8 @@ defaultLineHeightForFont(NSFont *font)
|
||||
freeWhenDone:NO];
|
||||
bytes += len;
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Draw string at (%d,%d) length=%d flags=%d fg=0x%x "
|
||||
"bg=0x%x sp=0x%x", row, col, len, flags, fg, bg, sp);
|
||||
ASLogDebug(@" Draw string at (%d,%d) length=%d flags=%d fg=0x%x "
|
||||
"bg=0x%x sp=0x%x", row, col, len, flags, fg, bg, sp);
|
||||
#endif
|
||||
unichar *characters = malloc(sizeof(unichar) * [string length]);
|
||||
[string getCharacters:characters];
|
||||
@@ -667,7 +679,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
int right = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Insert %d line(s) at row %d", count, row);
|
||||
ASLogDebug(@" Insert %d line(s) at row %d", count, row);
|
||||
#endif
|
||||
[self insertLinesAtRow:row lineCount:count
|
||||
scrollBottom:bot left:left right:right
|
||||
@@ -680,7 +692,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
int percent = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Draw cursor at (%d,%d)", row, col);
|
||||
ASLogDebug(@" Draw cursor at (%d,%d)", row, col);
|
||||
#endif
|
||||
[helper setInsertionPointColor:[NSColor colorWithRgbInt:color]];
|
||||
[self drawInsertionPointAtRow:row column:col shape:shape
|
||||
@@ -693,8 +705,8 @@ defaultLineHeightForFont(NSFont *font)
|
||||
/*int invert = *((int*)bytes);*/ bytes += sizeof(int);
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Draw inverted rect: row=%d col=%d nrows=%d ncols=%d",
|
||||
row, col, nr, nc);
|
||||
ASLogDebug(@" Draw inverted rect: row=%d col=%d nrows=%d "
|
||||
"ncols=%d", row, col, nr, nc);
|
||||
#endif
|
||||
[self drawInvertedRectAtRow:row column:col numRows:nr
|
||||
numColumns:nc];
|
||||
@@ -704,7 +716,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
/*cursorRow = *((int*)bytes);*/ bytes += sizeof(int);
|
||||
/*cursorCol = *((int*)bytes);*/ bytes += sizeof(int);
|
||||
} else {
|
||||
NSLog(@"WARNING: Unknown draw type (type=%d)", type);
|
||||
ASLogWarn(@"Unknown draw type (type=%d)", type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -718,7 +730,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
[self display];
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@"<==== END %s", _cmd);
|
||||
ASLogDebug(@"<==== END %s", _cmd);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -775,24 +787,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
|
||||
- (void)changeFont:(id)sender
|
||||
{
|
||||
NSFont *newFont = [sender convertFont:font];
|
||||
|
||||
if (newFont) {
|
||||
NSString *name = [newFont displayName];
|
||||
unsigned len = [name lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
if (len > 0) {
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
float pointSize = [newFont pointSize];
|
||||
|
||||
[data appendBytes:&pointSize length:sizeof(float)];
|
||||
|
||||
++len; // include NUL byte
|
||||
[data appendBytes:&len length:sizeof(unsigned)];
|
||||
[data appendBytes:[name UTF8String] length:len];
|
||||
|
||||
[[self vimController] sendMessage:SetFontMsgID data:data];
|
||||
}
|
||||
}
|
||||
[helper changeFont:sender];
|
||||
}
|
||||
|
||||
|
||||
@@ -1044,7 +1039,6 @@ defaultLineHeightForFont(NSFont *font)
|
||||
|
||||
- (void)resizeContentImage
|
||||
{
|
||||
//NSLog(@"resizeContentImage");
|
||||
[contentImage release];
|
||||
contentImage = [[NSImage alloc] initWithSize:[self textAreaSize]];
|
||||
[contentImage setFlipped:YES];
|
||||
@@ -1102,8 +1096,6 @@ defaultLineHeightForFont(NSFont *font)
|
||||
ATSUSetAttributes(style, sizeof(attribValues) / sizeof(attribValues[0]),
|
||||
attribTags, attribSizes, attribValues);
|
||||
|
||||
// NSLog(@"drawString: %d", length);
|
||||
|
||||
ATSUCreateTextLayout(&layout);
|
||||
ATSUSetTextPointerLocation(layout, string,
|
||||
kATSUFromTextBeginning, kATSUToTextEnd,
|
||||
@@ -1116,6 +1108,11 @@ defaultLineHeightForFont(NSFont *font)
|
||||
rect.size.width = rect.size.width * 2;
|
||||
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
|
||||
|
||||
// Clip drawing to avoid text bleeding into adjacent display cells when
|
||||
// antialiasing is enabled.
|
||||
CGContextSaveGState(context);
|
||||
CGContextClipToRect(context, *(CGRect*)&rect);
|
||||
|
||||
ATSUAttributeTag tags[] = { kATSUCGContextTag };
|
||||
ByteCount sizes[] = { sizeof(CGContextRef) };
|
||||
ATSUAttributeValuePtr values[] = { &context };
|
||||
@@ -1139,7 +1136,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
|
||||
if (flags & DRAW_UNDERL)
|
||||
{
|
||||
[fg set];
|
||||
[sp set];
|
||||
NSRectFill(NSMakeRect(rect.origin.x,
|
||||
(row + 1) * cellSize.height + kUnderlineOffset,
|
||||
rect.size.width, kUnderlineHeight));
|
||||
@@ -1165,6 +1162,8 @@ defaultLineHeightForFont(NSFont *font)
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
|
||||
- (void)scrollRect:(NSRect)rect lineCount:(int)count
|
||||
@@ -1231,8 +1230,6 @@ defaultLineHeightForFont(NSFont *font)
|
||||
NSRect rect = NSMakeRect(origin.x, origin.y,
|
||||
cellSize.width, cellSize.height);
|
||||
|
||||
// NSLog(@"shape = %d, fraction: %d", shape, percent);
|
||||
|
||||
if (MMInsertionPointHorizontal == shape) {
|
||||
int frac = (cellSize.height * percent + 99)/100;
|
||||
rect.origin.y += rect.size.height - frac;
|
||||
|
||||
+12
-2
@@ -21,7 +21,8 @@
|
||||
NSMutableArray *inputQueue;
|
||||
NSMutableData *drawData;
|
||||
NSConnection *connection;
|
||||
id frontendProxy;
|
||||
id appProxy;
|
||||
unsigned identifier;
|
||||
NSDictionary *colorDict;
|
||||
NSDictionary *sysColorDict;
|
||||
NSDictionary *actionDict;
|
||||
@@ -48,6 +49,9 @@
|
||||
BOOL flushDisabled;
|
||||
unsigned numWholeLineChanges;
|
||||
unsigned offsetForDrawDataPrune;
|
||||
BOOL imState;
|
||||
CFSocketRef netbeansSocket;
|
||||
CFRunLoopSourceRef netbeansRunLoopSource;
|
||||
}
|
||||
|
||||
+ (MMBackend *)sharedInstance;
|
||||
@@ -107,7 +111,7 @@
|
||||
- (void)setPreEditRow:(int)row column:(int)col;
|
||||
|
||||
- (int)lookupColorWithKey:(NSString *)key;
|
||||
- (BOOL)hasSpecialKeyWithValue:(NSString *)value;
|
||||
- (BOOL)hasSpecialKeyWithValue:(char_u *)value;
|
||||
|
||||
- (void)enterFullscreen:(int)fuoptions background:(int)bg;
|
||||
- (void)leaveFullscreen;
|
||||
@@ -130,6 +134,12 @@
|
||||
- (void)setWaitForAck:(BOOL)yn;
|
||||
- (void)waitForConnectionAcknowledgement;
|
||||
|
||||
- (BOOL)imState;
|
||||
- (void)setImState:(BOOL)activated;
|
||||
|
||||
- (void)messageFromNetbeans;
|
||||
- (void)setNetbeansSocket:(int)socket;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
+452
-295
File diff suppressed because it is too large
Load Diff
@@ -94,7 +94,7 @@
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
LOG_DEALLOC
|
||||
ASLogDebug(@"");
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
@@ -149,8 +149,10 @@
|
||||
|
||||
int fuRows = currRows, fuColumns = currColumns;
|
||||
|
||||
// NOTE: Do not use [NSScreen visibleFrame] when determining the screen
|
||||
// size since it compensates for menu and dock.
|
||||
int maxRows, maxColumns;
|
||||
NSSize size = [[self screen] visibleFrame].size;
|
||||
NSSize size = [[self screen] frame].size;
|
||||
[view constrainRows:&maxRows columns:&maxColumns toSize:size];
|
||||
|
||||
// Store current pre-fu vim size
|
||||
@@ -306,7 +308,6 @@
|
||||
- (void)centerView
|
||||
{
|
||||
NSRect outer = [self frame], inner = [view frame];
|
||||
//NSLog(@"%s %@%@", _cmd, NSStringFromRect(outer), NSStringFromRect(inner));
|
||||
|
||||
NSPoint origin = NSMakePoint((outer.size.width - inner.size.width)/2,
|
||||
(outer.size.height - inner.size.height)/2);
|
||||
|
||||
@@ -50,6 +50,8 @@ static MMPlugInManager *plugInManager = nil;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
ASLogDebug(@"");
|
||||
|
||||
[plugInClasses release]; plugInClasses = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
@@ -123,13 +125,13 @@ static MMPlugInManager *plugInManager = nil;
|
||||
if(currPrincipalClass && [self plugInClassIsValid:currPrincipalClass]) {
|
||||
if ([currPrincipalClass initializePlugIn:
|
||||
[MMPlugInAppMediator sharedAppMediator]]) {
|
||||
//NSLog(@"Plug-in initialized: %@", currPath);
|
||||
ASLogInfo(@"Plug-in initialized: %@", currPath);
|
||||
[plugInClasses addObject:currPrincipalClass];
|
||||
} else {
|
||||
NSLog(@"Plug-in failed to initialize: %@", currPath);
|
||||
ASLogErr(@"Plug-in failed to initialize: %@", currPath);
|
||||
}
|
||||
} else {
|
||||
NSLog(@"Plug-in did not conform to protocol: %@", currPath);
|
||||
ASLogErr(@"Plug-in did not conform to protocol: %@", currPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,8 @@ NSString *kOdbEditorIdentifierWriteRoom = @"com.hogbaysoftware.WriteRoom";
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
ASLogDebug(@"");
|
||||
|
||||
[supportedOdbEditors release]; supportedOdbEditors = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
@@ -383,7 +385,7 @@ NSString *kOdbEditorIdentifierWriteRoom = @"com.hogbaysoftware.WriteRoom";
|
||||
[self setOdbEditorByName:kOdbEditorNameMacVim];
|
||||
}
|
||||
} else {
|
||||
NSLog(@"Failed to install input manager, error is %d", err);
|
||||
ASLogErr(@"Failed to install input manager, error is %d", err);
|
||||
}
|
||||
[au release];
|
||||
|
||||
@@ -402,7 +404,7 @@ NSString *kOdbEditorIdentifierWriteRoom = @"com.hogbaysoftware.WriteRoom";
|
||||
initWithCommands:cmd];
|
||||
OSStatus err = [au run];
|
||||
if (err != errAuthorizationSuccess)
|
||||
NSLog(@"Failed to uninstall input manager, error is %d", err);
|
||||
ASLogErr(@"Failed to uninstall input manager, error is %d", err);
|
||||
[au release];
|
||||
|
||||
[self updateIntegrationPane];
|
||||
|
||||
+42
-44
@@ -84,7 +84,7 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
LOG_DEALLOC
|
||||
ASLogDebug(@"");
|
||||
|
||||
#if MM_USE_ROW_CACHE
|
||||
if (rowCache) {
|
||||
@@ -135,15 +135,13 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
withString:(NSString *)string
|
||||
{
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
NSLog(@"WARNING: calling %s on MMTextStorage is unsupported", _cmd);
|
||||
ASLogWarn(@"Calling %s on MMTextStorage is unsupported", _cmd);
|
||||
#endif
|
||||
//[attribString replaceCharactersInRange:range withString:string];
|
||||
}
|
||||
|
||||
- (void)setAttributes:(NSDictionary *)attributes range:(NSRange)range
|
||||
{
|
||||
//NSLog(@"%s%@", _cmd, NSStringFromRange(range));
|
||||
|
||||
// NOTE! This method must be implemented since the text system calls it
|
||||
// constantly to 'fix attributes', apply font substitution, etc.
|
||||
#if 0
|
||||
@@ -185,7 +183,6 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
|
||||
[attribString setAttributes:newAttr range:range];
|
||||
} else {
|
||||
//NSLog(@"NOT fixing font attribute!");
|
||||
[attribString setAttributes:attributes range:range];
|
||||
}
|
||||
#endif
|
||||
@@ -220,7 +217,7 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
{
|
||||
NSLayoutManager *lm = [[self layoutManagers] objectAtIndex:0];
|
||||
if (!lm) {
|
||||
NSLog(@"WARNING: No layout manager available in call to %s", _cmd);
|
||||
ASLogWarn(@"No layout manager available");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -253,9 +250,6 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
foregroundColor:(NSColor *)fg backgroundColor:(NSColor *)bg
|
||||
specialColor:(NSColor *)sp
|
||||
{
|
||||
//NSLog(@"replaceString:atRow:%d column:%d withFlags:%d "
|
||||
// "foreground:%@ background:%@ special:%@",
|
||||
// row, col, flags, fg, bg, sp);
|
||||
[self lazyResize:NO];
|
||||
|
||||
if (row < 0 || row >= maxRows || col < 0 || col >= maxColumns
|
||||
@@ -278,7 +272,7 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
NSRange range = [self charRangeForRow:row column:&acol cells:&acells];
|
||||
if (NSNotFound == range.location) {
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
NSLog(@"INTERNAL ERROR [%s] Out of bounds", _cmd);
|
||||
ASLogErr(@"INTERNAL ERROR: Out of bounds");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -344,13 +338,11 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
++changeInLength;
|
||||
#if 0
|
||||
} else if (acol == col - 1) {
|
||||
NSLog(@"acol == col - 1");
|
||||
[attribString replaceCharactersInRange:NSMakeRange(r.location,0)
|
||||
withAttributedString:[emptyRowString
|
||||
attributedSubstringFromRange:NSMakeRange(0,1)]];
|
||||
++changeInLength;
|
||||
} else if (acol == col + 1) {
|
||||
NSLog(@"acol == col + 1");
|
||||
[attribString replaceCharactersInRange:NSMakeRange(r.location-1,1)
|
||||
withAttributedString:[emptyRowString
|
||||
attributedSubstringFromRange:NSMakeRange(0,2)]];
|
||||
@@ -360,8 +352,8 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
// NOTE: It seems that this never gets called. If it ever does,
|
||||
// then there is another case to treat.
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
NSLog(@"row=%d col=%d acol=%d cells=%d acells=%d", row, col, acol,
|
||||
cells, acells);
|
||||
ASLogWarn(@"row=%d col=%d acol=%d cells=%d acells=%d", row, col,
|
||||
acol, cells, acells);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -387,7 +379,6 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
scrollBottom:(int)bottom left:(int)left right:(int)right
|
||||
color:(NSColor *)color
|
||||
{
|
||||
//NSLog(@"deleteLinesFromRow:%d lineCount:%d color:%@", row, count, color);
|
||||
[self lazyResize:NO];
|
||||
|
||||
if (row < 0 || row+count > maxRows || bottom > maxRows || left < 0
|
||||
@@ -407,7 +398,7 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
destRange = [self charRangeForRow:destRow column:&acol cells:&acells];
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
if (acells != width || acol != left)
|
||||
NSLog(@"INTERNAL ERROR [%s]", _cmd);
|
||||
ASLogErr(@"INTERNAL ERROR");
|
||||
#endif
|
||||
|
||||
acol = left; acells = width;
|
||||
@@ -415,13 +406,13 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
cells:&acells];
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
if (acells != width || acol != left)
|
||||
NSLog(@"INTERNAL ERROR [%s]", _cmd);
|
||||
ASLogErr(@"INTERNAL ERROR");
|
||||
#endif
|
||||
|
||||
if (NSNotFound == destRange.location || NSNotFound == srcRange.location)
|
||||
{
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
NSLog(@"INTERNAL ERROR [%s] Out of bounds", _cmd);
|
||||
ASLogErr(@"INTERNAL ERROR: Out of bounds");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -453,11 +444,11 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
destRange = [self charRangeForRow:destRow column:&acol cells:&acells];
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
if (acells != width || acol != left)
|
||||
NSLog(@"INTERNAL ERROR [%s]", _cmd);
|
||||
ASLogErr(@"INTERNAL ERROR");
|
||||
#endif
|
||||
if (NSNotFound == destRange.location) {
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
NSLog(@"INTERNAL ERROR [%s] Out of bounds", _cmd);
|
||||
ASLogErr(@"INTERNAL ERROR: Out of bounds");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -485,7 +476,6 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
scrollBottom:(int)bottom left:(int)left right:(int)right
|
||||
color:(NSColor *)color
|
||||
{
|
||||
//NSLog(@"insertLinesAtRow:%d lineCount:%d color:%@", row, count, color);
|
||||
[self lazyResize:NO];
|
||||
|
||||
if (row < 0 || row+count > maxRows || bottom > maxRows || left < 0
|
||||
@@ -506,19 +496,19 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
destRange = [self charRangeForRow:destRow column:&acol cells:&acells];
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
if (acells != width || acol != left)
|
||||
NSLog(@"INTERNAL ERROR [%s]", _cmd);
|
||||
ASLogErr(@"INTERNAL ERROR");
|
||||
#endif
|
||||
|
||||
acol = left; acells = width;
|
||||
srcRange = [self charRangeForRow:srcRow column:&acol cells:&acells];
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
if (acells != width || acol != left)
|
||||
NSLog(@"INTERNAL ERROR [%s]", _cmd);
|
||||
ASLogErr(@"INTERNAL ERROR");
|
||||
#endif
|
||||
if (NSNotFound == destRange.location || NSNotFound == srcRange.location)
|
||||
{
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
NSLog(@"INTERNAL ERROR [%s] Out of bounds", _cmd);
|
||||
ASLogErr(@"INTERNAL ERROR: Out of bounds");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -549,11 +539,11 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
destRange = [self charRangeForRow:destRow column:&acol cells:&acells];
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
if (acells != width || acol != left)
|
||||
NSLog(@"INTERNAL ERROR [%s]", _cmd);
|
||||
ASLogErr(@"INTERNAL ERROR");
|
||||
#endif
|
||||
if (NSNotFound == destRange.location) {
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
NSLog(@"INTERNAL ERROR [%s] Out of bounds", _cmd);
|
||||
ASLogErr(@"INTERNAL ERROR: Out of bounds");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -576,8 +566,6 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
- (void)clearBlockFromRow:(int)row1 column:(int)col1 toRow:(int)row2
|
||||
column:(int)col2 color:(NSColor *)color
|
||||
{
|
||||
//NSLog(@"clearBlockFromRow:%d column:%d toRow:%d column:%d color:%@",
|
||||
// row1, col1, row2, col2, color);
|
||||
[self lazyResize:NO];
|
||||
|
||||
if (row1 < 0 || row2 >= maxRows || col1 < 0 || col2 > maxColumns)
|
||||
@@ -598,11 +586,11 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
range = [self charRangeForRow:r column:&acol cells:&acells];
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
if (acells != cells || acol != col1)
|
||||
NSLog(@"INTERNAL ERROR [%s]", _cmd);
|
||||
ASLogErr(@"INTERNAL ERROR");
|
||||
#endif
|
||||
if (NSNotFound == range.location) {
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
NSLog(@"INTERNAL ERROR [%s] Out of bounds", _cmd);
|
||||
ASLogErr(@"INTERNAL ERROR: Out of bounds");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -624,7 +612,6 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
|
||||
- (void)clearAll
|
||||
{
|
||||
//NSLog(@"%s", _cmd);
|
||||
[self lazyResize:YES];
|
||||
}
|
||||
|
||||
@@ -683,7 +670,7 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
cellSize.height = linespace + [lm defaultLineHeightForFont:font];
|
||||
} else {
|
||||
// Should never happen, set some bogus value for cell height.
|
||||
NSLog(@"WARNING: No layout manager available in call to %s", _cmd);
|
||||
ASLogWarn(@"No layout manager available");
|
||||
cellSize.height = linespace + 16.0;
|
||||
}
|
||||
|
||||
@@ -1009,15 +996,16 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
return NSMakeRange(row*(actualColumns+1) + col, cells);
|
||||
|
||||
NSString *string = [attribString string];
|
||||
unsigned stringLen = [string length];
|
||||
NSRange r, range = { NSNotFound, 0 };
|
||||
unsigned idx, rowEnd;
|
||||
unsigned idx;
|
||||
int i;
|
||||
|
||||
if (row < 0 || row >= actualRows || col < 0 || col >= actualColumns
|
||||
|| col+cells > actualColumns) {
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
NSLog(@"%s row=%d col=%d cells=%d is out of range (length=%d)",
|
||||
_cmd, row, col, cells, [string length]);
|
||||
ASLogErr(@"row=%d col=%d cells=%d is out of range (length=%d)",
|
||||
row, col, cells, stringLen);
|
||||
#endif
|
||||
return range;
|
||||
}
|
||||
@@ -1029,12 +1017,12 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
for (i = 0; i < row; ++i, ++cache)
|
||||
idx += cache->length;
|
||||
|
||||
rowEnd = idx + cache->length;
|
||||
int rowEnd = idx + cache->length;
|
||||
#else
|
||||
// Locate the beginning of the row by scanning for EOL characters.
|
||||
r.location = 0;
|
||||
for (i = 0; i < row; ++i) {
|
||||
r.length = [string length] - r.location;
|
||||
r.length = stringLen - r.location;
|
||||
r = [string rangeOfString:@"\n" options:NSLiteralSearch range:r];
|
||||
if (NSNotFound == r.location)
|
||||
return range;
|
||||
@@ -1070,6 +1058,8 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
if (col > i) {
|
||||
// Forward search
|
||||
while (col > i) {
|
||||
if (idx >= stringLen)
|
||||
return NSMakeRange(NSNotFound, 0);
|
||||
r = [string rangeOfComposedCharacterSequenceAtIndex:idx];
|
||||
|
||||
// Wide chars take up two display cells.
|
||||
@@ -1084,6 +1074,8 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
} else if (col < i) {
|
||||
// Backward search
|
||||
while (col < i) {
|
||||
if (idx-1 >= stringLen)
|
||||
return NSMakeRange(NSNotFound, 0);
|
||||
r = [string rangeOfComposedCharacterSequenceAtIndex:idx-1];
|
||||
idx -= r.length;
|
||||
--i;
|
||||
@@ -1111,6 +1103,8 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
|
||||
// Forward search
|
||||
while (col > i) {
|
||||
if (idx >= stringLen)
|
||||
return NSMakeRange(NSNotFound, 0);
|
||||
r = [string rangeOfComposedCharacterSequenceAtIndex:idx];
|
||||
|
||||
// Wide chars take up two display cells.
|
||||
@@ -1131,6 +1125,8 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
#else
|
||||
idx = r.location;
|
||||
for (i = 0; i < col; ++i) {
|
||||
if (idx >= stringLen)
|
||||
return NSMakeRange(NSNotFound, 0);
|
||||
r = [string rangeOfComposedCharacterSequenceAtIndex:idx];
|
||||
|
||||
// Wide chars take up two display cells.
|
||||
@@ -1146,6 +1142,8 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
// Count the number of characters that cover the cells.
|
||||
range.location = idx;
|
||||
for (i = 0; i < cells; ++i) {
|
||||
if (idx >= stringLen)
|
||||
return NSMakeRange(NSNotFound, 0);
|
||||
r = [string rangeOfComposedCharacterSequenceAtIndex:idx];
|
||||
|
||||
// Wide chars take up two display cells.
|
||||
@@ -1163,20 +1161,20 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
#if MM_TS_PARANOIA_LOG
|
||||
#if MM_USE_ROW_CACHE
|
||||
if (range.location >= rowEnd-1) {
|
||||
NSLog(@"INTERNAL ERROR [%s] : row=%d col=%d cells=%d --> range=%@",
|
||||
_cmd, row, col, cells, NSStringFromRange(range));
|
||||
ASLogErr(@"INTERNAL ERROR: row=%d col=%d cells=%d --> range=%@",
|
||||
row, col, cells, NSStringFromRange(range));
|
||||
range.location = rowEnd - 2;
|
||||
range.length = 1;
|
||||
} else if (NSMaxRange(range) >= rowEnd) {
|
||||
NSLog(@"INTERNAL ERROR [%s] : row=%d col=%d cells=%d --> range=%@",
|
||||
_cmd, row, col, cells, NSStringFromRange(range));
|
||||
ASLogErr(@"INTERNAL ERROR: row=%d col=%d cells=%d --> range=%@",
|
||||
row, col, cells, NSStringFromRange(range));
|
||||
range.length = rowEnd - range.location - 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (NSMaxRange(range) > [string length]) {
|
||||
NSLog(@"INTERNAL ERROR [%s] : row=%d col=%d cells=%d --> range=%@",
|
||||
_cmd, row, col, cells, NSStringFromRange(range));
|
||||
if (NSMaxRange(range) > stringLen) {
|
||||
ASLogErr(@"INTERNAL ERROR: row=%d col=%d cells=%d --> range=%@",
|
||||
row, col, cells, NSStringFromRange(range));
|
||||
range.location = NSNotFound;
|
||||
range.length = 0;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
- (void)performBatchDrawWithData:(NSData *)data;
|
||||
- (void)setMouseShape:(int)shape;
|
||||
- (void)setAntialias:(BOOL)antialias;
|
||||
- (void)setImControl:(BOOL)enable;
|
||||
- (void)activateIm:(BOOL)enable;
|
||||
|
||||
//
|
||||
// MMTextStorage methods
|
||||
|
||||
+42
-46
@@ -63,10 +63,12 @@
|
||||
NSTypesetter *typesetter = [[MMTypesetter alloc] init];
|
||||
[lm setTypesetter:typesetter];
|
||||
[typesetter release];
|
||||
#if MM_USE_ROW_CACHE
|
||||
} else if ([typesetterString isEqual:@"MMTypesetter2"]) {
|
||||
NSTypesetter *typesetter = [[MMTypesetter2 alloc] init];
|
||||
[lm setTypesetter:typesetter];
|
||||
[typesetter release];
|
||||
#endif // MM_USE_ROW_CACHE
|
||||
} else {
|
||||
// Only MMTypesetter supports different cell width multipliers.
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
@@ -110,7 +112,7 @@
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
LOG_DEALLOC
|
||||
ASLogDebug(@"");
|
||||
|
||||
if (invertRects) {
|
||||
free(invertRects);
|
||||
@@ -151,7 +153,7 @@
|
||||
int cursorRow = -1, cursorCol = 0;
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@"====> BEGIN %s", _cmd);
|
||||
ASLogDebug(@"====> BEGIN %s", _cmd);
|
||||
#endif
|
||||
[textStorage beginEditing];
|
||||
|
||||
@@ -162,7 +164,7 @@
|
||||
|
||||
if (ClearAllDrawType == type) {
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Clear all");
|
||||
ASLogDebug(@" Clear all");
|
||||
#endif
|
||||
[textStorage clearAll];
|
||||
} else if (ClearBlockDrawType == type) {
|
||||
@@ -173,8 +175,8 @@
|
||||
int col2 = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Clear block (%d,%d) -> (%d,%d)", row1, col1,
|
||||
row2,col2);
|
||||
ASLogDebug(@" Clear block (%d,%d) -> (%d,%d)", row1, col1,
|
||||
row2,col2);
|
||||
#endif
|
||||
[textStorage clearBlockFromRow:row1 column:col1
|
||||
toRow:row2 column:col2
|
||||
@@ -188,7 +190,7 @@
|
||||
int right = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Delete %d line(s) from %d", count, row);
|
||||
ASLogDebug(@" Delete %d line(s) from %d", count, row);
|
||||
#endif
|
||||
[textStorage deleteLinesFromRow:row lineCount:count
|
||||
scrollBottom:bot left:left right:right
|
||||
@@ -208,9 +210,9 @@
|
||||
bytes += len;
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Draw string at (%d,%d) length=%d flags=%d fg=0x%x "
|
||||
"bg=0x%x sp=0x%x (%@)", row, col, len, flags, fg, bg, sp,
|
||||
len > 0 ? [string substringToIndex:1] : @"");
|
||||
ASLogDebug(@" Draw string at (%d,%d) length=%d flags=%d fg=0x%x "
|
||||
"bg=0x%x sp=0x%x (%@)", row, col, len, flags, fg, bg, sp,
|
||||
len > 0 ? [string substringToIndex:1] : @"");
|
||||
#endif
|
||||
// NOTE: If this is a call to draw the (block) cursor, then cancel
|
||||
// any previous request to draw the insertion point, or it might
|
||||
@@ -235,7 +237,7 @@
|
||||
int right = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Insert %d line(s) at row %d", count, row);
|
||||
ASLogDebug(@" Insert %d line(s) at row %d", count, row);
|
||||
#endif
|
||||
[textStorage insertLinesAtRow:row lineCount:count
|
||||
scrollBottom:bot left:left right:right
|
||||
@@ -248,7 +250,7 @@
|
||||
int percent = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Draw cursor at (%d,%d)", row, col);
|
||||
ASLogDebug(@" Draw cursor at (%d,%d)", row, col);
|
||||
#endif
|
||||
[helper setInsertionPointColor:[NSColor colorWithRgbInt:color]];
|
||||
[self drawInsertionPointAtRow:row column:col shape:shape
|
||||
@@ -261,8 +263,8 @@
|
||||
int invert = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Draw inverted rect: row=%d col=%d nrows=%d ncols=%d",
|
||||
row, col, nr, nc);
|
||||
ASLogDebug(@" Draw inverted rect: row=%d col=%d nrows=%d "
|
||||
"ncols=%d", row, col, nr, nc);
|
||||
#endif
|
||||
[self drawInvertedRectAtRow:row column:col numRows:nr numColumns:nc
|
||||
invert:invert];
|
||||
@@ -270,7 +272,7 @@
|
||||
cursorRow = *((int*)bytes); bytes += sizeof(int);
|
||||
cursorCol = *((int*)bytes); bytes += sizeof(int);
|
||||
} else {
|
||||
NSLog(@"WARNING: Unknown draw type (type=%d)", type);
|
||||
ASLogWarn(@"Unknown draw type (type=%d)", type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,7 +293,7 @@
|
||||
[self display];
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@"<==== END %s", _cmd);
|
||||
ASLogDebug(@"<==== END %s", _cmd);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -305,6 +307,16 @@
|
||||
antialias = state;
|
||||
}
|
||||
|
||||
- (void)setImControl:(BOOL)enable
|
||||
{
|
||||
[helper setImControl:enable];
|
||||
}
|
||||
|
||||
- (void)activateIm:(BOOL)enable
|
||||
{
|
||||
[helper activateIm:enable];
|
||||
}
|
||||
|
||||
- (NSFont *)font
|
||||
{
|
||||
return [(MMTextStorage*)[self textStorage] font];
|
||||
@@ -444,9 +456,6 @@
|
||||
if (row) *row = floor((point.y-origin.y-1) / cellSize.height);
|
||||
if (column) *column = floor((point.x-origin.x-1) / cellSize.width);
|
||||
|
||||
//NSLog(@"convertPoint:%@ toRow:%d column:%d", NSStringFromPoint(point),
|
||||
// *row, *column);
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@@ -513,7 +522,8 @@
|
||||
numInvertRects = 0;
|
||||
}
|
||||
|
||||
if ([self hasMarkedText]) {
|
||||
#ifdef INCLUDE_OLD_IM_CODE
|
||||
if ([self hasMarkedText] && ![helper useInlineIm]) {
|
||||
shouldDrawInsertionPoint = YES;
|
||||
MMTextStorage *ts = (MMTextStorage*)[self textStorage];
|
||||
NSSize inset = [self textContainerInset];
|
||||
@@ -571,6 +581,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // INCLUDE_OLD_IM_CODE
|
||||
|
||||
if (shouldDrawInsertionPoint) {
|
||||
MMTextStorage *ts = (MMTextStorage*)[self textStorage];
|
||||
@@ -580,8 +591,9 @@
|
||||
ipRect.origin.x += [self textContainerOrigin].x;
|
||||
ipRect.origin.y += [self textContainerOrigin].y;
|
||||
|
||||
#ifdef INCLUDE_OLD_IM_CODE
|
||||
// Draw insertion point inside marked text.
|
||||
if ([self hasMarkedText]) {
|
||||
if ([self hasMarkedText] && ![helper useInlineIm]) {
|
||||
NSFont *theFont = [[self markedTextAttributes]
|
||||
valueForKey:NSFontAttributeName];
|
||||
if (theFont == [ts font])
|
||||
@@ -593,6 +605,7 @@
|
||||
([helper imRange].location +
|
||||
[helper imRange].length);
|
||||
}
|
||||
#endif // INCLUDE_OLD_IM_CODE
|
||||
|
||||
if (MMInsertionPointHorizontal == insertionPointShape) {
|
||||
int frac = ([ts cellSize].height * insertionPointFraction + 99)/100;
|
||||
@@ -617,10 +630,6 @@
|
||||
// NOTE: We only draw the cursor once and rely on Vim to say when it
|
||||
// should be drawn again.
|
||||
shouldDrawInsertionPoint = NO;
|
||||
|
||||
//NSLog(@"%s draw insertion point %@ shape=%d color=%@", _cmd,
|
||||
// NSStringFromRect(ipRect), insertionPointShape,
|
||||
// [helper insertionPointColor]);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -808,28 +817,7 @@
|
||||
|
||||
- (void)changeFont:(id)sender
|
||||
{
|
||||
MMTextStorage *ts = (MMTextStorage*)[self textStorage];
|
||||
if (!ts) return;
|
||||
|
||||
NSFont *oldFont = [ts font];
|
||||
NSFont *newFont = [sender convertFont:oldFont];
|
||||
|
||||
if (newFont) {
|
||||
NSString *name = [newFont displayName];
|
||||
unsigned len = [name lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
if (len > 0) {
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
float pointSize = [newFont pointSize];
|
||||
|
||||
[data appendBytes:&pointSize length:sizeof(float)];
|
||||
|
||||
++len; // include NUL byte
|
||||
[data appendBytes:&len length:sizeof(unsigned)];
|
||||
[data appendBytes:[name UTF8String] length:len];
|
||||
|
||||
[[self vimController] sendMessage:SetFontMsgID data:data];
|
||||
}
|
||||
}
|
||||
[helper changeFont:sender];
|
||||
}
|
||||
|
||||
- (void)resetCursorRects
|
||||
@@ -878,6 +866,14 @@
|
||||
[[self windowController] vimMenuItemAction:sender];
|
||||
}
|
||||
|
||||
- (IBAction)cancelOperation:(id)sender
|
||||
{
|
||||
// NSTextView overrides this method to send complete:, whereas NSResponder
|
||||
// sends cancel: by default. So override it yet again to revert to the
|
||||
// default behavior (we resond to cancel: in MMTextViewHelper).
|
||||
[self doCommandBySelector:@selector(cancel:)];
|
||||
}
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item
|
||||
{
|
||||
if ([item action] == @selector(cut:)
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
// Need Carbon for TIS...() functions
|
||||
#import <Carbon/Carbon.h>
|
||||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
// These values are chosen so that the min text view size is not too small
|
||||
@@ -31,6 +36,8 @@ enum {
|
||||
int mouseShape;
|
||||
NSTrackingRectTag trackingRectTag;
|
||||
NSColor *insertionPointColor;
|
||||
BOOL interpretKeyEventsSwallowedKey;
|
||||
NSEvent *currentEvent;
|
||||
|
||||
// Input Manager
|
||||
NSRange imRange;
|
||||
@@ -39,6 +46,12 @@ enum {
|
||||
NSMutableAttributedString *markedText;
|
||||
int preEditRow;
|
||||
int preEditColumn;
|
||||
BOOL imControl;
|
||||
BOOL imState;
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
TISInputSourceRef lastImSource;
|
||||
TISInputSourceRef asciiImSource;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)setTextView:(id)view;
|
||||
@@ -63,6 +76,7 @@ enum {
|
||||
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender;
|
||||
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender;
|
||||
- (void)setMouseShape:(int)shape;
|
||||
- (void)changeFont:(id)sender;
|
||||
|
||||
// Input Manager
|
||||
- (BOOL)hasMarkedText;
|
||||
@@ -79,5 +93,8 @@ enum {
|
||||
- (NSRange)imRange;
|
||||
- (void)setMarkedRange:(NSRange)range;
|
||||
- (NSRect)firstRectForCharacterRange:(NSRange)range;
|
||||
- (void)setImControl:(BOOL)enable;
|
||||
- (void)activateIm:(BOOL)enable;
|
||||
- (BOOL)useInlineIm;
|
||||
|
||||
@end
|
||||
|
||||
+476
-261
@@ -23,9 +23,6 @@
|
||||
#import "Miscellaneous.h"
|
||||
|
||||
|
||||
static char MMKeypadEnter[2] = { 'K', 'A' };
|
||||
static NSString *MMKeypadEnterString = @"KA";
|
||||
|
||||
// The max/min drag timer interval in seconds
|
||||
static NSTimeInterval MMDragTimerMaxInterval = 0.3;
|
||||
static NSTimeInterval MMDragTimerMinInterval = 0.01;
|
||||
@@ -37,22 +34,59 @@ static float MMDragAreaSize = 73.0f;
|
||||
@interface MMTextViewHelper (Private)
|
||||
- (MMWindowController *)windowController;
|
||||
- (MMVimController *)vimController;
|
||||
- (void)dispatchKeyEvent:(NSEvent *)event;
|
||||
- (void)sendKeyDown:(const char *)chars length:(int)len modifiers:(int)flags
|
||||
isARepeat:(BOOL)isARepeat;
|
||||
- (void)doKeyDown:(NSString *)key;
|
||||
- (void)doInsertText:(NSString *)text;
|
||||
- (void)checkImState;
|
||||
- (void)hideMouseCursor;
|
||||
- (void)startDragTimerWithInterval:(NSTimeInterval)t;
|
||||
- (void)dragTimerFired:(NSTimer *)timer;
|
||||
- (void)setCursor;
|
||||
- (NSRect)trackingRect;
|
||||
- (BOOL)inputManagerHandleMouseEvent:(NSEvent *)event;
|
||||
- (void)sendMarkedText:(NSString *)text position:(unsigned)pos;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
static BOOL
|
||||
KeyboardInputSourcesEqual(TISInputSourceRef a, TISInputSourceRef b)
|
||||
{
|
||||
// Define two sources to be equal iff both are non-NULL and they have
|
||||
// identical source ID strings.
|
||||
|
||||
if (!(a && b))
|
||||
return NO;
|
||||
|
||||
NSString *as = TISGetInputSourceProperty(a, kTISPropertyInputSourceID);
|
||||
NSString *bs = TISGetInputSourceProperty(b, kTISPropertyInputSourceID);
|
||||
|
||||
return [as isEqualToString:bs];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@implementation MMTextViewHelper
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
ASLogDebug(@"");
|
||||
|
||||
[insertionPointColor release]; insertionPointColor = nil;
|
||||
[markedText release]; markedText = nil;
|
||||
[markedTextAttributes release]; markedTextAttributes = nil;
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
if (asciiImSource) {
|
||||
CFRelease(asciiImSource);
|
||||
asciiImSource = NULL;
|
||||
}
|
||||
if (lastImSource) {
|
||||
CFRelease(lastImSource);
|
||||
lastImSource = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
@@ -78,240 +112,202 @@ static float MMDragAreaSize = 73.0f;
|
||||
|
||||
- (void)keyDown:(NSEvent *)event
|
||||
{
|
||||
//NSLog(@"%s %@", _cmd, event);
|
||||
// HACK! If control modifier is held, don't pass the event along to
|
||||
// interpretKeyEvents: since some keys are bound to multiple commands which
|
||||
// means doCommandBySelector: is called several times. Do the same for
|
||||
// Alt+Function key presses (Alt+Up and Alt+Down are bound to two
|
||||
// commands). This hack may break input management, but unless we can
|
||||
// figure out a way to disable key bindings there seems little else to do.
|
||||
//
|
||||
// TODO: Figure out a way to disable Cocoa key bindings entirely, without
|
||||
// affecting input management.
|
||||
ASLogDebug(@"%@", event);
|
||||
|
||||
// When the Input Method is activated, some special key inputs
|
||||
// should be treated as key inputs for Input Method.
|
||||
if ([textView hasMarkedText]) {
|
||||
[textView interpretKeyEvents:[NSArray arrayWithObject:event]];
|
||||
// NOTE: Keyboard handling is complicated by the fact that we must call
|
||||
// interpretKeyEvents: otherwise key equivalents set up by input methods do
|
||||
// not work (e.g. Ctrl-Shift-; would not work under Kotoeri).
|
||||
|
||||
// NOTE: insertText: and doCommandBySelector: may need to extract data from
|
||||
// the key down event so keep a local reference to the event. This is
|
||||
// released and set to nil at the end of this method. Don't make any early
|
||||
// returns from this method without releasing and resetting this reference!
|
||||
currentEvent = [event retain];
|
||||
|
||||
if ([self hasMarkedText]) {
|
||||
// HACK! Need to redisplay manually otherwise the marked text may not
|
||||
// be correctly displayed (e.g. it is still visible after pressing Esc
|
||||
// even though the text has been unmarked).
|
||||
[textView setNeedsDisplay:YES];
|
||||
return;
|
||||
}
|
||||
|
||||
int flags = [event modifierFlags];
|
||||
if ((flags & NSControlKeyMask) ||
|
||||
((flags & NSAlternateKeyMask) && (flags & NSFunctionKeyMask))) {
|
||||
NSString *unmod = [event charactersIgnoringModifiers];
|
||||
if ([unmod length] == 1 && [unmod characterAtIndex:0] <= 0x7f
|
||||
&& [unmod characterAtIndex:0] >= 0x60) {
|
||||
// HACK! Send Ctrl-letter keys (and C-@, C-[, C-\, C-], C-^, C-_)
|
||||
// as normal text to be added to the Vim input buffer. This must
|
||||
// be done in order for the backend to be able to separate e.g.
|
||||
// Ctrl-i and Ctrl-tab.
|
||||
[self insertText:[event characters]];
|
||||
} else {
|
||||
[self dispatchKeyEvent:event];
|
||||
}
|
||||
} else if ((flags & NSAlternateKeyMask) &&
|
||||
[[[[self vimController] vimState] objectForKey:@"p_mmta"]
|
||||
boolValue]) {
|
||||
// If the 'macmeta' option is set, then send Alt+key presses directly
|
||||
// to Vim without interpreting the key press.
|
||||
NSString *unmod = [event charactersIgnoringModifiers];
|
||||
int len = [unmod lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
const char *bytes = [unmod UTF8String];
|
||||
[self hideMouseCursor];
|
||||
|
||||
[self sendKeyDown:bytes length:len modifiers:flags
|
||||
isARepeat:[event isARepeat]];
|
||||
unsigned flags = [event modifierFlags];
|
||||
id mmta = [[[self vimController] vimState] objectForKey:@"p_mmta"];
|
||||
NSString *string = [event characters];
|
||||
NSString *unmod = [event charactersIgnoringModifiers];
|
||||
|
||||
// Alt key presses should not be interpreted if the 'macmeta' option is
|
||||
// set. We still have to call interpretKeyEvents: for keys
|
||||
// like Enter, Esc, etc. to work as usual so only skip interpretation for
|
||||
// ASCII chars in the range after space (0x20) and before backspace (0x7f).
|
||||
// Note that this implies that 'mmta' (if enabled) breaks input methods
|
||||
// when the Alt key is held.
|
||||
if ((flags & NSAlternateKeyMask) && [mmta boolValue] && [unmod length] == 1
|
||||
&& [unmod characterAtIndex:0] > 0x20
|
||||
&& [unmod characterAtIndex:0] < 0x7f) {
|
||||
ASLogDebug(@"MACMETA key, don't interpret it");
|
||||
string = unmod;
|
||||
} else {
|
||||
// HACK! interpretKeyEvents: may call insertText: or
|
||||
// doCommandBySelector:, or it may swallow the key (most likely the
|
||||
// current input method used it). In the first two cases we have to
|
||||
// manually set the below flag to NO if the key wasn't handled.
|
||||
interpretKeyEventsSwallowedKey = YES;
|
||||
[textView interpretKeyEvents:[NSArray arrayWithObject:event]];
|
||||
if (interpretKeyEventsSwallowedKey)
|
||||
string = nil;
|
||||
else if (flags & NSCommandKeyMask) {
|
||||
// HACK! When Command is held we have to more or less guess whether
|
||||
// we should use characters or charactersIgnoringModifiers. The
|
||||
// following heuristic seems to work but it may have to change.
|
||||
// Note that the Shift and Alt flags may be cleared before passing
|
||||
// the event on to Vim (see doKeyDown:).
|
||||
if ((flags & NSShiftKeyMask && !(flags & NSAlternateKeyMask))
|
||||
|| flags & NSControlKeyMask)
|
||||
string = unmod;
|
||||
}
|
||||
}
|
||||
|
||||
if (string)
|
||||
[self doKeyDown:string];
|
||||
|
||||
// NOTE: Check IM state _after_ key has been interpreted or we'll pick up
|
||||
// the old IM state when it has been switched via a keyboard shortcut.
|
||||
if (imControl)
|
||||
[self checkImState];
|
||||
|
||||
[currentEvent release];
|
||||
currentEvent = nil;
|
||||
}
|
||||
|
||||
- (void)insertText:(id)string
|
||||
{
|
||||
//NSLog(@"%s %@", _cmd, string);
|
||||
// NOTE! This method is called for normal key presses but also for
|
||||
// Option-key presses --- even when Ctrl is held as well as Option. When
|
||||
// Ctrl is held, the AppKit translates the character to a Ctrl+key stroke,
|
||||
// so 'string' need not be a printable character! In this case it still
|
||||
// works to pass 'string' on to Vim as a printable character (since
|
||||
// modifiers are already included and should not be added to the input
|
||||
// buffer using CSI, K_MODIFIER).
|
||||
if ([self hasMarkedText]) {
|
||||
[self sendMarkedText:nil position:0];
|
||||
|
||||
if ([textView hasMarkedText]) {
|
||||
[textView unmarkText];
|
||||
// NOTE: If this call is left out then the marked text isn't properly
|
||||
// erased when Return is used to accept the text.
|
||||
// The input manager only ever sets new marked text, it never actually
|
||||
// calls to have it unmarked. It seems that whenever insertText: is
|
||||
// called the input manager expects the marked text to be unmarked
|
||||
// automatically, hence the explicit unmarkText: call here.
|
||||
[self unmarkText];
|
||||
}
|
||||
|
||||
NSEvent *event = [NSApp currentEvent];
|
||||
|
||||
// HACK! In order to be able to bind to <S-Space>, <S-M-Tab>, etc. we have
|
||||
// to watch for them here.
|
||||
if ([event type] == NSKeyDown
|
||||
&& [[event charactersIgnoringModifiers] length] > 0
|
||||
&& [event modifierFlags]
|
||||
& (NSShiftKeyMask|NSControlKeyMask|NSAlternateKeyMask)) {
|
||||
unichar c = [[event charactersIgnoringModifiers] characterAtIndex:0];
|
||||
|
||||
// <S-M-Tab> translates to 0x19
|
||||
if (' ' == c || 0x19 == c) {
|
||||
[self dispatchKeyEvent:event];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
[self hideMouseCursor];
|
||||
|
||||
// NOTE: 'string' is either an NSString or an NSAttributedString. Since we
|
||||
// do not support attributes, simply pass the corresponding NSString in the
|
||||
// latter case.
|
||||
if ([string isKindOfClass:[NSAttributedString class]])
|
||||
string = [string string];
|
||||
|
||||
//NSLog(@"send InsertTextMsgID: %@", string);
|
||||
//int len = [string length];
|
||||
//ASLogDebug(@"len=%d char[0]=%#x char[1]=%#x string='%@'", [string length],
|
||||
// [string characterAtIndex:0],
|
||||
// len > 1 ? [string characterAtIndex:1] : 0, string);
|
||||
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
int flags = [event modifierFlags] & 0xffff0000U;
|
||||
if ([event type] == NSKeyDown && [event isARepeat])
|
||||
flags |= 1;
|
||||
|
||||
[data appendBytes:&flags length:sizeof(int)];
|
||||
[data appendBytes:&len length:sizeof(int)];
|
||||
[data appendBytes:[string UTF8String] length:len];
|
||||
|
||||
[[self vimController] sendMessage:InsertTextMsgID data:data];
|
||||
[self doInsertText:string];
|
||||
}
|
||||
|
||||
- (void)doCommandBySelector:(SEL)selector
|
||||
- (void)doCommandBySelector:(SEL)sel
|
||||
{
|
||||
//NSLog(@"%s %@", _cmd, NSStringFromSelector(selector));
|
||||
// By ignoring the selector we effectively disable the key binding
|
||||
// mechanism of Cocoa. Hopefully this is what the user will expect
|
||||
// (pressing Ctrl+P would otherwise result in moveUp: instead of previous
|
||||
// match, etc.).
|
||||
ASLogDebug(@"%@", NSStringFromSelector(sel));
|
||||
|
||||
// Translate Ctrl-2 -> Ctrl-@ (see also Resources/KeyBinding.plist)
|
||||
if (@selector(keyCtrlAt:) == sel)
|
||||
[self doKeyDown:@"\x00"];
|
||||
// Translate Ctrl-6 -> Ctrl-^ (see also Resources/KeyBinding.plist)
|
||||
else if (@selector(keyCtrlHat:) == sel)
|
||||
[self doKeyDown:@"\x1e"];
|
||||
//
|
||||
// We usually end up here if the user pressed Ctrl+key (but not
|
||||
// Ctrl+Option+key).
|
||||
|
||||
NSEvent *event = [NSApp currentEvent];
|
||||
|
||||
if (selector == @selector(cancelOperation:)
|
||||
|| selector == @selector(insertNewline:)) {
|
||||
// HACK! If there was marked text which got abandoned as a result of
|
||||
// hitting escape or enter, then 'insertText:' is called with the
|
||||
// abandoned text but '[event characters]' includes the abandoned text
|
||||
// as well. Since 'dispatchKeyEvent:' looks at '[event characters]' we
|
||||
// must intercept these keys here or the abandonded text gets inserted
|
||||
// twice.
|
||||
NSString *key = [event charactersIgnoringModifiers];
|
||||
const char *chars = [key UTF8String];
|
||||
int len = [key lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
if (0x3 == chars[0]) {
|
||||
// HACK! AppKit turns enter (not return) into Ctrl-C, so we need to
|
||||
// handle it separately (else Ctrl-C doesn't work).
|
||||
len = sizeof(MMKeypadEnter)/sizeof(MMKeypadEnter[0]);
|
||||
chars = MMKeypadEnter;
|
||||
}
|
||||
|
||||
[self sendKeyDown:chars length:len modifiers:[event modifierFlags]
|
||||
isARepeat:[event isARepeat]];
|
||||
} else {
|
||||
[self dispatchKeyEvent:event];
|
||||
}
|
||||
// Check for selectors from AppKit.framework/StandardKeyBinding.dict and
|
||||
// send the corresponding key directly on to the backend. The reason for
|
||||
// not just letting all of these fall through is that -[NSEvent characters]
|
||||
// sometimes includes marked text as well as the actual key, but the marked
|
||||
// text is also passed to insertText:. For example, pressing Ctrl-i Return
|
||||
// on a US keyboard would call insertText:@"^" but the key event for the
|
||||
// Return press will contain "^\x0d" -- if we fell through the result would
|
||||
// be that "^^\x0d" got sent to the backend (i.e. one extra "^" would
|
||||
// appear).
|
||||
// For this reason we also have to make sure that there are key bindings to
|
||||
// all combinations of modifier with certain keys (these are set up in
|
||||
// KeyBinding.plist in the Resources folder).
|
||||
else if (@selector(insertTab:) == sel ||
|
||||
@selector(selectNextKeyView:) == sel ||
|
||||
@selector(insertTabIgnoringFieldEditor:) == sel)
|
||||
[self doKeyDown:@"\x09"];
|
||||
else if (@selector(insertNewline:) == sel ||
|
||||
@selector(insertLineBreak:) == sel ||
|
||||
@selector(insertNewlineIgnoringFieldEditor:) == sel)
|
||||
[self doKeyDown:@"\x0d"];
|
||||
else if (@selector(cancelOperation:) == sel ||
|
||||
@selector(complete:) == sel)
|
||||
[self doKeyDown:@"\x1b"];
|
||||
else if (@selector(insertBackTab:) == sel ||
|
||||
@selector(selectPreviousKeyView:) == sel)
|
||||
[self doKeyDown:@"\x19"];
|
||||
else if (@selector(deleteBackward:) == sel ||
|
||||
@selector(deleteWordBackward:) == sel ||
|
||||
@selector(deleteBackwardByDecomposingPreviousCharacter:) == sel ||
|
||||
@selector(deleteToBeginningOfLine:) == sel)
|
||||
[self doKeyDown:@"\x7f"];
|
||||
else if (@selector(keySpace:) == sel)
|
||||
[self doKeyDown:@" "];
|
||||
else if (@selector(cancel:) == sel)
|
||||
kill([[self vimController] pid], SIGINT);
|
||||
else interpretKeyEventsSwallowedKey = NO;
|
||||
}
|
||||
|
||||
- (BOOL)performKeyEquivalent:(NSEvent *)event
|
||||
{
|
||||
//NSLog(@"%s %@", _cmd, event);
|
||||
// Called for Cmd+key keystrokes, function keys, arrow keys, page
|
||||
// up/down, home, end.
|
||||
//
|
||||
// NOTE: This message cannot be ignored since Cmd+letter keys never are
|
||||
// passed to keyDown:. It seems as if the main menu consumes Cmd-key
|
||||
// strokes, unless the key is a function key.
|
||||
ASLogDebug(@"");
|
||||
|
||||
// NOTE: If the event that triggered this method represents a function key
|
||||
// down then we do nothing, otherwise the input method never gets the key
|
||||
// stroke (some input methods use e.g. arrow keys). The function key down
|
||||
// event will still reach Vim though (via keyDown:). The exceptions to
|
||||
// this rule are: PageUp/PageDown (keycode 116/121).
|
||||
int flags = [event modifierFlags] & 0xffff0000U;
|
||||
if ([event type] != NSKeyDown || flags & NSFunctionKeyMask
|
||||
&& !(116 == [event keyCode] || 121 == [event keyCode]))
|
||||
// NOTE: Key equivalent handling was fixed in Leopard. That is, an
|
||||
// unhandled key equivalent is passed to keyDown: -- contrast this with
|
||||
// pre-Leopard where unhandled key equivalents would simply disappear
|
||||
// (hence the ugly hack below for Tiger).
|
||||
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_4)
|
||||
return NO;
|
||||
|
||||
// HACK! KeyCode 50 represent the key which switches between windows
|
||||
// HACK! KeyCode 50 represent the key which switches between windows
|
||||
// within an application (like Cmd+Tab is used to switch between
|
||||
// applications). Return NO here, else the window switching does not work.
|
||||
if ([event keyCode] == 50)
|
||||
return NO;
|
||||
|
||||
// HACK! Let the main menu try to handle any key down event, before
|
||||
// HACK! The -[NSRespoder cancelOperation:] indicates that Cmd-. is handled
|
||||
// in a special way by the key window. Indeed, if we pass this event on to
|
||||
// keyDown: it will result in doCommandBySelector: being called with
|
||||
// cancelOperation: as selector, otherwise it is called with cancel: as the
|
||||
// selector (and we respond to cancel: there).
|
||||
int flags = [event modifierFlags] & NSDeviceIndependentModifierFlagsMask;
|
||||
NSString *unmod = [event charactersIgnoringModifiers];
|
||||
if (flags == NSCommandKeyMask && [unmod isEqual:@"."])
|
||||
return NO;
|
||||
|
||||
// HACK! Let the main menu try to handle any key down event, before
|
||||
// passing it on to vim, otherwise key equivalents for menus will
|
||||
// effectively be disabled.
|
||||
if ([[NSApp mainMenu] performKeyEquivalent:event])
|
||||
return YES;
|
||||
|
||||
// HACK! On Leopard Ctrl-key events end up here instead of keyDown:.
|
||||
if (flags & NSControlKeyMask) {
|
||||
[self keyDown:event];
|
||||
return YES;
|
||||
}
|
||||
|
||||
// HACK! Don't handle Cmd-? or the "Help" menu does not work on Leopard.
|
||||
NSString *unmodchars = [event charactersIgnoringModifiers];
|
||||
if ([unmodchars isEqual:@"?"])
|
||||
return NO;
|
||||
|
||||
// Cmd-. is hard-wired to send SIGINT unlike Ctrl-C which is just another
|
||||
// key press which Vim has to interpret. This means that Cmd-. always
|
||||
// works to interrupt a Vim process whereas Ctrl-C can suffer from problems
|
||||
// such as dropped DO messages (or if Vim is stuck in a loop without
|
||||
// checking for keyboard input).
|
||||
if ((flags & NSDeviceIndependentModifierFlagsMask) == NSCommandKeyMask &&
|
||||
[unmodchars isEqual:@"."]) {
|
||||
kill([[self vimController] pid], SIGINT);
|
||||
return YES;
|
||||
}
|
||||
|
||||
//NSLog(@"%s%@", _cmd, event);
|
||||
|
||||
NSString *chars = [event characters];
|
||||
int len = [unmodchars lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
|
||||
if (len <= 0)
|
||||
return NO;
|
||||
|
||||
// If 'chars' and 'unmodchars' differs when shift flag is present, then we
|
||||
// can clear the shift flag as it is already included in 'unmodchars'.
|
||||
// Failing to clear the shift flag means <D-Bar> turns into <S-D-Bar> (on
|
||||
// an English keyboard).
|
||||
if (flags & NSShiftKeyMask && ![chars isEqual:unmodchars])
|
||||
flags &= ~NSShiftKeyMask;
|
||||
|
||||
if (0x3 == [unmodchars characterAtIndex:0]) {
|
||||
// HACK! AppKit turns enter (not return) into Ctrl-C, so we need to
|
||||
// handle it separately (else Cmd-enter turns into Ctrl-C).
|
||||
unmodchars = MMKeypadEnterString;
|
||||
len = [unmodchars lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
if ([event isARepeat])
|
||||
flags |= 1;
|
||||
|
||||
[data appendBytes:&flags length:sizeof(int)];
|
||||
[data appendBytes:&len length:sizeof(int)];
|
||||
[data appendBytes:[unmodchars UTF8String] length:len];
|
||||
|
||||
[[self vimController] sendMessage:CmdKeyMsgID data:data];
|
||||
|
||||
// HACK! Pass the event on or it may disappear (Tiger does not pass Cmd-key
|
||||
// events to keyDown:).
|
||||
[self keyDown:event];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)scrollWheel:(NSEvent *)event
|
||||
{
|
||||
if ([self hasMarkedText]) {
|
||||
// We must clear the marked text since the cursor may move if the
|
||||
// marked text moves outside the view as a result of scrolling.
|
||||
[self sendMarkedText:nil position:0];
|
||||
[self unmarkText];
|
||||
[[NSInputManager currentInputManager] markedTextAbandoned:self];
|
||||
}
|
||||
|
||||
if ([event deltaY] == 0)
|
||||
return;
|
||||
|
||||
@@ -333,6 +329,9 @@ static float MMDragAreaSize = 73.0f;
|
||||
|
||||
- (void)mouseDown:(NSEvent *)event
|
||||
{
|
||||
if ([self inputManagerHandleMouseEvent:event])
|
||||
return;
|
||||
|
||||
int row, col;
|
||||
NSPoint pt = [textView convertPoint:[event locationInWindow] fromView:nil];
|
||||
if (![textView convertPoint:pt toRow:&row column:&col])
|
||||
@@ -365,6 +364,9 @@ static float MMDragAreaSize = 73.0f;
|
||||
|
||||
- (void)mouseUp:(NSEvent *)event
|
||||
{
|
||||
if ([self inputManagerHandleMouseEvent:event])
|
||||
return;
|
||||
|
||||
int row, col;
|
||||
NSPoint pt = [textView convertPoint:[event locationInWindow] fromView:nil];
|
||||
if (![textView convertPoint:pt toRow:&row column:&col])
|
||||
@@ -384,6 +386,9 @@ static float MMDragAreaSize = 73.0f;
|
||||
|
||||
- (void)mouseDragged:(NSEvent *)event
|
||||
{
|
||||
if ([self inputManagerHandleMouseEvent:event])
|
||||
return;
|
||||
|
||||
int flags = [event modifierFlags];
|
||||
int row, col;
|
||||
NSPoint pt = [textView convertPoint:[event locationInWindow] fromView:nil];
|
||||
@@ -414,6 +419,9 @@ static float MMDragAreaSize = 73.0f;
|
||||
|
||||
- (void)mouseMoved:(NSEvent *)event
|
||||
{
|
||||
if ([self inputManagerHandleMouseEvent:event])
|
||||
return;
|
||||
|
||||
// HACK! NSTextView has a nasty habit of resetting the cursor to the
|
||||
// default I-beam cursor at random moments. The only reliable way we know
|
||||
// of to work around this is to set the cursor each time the mouse moves.
|
||||
@@ -437,15 +445,11 @@ static float MMDragAreaSize = 73.0f;
|
||||
[data appendBytes:&col length:sizeof(int)];
|
||||
|
||||
[[self vimController] sendMessage:MouseMovedMsgID data:data];
|
||||
|
||||
//NSLog(@"Moved %d %d\n", col, row);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseEntered:(NSEvent *)event
|
||||
{
|
||||
//NSLog(@"%s", _cmd);
|
||||
|
||||
// NOTE: This event is received even when the window is not key; thus we
|
||||
// have to take care not to enable mouse moved events unless our window is
|
||||
// key.
|
||||
@@ -456,8 +460,6 @@ static float MMDragAreaSize = 73.0f;
|
||||
|
||||
- (void)mouseExited:(NSEvent *)event
|
||||
{
|
||||
//NSLog(@"%s", _cmd);
|
||||
|
||||
[[textView window] setAcceptsMouseMovedEvents:NO];
|
||||
|
||||
// NOTE: This event is received even when the window is not key; if the
|
||||
@@ -473,8 +475,6 @@ static float MMDragAreaSize = 73.0f;
|
||||
|
||||
- (void)setFrame:(NSRect)frame
|
||||
{
|
||||
//NSLog(@"%s", _cmd);
|
||||
|
||||
// When the frame changes we also need to update the tracking rect.
|
||||
[textView removeTrackingRect:trackingRectTag];
|
||||
trackingRectTag = [textView addTrackingRect:[self trackingRect]
|
||||
@@ -485,8 +485,6 @@ static float MMDragAreaSize = 73.0f;
|
||||
|
||||
- (void)viewDidMoveToWindow
|
||||
{
|
||||
//NSLog(@"%s (window=%@)", _cmd, [self window]);
|
||||
|
||||
// Set a tracking rect which covers the text.
|
||||
// NOTE: While the mouse cursor is in this rect the view will receive
|
||||
// 'mouseMoved:' events so that Vim can take care of updating the mouse
|
||||
@@ -502,8 +500,6 @@ static float MMDragAreaSize = 73.0f;
|
||||
|
||||
- (void)viewWillMoveToWindow:(NSWindow *)newWindow
|
||||
{
|
||||
//NSLog(@"%s%@", _cmd, newWindow);
|
||||
|
||||
// Remove tracking rect if view moves or is removed.
|
||||
if ([textView window] && trackingRectTag) {
|
||||
[textView removeTrackingRect:trackingRectTag];
|
||||
@@ -564,6 +560,40 @@ static float MMDragAreaSize = 73.0f;
|
||||
[self setCursor];
|
||||
}
|
||||
|
||||
- (void)changeFont:(id)sender
|
||||
{
|
||||
NSFont *newFont = [sender convertFont:[textView font]];
|
||||
NSFont *newFontWide = [sender convertFont:[textView fontWide]];
|
||||
|
||||
if (newFont) {
|
||||
NSString *name = [newFont displayName];
|
||||
NSString *wideName = [newFontWide displayName];
|
||||
unsigned len = [name lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
unsigned wideLen = [wideName lengthOfBytesUsingEncoding:
|
||||
NSUTF8StringEncoding];
|
||||
if (len > 0) {
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
float pointSize = [newFont pointSize];
|
||||
|
||||
[data appendBytes:&pointSize length:sizeof(float)];
|
||||
|
||||
++len; // include NUL byte
|
||||
[data appendBytes:&len length:sizeof(unsigned)];
|
||||
[data appendBytes:[name UTF8String] length:len];
|
||||
|
||||
if (wideLen > 0) {
|
||||
++wideLen; // include NUL byte
|
||||
[data appendBytes:&wideLen length:sizeof(unsigned)];
|
||||
[data appendBytes:[wideName UTF8String] length:wideLen];
|
||||
} else {
|
||||
[data appendBytes:&wideLen length:sizeof(unsigned)];
|
||||
}
|
||||
|
||||
[[self vimController] sendMessage:SetFontMsgID data:data];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)hasMarkedText
|
||||
{
|
||||
return markedRange.length > 0 ? YES : NO;
|
||||
@@ -584,6 +614,7 @@ static float MMDragAreaSize = 73.0f;
|
||||
|
||||
- (void)setMarkedTextAttributes:(NSDictionary *)attr
|
||||
{
|
||||
ASLogDebug(@"%@", attr);
|
||||
if (attr != markedTextAttributes) {
|
||||
[markedTextAttributes release];
|
||||
markedTextAttributes = [attr retain];
|
||||
@@ -592,8 +623,23 @@ static float MMDragAreaSize = 73.0f;
|
||||
|
||||
- (void)setMarkedText:(id)text selectedRange:(NSRange)range
|
||||
{
|
||||
ASLogDebug(@"text='%@' range=%@", text, NSStringFromRange(range));
|
||||
[self unmarkText];
|
||||
|
||||
if ([self useInlineIm]) {
|
||||
if ([text isKindOfClass:[NSAttributedString class]])
|
||||
text = [text string];
|
||||
|
||||
if ([text length] > 0) {
|
||||
markedRange = NSMakeRange(0, [text length]);
|
||||
imRange = range;
|
||||
}
|
||||
|
||||
[self sendMarkedText:text position:range.location];
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_OLD_IM_CODE
|
||||
if (!(text && [text length] > 0))
|
||||
return;
|
||||
|
||||
@@ -633,10 +679,12 @@ static float MMDragAreaSize = 73.0f;
|
||||
}
|
||||
|
||||
[textView setNeedsDisplay:YES];
|
||||
#endif // INCLUDE_OLD_IM_CODE
|
||||
}
|
||||
|
||||
- (void)unmarkText
|
||||
{
|
||||
ASLogDebug(@"");
|
||||
imRange = NSMakeRange(0, 0);
|
||||
markedRange = NSMakeRange(NSNotFound, 0);
|
||||
[markedText release];
|
||||
@@ -716,6 +764,105 @@ static float MMDragAreaSize = 73.0f;
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (void)setImControl:(BOOL)enable
|
||||
{
|
||||
// This flag corresponds to the (negation of the) 'imd' option. When
|
||||
// enabled changes to the input method are detected and forwarded to the
|
||||
// backend. On >=10.5 and later we do not forward changes to the input
|
||||
// method, instead we let Vim be in complete control.
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
// The TIS symbols are weakly linked.
|
||||
if (NULL != TISCopyCurrentKeyboardInputSource) {
|
||||
// We get here when compiled on =>10.5 and running on >=10.5.
|
||||
|
||||
if (asciiImSource) {
|
||||
CFRelease(asciiImSource);
|
||||
asciiImSource = NULL;
|
||||
}
|
||||
if (lastImSource) {
|
||||
CFRelease(lastImSource);
|
||||
lastImSource = NULL;
|
||||
}
|
||||
if (enable) {
|
||||
// Save current input source for use when IM is active and get an
|
||||
// ASCII source for use when IM is deactivated (by Vim).
|
||||
asciiImSource = TISCopyCurrentASCIICapableKeyboardInputSource();
|
||||
lastImSource = TISCopyCurrentKeyboardInputSource();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// The imControl flag is only used on 10.4 -- on >=10.5 we wait for Vim to
|
||||
// call activateIm: and never explicitly check if the input source changes.
|
||||
imControl = enable;
|
||||
ASLogInfo(@"IM control %sabled", enable ? "en" : "dis");
|
||||
}
|
||||
|
||||
- (void)activateIm:(BOOL)enable
|
||||
{
|
||||
ASLogInfo(@"Activate IM=%d", enable);
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
// The TIS symbols are weakly linked.
|
||||
if (NULL != TISCopyCurrentKeyboardInputSource) {
|
||||
// We get here when compiled on >=10.5 and running on >=10.5.
|
||||
|
||||
TISInputSourceRef ref = NULL;
|
||||
if (enable) {
|
||||
// Enable IM: switch back to input source used when IM was last on.
|
||||
ref = lastImSource;
|
||||
} else {
|
||||
// Disable IM: switch back to ASCII input source that was used when
|
||||
// IM was last off.
|
||||
ref = asciiImSource;
|
||||
|
||||
TISInputSourceRef cur = TISCopyCurrentKeyboardInputSource();
|
||||
if (!KeyboardInputSourcesEqual(asciiImSource, cur)) {
|
||||
// Remember current input source so we can switch back to it
|
||||
// when IM is once more enabled. Note that Vim will call this
|
||||
// method with "enable=NO" even when the ASCII input source is
|
||||
// in use which is why we only remember the current input
|
||||
// source unless it is the ASCII source.
|
||||
ASLogDebug(@"Remember last input source: %@",
|
||||
TISGetInputSourceProperty(cur, kTISPropertyInputSourceID));
|
||||
if (lastImSource) CFRelease(lastImSource);
|
||||
lastImSource = cur;
|
||||
} else {
|
||||
CFRelease(cur);
|
||||
cur = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ref) {
|
||||
ASLogDebug(@"Change input source: %@",
|
||||
TISGetInputSourceProperty(ref, kTISPropertyInputSourceID));
|
||||
TISSelectInputSource(ref);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// We get here when compiled on >=10.5 but running on 10.4 -- fall through
|
||||
// and use old IM code...
|
||||
#endif
|
||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4)
|
||||
// NOTE: The IM code is delegated to the frontend since calling it in
|
||||
// the backend caused weird bugs (second dock icon appearing etc.).
|
||||
KeyScript(enable ? smKeySysScript : smKeyRoman);
|
||||
#endif
|
||||
}
|
||||
|
||||
- (BOOL)useInlineIm
|
||||
{
|
||||
#ifdef INCLUDE_OLD_IM_CODE
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
return [ud boolForKey:MMUseInlineImKey];
|
||||
#else
|
||||
return YES;
|
||||
#endif // INCLUDE_OLD_IM_CODE
|
||||
}
|
||||
|
||||
@end // MMTextViewHelper
|
||||
|
||||
|
||||
@@ -736,72 +883,107 @@ static float MMDragAreaSize = 73.0f;
|
||||
return [[self windowController] vimController];
|
||||
}
|
||||
|
||||
- (void)dispatchKeyEvent:(NSEvent *)event
|
||||
- (void)doKeyDown:(NSString *)key
|
||||
{
|
||||
// Only handle the command if it came from a keyDown event
|
||||
if ([event type] != NSKeyDown)
|
||||
if (!currentEvent) {
|
||||
ASLogDebug(@"No current event; ignore key");
|
||||
return;
|
||||
|
||||
NSString *chars = [event characters];
|
||||
NSString *unmodchars = [event charactersIgnoringModifiers];
|
||||
unichar c = [chars characterAtIndex:0];
|
||||
unichar imc = [unmodchars characterAtIndex:0];
|
||||
int len = 0;
|
||||
const char *bytes = 0;
|
||||
int mods = [event modifierFlags];
|
||||
|
||||
//NSLog(@"%s chars[0]=0x%x unmodchars[0]=0x%x (chars=%@ unmodchars=%@)",
|
||||
// _cmd, c, imc, chars, unmodchars);
|
||||
|
||||
if (' ' == imc && 0xa0 != c) {
|
||||
// HACK! The AppKit turns <C-Space> into <C-@> which is not standard
|
||||
// Vim behaviour, so bypass this problem. (0xa0 is <M-Space>, which
|
||||
// should be passed on as is.)
|
||||
len = [unmodchars lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
bytes = [unmodchars UTF8String];
|
||||
} else if (imc == c && '2' == c) {
|
||||
// HACK! Translate Ctrl+2 to <C-@>.
|
||||
static char ctrl_at = 0;
|
||||
len = 1; bytes = &ctrl_at;
|
||||
} else if (imc == c && '6' == c) {
|
||||
// HACK! Translate Ctrl+6 to <C-^>.
|
||||
static char ctrl_hat = 0x1e;
|
||||
len = 1; bytes = &ctrl_hat;
|
||||
} else if (c == 0x19 && imc == 0x19) {
|
||||
// HACK! AppKit turns back tab into Ctrl-Y, so we need to handle it
|
||||
// separately (else Ctrl-Y doesn't work).
|
||||
static char tab = 0x9;
|
||||
len = 1; bytes = &tab; mods |= NSShiftKeyMask;
|
||||
} else {
|
||||
len = [chars lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
bytes = [chars UTF8String];
|
||||
}
|
||||
|
||||
[self sendKeyDown:bytes length:len modifiers:mods
|
||||
isARepeat:[event isARepeat]];
|
||||
const char *chars = [key UTF8String];
|
||||
unsigned length = [key lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
unsigned keyCode = [currentEvent keyCode];
|
||||
unsigned flags = [currentEvent modifierFlags];
|
||||
|
||||
if (flags & NSCommandKeyMask) {
|
||||
// The Shift flag is already included in the key when the Command key
|
||||
// is held. The same goes for Alt, unless Ctrl is held or 'macmeta' is
|
||||
// set.
|
||||
flags &= ~NSShiftKeyMask;
|
||||
if (!(flags & NSControlKeyMask)) {
|
||||
id mmta = [[[self vimController] vimState] objectForKey:@"p_mmta"];
|
||||
if (![mmta boolValue])
|
||||
flags &= ~NSAlternateKeyMask;
|
||||
}
|
||||
}
|
||||
|
||||
// The low 16 bits are not used for modifier flags by NSEvent. Use
|
||||
// these bits for custom flags.
|
||||
flags &= NSDeviceIndependentModifierFlagsMask;
|
||||
if ([currentEvent isARepeat])
|
||||
flags |= 1;
|
||||
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
[data appendBytes:&flags length:sizeof(unsigned)];
|
||||
[data appendBytes:&keyCode length:sizeof(unsigned)];
|
||||
[data appendBytes:&length length:sizeof(unsigned)];
|
||||
if (length > 0)
|
||||
[data appendBytes:chars length:length];
|
||||
|
||||
[[self vimController] sendMessage:KeyDownMsgID data:data];
|
||||
}
|
||||
|
||||
- (void)sendKeyDown:(const char *)chars length:(int)len modifiers:(int)flags
|
||||
isARepeat:(BOOL)isARepeat
|
||||
- (void)doInsertText:(NSString *)text
|
||||
{
|
||||
if (chars && len > 0) {
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
unsigned length = [text lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
if (0 == length)
|
||||
return;
|
||||
|
||||
// The low 16 bits are not used for modifier flags by NSEvent. Use
|
||||
// these bits for custom flags.
|
||||
flags &= 0xffff0000;
|
||||
if (isARepeat)
|
||||
const char *chars = [text UTF8String];
|
||||
unsigned keyCode = 0;
|
||||
unsigned flags = 0;
|
||||
|
||||
// HACK! insertText: can be called from outside a keyDown: event in which
|
||||
// case currentEvent is nil. This happens e.g. when the "Special
|
||||
// Characters" palette is used to insert text. In this situation we assume
|
||||
// that the key is not a repeat (if there was a palette that did auto
|
||||
// repeat of input we might have to rethink this).
|
||||
if (currentEvent) {
|
||||
// HACK! Keys on the numeric key pad are treated as special keys by Vim
|
||||
// so we need to pass on key code and modifier flags in this situation.
|
||||
unsigned mods = [currentEvent modifierFlags];
|
||||
if (mods & NSNumericPadKeyMask) {
|
||||
flags = mods & NSDeviceIndependentModifierFlagsMask;
|
||||
keyCode = [currentEvent keyCode];
|
||||
}
|
||||
|
||||
if ([currentEvent isARepeat])
|
||||
flags |= 1;
|
||||
|
||||
[data appendBytes:&flags length:sizeof(int)];
|
||||
[data appendBytes:&len length:sizeof(int)];
|
||||
[data appendBytes:chars length:len];
|
||||
|
||||
[self hideMouseCursor];
|
||||
|
||||
//NSLog(@"%s len=%d chars=0x%x", _cmd, len, chars[0]);
|
||||
[[self vimController] sendMessage:KeyDownMsgID data:data];
|
||||
}
|
||||
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
[data appendBytes:&flags length:sizeof(unsigned)];
|
||||
[data appendBytes:&keyCode length:sizeof(unsigned)];
|
||||
[data appendBytes:&length length:sizeof(unsigned)];
|
||||
[data appendBytes:chars length:length];
|
||||
|
||||
[[self vimController] sendMessage:KeyDownMsgID data:data];
|
||||
}
|
||||
|
||||
- (void)checkImState
|
||||
{
|
||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4)
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
if (NULL != TISCopyCurrentKeyboardInputSource)
|
||||
return; // Compiled for >=10.4, running on >=10.5
|
||||
#endif
|
||||
// Compiled for >=10.4, running on 10.4
|
||||
|
||||
// IM is active whenever the current script is the system script and the
|
||||
// system script isn't roman. (Hence IM can only be active when using
|
||||
// non-roman scripts.)
|
||||
|
||||
// NOTE: The IM code is delegated to the frontend since calling it in the
|
||||
// backend caused weird bugs (second dock icon appearing etc.).
|
||||
SInt32 currentScript = GetScriptManagerVariable(smKeyScript);
|
||||
SInt32 systemScript = GetScriptManagerVariable(smSysScript);
|
||||
BOOL state = currentScript != smRoman && currentScript == systemScript;
|
||||
if (imState != state) {
|
||||
imState = state;
|
||||
int msgid = state ? ActivatedImMsgID : DeactivatedImMsgID;
|
||||
[[self vimController] sendMessage:msgid data:nil];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)hideMouseCursor
|
||||
@@ -880,7 +1062,7 @@ static float MMDragAreaSize = 73.0f;
|
||||
initWithImage:ibeamImage hotSpot:hotSpot];
|
||||
}
|
||||
if (!customIbeamCursor) {
|
||||
NSLog(@"WARNING: Failed to load custom Ibeam cursor");
|
||||
ASLogWarn(@"Failed to load custom Ibeam cursor");
|
||||
customIbeamCursor = [NSCursor IBeamCursor];
|
||||
}
|
||||
}
|
||||
@@ -921,4 +1103,37 @@ static float MMDragAreaSize = 73.0f;
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (BOOL)inputManagerHandleMouseEvent:(NSEvent *)event
|
||||
{
|
||||
// NOTE: The input manager usually handles events like mouse clicks (e.g.
|
||||
// the Kotoeri manager "commits" the text on left clicks).
|
||||
|
||||
if (event) {
|
||||
NSInputManager *imgr = [NSInputManager currentInputManager];
|
||||
if ([imgr wantsToHandleMouseEvents])
|
||||
return [imgr handleMouseEvent:event];
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)sendMarkedText:(NSString *)text position:(unsigned)pos
|
||||
{
|
||||
if (![self useInlineIm])
|
||||
return;
|
||||
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
unsigned len = text == nil ? 0
|
||||
: [text lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
[data appendBytes:&pos length:sizeof(unsigned)];
|
||||
[data appendBytes:&len length:sizeof(unsigned)];
|
||||
if (len > 0) {
|
||||
[data appendBytes:[text UTF8String] length:len];
|
||||
[data appendBytes:"\x00" length:1];
|
||||
}
|
||||
|
||||
[[self vimController] sendMessage:SetMarkedTextMsgID data:data];
|
||||
}
|
||||
|
||||
@end // MMTextViewHelper (Private)
|
||||
|
||||
@@ -60,7 +60,6 @@
|
||||
- (NSTypesetterControlCharacterAction)
|
||||
actionForControlCharacterAtIndex:(unsigned)charIndex
|
||||
{
|
||||
//NSLog(@"%s%d", _cmd, charIndex);
|
||||
/*NSTextStorage *ts = [[self layoutManager] textStorage];
|
||||
|
||||
if ('\n' == [[ts string] characterAtIndex:charIndex])
|
||||
@@ -75,9 +74,9 @@
|
||||
withAdvancements:(const float *)advancements
|
||||
forStartOfGlyphRange:(NSRange)glyphRange
|
||||
{
|
||||
NSLog(@"setLocation:%@ withAdvancements:%f forStartOfGlyphRange:%@",
|
||||
NSStringFromPoint(location), advancements ? *advancements : 0,
|
||||
NSStringFromRange(glyphRange));
|
||||
ASLogDebug(@"setLocation:%@ withAdvancements:%f forStartOfGlyphRange:%@",
|
||||
NSStringFromPoint(location), advancements ? *advancements : 0,
|
||||
NSStringFromRange(glyphRange));
|
||||
[super setLocation:location withAdvancements:advancements
|
||||
forStartOfGlyphRange:glyphRange];
|
||||
}
|
||||
@@ -89,6 +88,8 @@
|
||||
|
||||
|
||||
|
||||
#if MM_USE_ROW_CACHE
|
||||
|
||||
@implementation MMTypesetter2
|
||||
|
||||
//
|
||||
@@ -188,3 +189,5 @@
|
||||
|
||||
@end // MMTypesetter2
|
||||
|
||||
#endif // MM_USE_ROW_CACHE
|
||||
|
||||
|
||||
@@ -20,14 +20,11 @@
|
||||
|
||||
|
||||
|
||||
@interface MMVimController : NSObject <MMFrontendProtocol>
|
||||
{
|
||||
@interface MMVimController : NSObject {
|
||||
unsigned identifier;
|
||||
BOOL isInitialized;
|
||||
MMWindowController *windowController;
|
||||
id backendProxy;
|
||||
BOOL inProcessCommandQueue;
|
||||
NSMutableArray *sendQueue;
|
||||
NSMutableArray *receiveQueue;
|
||||
NSMenu *mainMenu;
|
||||
NSMutableArray *popupMenuItems;
|
||||
NSToolbar *toolbar;
|
||||
@@ -43,6 +40,7 @@
|
||||
}
|
||||
|
||||
- (id)initWithBackend:(id)backend pid:(int)processIdentifier;
|
||||
- (unsigned)identifier;
|
||||
- (id)backendProxy;
|
||||
- (int)pid;
|
||||
- (void)setServerName:(NSString *)name;
|
||||
@@ -65,7 +63,9 @@
|
||||
timeout:(NSTimeInterval)timeout;
|
||||
- (void)addVimInput:(NSString *)string;
|
||||
- (NSString *)evaluateVimExpression:(NSString *)expr;
|
||||
- (id)evaluateVimExpressionCocoa:(NSString *)expr errorString:(NSString **)errstr;
|
||||
- (id)evaluateVimExpressionCocoa:(NSString *)expr
|
||||
errorString:(NSString **)errstr;
|
||||
- (void)processInputQueue:(NSArray *)queue;
|
||||
#ifdef MM_ENABLE_PLUGINS
|
||||
- (MMPlugInInstanceMediator *)instanceMediator;
|
||||
#endif
|
||||
|
||||
+313
-317
@@ -10,17 +10,20 @@
|
||||
/*
|
||||
* MMVimController
|
||||
*
|
||||
* Coordinates input/output to/from backend. Each MMBackend communicates
|
||||
* directly with a MMVimController.
|
||||
* Coordinates input/output to/from backend. A MMVimController sends input
|
||||
* directly to a MMBackend, but communication from MMBackend to MMVimController
|
||||
* goes via MMAppController so that it can coordinate all incoming distributed
|
||||
* object messages.
|
||||
*
|
||||
* MMVimController does not deal with visual presentation. Essentially it
|
||||
* should be able to run with no window present.
|
||||
*
|
||||
* Output from the backend is received in processCommandQueue:. Input is sent
|
||||
* to the backend via sendMessage:data: or addVimInput:. The latter allows
|
||||
* execution of arbitrary strings in the Vim process, much like the Vim script
|
||||
* function remote_send() does. The messages that may be passed between
|
||||
* frontend and backend are defined in an enum in MacVim.h.
|
||||
* Output from the backend is received in processInputQueue: (this message is
|
||||
* called from MMAppController so it is not a DO call). Input is sent to the
|
||||
* backend via sendMessage:data: or addVimInput:. The latter allows execution
|
||||
* of arbitrary strings in the Vim process, much like the Vim script function
|
||||
* remote_send() does. The messages that may be passed between frontend and
|
||||
* backend are defined in an enum in MacVim.h.
|
||||
*/
|
||||
|
||||
#import "MMAppController.h"
|
||||
@@ -49,9 +52,7 @@ static NSTimeInterval MMBackendProxyRequestTimeout = 0;
|
||||
// Timeout used for setDialogReturn:.
|
||||
static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
|
||||
|
||||
// Maximum number of items in the receiveQueue. (It is hard to predict what
|
||||
// consequences changing this number will have.)
|
||||
static int MMReceiveQueueCap = 100;
|
||||
static unsigned identifierCounter = 1;
|
||||
|
||||
static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
@@ -65,7 +66,7 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
|
||||
@interface MMVimController (Private)
|
||||
- (void)doProcessCommandQueue:(NSArray *)queue;
|
||||
- (void)doProcessInputQueue:(NSArray *)queue;
|
||||
- (void)handleMessage:(int)msgid data:(NSData *)data;
|
||||
- (void)savePanelDidEnd:(NSSavePanel *)panel code:(int)code
|
||||
context:(void *)context;
|
||||
@@ -95,6 +96,8 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
- (void)popupMenuWithAttributes:(NSDictionary *)attrs;
|
||||
- (void)connectionDidDie:(NSNotification *)notification;
|
||||
- (void)scheduleClose;
|
||||
- (void)handleBrowseForFile:(NSDictionary *)attr;
|
||||
- (void)handleShowDialog:(NSDictionary *)attr;
|
||||
@end
|
||||
|
||||
|
||||
@@ -107,11 +110,12 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
if (!(self = [super init]))
|
||||
return nil;
|
||||
|
||||
// TODO: Come up with a better way of creating an identifier.
|
||||
identifier = identifierCounter++;
|
||||
|
||||
windowController =
|
||||
[[MMWindowController alloc] initWithVimController:self];
|
||||
backendProxy = [backend retain];
|
||||
sendQueue = [NSMutableArray new];
|
||||
receiveQueue = [NSMutableArray new];
|
||||
popupMenuItems = [[NSMutableArray alloc] init];
|
||||
toolbarItemDict = [[NSMutableDictionary alloc] init];
|
||||
pid = processIdentifier;
|
||||
@@ -158,7 +162,7 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
LOG_DEALLOC
|
||||
ASLogDebug(@"");
|
||||
|
||||
isInitialized = NO;
|
||||
|
||||
@@ -168,8 +172,6 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
[serverName release]; serverName = nil;
|
||||
[backendProxy release]; backendProxy = nil;
|
||||
[sendQueue release]; sendQueue = nil;
|
||||
[receiveQueue release]; receiveQueue = nil;
|
||||
|
||||
[toolbarItemDict release]; toolbarItemDict = nil;
|
||||
[toolbar release]; toolbar = nil;
|
||||
@@ -183,6 +185,11 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (unsigned)identifier
|
||||
{
|
||||
return identifier;
|
||||
}
|
||||
|
||||
- (MMWindowController *)windowController
|
||||
{
|
||||
return windowController;
|
||||
@@ -245,6 +252,9 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
- (void)dropFiles:(NSArray *)filenames forceOpen:(BOOL)force
|
||||
{
|
||||
filenames = normalizeFilenames(filenames);
|
||||
ASLogInfo(@"filenames=%@ force=%d", filenames, force);
|
||||
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
// Default to opening in tabs if layout is invalid or set to "windows".
|
||||
@@ -252,6 +262,10 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
if (layout < 0 || layout > MMLayoutTabs)
|
||||
layout = MMLayoutTabs;
|
||||
|
||||
BOOL splitVert = [ud boolForKey:MMVerticalSplitKey];
|
||||
if (splitVert && MMLayoutHorizontalSplit == layout)
|
||||
layout = MMLayoutVerticalSplit;
|
||||
|
||||
NSDictionary *args = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithInt:layout], @"layout",
|
||||
filenames, @"filenames",
|
||||
@@ -263,6 +277,9 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
- (void)file:(NSString *)filename draggedToTabAtIndex:(NSUInteger)tabIndex
|
||||
{
|
||||
filename = normalizeFilename(filename);
|
||||
ASLogInfo(@"filename=%@ index=%d", filename, tabIndex);
|
||||
|
||||
NSString *fnEsc = [filename stringByEscapingSpecialFilenameCharacters];
|
||||
NSString *input = [NSString stringWithFormat:@"<C-\\><C-N>:silent "
|
||||
"tabnext %d |"
|
||||
@@ -272,6 +289,9 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
- (void)filesDraggedToTabBar:(NSArray *)filenames
|
||||
{
|
||||
filenames = normalizeFilenames(filenames);
|
||||
ASLogInfo(@"%@", filenames);
|
||||
|
||||
NSUInteger i, count = [filenames count];
|
||||
NSMutableString *input = [NSMutableString stringWithString:@"<C-\\><C-N>"
|
||||
":silent! tabnext 9999"];
|
||||
@@ -286,6 +306,7 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
- (void)dropString:(NSString *)string
|
||||
{
|
||||
ASLogInfo(@"%@", string);
|
||||
int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1;
|
||||
if (len > 0) {
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
@@ -301,6 +322,8 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
{
|
||||
if (!args) return;
|
||||
|
||||
ASLogDebug(@"args=%@", args);
|
||||
|
||||
[self sendMessage:OpenWithArgumentsMsgID data:[args dictionaryAsData]];
|
||||
|
||||
// HACK! Fool findUnusedEditor into thinking that this controller is not
|
||||
@@ -317,27 +340,17 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
- (void)sendMessage:(int)msgid data:(NSData *)data
|
||||
{
|
||||
//NSLog(@"sendMessage:%s (isInitialized=%d inProcessCommandQueue=%d)",
|
||||
// MessageStrings[msgid], isInitialized, inProcessCommandQueue);
|
||||
ASLogDebug(@"msg=%s (isInitialized=%d)",
|
||||
MessageStrings[msgid], isInitialized);
|
||||
|
||||
if (!isInitialized) return;
|
||||
|
||||
if (inProcessCommandQueue) {
|
||||
//NSLog(@"In process command queue; delaying message send.");
|
||||
[sendQueue addObject:[NSNumber numberWithInt:msgid]];
|
||||
if (data)
|
||||
[sendQueue addObject:data];
|
||||
else
|
||||
[sendQueue addObject:[NSNull null]];
|
||||
return;
|
||||
}
|
||||
|
||||
@try {
|
||||
[backendProxy processInput:msgid data:data];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
//NSLog(@"%@ %s Exception caught during DO call: %@",
|
||||
// [self className], _cmd, e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"processInput:data: failed: pid=%d id=%d msg=%s reason=%@",
|
||||
pid, identifier, MessageStrings[msgid], ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,7 +362,10 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
// ball forever. In almost all circumstances sendMessage:data: should be
|
||||
// used instead.
|
||||
|
||||
if (!isInitialized || inProcessCommandQueue)
|
||||
ASLogDebug(@"msg=%s (isInitialized=%d)",
|
||||
MessageStrings[msgid], isInitialized);
|
||||
|
||||
if (!isInitialized)
|
||||
return NO;
|
||||
|
||||
if (timeout < 0) timeout = 0;
|
||||
@@ -363,8 +379,10 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
@try {
|
||||
[backendProxy processInput:msgid data:data];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
@catch (NSException *ex) {
|
||||
sendOk = NO;
|
||||
ASLogNotice(@"processInput:data: failed: pid=%d id=%d msg=%s reason=%@",
|
||||
pid, identifier, MessageStrings[msgid], ex);
|
||||
}
|
||||
@finally {
|
||||
[conn setRequestTimeout:oldTimeout];
|
||||
@@ -375,6 +393,8 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
- (void)addVimInput:(NSString *)string
|
||||
{
|
||||
ASLogDebug(@"%@", string);
|
||||
|
||||
// This is a very general method of adding input to the Vim process. It is
|
||||
// basically the same as calling remote_send() on the process (see
|
||||
// ':h remote_send').
|
||||
@@ -390,20 +410,28 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
@try {
|
||||
eval = [backendProxy evaluateExpression:expr];
|
||||
ASLogDebug(@"eval(%@)=%@", expr, eval);
|
||||
}
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"evaluateExpression: failed: pid=%d id=%d reason=%@",
|
||||
pid, identifier, ex);
|
||||
}
|
||||
@catch (NSException *ex) { /* do nothing */ }
|
||||
|
||||
return eval;
|
||||
}
|
||||
|
||||
- (id)evaluateVimExpressionCocoa:(NSString *)expr errorString:(NSString **)errstr
|
||||
- (id)evaluateVimExpressionCocoa:(NSString *)expr
|
||||
errorString:(NSString **)errstr
|
||||
{
|
||||
id eval = nil;
|
||||
|
||||
@try {
|
||||
eval = [backendProxy evaluateExpressionCocoa:expr
|
||||
errorString:errstr];
|
||||
ASLogDebug(@"eval(%@)=%@", expr, eval);
|
||||
} @catch (NSException *ex) {
|
||||
ASLogNotice(@"evaluateExpressionCocoa: failed: pid=%d id=%d reason=%@",
|
||||
pid, identifier, ex);
|
||||
*errstr = [ex reason];
|
||||
}
|
||||
|
||||
@@ -419,6 +447,9 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
// Remove any delayed calls made on this object.
|
||||
[NSObject cancelPreviousPerformRequestsWithTarget:self];
|
||||
|
||||
isInitialized = NO;
|
||||
[toolbar setDelegate:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
@@ -427,204 +458,19 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
[windowController cleanup];
|
||||
}
|
||||
|
||||
- (oneway void)showSavePanelWithAttributes:(in bycopy NSDictionary *)attr
|
||||
- (void)processInputQueue:(NSArray *)queue
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
BOOL inDefaultMode = [[[NSRunLoop currentRunLoop] currentMode]
|
||||
isEqual:NSDefaultRunLoopMode];
|
||||
if (!inDefaultMode) {
|
||||
// Delay call until run loop is in default mode.
|
||||
[self performSelectorOnMainThread:
|
||||
@selector(showSavePanelWithAttributes:)
|
||||
withObject:attr
|
||||
waitUntilDone:NO
|
||||
modes:[NSArray arrayWithObject:
|
||||
NSDefaultRunLoopMode]];
|
||||
return;
|
||||
// NOTE: This method must not raise any exceptions (see comment in the
|
||||
// calling method).
|
||||
@try {
|
||||
[self doProcessInputQueue:queue];
|
||||
[windowController processInputQueueDidFinish];
|
||||
}
|
||||
|
||||
NSString *dir = [attr objectForKey:@"dir"];
|
||||
BOOL saving = [[attr objectForKey:@"saving"] boolValue];
|
||||
|
||||
if (!dir) {
|
||||
// 'dir == nil' means: set dir to the pwd of the Vim process, or let
|
||||
// open dialog decide (depending on the below user default).
|
||||
BOOL trackPwd = [[NSUserDefaults standardUserDefaults]
|
||||
boolForKey:MMDialogsTrackPwdKey];
|
||||
if (trackPwd)
|
||||
dir = [vimState objectForKey:@"pwd"];
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"Exception: pid=%d id=%d reason=%@", pid, identifier, ex);
|
||||
}
|
||||
|
||||
if (saving) {
|
||||
[[NSSavePanel savePanel] beginSheetForDirectory:dir file:nil
|
||||
modalForWindow:[windowController window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(savePanelDidEnd:code:context:)
|
||||
contextInfo:NULL];
|
||||
} else {
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
[panel setAllowsMultipleSelection:NO];
|
||||
[panel setAccessoryView:openPanelAccessoryView()];
|
||||
|
||||
[panel beginSheetForDirectory:dir file:nil types:nil
|
||||
modalForWindow:[windowController window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(savePanelDidEnd:code:context:)
|
||||
contextInfo:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
- (oneway void)presentDialogWithAttributes:(in bycopy NSDictionary *)attr
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
BOOL inDefaultMode = [[[NSRunLoop currentRunLoop] currentMode]
|
||||
isEqual:NSDefaultRunLoopMode];
|
||||
if (!inDefaultMode) {
|
||||
// Delay call until run loop is in default mode.
|
||||
[self performSelectorOnMainThread:
|
||||
@selector(presentDialogWithAttributes:)
|
||||
withObject:attr
|
||||
waitUntilDone:NO
|
||||
modes:[NSArray arrayWithObject:
|
||||
NSDefaultRunLoopMode]];
|
||||
return;
|
||||
}
|
||||
|
||||
NSArray *buttonTitles = [attr objectForKey:@"buttonTitles"];
|
||||
if (!(buttonTitles && [buttonTitles count])) return;
|
||||
|
||||
int style = [[attr objectForKey:@"alertStyle"] intValue];
|
||||
NSString *message = [attr objectForKey:@"messageText"];
|
||||
NSString *text = [attr objectForKey:@"informativeText"];
|
||||
NSString *textFieldString = [attr objectForKey:@"textFieldString"];
|
||||
MMAlert *alert = [[MMAlert alloc] init];
|
||||
|
||||
// NOTE! This has to be done before setting the informative text.
|
||||
if (textFieldString)
|
||||
[alert setTextFieldString:textFieldString];
|
||||
|
||||
[alert setAlertStyle:style];
|
||||
|
||||
if (message) {
|
||||
[alert setMessageText:message];
|
||||
} else {
|
||||
// If no message text is specified 'Alert' is used, which we don't
|
||||
// want, so set an empty string as message text.
|
||||
[alert setMessageText:@""];
|
||||
}
|
||||
|
||||
if (text) {
|
||||
[alert setInformativeText:text];
|
||||
} else if (textFieldString) {
|
||||
// Make sure there is always room for the input text field.
|
||||
[alert setInformativeText:@""];
|
||||
}
|
||||
|
||||
unsigned i, count = [buttonTitles count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSString *title = [buttonTitles objectAtIndex:i];
|
||||
// NOTE: The title of the button may contain the character '&' to
|
||||
// indicate that the following letter should be the key equivalent
|
||||
// associated with the button. Extract this letter and lowercase it.
|
||||
NSString *keyEquivalent = nil;
|
||||
NSRange hotkeyRange = [title rangeOfString:@"&"];
|
||||
if (NSNotFound != hotkeyRange.location) {
|
||||
if ([title length] > NSMaxRange(hotkeyRange)) {
|
||||
NSRange keyEquivRange = NSMakeRange(hotkeyRange.location+1, 1);
|
||||
keyEquivalent = [[title substringWithRange:keyEquivRange]
|
||||
lowercaseString];
|
||||
}
|
||||
|
||||
NSMutableString *string = [NSMutableString stringWithString:title];
|
||||
[string deleteCharactersInRange:hotkeyRange];
|
||||
title = string;
|
||||
}
|
||||
|
||||
[alert addButtonWithTitle:title];
|
||||
|
||||
// Set key equivalent for the button, but only if NSAlert hasn't
|
||||
// already done so. (Check the documentation for
|
||||
// - [NSAlert addButtonWithTitle:] to see what key equivalents are
|
||||
// automatically assigned.)
|
||||
NSButton *btn = [[alert buttons] lastObject];
|
||||
if ([[btn keyEquivalent] length] == 0 && keyEquivalent) {
|
||||
[btn setKeyEquivalent:keyEquivalent];
|
||||
}
|
||||
}
|
||||
|
||||
[alert beginSheetModalForWindow:[windowController window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(alertDidEnd:code:context:)
|
||||
contextInfo:NULL];
|
||||
|
||||
[alert release];
|
||||
}
|
||||
|
||||
- (oneway void)processCommandQueue:(in bycopy NSArray *)queue
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
if (inProcessCommandQueue) {
|
||||
// NOTE! If a synchronous DO call is made during
|
||||
// doProcessCommandQueue: below it may happen that this method is
|
||||
// called a second time while the synchronous message is waiting for a
|
||||
// reply (could also happen if doProcessCommandQueue: enters a modal
|
||||
// loop, see comment below). Since this method cannot be considered
|
||||
// reentrant, we queue the input and return immediately.
|
||||
//
|
||||
// If doProcessCommandQueue: enters a modal loop (happens e.g. on
|
||||
// ShowPopupMenuMsgID) then the receiveQueue could grow to become
|
||||
// arbitrarily large because DO calls still get processed. To avoid
|
||||
// this we set a cap on the size of the queue and simply clear it if it
|
||||
// becomes too large. (That is messages will be dropped and hence Vim
|
||||
// and MacVim will at least temporarily be out of sync.)
|
||||
if ([receiveQueue count] >= MMReceiveQueueCap)
|
||||
[receiveQueue removeAllObjects];
|
||||
|
||||
[receiveQueue addObject:queue];
|
||||
return;
|
||||
}
|
||||
|
||||
inProcessCommandQueue = YES;
|
||||
[self doProcessCommandQueue:queue];
|
||||
|
||||
int i;
|
||||
for (i = 0; i < [receiveQueue count]; ++i) {
|
||||
// Note that doProcessCommandQueue: may cause the receiveQueue to grow
|
||||
// or get cleared (due to cap being hit). Make sure to retain the item
|
||||
// to process or it may get released from under us.
|
||||
NSArray *q = [[receiveQueue objectAtIndex:i] retain];
|
||||
[self doProcessCommandQueue:q];
|
||||
[q release];
|
||||
}
|
||||
|
||||
// We assume that the remaining calls make no synchronous DO calls. If
|
||||
// that did happen anyway, the command queue could get processed out of
|
||||
// order.
|
||||
|
||||
// See comment below why this is called here and not later.
|
||||
[windowController processCommandQueueDidFinish];
|
||||
|
||||
// NOTE: Ensure that no calls are made after this "if" clause that may call
|
||||
// sendMessage::. If this happens anyway, such messages will be put on the
|
||||
// send queue and then the queue will not be flushed until the next time
|
||||
// this method is called.
|
||||
if ([sendQueue count] > 0) {
|
||||
@try {
|
||||
[backendProxy processInputAndData:sendQueue];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
// Connection timed out, just ignore this.
|
||||
//NSLog(@"WARNING! Connection timed out in %s", _cmd);
|
||||
}
|
||||
|
||||
[sendQueue removeAllObjects];
|
||||
}
|
||||
|
||||
[receiveQueue removeAllObjects];
|
||||
inProcessCommandQueue = NO;
|
||||
}
|
||||
|
||||
- (NSToolbarItem *)toolbar:(NSToolbar *)theToolbar
|
||||
@@ -633,7 +479,7 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
{
|
||||
NSToolbarItem *item = [toolbarItemDict objectForKey:itemId];
|
||||
if (!item) {
|
||||
NSLog(@"WARNING: No toolbar item with id '%@'", itemId);
|
||||
ASLogWarn(@"No toolbar item with id '%@'", itemId);
|
||||
}
|
||||
|
||||
return item;
|
||||
@@ -655,76 +501,63 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
@implementation MMVimController (Private)
|
||||
|
||||
- (void)doProcessCommandQueue:(NSArray *)queue
|
||||
- (void)doProcessInputQueue:(NSArray *)queue
|
||||
{
|
||||
NSMutableArray *delayQueue = nil;
|
||||
|
||||
@try {
|
||||
unsigned i, count = [queue count];
|
||||
if (count % 2) {
|
||||
NSLog(@"WARNING: Uneven number of components (%d) in command "
|
||||
"queue. Skipping...", count);
|
||||
return;
|
||||
}
|
||||
|
||||
//NSLog(@"======== %s BEGIN ========", _cmd);
|
||||
for (i = 0; i < count; i += 2) {
|
||||
NSData *value = [queue objectAtIndex:i];
|
||||
NSData *data = [queue objectAtIndex:i+1];
|
||||
|
||||
int msgid = *((int*)[value bytes]);
|
||||
//NSLog(@"%s%s", _cmd, MessageStrings[msgid]);
|
||||
|
||||
BOOL inDefaultMode = [[[NSRunLoop currentRunLoop] currentMode]
|
||||
isEqual:NSDefaultRunLoopMode];
|
||||
if (!inDefaultMode && isUnsafeMessage(msgid)) {
|
||||
// NOTE: Because we may be listening to DO messages in "event
|
||||
// tracking mode" we have to take extra care when doing things
|
||||
// like releasing view items (and other Cocoa objects).
|
||||
// Messages that may be potentially "unsafe" are delayed until
|
||||
// the run loop is back to default mode at which time they are
|
||||
// safe to call again.
|
||||
// A problem with this approach is that it is hard to
|
||||
// classify which messages are unsafe. As a rule of thumb, if
|
||||
// a message may release an object used by the Cocoa framework
|
||||
// (e.g. views) then the message should be considered unsafe.
|
||||
// Delaying messages may have undesired side-effects since it
|
||||
// means that messages may not be processed in the order Vim
|
||||
// sent them, so beware.
|
||||
if (!delayQueue)
|
||||
delayQueue = [NSMutableArray array];
|
||||
|
||||
//NSLog(@"Adding unsafe message '%s' to delay queue (mode=%@)",
|
||||
// MessageStrings[msgid],
|
||||
// [[NSRunLoop currentRunLoop] currentMode]);
|
||||
[delayQueue addObject:value];
|
||||
[delayQueue addObject:data];
|
||||
} else {
|
||||
[self handleMessage:msgid data:data];
|
||||
}
|
||||
}
|
||||
//NSLog(@"======== %s END ========", _cmd);
|
||||
unsigned i, count = [queue count];
|
||||
if (count % 2) {
|
||||
ASLogWarn(@"Uneven number of components (%d) in command queue. "
|
||||
"Skipping...", count);
|
||||
return;
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught whilst processing command queue: %@", e);
|
||||
|
||||
for (i = 0; i < count; i += 2) {
|
||||
NSData *value = [queue objectAtIndex:i];
|
||||
NSData *data = [queue objectAtIndex:i+1];
|
||||
|
||||
int msgid = *((int*)[value bytes]);
|
||||
|
||||
BOOL inDefaultMode = [[[NSRunLoop currentRunLoop] currentMode]
|
||||
isEqual:NSDefaultRunLoopMode];
|
||||
if (!inDefaultMode && isUnsafeMessage(msgid)) {
|
||||
// NOTE: Because we may be listening to DO messages in "event
|
||||
// tracking mode" we have to take extra care when doing things
|
||||
// like releasing view items (and other Cocoa objects).
|
||||
// Messages that may be potentially "unsafe" are delayed until
|
||||
// the run loop is back to default mode at which time they are
|
||||
// safe to call again.
|
||||
// A problem with this approach is that it is hard to
|
||||
// classify which messages are unsafe. As a rule of thumb, if
|
||||
// a message may release an object used by the Cocoa framework
|
||||
// (e.g. views) then the message should be considered unsafe.
|
||||
// Delaying messages may have undesired side-effects since it
|
||||
// means that messages may not be processed in the order Vim
|
||||
// sent them, so beware.
|
||||
if (!delayQueue)
|
||||
delayQueue = [NSMutableArray array];
|
||||
|
||||
ASLogDebug(@"Adding unsafe message '%s' to delay queue (mode=%@)",
|
||||
MessageStrings[msgid],
|
||||
[[NSRunLoop currentRunLoop] currentMode]);
|
||||
[delayQueue addObject:value];
|
||||
[delayQueue addObject:data];
|
||||
} else {
|
||||
[self handleMessage:msgid data:data];
|
||||
}
|
||||
}
|
||||
|
||||
if (delayQueue) {
|
||||
//NSLog(@" Flushing delay queue (%d items)", [delayQueue count]/2);
|
||||
[self performSelectorOnMainThread:@selector(processCommandQueue:)
|
||||
withObject:delayQueue
|
||||
waitUntilDone:NO
|
||||
modes:[NSArray arrayWithObject:
|
||||
NSDefaultRunLoopMode]];
|
||||
ASLogDebug(@" Flushing delay queue (%d items)",
|
||||
[delayQueue count]/2);
|
||||
[self performSelector:@selector(processInputQueue:)
|
||||
withObject:delayQueue
|
||||
afterDelay:0];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleMessage:(int)msgid data:(NSData *)data
|
||||
{
|
||||
//if (msgid != AddMenuMsgID && msgid != AddMenuItemMsgID &&
|
||||
// msgid != EnableMenuItemMsgID)
|
||||
// NSLog(@"%@ %s%s", [self className], _cmd, MessageStrings[msgid]);
|
||||
|
||||
if (OpenWindowMsgID == msgid) {
|
||||
[windowController openWindow];
|
||||
|
||||
@@ -738,7 +571,6 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
#if 0 // NOTE: Tab selection is done inside updateTabsWithData:.
|
||||
const void *bytes = [data bytes];
|
||||
int idx = *((int*)bytes);
|
||||
//NSLog(@"Selecting tab with index %d", idx);
|
||||
[windowController selectTabWithIndex:idx];
|
||||
#endif
|
||||
} else if (UpdateTabBarMsgID == msgid) {
|
||||
@@ -911,12 +743,10 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
NSDictionary *attrs = [NSDictionary dictionaryWithData:data];
|
||||
|
||||
// The popup menu enters a modal loop so delay this call so that we
|
||||
// don't block inside processCommandQueue:.
|
||||
[self performSelectorOnMainThread:@selector(popupMenuWithAttributes:)
|
||||
withObject:attrs
|
||||
waitUntilDone:NO
|
||||
modes:[NSArray arrayWithObject:
|
||||
NSDefaultRunLoopMode]];
|
||||
// don't block inside processInputQueue:.
|
||||
[self performSelector:@selector(popupMenuWithAttributes:)
|
||||
withObject:attrs
|
||||
afterDelay:0];
|
||||
} else if (SetMouseShapeMsgID == msgid) {
|
||||
const void *bytes = [data bytes];
|
||||
int shape = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -928,7 +758,6 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
[windowController adjustLinespace:linespace];
|
||||
} else if (ActivateMsgID == msgid) {
|
||||
//NSLog(@"ActivateMsgID");
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
[[windowController window] makeKeyAndOrderFront:self];
|
||||
} else if (SetServerNameMsgID == msgid) {
|
||||
@@ -977,10 +806,26 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
showWithText:[dict objectForKey:@"text"]
|
||||
flags:[[dict objectForKey:@"flags"] intValue]];
|
||||
}
|
||||
} else if (ActivateKeyScriptMsgID == msgid) {
|
||||
[[[windowController vimView] textView] activateIm:YES];
|
||||
} else if (DeactivateKeyScriptMsgID == msgid) {
|
||||
[[[windowController vimView] textView] activateIm:NO];
|
||||
} else if (EnableImControlMsgID == msgid) {
|
||||
[[[windowController vimView] textView] setImControl:YES];
|
||||
} else if (DisableImControlMsgID == msgid) {
|
||||
[[[windowController vimView] textView] setImControl:NO];
|
||||
} else if (BrowseForFileMsgID == msgid) {
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithData:data];
|
||||
if (dict)
|
||||
[self handleBrowseForFile:dict];
|
||||
} else if (ShowDialogMsgID == msgid) {
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithData:data];
|
||||
if (dict)
|
||||
[self handleShowDialog:dict];
|
||||
// IMPORTANT: When adding a new message, make sure to update
|
||||
// isUnsafeMessage() if necessary!
|
||||
} else {
|
||||
NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid);
|
||||
ASLogWarn(@"Unknown message received (msgid=%d)", msgid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -988,6 +833,14 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
context:(void *)context
|
||||
{
|
||||
NSString *path = (code == NSOKButton) ? [panel filename] : nil;
|
||||
ASLogDebug(@"Open/save panel path=%@", path);
|
||||
|
||||
// NOTE! This causes the sheet animation to run its course BEFORE the rest
|
||||
// of this function is executed. If we do not wait for the sheet to
|
||||
// disappear before continuing it can happen that the controller is
|
||||
// released from under us (i.e. we'll crash and burn) because this
|
||||
// animation is otherwise performed in the default run loop mode!
|
||||
[panel orderOut:self];
|
||||
|
||||
// NOTE! setDialogReturn: is a synchronous call so set a proper timeout to
|
||||
// avoid waiting forever for it to finish. We make this a synchronous call
|
||||
@@ -1006,8 +859,8 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
[[NSDocumentController sharedDocumentController]
|
||||
noteNewRecentFilePath:path];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught in %s %@", _cmd, e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"Exception: pid=%d id=%d reason=%@", pid, identifier, ex);
|
||||
}
|
||||
@finally {
|
||||
[conn setRequestTimeout:oldTimeout];
|
||||
@@ -1027,11 +880,21 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
ret = [NSArray arrayWithObject:[NSNumber numberWithInt:code]];
|
||||
}
|
||||
|
||||
ASLogDebug(@"Alert return=%@", ret);
|
||||
|
||||
// NOTE! This causes the sheet animation to run its course BEFORE the rest
|
||||
// of this function is executed. If we do not wait for the sheet to
|
||||
// disappear before continuing it can happen that the controller is
|
||||
// released from under us (i.e. we'll crash and burn) because this
|
||||
// animation is otherwise performed in the default run loop mode!
|
||||
[[alert window] orderOut:self];
|
||||
|
||||
@try {
|
||||
[backendProxy setDialogReturn:ret];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught in %s %@", _cmd, e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"setDialogReturn: failed: pid=%d id=%d reason=%@",
|
||||
pid, identifier, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1191,8 +1054,8 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
NSMenu *parent = [self parentMenuForDescriptor:desc];
|
||||
if (!parent) {
|
||||
NSLog(@"WARNING: Menu item '%@' has no parent",
|
||||
[desc componentsJoinedByString:@"->"]);
|
||||
ASLogWarn(@"Menu item '%@' has no parent",
|
||||
[desc componentsJoinedByString:@"->"]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1254,8 +1117,8 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
NSMenuItem *item = [self menuItemForDescriptor:desc];
|
||||
if (!item) {
|
||||
NSLog(@"Failed to remove menu item, descriptor not found: %@",
|
||||
[desc componentsJoinedByString:@"->"]);
|
||||
ASLogWarn(@"Failed to remove menu item, descriptor not found: %@",
|
||||
[desc componentsJoinedByString:@"->"]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1278,9 +1141,6 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
{
|
||||
if (!(desc && [desc count] > 0)) return;
|
||||
|
||||
/*NSLog(@"%sable item %@", on ? "En" : "Dis",
|
||||
[desc componentsJoinedByString:@"->"]);*/
|
||||
|
||||
NSString *rootName = [desc objectAtIndex:0];
|
||||
if ([rootName isEqual:@"ToolBar"]) {
|
||||
if (toolbar && [desc count] == 2) {
|
||||
@@ -1320,10 +1180,10 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
img = nil;
|
||||
}
|
||||
if (!img) {
|
||||
NSLog(@"WARNING: Could not find image with name '%@' to use as toolbar"
|
||||
" image for identifier '%@';"
|
||||
" using default toolbar icon '%@' instead.",
|
||||
icon, title, MMDefaultToolbarImageName);
|
||||
ASLogNotice(@"Could not find image with name '%@' to use as toolbar"
|
||||
" image for identifier '%@';"
|
||||
" using default toolbar icon '%@' instead.",
|
||||
icon, title, MMDefaultToolbarImageName);
|
||||
|
||||
img = [NSImage imageNamed:MMDefaultToolbarImageName];
|
||||
}
|
||||
@@ -1410,12 +1270,14 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
- (void)connectionDidDie:(NSNotification *)notification
|
||||
{
|
||||
//NSLog(@"%@ %s%@", [self className], _cmd, notification);
|
||||
ASLogDebug(@"%@", notification);
|
||||
[self scheduleClose];
|
||||
}
|
||||
|
||||
- (void)scheduleClose
|
||||
{
|
||||
ASLogDebug(@"pid=%d id=%d", pid, identifier);
|
||||
|
||||
// NOTE! This message can arrive at pretty much anytime, e.g. while
|
||||
// the run loop is the 'event tracking' mode. This means that Cocoa may
|
||||
// well be in the middle of processing some message while this message is
|
||||
@@ -1424,21 +1286,153 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
// following call ensures that the vim controller is not released until the
|
||||
// run loop is back in the 'default' mode.
|
||||
[[MMAppController sharedInstance]
|
||||
performSelectorOnMainThread:@selector(removeVimController:)
|
||||
withObject:self
|
||||
waitUntilDone:NO
|
||||
modes:[NSArray arrayWithObject:
|
||||
NSDefaultRunLoopMode]];
|
||||
performSelector:@selector(removeVimController:)
|
||||
withObject:self
|
||||
afterDelay:0];
|
||||
}
|
||||
|
||||
// NSSavePanel delegate
|
||||
- (void)panel:(id)sender willExpand:(BOOL)expanding
|
||||
{
|
||||
// Show or hide the "show hidden files" button
|
||||
if (expanding) {
|
||||
[sender setAccessoryView:showHiddenFilesView()];
|
||||
} else {
|
||||
[sender setShowsHiddenFiles:NO];
|
||||
[sender setAccessoryView:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleBrowseForFile:(NSDictionary *)attr
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
NSString *dir = [attr objectForKey:@"dir"];
|
||||
BOOL saving = [[attr objectForKey:@"saving"] boolValue];
|
||||
|
||||
if (!dir) {
|
||||
// 'dir == nil' means: set dir to the pwd of the Vim process, or let
|
||||
// open dialog decide (depending on the below user default).
|
||||
BOOL trackPwd = [[NSUserDefaults standardUserDefaults]
|
||||
boolForKey:MMDialogsTrackPwdKey];
|
||||
if (trackPwd)
|
||||
dir = [vimState objectForKey:@"pwd"];
|
||||
}
|
||||
|
||||
if (saving) {
|
||||
NSSavePanel *panel = [NSSavePanel savePanel];
|
||||
|
||||
// The delegate will be notified when the panel is expanded at which
|
||||
// time we may hide/show the "show hidden files" button (this button is
|
||||
// always visible for the open panel since it is always expanded).
|
||||
[panel setDelegate:self];
|
||||
if ([panel isExpanded])
|
||||
[panel setAccessoryView:showHiddenFilesView()];
|
||||
|
||||
[panel beginSheetForDirectory:dir file:nil
|
||||
modalForWindow:[windowController window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(savePanelDidEnd:code:context:)
|
||||
contextInfo:NULL];
|
||||
} else {
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
[panel setAllowsMultipleSelection:NO];
|
||||
[panel setAccessoryView:showHiddenFilesView()];
|
||||
|
||||
[panel beginSheetForDirectory:dir file:nil types:nil
|
||||
modalForWindow:[windowController window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(savePanelDidEnd:code:context:)
|
||||
contextInfo:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleShowDialog:(NSDictionary *)attr
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
NSArray *buttonTitles = [attr objectForKey:@"buttonTitles"];
|
||||
if (!(buttonTitles && [buttonTitles count])) return;
|
||||
|
||||
int style = [[attr objectForKey:@"alertStyle"] intValue];
|
||||
NSString *message = [attr objectForKey:@"messageText"];
|
||||
NSString *text = [attr objectForKey:@"informativeText"];
|
||||
NSString *textFieldString = [attr objectForKey:@"textFieldString"];
|
||||
MMAlert *alert = [[MMAlert alloc] init];
|
||||
|
||||
// NOTE! This has to be done before setting the informative text.
|
||||
if (textFieldString)
|
||||
[alert setTextFieldString:textFieldString];
|
||||
|
||||
[alert setAlertStyle:style];
|
||||
|
||||
if (message) {
|
||||
[alert setMessageText:message];
|
||||
} else {
|
||||
// If no message text is specified 'Alert' is used, which we don't
|
||||
// want, so set an empty string as message text.
|
||||
[alert setMessageText:@""];
|
||||
}
|
||||
|
||||
if (text) {
|
||||
[alert setInformativeText:text];
|
||||
} else if (textFieldString) {
|
||||
// Make sure there is always room for the input text field.
|
||||
[alert setInformativeText:@""];
|
||||
}
|
||||
|
||||
unsigned i, count = [buttonTitles count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSString *title = [buttonTitles objectAtIndex:i];
|
||||
// NOTE: The title of the button may contain the character '&' to
|
||||
// indicate that the following letter should be the key equivalent
|
||||
// associated with the button. Extract this letter and lowercase it.
|
||||
NSString *keyEquivalent = nil;
|
||||
NSRange hotkeyRange = [title rangeOfString:@"&"];
|
||||
if (NSNotFound != hotkeyRange.location) {
|
||||
if ([title length] > NSMaxRange(hotkeyRange)) {
|
||||
NSRange keyEquivRange = NSMakeRange(hotkeyRange.location+1, 1);
|
||||
keyEquivalent = [[title substringWithRange:keyEquivRange]
|
||||
lowercaseString];
|
||||
}
|
||||
|
||||
NSMutableString *string = [NSMutableString stringWithString:title];
|
||||
[string deleteCharactersInRange:hotkeyRange];
|
||||
title = string;
|
||||
}
|
||||
|
||||
[alert addButtonWithTitle:title];
|
||||
|
||||
// Set key equivalent for the button, but only if NSAlert hasn't
|
||||
// already done so. (Check the documentation for
|
||||
// - [NSAlert addButtonWithTitle:] to see what key equivalents are
|
||||
// automatically assigned.)
|
||||
NSButton *btn = [[alert buttons] lastObject];
|
||||
if ([[btn keyEquivalent] length] == 0 && keyEquivalent) {
|
||||
[btn setKeyEquivalent:keyEquivalent];
|
||||
}
|
||||
}
|
||||
|
||||
[alert beginSheetModalForWindow:[windowController window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(alertDidEnd:code:context:)
|
||||
contextInfo:NULL];
|
||||
|
||||
[alert release];
|
||||
}
|
||||
|
||||
|
||||
@end // MMVimController (Private)
|
||||
|
||||
|
||||
|
||||
|
||||
@implementation MMAlert
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
ASLogDebug(@"");
|
||||
|
||||
[textField release]; textField = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
@@ -1521,6 +1515,8 @@ isUnsafeMessage(int msgid)
|
||||
EnterFullscreenMsgID, // Modifies delegate of window controller
|
||||
LeaveFullscreenMsgID, // Modifies delegate of window controller
|
||||
CloseWindowMsgID, // See note below
|
||||
BrowseForFileMsgID, // Enters modal loop
|
||||
ShowDialogMsgID, // Enters modal loop
|
||||
};
|
||||
|
||||
// NOTE about CloseWindowMsgID: If this arrives at the same time as say
|
||||
|
||||
+6
-21
@@ -152,7 +152,7 @@ enum {
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
LOG_DEALLOC
|
||||
ASLogDebug(@"");
|
||||
|
||||
[tabBarControl release]; tabBarControl = nil;
|
||||
[tabView release]; tabView = nil;
|
||||
@@ -311,7 +311,7 @@ enum {
|
||||
forTabViewItem:tvi];
|
||||
break;
|
||||
default:
|
||||
NSLog(@"WARNING: Unknown tab info for index: %d", i);
|
||||
ASLogWarn(@"Unknown tab info for index: %d", i);
|
||||
}
|
||||
|
||||
[val release];
|
||||
@@ -326,7 +326,6 @@ enum {
|
||||
int i, count = [[self tabView] numberOfTabViewItems];
|
||||
for (i = count-1; i >= tabIdx; --i) {
|
||||
id tvi = [tabViewItems objectAtIndex:i];
|
||||
//NSLog(@"Removing tab with index %d", i);
|
||||
[[self tabView] removeTabViewItem:tvi];
|
||||
}
|
||||
vimTaskSelectedTab = NO;
|
||||
@@ -336,11 +335,9 @@ enum {
|
||||
|
||||
- (void)selectTabWithIndex:(int)idx
|
||||
{
|
||||
//NSLog(@"%s%d", _cmd, idx);
|
||||
|
||||
NSArray *tabViewItems = [[self tabBarControl] representedTabViewItems];
|
||||
if (idx < 0 || idx >= [tabViewItems count]) {
|
||||
NSLog(@"WARNING: No tab with index %d exists.", idx);
|
||||
ASLogWarn(@"No tab with index %d exists.", idx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -376,8 +373,6 @@ enum {
|
||||
|
||||
- (void)createScrollbarWithIdentifier:(long)ident type:(int)type
|
||||
{
|
||||
//NSLog(@"Create scroller %d of type %d", ident, type);
|
||||
|
||||
MMScroller *scroller = [[MMScroller alloc] initWithIdentifier:ident
|
||||
type:type];
|
||||
[scroller setTarget:self];
|
||||
@@ -390,8 +385,6 @@ enum {
|
||||
|
||||
- (BOOL)destroyScrollbarWithIdentifier:(long)ident
|
||||
{
|
||||
//NSLog(@"Destroy scroller %d", ident);
|
||||
|
||||
unsigned idx = 0;
|
||||
MMScroller *scroller = [self scrollbarForIdentifier:ident index:&idx];
|
||||
if (!scroller) return NO;
|
||||
@@ -410,8 +403,6 @@ enum {
|
||||
if (!scroller) return NO;
|
||||
|
||||
BOOL wasVisible = ![scroller isHidden];
|
||||
//NSLog(@"%s scroller %d (was %svisible)", visible ? "Show" : "Hide",
|
||||
// ident, wasVisible ? "" : "in");
|
||||
[scroller setHidden:!visible];
|
||||
|
||||
// If a scroller was hidden or shown then the vim view must resize. This
|
||||
@@ -423,8 +414,6 @@ enum {
|
||||
identifier:(long)ident
|
||||
{
|
||||
MMScroller *scroller = [self scrollbarForIdentifier:ident index:NULL];
|
||||
//NSLog(@"Set thumb value %.2f proportion %.2f for scroller %d",
|
||||
// val, prop, ident);
|
||||
[scroller setFloatValue:val knobProportion:prop];
|
||||
[scroller setEnabled:prop != 1.f];
|
||||
}
|
||||
@@ -449,8 +438,6 @@ enum {
|
||||
MMScroller *scroller = [self scrollbarForIdentifier:ident index:NULL];
|
||||
NSRange range = NSMakeRange(pos, len);
|
||||
if (!NSEqualRanges(range, [scroller range])) {
|
||||
//NSLog(@"Set range %@ for scroller %d",
|
||||
// NSStringFromRange(range), ident);
|
||||
[scroller setRange:range];
|
||||
// TODO! Should only do this once per update.
|
||||
|
||||
@@ -502,7 +489,6 @@ enum {
|
||||
// on the tab. Instead of letting the tab bar close the tab, we return NO
|
||||
// and pass a message on to Vim to let it handle the closing.
|
||||
int idx = [self representedIndexOfTabViewItem:tabViewItem];
|
||||
//NSLog(@"Closing tab with index %d", idx);
|
||||
NSData *data = [NSData dataWithBytes:&idx length:sizeof(int)];
|
||||
[vimController sendMessage:CloseTabMsgID data:data];
|
||||
|
||||
@@ -743,7 +729,6 @@ enum {
|
||||
rect.size.height = 0;
|
||||
}
|
||||
|
||||
//NSLog(@"set scroller #%d frame = %@", i, NSStringFromRect(rect));
|
||||
NSRect oldRect = [scroller frame];
|
||||
if (!NSEqualRects(oldRect, rect)) {
|
||||
[scroller setFrame:rect];
|
||||
@@ -856,9 +841,9 @@ enum {
|
||||
int msgid = [self inLiveResize] ? LiveResizeMsgID
|
||||
: SetTextDimensionsMsgID;
|
||||
|
||||
//NSLog(@"Notify Vim that text dimensions changed from %dx%d to %dx%d"
|
||||
// " (%s)", cols, rows, constrained[1], constrained[0],
|
||||
// MessageStrings[msgid]);
|
||||
ASLogDebug(@"Notify Vim that text dimensions changed from %dx%d to "
|
||||
"%dx%d (%s)", cols, rows, constrained[1], constrained[0],
|
||||
MessageStrings[msgid]);
|
||||
|
||||
[vimController sendMessage:msgid data:data];
|
||||
|
||||
|
||||
+12
-2
@@ -63,7 +63,7 @@
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
LOG_DEALLOC
|
||||
ASLogDebug(@"");
|
||||
|
||||
// TODO: Is there any reason why we would want the following call?
|
||||
//[tablineSeparator removeFromSuperviewWithoutNeedingDisplay];
|
||||
@@ -142,8 +142,18 @@
|
||||
|
||||
- (IBAction)zoom:(id)sender
|
||||
{
|
||||
NSScreen *screen = [self screen];
|
||||
if (!screen) {
|
||||
ASLogNotice(@"Window not on screen, zoom to main screen");
|
||||
screen = [NSScreen mainScreen];
|
||||
if (!screen) {
|
||||
ASLogNotice(@"No main screen, abort zoom");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
NSRect frame = [self frame];
|
||||
NSRect defaultFrame = [[self screen] visibleFrame];
|
||||
NSRect defaultFrame = [screen visibleFrame];
|
||||
defaultFrame = [[self delegate] windowWillUseStandardFrame:self
|
||||
defaultFrame:defaultFrame];
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
MMVimView *vimView;
|
||||
BOOL setupDone;
|
||||
BOOL shouldResizeVimView;
|
||||
int updateToolbarFlag;
|
||||
BOOL keepOnScreen;
|
||||
BOOL fullscreenEnabled;
|
||||
NSString *windowAutosaveKey;
|
||||
@@ -54,7 +55,7 @@
|
||||
- (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore;
|
||||
- (void)setFont:(NSFont *)font;
|
||||
- (void)setWideFont:(NSFont *)font;
|
||||
- (void)processCommandQueueDidFinish;
|
||||
- (void)processInputQueueDidFinish;
|
||||
- (void)showTabBar:(BOOL)on;
|
||||
- (void)showToolbar:(BOOL)on size:(int)size mode:(int)mode;
|
||||
- (void)setMouseShape:(int)shape;
|
||||
|
||||
+100
-48
@@ -81,6 +81,7 @@
|
||||
- (BOOL)askBackendForStarRegister:(NSPasteboard *)pb;
|
||||
- (void)hideTablineSeparator:(BOOL)hide;
|
||||
- (void)doFindNext:(BOOL)next;
|
||||
- (void)updateToolbar;
|
||||
@end
|
||||
|
||||
|
||||
@@ -121,9 +122,6 @@
|
||||
|
||||
- (id)initWithVimController:(MMVimController *)controller
|
||||
{
|
||||
#ifndef NSAppKitVersionNumber10_4 // needed for non-10.5 sdk
|
||||
# define NSAppKitVersionNumber10_4 824
|
||||
#endif
|
||||
unsigned styleMask = NSTitledWindowMask | NSClosableWindowMask
|
||||
| NSMiniaturizableWindowMask | NSResizableWindowMask
|
||||
| NSUnifiedTitleAndToolbarWindowMask;
|
||||
@@ -200,7 +198,7 @@
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
LOG_DEALLOC
|
||||
ASLogDebug(@"");
|
||||
|
||||
[decoratedWindow release]; decoratedWindow = nil;
|
||||
[windowAutosaveKey release]; windowAutosaveKey = nil;
|
||||
@@ -240,7 +238,7 @@
|
||||
|
||||
- (void)cleanup
|
||||
{
|
||||
//NSLog(@"%@ %s", [self className], _cmd);
|
||||
ASLogDebug(@"%@ %s", [self className], _cmd);
|
||||
|
||||
if (fullscreenEnabled) {
|
||||
// If we are closed while still in fullscreen, end fullscreen mode,
|
||||
@@ -301,13 +299,13 @@
|
||||
- (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
|
||||
isReply:(BOOL)reply
|
||||
{
|
||||
//NSLog(@"setTextDimensionsWithRows:%d columns:%d isLive:%d isReply:%d",
|
||||
// rows, cols, live, reply);
|
||||
ASLogDebug(@"setTextDimensionsWithRows:%d columns:%d isLive:%d isReply:%d",
|
||||
rows, cols, live, reply);
|
||||
|
||||
// NOTE: The only place where the (rows,columns) of the vim view are
|
||||
// modified is here and when entering/leaving full-screen. Setting these
|
||||
// values have no immediate effect, the actual resizing of the view is done
|
||||
// in processCommandQueueDidFinish.
|
||||
// in processInputQueueDidFinish.
|
||||
//
|
||||
// The 'live' flag indicates that this resize originated from a live
|
||||
// resize; it may very well happen that the view is no longer in live
|
||||
@@ -418,16 +416,16 @@
|
||||
[[vimView textView] setWideFont:font];
|
||||
}
|
||||
|
||||
- (void)processCommandQueueDidFinish
|
||||
- (void)processInputQueueDidFinish
|
||||
{
|
||||
// IMPORTANT! No synchronous DO calls are allowed in this method. They
|
||||
// may cause the command queue to get processed out of order.
|
||||
|
||||
// NOTE: Resizing is delayed until after all commands have been processed
|
||||
// since it often happens that more than one command will cause a resize.
|
||||
// If we were to immediately resize then the vim view size would jitter
|
||||
// (e.g. hiding/showing scrollbars often happens several time in one
|
||||
// update).
|
||||
// Also delay toggling the toolbar until after scrollbars otherwise
|
||||
// problems arise when showing toolbar and scrollbar at the same time, i.e.
|
||||
// on "set go+=rT".
|
||||
|
||||
if (shouldResizeVimView) {
|
||||
shouldResizeVimView = NO;
|
||||
@@ -448,6 +446,9 @@
|
||||
|
||||
keepOnScreen = NO;
|
||||
}
|
||||
|
||||
if (updateToolbarFlag != 0)
|
||||
[self updateToolbar];
|
||||
}
|
||||
|
||||
- (void)showTabBar:(BOOL)on
|
||||
@@ -481,21 +482,17 @@
|
||||
|
||||
[toolbar setSizeMode:size];
|
||||
[toolbar setDisplayMode:mode];
|
||||
[toolbar setVisible:on];
|
||||
|
||||
if (([decoratedWindow styleMask] & NSTexturedBackgroundWindowMask) == 0) {
|
||||
if (!on) {
|
||||
[self hideTablineSeparator:YES];
|
||||
} else {
|
||||
[self hideTablineSeparator:![[vimView tabBarControl] isHidden]];
|
||||
}
|
||||
} else {
|
||||
// Textured windows don't have a line below there title bar, so we
|
||||
// need the separator in this case as well. In fact, the only case
|
||||
// where we don't need the separator is when the tab bar control
|
||||
// is visible (because it brings its own separator).
|
||||
[self hideTablineSeparator:![[vimView tabBarControl] isHidden]];
|
||||
}
|
||||
// Positive flag shows toolbar, negative hides it.
|
||||
updateToolbarFlag = on ? 1 : -1;
|
||||
|
||||
// NOTE: If the window is not visible we must toggle the toolbar
|
||||
// immediately, otherwise "set go-=T" in .gvimrc will lead to the toolbar
|
||||
// showing its hide animation every time a new window is opened. (See
|
||||
// processInputQueueDidFinish for the reason why we need to delay toggling
|
||||
// the toolbar when the window is visible.)
|
||||
if (![decoratedWindow isVisible])
|
||||
[self updateToolbar];
|
||||
}
|
||||
|
||||
- (void)setMouseShape:(int)shape
|
||||
@@ -551,8 +548,8 @@
|
||||
[[vimView textView] constrainRows:&constrained[0] columns:&constrained[1]
|
||||
toSize:textViewSize];
|
||||
|
||||
//NSLog(@"End of live resize, notify Vim that text dimensions are %dx%d",
|
||||
// constrained[1], constrained[0]);
|
||||
ASLogDebug(@"End of live resize, notify Vim that text dimensions are %dx%d",
|
||||
constrained[1], constrained[0]);
|
||||
|
||||
NSData *data = [NSData dataWithBytes:constrained length:2*sizeof(int)];
|
||||
BOOL sendOk = [vimController sendMessageNow:SetTextDimensionsMsgID
|
||||
@@ -757,7 +754,19 @@
|
||||
|
||||
- (void)windowDidMove:(NSNotification *)notification
|
||||
{
|
||||
if (setupDone && windowAutosaveKey) {
|
||||
if (!setupDone)
|
||||
return;
|
||||
|
||||
if (fullscreenEnabled) {
|
||||
// HACK! The full-screen is not supposed to be able to be moved. If we
|
||||
// do get here while in full-screen something unexpected happened (e.g.
|
||||
// the full-screen window was on an external display that got
|
||||
// unplugged) and we handle this situation by leaving full-screen.
|
||||
[self leaveFullscreen];
|
||||
return;
|
||||
}
|
||||
|
||||
if (windowAutosaveKey) {
|
||||
NSRect frame = [decoratedWindow frame];
|
||||
NSPoint topLeft = { frame.origin.x, NSMaxY(frame) };
|
||||
NSString *topLeftString = NSStringFromPoint(topLeft);
|
||||
@@ -774,7 +783,11 @@
|
||||
// size in updateResizeConstraints since the screen's visible frame may
|
||||
// change at any time (dock could move, resolution could change, window
|
||||
// could be moved to another screen, ...).
|
||||
if (![win screen])
|
||||
return proposedFrameSize;
|
||||
|
||||
// NOTE: Not called in full-screen mode so use "visibleFrame" instead of
|
||||
// "frame".
|
||||
NSRect maxFrame = [self constrainFrame:[[win screen] visibleFrame]];
|
||||
|
||||
if (proposedFrameSize.width > maxFrame.size.width)
|
||||
@@ -891,24 +904,28 @@
|
||||
|
||||
NSRect newFrame = [decoratedWindow frameRectForContentRect:contentRect];
|
||||
|
||||
// Ensure that the window fits inside the visible part of the screen.
|
||||
NSRect maxFrame = [[decoratedWindow screen] visibleFrame];
|
||||
maxFrame = [self constrainFrame:maxFrame];
|
||||
if ([decoratedWindow screen]) {
|
||||
// Ensure that the window fits inside the visible part of the screen.
|
||||
// NOTE: Not called in full-screen mode so use "visibleFrame' instead
|
||||
// of "frame".
|
||||
NSRect maxFrame = [[decoratedWindow screen] visibleFrame];
|
||||
maxFrame = [self constrainFrame:maxFrame];
|
||||
|
||||
if (newFrame.size.width > maxFrame.size.width) {
|
||||
newFrame.size.width = maxFrame.size.width;
|
||||
newFrame.origin.x = maxFrame.origin.x;
|
||||
}
|
||||
if (newFrame.size.height > maxFrame.size.height) {
|
||||
newFrame.size.height = maxFrame.size.height;
|
||||
newFrame.origin.y = maxFrame.origin.y;
|
||||
}
|
||||
|
||||
if (onScreen) {
|
||||
if (newFrame.origin.y < maxFrame.origin.y)
|
||||
if (newFrame.size.width > maxFrame.size.width) {
|
||||
newFrame.size.width = maxFrame.size.width;
|
||||
newFrame.origin.x = maxFrame.origin.x;
|
||||
}
|
||||
if (newFrame.size.height > maxFrame.size.height) {
|
||||
newFrame.size.height = maxFrame.size.height;
|
||||
newFrame.origin.y = maxFrame.origin.y;
|
||||
if (NSMaxX(newFrame) > NSMaxX(maxFrame))
|
||||
newFrame.origin.x = NSMaxX(maxFrame) - newFrame.size.width;
|
||||
}
|
||||
|
||||
if (onScreen) {
|
||||
if (newFrame.origin.y < maxFrame.origin.y)
|
||||
newFrame.origin.y = maxFrame.origin.y;
|
||||
if (NSMaxX(newFrame) > NSMaxX(maxFrame))
|
||||
newFrame.origin.x = NSMaxX(maxFrame) - newFrame.size.width;
|
||||
}
|
||||
}
|
||||
|
||||
[decoratedWindow setFrame:newFrame display:YES];
|
||||
@@ -917,7 +934,15 @@
|
||||
- (NSSize)constrainContentSizeToScreenSize:(NSSize)contentSize
|
||||
{
|
||||
NSWindow *win = [self window];
|
||||
NSRect rect = [win contentRectForFrameRect:[[win screen] visibleFrame]];
|
||||
if (![win screen])
|
||||
return contentSize;
|
||||
|
||||
// NOTE: This may be called in both windowed and full-screen mode. The
|
||||
// "visibleFrame" method does not overlap menu and dock so should not be
|
||||
// used in full-screen.
|
||||
NSRect screenRect = fullscreenEnabled ? [[win screen] frame]
|
||||
: [[win screen] visibleFrame];
|
||||
NSRect rect = [win contentRectForFrameRect:screenRect];
|
||||
|
||||
if (contentSize.height > rect.size.height)
|
||||
contentSize.height = rect.size.height;
|
||||
@@ -970,8 +995,9 @@
|
||||
@try {
|
||||
reply = [backendProxy starRegisterToPasteboard:pb];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"WARNING: Caught exception in %s: \"%@\"", _cmd, e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"starRegisterToPasteboard: failed: pid=%d reason=%@",
|
||||
[vimController pid], ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1025,4 +1051,30 @@
|
||||
[vimController addVimInput:input];
|
||||
}
|
||||
|
||||
- (void)updateToolbar
|
||||
{
|
||||
NSToolbar *toolbar = [decoratedWindow toolbar];
|
||||
if (nil == toolbar || 0 == updateToolbarFlag) return;
|
||||
|
||||
// Positive flag shows toolbar, negative hides it.
|
||||
BOOL on = updateToolbarFlag > 0 ? YES : NO;
|
||||
[toolbar setVisible:on];
|
||||
|
||||
if (([decoratedWindow styleMask] & NSTexturedBackgroundWindowMask) == 0) {
|
||||
if (!on) {
|
||||
[self hideTablineSeparator:YES];
|
||||
} else {
|
||||
[self hideTablineSeparator:![[vimView tabBarControl] isHidden]];
|
||||
}
|
||||
} else {
|
||||
// Textured windows don't have a line below there title bar, so we
|
||||
// need the separator in this case as well. In fact, the only case
|
||||
// where we don't need the separator is when the tab bar control
|
||||
// is visible (because it brings its own separator).
|
||||
[self hideTablineSeparator:![[vimView tabBarControl] isHidden]];
|
||||
}
|
||||
|
||||
updateToolbarFlag = 0;
|
||||
}
|
||||
|
||||
@end // MMWindowController (Private)
|
||||
|
||||
+95
-22
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <asl.h>
|
||||
|
||||
|
||||
//
|
||||
@@ -33,7 +34,6 @@
|
||||
//
|
||||
@protocol MMBackendProtocol
|
||||
- (oneway void)processInput:(int)msgid data:(in bycopy NSData *)data;
|
||||
- (oneway void)processInputAndData:(in bycopy NSArray *)messages;
|
||||
- (oneway void)setDialogReturn:(in bycopy id)obj;
|
||||
- (NSString *)evaluateExpression:(in bycopy NSString *)expr;
|
||||
- (id)evaluateExpressionCocoa:(in bycopy NSString *)expr
|
||||
@@ -42,30 +42,23 @@
|
||||
- (oneway void)acknowledgeConnection;
|
||||
@end
|
||||
|
||||
//
|
||||
// This is the protocol MMVimController implements.
|
||||
//
|
||||
// Be very careful if you want to add methods to this protocol. Since DO
|
||||
// messages may arrive while Cocoa is in the middle of processing some other
|
||||
// message be sure to consider reentrancy issues. Look at processCommandQueue:
|
||||
// to see an example of how to deal with this.
|
||||
//
|
||||
@protocol MMFrontendProtocol
|
||||
- (oneway void)processCommandQueue:(in bycopy NSArray *)queue;
|
||||
- (oneway void)showSavePanelWithAttributes:(in bycopy NSDictionary *)attr;
|
||||
- (oneway void)presentDialogWithAttributes:(in bycopy NSDictionary *)attr;
|
||||
@end
|
||||
|
||||
|
||||
//
|
||||
// This is the protocol MMAppController implements.
|
||||
//
|
||||
// It handles connections between MacVim and Vim.
|
||||
// It handles connections between MacVim and Vim and communication from Vim to
|
||||
// MacVim.
|
||||
//
|
||||
// Do not add methods to this interface without a _very_ good reason (if
|
||||
// possible, instead add a new message to the *MsgID enum below and pass it via
|
||||
// processInput:forIdentifier). Methods should not modify the state directly
|
||||
// but should instead delay any potential modifications (see
|
||||
// connectBackend:pid: and processInput:forIdentifier:).
|
||||
//
|
||||
@protocol MMAppProtocol
|
||||
- (byref id <MMFrontendProtocol>)
|
||||
connectBackend:(byref in id <MMBackendProtocol>)backend
|
||||
pid:(int)pid;
|
||||
- (unsigned)connectBackend:(byref in id <MMBackendProtocol>)proxy pid:(int)pid;
|
||||
- (oneway void)processInput:(in bycopy NSArray *)queue
|
||||
forIdentifier:(unsigned)identifier;
|
||||
- (NSArray *)serverList;
|
||||
@end
|
||||
|
||||
@@ -109,10 +102,8 @@
|
||||
extern char *MessageStrings[];
|
||||
|
||||
enum {
|
||||
OpenWindowMsgID = 1,
|
||||
InsertTextMsgID,
|
||||
OpenWindowMsgID = 1, // NOTE: FIRST IN ENUM MUST BE 1
|
||||
KeyDownMsgID,
|
||||
CmdKeyMsgID,
|
||||
BatchDrawMsgID,
|
||||
SelectTabMsgID,
|
||||
CloseTabMsgID,
|
||||
@@ -177,6 +168,17 @@ enum {
|
||||
SetFullscreenColorMsgID,
|
||||
ShowFindReplaceDialogMsgID,
|
||||
FindReplaceMsgID,
|
||||
ActivateKeyScriptMsgID,
|
||||
DeactivateKeyScriptMsgID,
|
||||
EnableImControlMsgID,
|
||||
DisableImControlMsgID,
|
||||
ActivatedImMsgID,
|
||||
DeactivatedImMsgID,
|
||||
BrowseForFileMsgID,
|
||||
ShowDialogMsgID,
|
||||
NetBeansMsgID,
|
||||
SetMarkedTextMsgID,
|
||||
LastMsgID // NOTE: MUST BE LAST MESSAGE IN ENUM!
|
||||
};
|
||||
|
||||
|
||||
@@ -215,10 +217,25 @@ enum {
|
||||
MMTabInfoCount
|
||||
};
|
||||
|
||||
|
||||
// Create a string holding the labels of all messages in message queue for
|
||||
// debugging purposes (condense some messages since there may typically be LOTS
|
||||
// of them on a queue).
|
||||
NSString *debugStringForMessageQueue(NSArray *queue);
|
||||
|
||||
|
||||
// Shared user defaults (most user defaults are in Miscellaneous.h).
|
||||
// Contrary to the user defaults in Miscellaneous.h these defaults are not
|
||||
// intitialized to any default values. That is, unless the user sets them
|
||||
// these keys will not be present in the user default database.
|
||||
extern NSString *MMLogLevelKey;
|
||||
extern NSString *MMLogToStdErrKey;
|
||||
|
||||
// Argument used to stop MacVim from opening an empty window on startup
|
||||
// (techincally this is a user default but should not be used as such).
|
||||
extern NSString *MMNoWindowKey;
|
||||
|
||||
|
||||
// Vim pasteboard type (holds motion type + string)
|
||||
extern NSString *VimPBoardType;
|
||||
|
||||
@@ -275,3 +292,59 @@ typedef int NSInteger;
|
||||
typedef unsigned int NSUInteger;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef NSAppKitVersionNumber10_4 // Needed for pre-10.5 SDK
|
||||
# define NSAppKitVersionNumber10_4 824
|
||||
#endif
|
||||
|
||||
|
||||
// Logging related functions and macros.
|
||||
//
|
||||
// This is a very simplistic logging facility built on top of ASL. Two user
|
||||
// defaults allow for changing the local log filter level (MMLogLevel) and
|
||||
// whether logs should be sent to stderr (MMLogToStdErr). (These user defaults
|
||||
// are only checked during startup.) The default is to block level 6 (info)
|
||||
// and 7 (debug) logs and _not_ to send logs to stderr. Apart from this
|
||||
// "syslog" (see "man syslog") can be used to modify the ASL filters (it is
|
||||
// currently not possible to change the local filter at runtime). For example:
|
||||
// Enable all logs to reach the ASL database (by default 'debug' and 'info'
|
||||
// are filtered out, see "man syslogd"):
|
||||
// $ sudo syslog -c syslogd -d
|
||||
// Reset the ASL database filter:
|
||||
// $ sudo syslog -c syslogd off
|
||||
// Change the master filter to block logs less severe than errors:
|
||||
// $ sudo syslog -c 0 -e
|
||||
// Change per-process filter for running MacVim process to block logs less
|
||||
// severe than warnings:
|
||||
// $ syslog -c MacVim -w
|
||||
//
|
||||
// Note that there are four ASL filters:
|
||||
// 1) The ASL database filter (syslog -c syslogd ...)
|
||||
// 2) The master filter (syslog -c 0 ...)
|
||||
// 3) The per-process filter (syslog -c PID ...)
|
||||
// 4) The local filter (MMLogLevel)
|
||||
//
|
||||
// To view the logs, either use "Console.app" or the "syslog" command:
|
||||
// $ syslog -w | grep Vim
|
||||
// To get the logs to show up in Xcode enable the MMLogToStdErr user default.
|
||||
|
||||
extern int ASLogLevel;
|
||||
|
||||
void ASLInit();
|
||||
|
||||
#define ASLog(level, fmt, ...) \
|
||||
if (level <= ASLogLevel) { \
|
||||
asl_log(NULL, NULL, level, "%s@%d: %s", \
|
||||
__PRETTY_FUNCTION__, __LINE__, \
|
||||
[[NSString stringWithFormat:fmt, ##__VA_ARGS__] UTF8String]); \
|
||||
}
|
||||
|
||||
// Note: These macros are used like ASLogErr(@"text num=%d", 42). Objective-C
|
||||
// style specifiers (%@) are supported.
|
||||
#define ASLogCrit(fmt, ...) ASLog(ASL_LEVEL_CRIT, fmt, ##__VA_ARGS__)
|
||||
#define ASLogErr(fmt, ...) ASLog(ASL_LEVEL_ERR, fmt, ##__VA_ARGS__)
|
||||
#define ASLogWarn(fmt, ...) ASLog(ASL_LEVEL_WARNING, fmt, ##__VA_ARGS__)
|
||||
#define ASLogNotice(fmt, ...) ASLog(ASL_LEVEL_NOTICE, fmt, ##__VA_ARGS__)
|
||||
#define ASLogInfo(fmt, ...) ASLog(ASL_LEVEL_INFO, fmt, ##__VA_ARGS__)
|
||||
#define ASLogDebug(fmt, ...) ASLog(ASL_LEVEL_DEBUG, fmt, ##__VA_ARGS__)
|
||||
#define ASLogTmp(fmt, ...) ASLog(ASL_LEVEL_NOTICE, fmt, ##__VA_ARGS__)
|
||||
|
||||
+90
-3
@@ -13,13 +13,12 @@
|
||||
|
||||
#import "MacVim.h"
|
||||
|
||||
|
||||
char *MessageStrings[] =
|
||||
{
|
||||
"INVALID MESSAGE ID",
|
||||
"OpenWindowMsgID",
|
||||
"InsertTextMsgID",
|
||||
"KeyDownMsgID",
|
||||
"CmdKeyMsgID",
|
||||
"BatchDrawMsgID",
|
||||
"SelectTabMsgID",
|
||||
"CloseTabMsgID",
|
||||
@@ -29,7 +28,7 @@ char *MessageStrings[] =
|
||||
"ShowTabBarMsgID",
|
||||
"HideTabBarMsgID",
|
||||
"SetTextRowsMsgID",
|
||||
"SetTextColumsMsgID",
|
||||
"SetTextColumnsMsgID",
|
||||
"SetTextDimensionsMsgID",
|
||||
"LiveResizeMsgID",
|
||||
"SetTextDimensionsReplyMsgID",
|
||||
@@ -84,11 +83,25 @@ char *MessageStrings[] =
|
||||
"SetFullscreenColorMsgID",
|
||||
"ShowFindReplaceDialogMsgID",
|
||||
"FindReplaceMsgID",
|
||||
"ActivateKeyScriptMsgID",
|
||||
"DeactivateKeyScriptMsgID",
|
||||
"EnableImControlMsgID",
|
||||
"DisableImControlMsgID",
|
||||
"ActivatedImMsgID",
|
||||
"DeactivatedImMsgID",
|
||||
"BrowseForFileMsgID",
|
||||
"ShowDialogMsgID",
|
||||
"NetBeansMsgID",
|
||||
"SetMarkedTextMsgID",
|
||||
"END OF MESSAGE IDs" // NOTE: Must be last!
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
NSString *MMLogLevelKey = @"MMLogLevel";
|
||||
NSString *MMLogToStdErrKey = @"MMLogToStdErr";
|
||||
|
||||
// Argument used to stop MacVim from opening an empty window on startup
|
||||
// (techincally this is a user default but should not be used as such).
|
||||
NSString *MMNoWindowKey = @"MMNoWindow";
|
||||
@@ -96,6 +109,49 @@ NSString *MMNoWindowKey = @"MMNoWindow";
|
||||
// Vim pasteboard type (holds motion type + string)
|
||||
NSString *VimPBoardType = @"VimPBoardType";
|
||||
|
||||
int ASLogLevel = ASL_LEVEL_NOTICE;
|
||||
|
||||
|
||||
|
||||
// Create a string holding the labels of all messages in message queue for
|
||||
// debugging purposes (condense some messages since there may typically be LOTS
|
||||
// of them on a queue).
|
||||
NSString *
|
||||
debugStringForMessageQueue(NSArray *queue)
|
||||
{
|
||||
NSMutableString *s = [NSMutableString new];
|
||||
unsigned i, count = [queue count];
|
||||
int item = 0, menu = 0, enable = 0, remove = 0;
|
||||
int sets = 0, sett = 0, shows = 0, cres = 0, dess = 0;
|
||||
for (i = 0; i < count; i += 2) {
|
||||
NSData *value = [queue objectAtIndex:i];
|
||||
int msgid = *((int*)[value bytes]);
|
||||
if (msgid < 1 || msgid >= LastMsgID)
|
||||
continue;
|
||||
if (msgid == AddMenuItemMsgID) ++item;
|
||||
else if (msgid == AddMenuMsgID) ++menu;
|
||||
else if (msgid == EnableMenuItemMsgID) ++enable;
|
||||
else if (msgid == RemoveMenuItemMsgID) ++remove;
|
||||
else if (msgid == SetScrollbarPositionMsgID) ++sets;
|
||||
else if (msgid == SetScrollbarThumbMsgID) ++sett;
|
||||
else if (msgid == ShowScrollbarMsgID) ++shows;
|
||||
else if (msgid == CreateScrollbarMsgID) ++cres;
|
||||
else if (msgid == DestroyScrollbarMsgID) ++dess;
|
||||
else [s appendFormat:@"%s ", MessageStrings[msgid]];
|
||||
}
|
||||
if (item > 0) [s appendFormat:@"AddMenuItemMsgID(%d) ", item];
|
||||
if (menu > 0) [s appendFormat:@"AddMenuMsgID(%d) ", menu];
|
||||
if (enable > 0) [s appendFormat:@"EnableMenuItemMsgID(%d) ", enable];
|
||||
if (remove > 0) [s appendFormat:@"RemoveMenuItemMsgID(%d) ", remove];
|
||||
if (sets > 0) [s appendFormat:@"SetScrollbarPositionMsgID(%d) ", sets];
|
||||
if (sett > 0) [s appendFormat:@"SetScrollbarThumbMsgID(%d) ", sett];
|
||||
if (shows > 0) [s appendFormat:@"ShowScrollbarMsgID(%d) ", shows];
|
||||
if (cres > 0) [s appendFormat:@"CreateScrollbarMsgID(%d) ", cres];
|
||||
if (dess > 0) [s appendFormat:@"DestroyScrollbarMsgID(%d) ", dess];
|
||||
|
||||
return [s autorelease];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -206,3 +262,34 @@ NSString *VimPBoardType = @"VimPBoardType";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
ASLInit()
|
||||
{
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
// Allow for changing the log level via user defaults. If no key is found
|
||||
// the default log level will be used (which for ASL is to log everything
|
||||
// up to ASL_LEVEL_NOTICE). This key is an integer which corresponds to
|
||||
// the ASL_LEVEL_* macros (0 is most severe, 7 is debug level).
|
||||
id logLevelObj = [ud objectForKey:MMLogLevelKey];
|
||||
if (logLevelObj) {
|
||||
int logLevel = [logLevelObj intValue];
|
||||
if (logLevel < 0) logLevel = 0;
|
||||
if (logLevel > ASL_LEVEL_DEBUG) logLevel = ASL_LEVEL_DEBUG;
|
||||
|
||||
ASLogLevel = logLevel;
|
||||
asl_set_filter(NULL, ASL_FILTER_MASK_UPTO(logLevel));
|
||||
}
|
||||
|
||||
// Allow for changing whether a copy of each log should be sent to stderr
|
||||
// (this defaults to NO if this key is missing in the user defaults
|
||||
// database). The above filter mask is applied to logs going to stderr,
|
||||
// contrary to how "vanilla" ASL works.
|
||||
BOOL logToStdErr = [ud boolForKey:MMLogToStdErrKey];
|
||||
if (logToStdErr)
|
||||
asl_add_log_file(NULL, 2); // The file descriptor for stderr is 2
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
1D1474B60C56796D0038FA2B /* MMVimController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1474B40C56796D0038FA2B /* MMVimController.m */; };
|
||||
1D1474BC0C567A910038FA2B /* MMWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1474BA0C567A910038FA2B /* MMWindowController.m */; };
|
||||
1D22374B0E45DF4800E6FFFF /* Advanced.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D22374A0E45DF4800E6FFFF /* Advanced.png */; };
|
||||
1D384A0E100D671700D3C22F /* KeyBinding.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1D384A0D100D671700D3C22F /* KeyBinding.plist */; };
|
||||
1D3D19110CA690FF0004A0A5 /* DejaVuSansMono-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 1D3D190D0CA690FF0004A0A5 /* DejaVuSansMono-Bold.ttf */; };
|
||||
1D3D19120CA690FF0004A0A5 /* DejaVuSansMono-BoldOblique.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 1D3D190E0CA690FF0004A0A5 /* DejaVuSansMono-BoldOblique.ttf */; };
|
||||
1D3D19130CA690FF0004A0A5 /* DejaVuSansMono-Oblique.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 1D3D190F0CA690FF0004A0A5 /* DejaVuSansMono-Oblique.ttf */; };
|
||||
@@ -65,7 +66,6 @@
|
||||
1DD0C20C0C60FFB4008CD84A /* gvimrc in Copy Vim Runtime Files */ = {isa = PBXBuildFile; fileRef = 1DD0C20A0C60FF9A008CD84A /* gvimrc */; };
|
||||
1DD3D51E0D82D4C9006E4320 /* ibeam.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DD3D51D0D82D4C9006E4320 /* ibeam.png */; };
|
||||
1DD66ECE0C803D3600EBDAB3 /* MMApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DD66ECC0C803D3600EBDAB3 /* MMApplication.m */; };
|
||||
1DD704310BA9F9C2008679E9 /* SpecialKeys.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DD704300BA9F9C2008679E9 /* SpecialKeys.plist */; };
|
||||
1DD9F5E50C85D60500E8D5A5 /* SystemColors.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DD9F5E40C85D60500E8D5A5 /* SystemColors.plist */; };
|
||||
1DE3F8E70D50F80500052B9E /* Preferences.nib in Resources */ = {isa = PBXBuildFile; fileRef = 1DE3F8E50D50F80500052B9E /* Preferences.nib */; };
|
||||
1DE3F8EB0D50F84600052B9E /* MMPreferenceController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DE3F8E90D50F84600052B9E /* MMPreferenceController.m */; };
|
||||
@@ -199,6 +199,7 @@
|
||||
1D1474B90C567A910038FA2B /* MMWindowController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MMWindowController.h; sourceTree = "<group>"; };
|
||||
1D1474BA0C567A910038FA2B /* MMWindowController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMWindowController.m; sourceTree = "<group>"; };
|
||||
1D22374A0E45DF4800E6FFFF /* Advanced.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Advanced.png; sourceTree = "<group>"; };
|
||||
1D384A0D100D671700D3C22F /* KeyBinding.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = KeyBinding.plist; sourceTree = "<group>"; };
|
||||
1D3D190D0CA690FF0004A0A5 /* DejaVuSansMono-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "DejaVuSansMono-Bold.ttf"; path = "dejavu-ttf/DejaVuSansMono-Bold.ttf"; sourceTree = "<group>"; };
|
||||
1D3D190E0CA690FF0004A0A5 /* DejaVuSansMono-BoldOblique.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "DejaVuSansMono-BoldOblique.ttf"; path = "dejavu-ttf/DejaVuSansMono-BoldOblique.ttf"; sourceTree = "<group>"; };
|
||||
1D3D190F0CA690FF0004A0A5 /* DejaVuSansMono-Oblique.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "DejaVuSansMono-Oblique.ttf"; path = "dejavu-ttf/DejaVuSansMono-Oblique.ttf"; sourceTree = "<group>"; };
|
||||
@@ -245,7 +246,6 @@
|
||||
1DD3D51D0D82D4C9006E4320 /* ibeam.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ibeam.png; sourceTree = "<group>"; };
|
||||
1DD66ECB0C803D3600EBDAB3 /* MMApplication.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MMApplication.h; sourceTree = "<group>"; };
|
||||
1DD66ECC0C803D3600EBDAB3 /* MMApplication.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMApplication.m; sourceTree = "<group>"; };
|
||||
1DD704300BA9F9C2008679E9 /* SpecialKeys.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = SpecialKeys.plist; sourceTree = "<group>"; };
|
||||
1DD9F5E40C85D60500E8D5A5 /* SystemColors.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = SystemColors.plist; sourceTree = "<group>"; };
|
||||
1DE3F8E60D50F80500052B9E /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/Preferences.nib; sourceTree = "<group>"; };
|
||||
1DE3F8E80D50F84600052B9E /* MMPreferenceController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MMPreferenceController.h; sourceTree = "<group>"; };
|
||||
@@ -478,6 +478,7 @@
|
||||
29B97317FDCFA39411CA2CEA /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1D384A0D100D671700D3C22F /* KeyBinding.plist */,
|
||||
1D9C602E0EF79C0C0034AD44 /* MacVim.icns */,
|
||||
1D6008820E96886D003763F0 /* FindAndReplace.nib */,
|
||||
0395A8A90D72D88B00881434 /* General.png */,
|
||||
@@ -490,7 +491,6 @@
|
||||
1DD9F5E40C85D60500E8D5A5 /* SystemColors.plist */,
|
||||
1DE8CC610C5E2AAD003F56E3 /* Actions.plist */,
|
||||
1DD04DEB0C529C5E006CDC2B /* Credits.rtf */,
|
||||
1DD704300BA9F9C2008679E9 /* SpecialKeys.plist */,
|
||||
1D0E051B0BA5F83800B6049E /* Colors.plist */,
|
||||
8D1107310486CEB800E47090 /* Info.plist */,
|
||||
089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
|
||||
@@ -593,7 +593,6 @@
|
||||
8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */,
|
||||
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
|
||||
1D0E051C0BA5F83800B6049E /* Colors.plist in Resources */,
|
||||
1DD704310BA9F9C2008679E9 /* SpecialKeys.plist in Resources */,
|
||||
1DD04DEC0C529C5E006CDC2B /* Credits.rtf in Resources */,
|
||||
1DE8CC620C5E2AAD003F56E3 /* Actions.plist in Resources */,
|
||||
1DD9F5E50C85D60500E8D5A5 /* SystemColors.plist in Resources */,
|
||||
@@ -630,6 +629,7 @@
|
||||
1DCD00D30E50B2B700460166 /* Undo.png in Resources */,
|
||||
1D6008830E96886D003763F0 /* FindAndReplace.nib in Resources */,
|
||||
1D9C60520EF79C0C0034AD44 /* MacVim.icns in Resources */,
|
||||
1D384A0E100D671700D3C22F /* KeyBinding.plist in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -737,7 +737,7 @@
|
||||
i386,
|
||||
);
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 42;
|
||||
CURRENT_PROJECT_VERSION = 48;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
@@ -778,7 +778,7 @@
|
||||
buildSettings = {
|
||||
ARCHS = "$(NATIVE_ARCH)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 42;
|
||||
CURRENT_PROJECT_VERSION = 48;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
@@ -810,7 +810,7 @@
|
||||
buildSettings = {
|
||||
ARCHS = "$(NATIVE_ARCH)";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 42;
|
||||
CURRENT_PROJECT_VERSION = 48;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
|
||||
+20
-11
@@ -12,14 +12,9 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "MacVim.h"
|
||||
|
||||
#define MM_LOG_DEALLOCATIONS 0
|
||||
|
||||
|
||||
#if MM_LOG_DEALLOCATIONS
|
||||
# define LOG_DEALLOC NSLog(@"%s %@", _cmd, [self className]);
|
||||
#else
|
||||
# define LOG_DEALLOC
|
||||
#endif
|
||||
// TODO: Remove this when the inline IM code has been tested
|
||||
#define INCLUDE_OLD_IM_CODE
|
||||
|
||||
|
||||
// NSUserDefaults keys
|
||||
@@ -55,6 +50,9 @@ extern NSString *MMVerticalSplitKey;
|
||||
extern NSString *MMPreloadCacheSizeKey;
|
||||
extern NSString *MMLastWindowClosedBehaviorKey;
|
||||
extern NSString *MMLoadDefaultFontKey;
|
||||
#ifdef INCLUDE_OLD_IM_CODE
|
||||
extern NSString *MMUseInlineImKey;
|
||||
#endif // INCLUDE_OLD_IM_CODE
|
||||
|
||||
|
||||
// Enum for MMUntitledWindowKey
|
||||
@@ -95,7 +93,7 @@ enum {
|
||||
@end
|
||||
|
||||
|
||||
@interface NSOpenPanel (MMExtras)
|
||||
@interface NSSavePanel (MMExtras)
|
||||
- (void)hiddenFilesButtonToggled:(id)sender;
|
||||
- (void)setShowsHiddenFiles:(BOOL)show;
|
||||
@end
|
||||
@@ -130,7 +128,18 @@ enum {
|
||||
|
||||
|
||||
|
||||
// Create a view to be used as accessory for open panel. This function assumes
|
||||
// ownership of the view so do not release it.
|
||||
NSView *openPanelAccessoryView();
|
||||
// Create a view with a "show hidden files" button to be used as accessory for
|
||||
// open/save panels. This function assumes ownership of the view so do not
|
||||
// release it.
|
||||
NSView *showHiddenFilesView();
|
||||
|
||||
|
||||
// Convert filenames (which are in a variant of decomposed form, NFD, on HFS+)
|
||||
// to normalization form C (NFC). (This is necessary because Vim does not
|
||||
// automatically compose NFD.) For more information see:
|
||||
// http://developer.apple.com/technotes/tn/tn1150.html
|
||||
// http://developer.apple.com/technotes/tn/tn1150table.html
|
||||
// http://developer.apple.com/qa/qa2001/qa1235.html
|
||||
// http://www.unicode.org/reports/tr15/
|
||||
NSString *normalizeFilename(NSString *filename);
|
||||
NSArray *normalizeFilenames(NSArray *filenames);
|
||||
|
||||
@@ -46,6 +46,9 @@ NSString *MMVerticalSplitKey = @"MMVerticalSplit";
|
||||
NSString *MMPreloadCacheSizeKey = @"MMPreloadCacheSize";
|
||||
NSString *MMLastWindowClosedBehaviorKey = @"MMLastWindowClosedBehavior";
|
||||
NSString *MMLoadDefaultFontKey = @"MMLoadDefaultFont";
|
||||
#ifdef INCLUDE_OLD_IM_CODE
|
||||
NSString *MMUseInlineImKey = @"MMUseInlineIm";
|
||||
#endif // INCLUDE_OLD_IM_CODE
|
||||
|
||||
|
||||
|
||||
@@ -93,7 +96,7 @@ NSString *MMLoadDefaultFontKey = @"MMLoadDefaultFont";
|
||||
|
||||
|
||||
|
||||
@implementation NSOpenPanel (MMExtras)
|
||||
@implementation NSSavePanel (MMExtras)
|
||||
|
||||
- (void)hiddenFilesButtonToggled:(id)sender
|
||||
{
|
||||
@@ -122,7 +125,7 @@ NSString *MMLoadDefaultFontKey = @"MMLoadDefaultFont";
|
||||
[invocation invoke];
|
||||
}
|
||||
|
||||
@end // NSOpenPanel (MMExtras)
|
||||
@end // NSSavePanel (MMExtras)
|
||||
|
||||
|
||||
|
||||
@@ -263,7 +266,7 @@ NSString *MMLoadDefaultFontKey = @"MMLoadDefaultFont";
|
||||
|
||||
|
||||
NSView *
|
||||
openPanelAccessoryView()
|
||||
showHiddenFilesView()
|
||||
{
|
||||
// Return a new button object for each NSOpenPanel -- several of them
|
||||
// could be displayed at once.
|
||||
@@ -272,13 +275,13 @@ openPanelAccessoryView()
|
||||
NSButton *button = [[[NSButton alloc]
|
||||
initWithFrame:NSMakeRect(0, 0, 140, 18)] autorelease];
|
||||
[button setTitle:
|
||||
NSLocalizedString(@"Show Hidden Files", @"Open File Dialog")];
|
||||
NSLocalizedString(@"Show Hidden Files", @"Show Hidden Files Checkbox")];
|
||||
[button setButtonType:NSSwitchButton];
|
||||
|
||||
[button setTarget:nil];
|
||||
[button setAction:@selector(hiddenFilesButtonToggled:)];
|
||||
|
||||
// use the regular control size (checkbox is a bit smaller without this)
|
||||
// Use the regular control size (checkbox is a bit smaller without this)
|
||||
NSControlSize buttonSize = NSRegularControlSize;
|
||||
float fontSize = [NSFont systemFontSizeForControlSize:buttonSize];
|
||||
NSCell *theCell = [button cell];
|
||||
@@ -290,3 +293,28 @@ openPanelAccessoryView()
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
NSString *
|
||||
normalizeFilename(NSString *filename)
|
||||
{
|
||||
return [filename precomposedStringWithCanonicalMapping];
|
||||
}
|
||||
|
||||
NSArray *
|
||||
normalizeFilenames(NSArray *filenames)
|
||||
{
|
||||
NSMutableArray *outnames = [NSMutableArray array];
|
||||
if (!filenames)
|
||||
return outnames;
|
||||
|
||||
unsigned i, count = [filenames count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSString *nfkc = normalizeFilename([filenames objectAtIndex:i]);
|
||||
[outnames addObject:nfkc];
|
||||
}
|
||||
|
||||
return outnames;
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ NSString *MMPlugInViewPboardType = @"MMPlugInViewPboardType";
|
||||
if ((self = [super init]) == nil) return nil;
|
||||
|
||||
if (![NSBundle loadNibNamed:@"PlugInView" owner:self])
|
||||
NSLog(@"Error loading PlugIn nib");
|
||||
ASLogErr(@"Error loading PlugIn nib");
|
||||
|
||||
[titleField setStringValue:title];
|
||||
|
||||
@@ -196,6 +196,8 @@ NSString *MMPlugInViewPboardType = @"MMPlugInViewPboardType";
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
ASLogDebug(@"");
|
||||
|
||||
[fillerView release]; fillerView = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ static int MMPlugInArchMinorVersion = 0;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
//NSLog(@"%@ %s", [self className], _cmd);
|
||||
ASLogDebug(@"");
|
||||
|
||||
[plugInViews release]; plugInViews = nil;
|
||||
[instances release]; instances = nil;
|
||||
@@ -126,8 +126,6 @@ static int MMPlugInArchMinorVersion = 0;
|
||||
|
||||
- (void)addPlugInView:(NSView *)view withTitle:(NSString *)title
|
||||
{
|
||||
//NSLog(@"%@ %s", [self className], _cmd);
|
||||
|
||||
// Do this here so that the drawer is never opened automatically when there
|
||||
// are no plugin views.
|
||||
if ([[NSUserDefaults standardUserDefaults]
|
||||
|
||||
+17
-18
@@ -20,16 +20,16 @@ is very easy to pick up if you know C and some object oriented programming.)
|
||||
Each editor window in MacVim runs its own Vim process (but there is always
|
||||
only one MacVim process). Communication between MacVim and a Vim process is
|
||||
done using Distributed Objects (DO). Each Vim process is represented by a
|
||||
backend object (MMBackend) and it communicates with a frontend object in the
|
||||
Vim process (MMVimController). The interface between the backend and frontend
|
||||
backend object (MMBackend) and it communicates with the frontend object in the
|
||||
Vim process (MMAppController). The interface between the backend and frontend
|
||||
is defined in MacVim.h.
|
||||
|
||||
The frontend sends input to the backend by calling
|
||||
-[MMBackend processInput:data:]. The backend queues output on a command queue
|
||||
and sends it to the frontend at opportune times by calling
|
||||
-[MMVimController processCommandQueue:]. These are both asynchronous calls so
|
||||
MacVim can keep drawing and receiving input while Vim is working away, thus
|
||||
always keeping the user interface responsive.
|
||||
-[MMAppController processInput:forIdentifier:]. These are both asynchronous
|
||||
calls so MacVim can keep drawing and receiving input while Vim is working away,
|
||||
thus always keeping the user interface responsive.
|
||||
|
||||
The state of each editor window is kept entirely in the Vim process. MacVim
|
||||
should remain "ignorant" in the sense that it knows nothing of the actual
|
||||
@@ -46,7 +46,7 @@ to MacVim inside -[MMBackend queueVimStateMessage].
|
||||
|
||||
Vim:
|
||||
|
||||
Hooks from within Vim are implmented in gui_macvim.m, the name of such
|
||||
Hooks from within Vim are implemented in gui_macvim.m, the name of such
|
||||
functions usually start with "gui_mch_" and they should simply put a message
|
||||
on the output queue, by calling queueMessage:properties: on the singleton
|
||||
MMBackend object [MMBackend sharedInstance] (see e.g. gui_mch_destroy_menu()).
|
||||
@@ -63,7 +63,7 @@ for some reason fails to update the run loop then incoming DO calls will not
|
||||
be processed and for this reason it is best to avoid making synchronous DO
|
||||
calls from MacVim. (If synchronous calls must be made then it is important to
|
||||
set proper timeouts so that MacVim doesn't "hang", see
|
||||
-[MMVimConroller sendMessageNow:::] to see how this can be done.)
|
||||
-[MMVimController sendMessageNow:::] to see how this can be done.)
|
||||
|
||||
|
||||
MacVim:
|
||||
@@ -71,16 +71,15 @@ MacVim:
|
||||
The main nib of MacVim.app is MainMenu.nib which contains the default menu and
|
||||
an instance of MMAppController, which is connected as the delegate of
|
||||
NSApplication. That means, when MacVim starts it will load this nib file and
|
||||
automatically create an instance of the MMAppController singleton.
|
||||
automatically create an instance of the MMAppController singleton. All
|
||||
incoming distributed object calls go via MMAppController.
|
||||
|
||||
A new editor window is opened by calling
|
||||
-[MMAppController launchVimProcessWithArguments:]. This functions starts a
|
||||
new Vim process (by executing the Vim binary). The Vim process lets MacVim
|
||||
know when it has launched by calling -[MMAppController connectBackend:pid:]
|
||||
and MacVim responds to this message by creating a new frontend object
|
||||
(MMVimController) and returns a proxy to this object back to the Vim process.
|
||||
From this point onward the Vim process communicates directly with the
|
||||
MMVimController.
|
||||
and MacVim responds to this message by creating a new vim controller and
|
||||
returns an identifier for this object back to the Vim process.
|
||||
|
||||
The MMVimController represents the frontend of a Vim process inside MacVim.
|
||||
It coordinates all communication with the Vim process and delegates output
|
||||
@@ -88,7 +87,7 @@ that affects visual presentation to a MMWindowController object. Read the
|
||||
Cocoa documentation on the responsibilities of a window controller.
|
||||
|
||||
Input (keyboard & mouse) handling and drawing is handled by a helper object
|
||||
(MMTextViewHelper) to the current text view (MMTextView, MMAtsuiTextView).
|
||||
(MMTextViewHelper) to the current text view (MMTextView, MMAtsuiTextView, ...).
|
||||
|
||||
|
||||
Distributed Object dangers:
|
||||
@@ -106,7 +105,7 @@ message may arrive.
|
||||
the menu flashes briefly. During this "flash" a modal loop is entered.
|
||||
|
||||
Item 1 can cause a problem if MacVim sends a synchronous message and before a
|
||||
reply reacheds MacVim another message is received. From the source code it
|
||||
reply reaches MacVim another message is received. From the source code it
|
||||
looks like the synchronous message blocks but in fact the other message is
|
||||
executed during this "block". If the other message changes state radically
|
||||
something may go wrong after the synchronous DO message returns.
|
||||
@@ -117,8 +116,8 @@ which may be even more puzzling.
|
||||
One way to alleviate these problems is to ensure a DO message isn't entered
|
||||
twice by setting a boolean at the beginning of the message and clearing it
|
||||
afterwards. If the boolean is already set when entering the call must somehow
|
||||
be delayed. See -[MMVimController processCommandQueue:] for a concrete
|
||||
example.
|
||||
be delayed. See processInput:forIdentifier: and processInputQueues: inside
|
||||
MMAppController for a concrete example.
|
||||
|
||||
Another danger is that we must take care when releasing objects that Cocoa may
|
||||
be using. See -[MMVimController connectionDidDie:] how MacVim releases
|
||||
@@ -133,7 +132,7 @@ what they contain:
|
||||
MMAppController.* Everything related to running the application
|
||||
MMBackend.* Object representing a Vim process in backend
|
||||
MMTextView.* Handles input and drawing
|
||||
MMVimController.* Object representing a Vim Process in frontend
|
||||
MMVimController.* Object representing a Vim process in frontend
|
||||
MMVimView.* Cocoa view object
|
||||
MMWindowController.* Coordinates visual presentation
|
||||
MacVim.* Code shared between MacVim and Vim
|
||||
@@ -161,4 +160,4 @@ The application bundle can be found inside "src/MacVim/build/Release".
|
||||
|
||||
|
||||
Bjorn Winckler <bjorn.winckler@gmail.com>
|
||||
November 22, 2008
|
||||
April 5, 2009
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
MacVim is a port of the text editor Vim to Mac OS X. More information can be
|
||||
found on the [project webpage][gcode]. The file `src/MacVim/README` gives an
|
||||
overview of the MacVim source code.
|
||||
|
||||
|
||||
### Branches ###
|
||||
|
||||
`master`
|
||||
: MacVim and core Vim sources
|
||||
`vim`
|
||||
: Core Vim sources pulled from the SVN repository with the latest runtime
|
||||
: files from the Vim FTP included
|
||||
`stable`
|
||||
: Used to build the Stable binary distribution
|
||||
`feat/core-text`
|
||||
: Core Text renderer (fast with improved Unicode rendering, but has some
|
||||
: display issues)
|
||||
|
||||
_Note:_ Branches starting with `feat/` are experimental and will be rebased
|
||||
against master occasionally (other branches will not be rebased).
|
||||
|
||||
|
||||
[gcode]: http://code.google.com/p/macvim/
|
||||
@@ -1,62 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>KA</key>
|
||||
<string>KA</string>
|
||||
<key></key>
|
||||
<string>kb</string>
|
||||
<key></key>
|
||||
<string>ku</string>
|
||||
<key></key>
|
||||
<string>kd</string>
|
||||
<key></key>
|
||||
<string>kl</string>
|
||||
<key></key>
|
||||
<string>kr</string>
|
||||
<key></key>
|
||||
<string>k1</string>
|
||||
<key></key>
|
||||
<string>k2</string>
|
||||
<key></key>
|
||||
<string>k3</string>
|
||||
<key></key>
|
||||
<string>k4</string>
|
||||
<key></key>
|
||||
<string>k5</string>
|
||||
<key></key>
|
||||
<string>k6</string>
|
||||
<key></key>
|
||||
<string>k7</string>
|
||||
<key></key>
|
||||
<string>k8</string>
|
||||
<key></key>
|
||||
<string>k9</string>
|
||||
<key></key>
|
||||
<string>k;</string>
|
||||
<key></key>
|
||||
<string>F1</string>
|
||||
<key></key>
|
||||
<string>F2</string>
|
||||
<key></key>
|
||||
<string>F3</string>
|
||||
<key></key>
|
||||
<string>F4</string>
|
||||
<key></key>
|
||||
<string>F5</string>
|
||||
<key></key>
|
||||
<string>F6</string>
|
||||
<key></key>
|
||||
<string>kD</string>
|
||||
<key></key>
|
||||
<string>kh</string>
|
||||
<key></key>
|
||||
<string>@7</string>
|
||||
<key></key>
|
||||
<string>kP</string>
|
||||
<key></key>
|
||||
<string>kN</string>
|
||||
<key></key>
|
||||
<string>%1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
+72
-73
@@ -25,7 +25,6 @@ static NSString *MMDefaultFontName = @"DejaVu Sans Mono";
|
||||
static int MMDefaultFontSize = 12;
|
||||
static int MMMinFontSize = 6;
|
||||
static int MMMaxFontSize = 100;
|
||||
static BOOL gui_mch_init_has_finished = NO;
|
||||
|
||||
|
||||
static GuiFont gui_macvim_font_with_name(char_u *name);
|
||||
@@ -43,12 +42,11 @@ vimmenu_T *menu_for_descriptor(NSArray *desc);
|
||||
* Parse the GUI related command-line arguments. Any arguments used are
|
||||
* deleted from argv, and *argc is decremented accordingly. This is called
|
||||
* when vim is started, whether or not the GUI has been started.
|
||||
* NOTE: This function will be called twice if the Vim process forks.
|
||||
*/
|
||||
void
|
||||
gui_mch_prepare(int *argc, char **argv)
|
||||
{
|
||||
//NSLog(@"gui_mch_prepare(argc=%d)", *argc);
|
||||
|
||||
// Set environment variables $VIM and $VIMRUNTIME
|
||||
// NOTE! If vim_getenv is called with one of these as parameters before
|
||||
// they have been set here, they will most likely end up with the wrong
|
||||
@@ -75,6 +73,19 @@ gui_mch_prepare(int *argc, char **argv)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
for (i = 0; i < *argc; ++i) {
|
||||
if (strncmp(argv[i], "-nb", 3) == 0) {
|
||||
usingNetbeans++;
|
||||
netbeansArg = argv[i];
|
||||
--*argc;
|
||||
if (*argc > i)
|
||||
mch_memmove(&argv[i], &argv[i+1], (*argc-i) * sizeof(char*));
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +96,6 @@ gui_mch_prepare(int *argc, char **argv)
|
||||
int
|
||||
gui_mch_init_check(void)
|
||||
{
|
||||
//NSLog(@"gui_mch_init_check()");
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -97,16 +107,8 @@ gui_mch_init_check(void)
|
||||
int
|
||||
gui_mch_init(void)
|
||||
{
|
||||
//NSLog(@"gui_mch_init()");
|
||||
|
||||
// NOTE! Because OS X has to exec after fork we effectively end up doing
|
||||
// the initialization twice (because this function is called before the
|
||||
// fork). To avoid all this extra work we check if Vim is about to fork,
|
||||
// and if so do nothing for now.
|
||||
//
|
||||
// TODO: Is this check 100% foolproof?
|
||||
if (gui.dofork && (vim_strchr(p_go, GO_FORG) == NULL))
|
||||
return OK;
|
||||
ASLInit();
|
||||
ASLogDebug(@"");
|
||||
|
||||
if (![[MMBackend sharedInstance] checkin]) {
|
||||
// TODO: Kill the process if there is no terminal to fall back on,
|
||||
@@ -140,8 +142,6 @@ gui_mch_init(void)
|
||||
// in [g]vimrc.
|
||||
gui_mch_adjust_charheight();
|
||||
|
||||
gui_mch_init_has_finished = YES;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ gui_mch_init(void)
|
||||
void
|
||||
gui_mch_exit(int rc)
|
||||
{
|
||||
//NSLog(@"gui_mch_exit(rc=%d)", rc);
|
||||
ASLogDebug(@"rc=%d", rc);
|
||||
|
||||
[[MMBackend sharedInstance] exit];
|
||||
}
|
||||
@@ -162,12 +162,6 @@ gui_mch_exit(int rc)
|
||||
int
|
||||
gui_mch_open(void)
|
||||
{
|
||||
//NSLog(@"gui_mch_open()");
|
||||
|
||||
// This check is to avoid doing extra work when we're about to fork.
|
||||
if (!gui_mch_init_has_finished)
|
||||
return OK;
|
||||
|
||||
return [[MMBackend sharedInstance] openGUIWindow];
|
||||
}
|
||||
|
||||
@@ -234,13 +228,13 @@ gui_macvim_flush(void)
|
||||
if (delta > 1.0)
|
||||
delay = 1;
|
||||
|
||||
// We assume that each call corresponds roughly to one line out output.
|
||||
// We assume that each call corresponds roughly to one line of output.
|
||||
// When one page has scrolled by we increase the delay before the next
|
||||
// flush.
|
||||
if (++scrolls > gui.num_rows) {
|
||||
delay <<= 1;
|
||||
if (delay > 0x10000)
|
||||
delay = 0x10000;
|
||||
if (delay > 2048)
|
||||
delay = 2048;
|
||||
scrolls = 0;
|
||||
}
|
||||
|
||||
@@ -471,8 +465,7 @@ gui_mch_new_colors(void)
|
||||
gui.def_back_pixel = gui.back_pixel;
|
||||
gui.def_norm_pixel = gui.norm_pixel;
|
||||
|
||||
//NSLog(@"gui_mch_new_colors(back=%x, norm=%x)", gui.def_back_pixel,
|
||||
// gui.def_norm_pixel);
|
||||
ASLogDebug(@"back=%x norm=%x", gui.def_back_pixel, gui.def_norm_pixel);
|
||||
|
||||
[[MMBackend sharedInstance]
|
||||
setDefaultColorsBackground:gui.def_back_pixel
|
||||
@@ -939,7 +932,7 @@ gui_mch_free_font(font)
|
||||
GuiFont font;
|
||||
{
|
||||
if (font != NOFONT) {
|
||||
//NSLog(@"gui_mch_free_font(font=0x%x)", font);
|
||||
ASLogDebug(@"font=0x%x", font);
|
||||
[(id)font release];
|
||||
}
|
||||
}
|
||||
@@ -958,8 +951,7 @@ gui_mch_retain_font(GuiFont font)
|
||||
GuiFont
|
||||
gui_mch_get_font(char_u *name, int giveErrorIfMissing)
|
||||
{
|
||||
//NSLog(@"gui_mch_get_font(name=%s, giveErrorIfMissing=%d)", name,
|
||||
// giveErrorIfMissing);
|
||||
ASLogDebug(@"name='%s' giveErrorIfMissing=%d", name, giveErrorIfMissing);
|
||||
|
||||
GuiFont font = gui_macvim_font_with_name(name);
|
||||
if (font != NOFONT)
|
||||
@@ -992,7 +984,7 @@ gui_mch_get_fontname(GuiFont font, char_u *name)
|
||||
int
|
||||
gui_mch_init_font(char_u *font_name, int fontset)
|
||||
{
|
||||
//NSLog(@"gui_mch_init_font(font_name=%s, fontset=%d)", font_name, fontset);
|
||||
ASLogDebug(@"font_name='%s' fontset=%d", font_name, fontset);
|
||||
|
||||
if (font_name && STRCMP(font_name, "*") == 0) {
|
||||
// :set gfn=* shows the font panel.
|
||||
@@ -1244,14 +1236,14 @@ gui_mch_stop_blink(void)
|
||||
void
|
||||
gui_mch_getmouse(int *x, int *y)
|
||||
{
|
||||
//NSLog(@"gui_mch_getmouse()");
|
||||
ASLogInfo(@"Not implemented!");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gui_mch_setmouse(int x, int y)
|
||||
{
|
||||
//NSLog(@"gui_mch_setmouse(x=%d, y=%d)", x, y);
|
||||
ASLogInfo(@"Not implemented!");
|
||||
}
|
||||
|
||||
|
||||
@@ -1276,28 +1268,32 @@ im_set_position(int row, int col)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
im_set_control(int enable)
|
||||
{
|
||||
// Tell frontend whether it should notify us when the input method changes
|
||||
// or not (called when 'imd' is toggled).
|
||||
int msgid = enable ? EnableImControlMsgID : DisableImControlMsgID;
|
||||
[[MMBackend sharedInstance] queueMessage:msgid properties:nil];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
im_set_active(int active)
|
||||
{
|
||||
// Set roman or the system script if 'active' is TRUE or FALSE,
|
||||
// respectively.
|
||||
SInt32 systemScript = GetScriptManagerVariable(smSysScript);
|
||||
|
||||
if (!p_imdisable && smRoman != systemScript)
|
||||
KeyScript(active ? smKeySysScript : smKeyRoman);
|
||||
// Tell frontend to enable/disable IM (called e.g. when the mode changes).
|
||||
if (!p_imdisable) {
|
||||
int msgid = active ? ActivateKeyScriptMsgID : DeactivateKeyScriptMsgID;
|
||||
[[MMBackend sharedInstance] setImState:active];
|
||||
[[MMBackend sharedInstance] queueMessage:msgid properties:nil];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
im_get_status(void)
|
||||
{
|
||||
// IM is active whenever the current script is the system script and the
|
||||
// system script isn't roman. (Hence IM can only be active when using
|
||||
// non-roman scripts.)
|
||||
SInt32 currentScript = GetScriptManagerVariable(smKeyScript);
|
||||
SInt32 systemScript = GetScriptManagerVariable(smSysScript);
|
||||
|
||||
return currentScript != smRoman && currentScript == systemScript;
|
||||
return [[MMBackend sharedInstance] imState];
|
||||
}
|
||||
|
||||
#endif // defined(USE_IM_CONTROL)
|
||||
@@ -1425,8 +1421,8 @@ gui_mch_browse(
|
||||
char_u *initdir,
|
||||
char_u *filter)
|
||||
{
|
||||
//NSLog(@"gui_mch_browse(saving=%d, title=%s, dflt=%s, ext=%s, initdir=%s,"
|
||||
// " filter=%s", saving, title, dflt, ext, initdir, filter);
|
||||
ASLogDebug(@"saving=%d title='%s' dflt='%s' ext='%s' initdir='%s' "
|
||||
"filter='%s'", saving, title, dflt, ext, initdir, filter);
|
||||
|
||||
// Ensure no data is on the output queue before presenting the dialog.
|
||||
gui_macvim_force_flush();
|
||||
@@ -1455,9 +1451,9 @@ gui_mch_dialog(
|
||||
int dfltbutton,
|
||||
char_u *textfield)
|
||||
{
|
||||
//NSLog(@"gui_mch_dialog(type=%d title=%s message=%s buttons=%s "
|
||||
// "dfltbutton=%d textfield=%s)", type, title, message, buttons,
|
||||
// dfltbutton, textfield);
|
||||
ASLogDebug(@"type=%d title='%s' message='%s' buttons='%s' dfltbutton=%d "
|
||||
"textfield='%s'", type, title, message, buttons, dfltbutton,
|
||||
textfield);
|
||||
|
||||
// Ensure no data is on the output queue before presenting the dialog.
|
||||
gui_macvim_force_flush();
|
||||
@@ -1570,7 +1566,7 @@ gui_mch_get_rgb(guicolor_T pixel)
|
||||
void
|
||||
gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
|
||||
{
|
||||
//NSLog(@"gui_mch_get_screen_dimensions()");
|
||||
ASLogDebug(@"Columns=%d Rows=%d", Columns, Rows);
|
||||
*screen_w = Columns;
|
||||
*screen_h = Rows;
|
||||
}
|
||||
@@ -1593,21 +1589,7 @@ gui_mch_get_winpos(int *x, int *y)
|
||||
int
|
||||
gui_mch_haskey(char_u *name)
|
||||
{
|
||||
BOOL ok = NO;
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
name = CONVERT_TO_UTF8(name);
|
||||
#endif
|
||||
|
||||
NSString *value = [NSString stringWithUTF8String:(char*)name];
|
||||
if (value)
|
||||
ok = [[MMBackend sharedInstance] hasSpecialKeyWithValue:value];
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
CONVERT_TO_UTF8_FREE(name);
|
||||
#endif
|
||||
|
||||
return ok;
|
||||
return [[MMBackend sharedInstance] hasSpecialKeyWithValue:name];
|
||||
}
|
||||
|
||||
|
||||
@@ -1643,10 +1625,9 @@ gui_mch_set_shellsize(
|
||||
int base_height,
|
||||
int direction)
|
||||
{
|
||||
//NSLog(@"gui_mch_set_shellsize(width=%d, height=%d, min_width=%d,"
|
||||
// " min_height=%d, base_width=%d, base_height=%d, direction=%d)",
|
||||
// width, height, min_width, min_height, base_width, base_height,
|
||||
// direction);
|
||||
ASLogDebug(@"width=%d height=%d min_width=%d min_height=%d base_width=%d "
|
||||
"base_height=%d direction=%d", width, height, min_width,
|
||||
min_height, base_width, base_height, direction);
|
||||
[[MMBackend sharedInstance] setRows:height columns:width];
|
||||
}
|
||||
|
||||
@@ -1674,7 +1655,7 @@ gui_mch_set_winpos(int x, int y)
|
||||
void
|
||||
gui_mch_settitle(char_u *title, char_u *icon)
|
||||
{
|
||||
//NSLog(@"gui_mch_settitle(title=%s, icon=%s)", title, icon);
|
||||
ASLogDebug(@"title='%s' icon='%s'", title, icon);
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
title = CONVERT_TO_UTF8(title);
|
||||
@@ -1718,6 +1699,9 @@ gui_mch_leave_fullscreen()
|
||||
void
|
||||
gui_mch_fuopt_update()
|
||||
{
|
||||
if (!gui.in_use)
|
||||
return;
|
||||
|
||||
guicolor_T fg, bg;
|
||||
if (fuoptions_flags & FUOPT_BGCOLOR_HLGROUP) {
|
||||
syn_id2colors(fuoptions_bgcolor, &fg, &bg);
|
||||
@@ -2191,3 +2175,18 @@ static int vimModMaskToEventModifierFlags(int mods)
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- NetBeans Support ------------------------------------------------------
|
||||
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
|
||||
/* Set NetBeans socket to CFRunLoop */
|
||||
void
|
||||
gui_macvim_set_netbeans_socket(int socket)
|
||||
{
|
||||
[[MMBackend sharedInstance] setNetbeansSocket:socket];
|
||||
}
|
||||
|
||||
#endif // FEAT_NETBEANS_INTG
|
||||
|
||||
+8
-5
@@ -1,7 +1,7 @@
|
||||
" System gvimrc file for MacVim
|
||||
"
|
||||
" Maintainer: Bjorn Winckler <bjorn.winckler@gmail.com>
|
||||
" Last Change: Sun Oct 04 2008
|
||||
" Last Change: Sun Mar 15 2009
|
||||
"
|
||||
" This is a work in progress. If you feel so inclined, please help me improve
|
||||
" this file.
|
||||
@@ -26,6 +26,9 @@ if !exists("colors_name")
|
||||
colorscheme macvim
|
||||
endif
|
||||
|
||||
" To make tabs more readable, the label only contains the tail of the file
|
||||
" name and the buffer modified flag.
|
||||
set guitablabel=%M%t
|
||||
|
||||
|
||||
" Send print jobs to Preview.app. This does not delete the temporary ps file
|
||||
@@ -94,8 +97,8 @@ an <silent> 9900.311 Window.Zoom\ All <Nop>
|
||||
an <silent> 9900.320 Window.Toggle\ Full\ Screen\ Mode :set invfullscreen<CR>
|
||||
an 9900.330 Window.-SEP1- <Nop>
|
||||
" TODO! Grey out if no tabs are visible.
|
||||
an <silent> 9900.340 Window.Previous\ Tab :tabprevious<CR>
|
||||
an <silent> 9900.350 Window.Next\ Tab :tabnext<CR>
|
||||
an <silent> 9900.340 Window.Select\ Next\ Tab :tabnext<CR>
|
||||
an <silent> 9900.350 Window.Select\ Previous\ Tab :tabprevious<CR>
|
||||
an 9900.360 Window.-SEP2- <Nop>
|
||||
an <silent> 9900.370 Window.Bring\ All\ To\ Front <Nop>
|
||||
|
||||
@@ -254,8 +257,8 @@ macm Window.Minimize\ All key=<D-M-m> action=miniaturizeAll: alt=YES
|
||||
macm Window.Zoom key=<D-C-z> action=performZoom:
|
||||
macm Window.Zoom\ All key=<D-M-C-z> action=zoomAll: alt=YES
|
||||
macm Window.Toggle\ Full\ Screen\ Mode key=<D-F>
|
||||
macm Window.Previous\ Tab key=<D-{>
|
||||
macm Window.Next\ Tab key=<D-}>
|
||||
macm Window.Select\ Next\ Tab key=<D-}>
|
||||
macm Window.Select\ Previous\ Tab key=<D-{>
|
||||
macm Window.Bring\ All\ To\ Front action=arrangeInFront:
|
||||
|
||||
macm Help.MacVim\ Help key=<D-?>
|
||||
|
||||
@@ -2,10 +2,25 @@
|
||||
|
||||
OUTDIR ?= .
|
||||
|
||||
$(OUTDIR)/MacVim-generic.icns: make_icons.py vim-noshadow-512.png
|
||||
$(OUTDIR)/MacVim-generic.icns: make_icons.py vim-noshadow-512.png loadfont.so Envy\ Code\ R\ Bold.ttf
|
||||
$(MAKE) -C makeicns
|
||||
/usr/bin/python make_icons.py $(OUTDIR)
|
||||
|
||||
loadfont.so: loadfont.c
|
||||
/usr/bin/python setup.py install --install-lib .
|
||||
|
||||
Envy\ Code\ R\ Bold.ttf: EnvyCodeR.zip
|
||||
unzip -jo EnvyCodeR.zip
|
||||
# unzip uses the file date from the zip file. Change the file date to
|
||||
# "now", so that the zip is not unzipped in every `make` run.`
|
||||
touch Envy\ Code\ R\ Bold.ttf
|
||||
|
||||
ENVYCODE_URL=http://download.damieng.com/latest/EnvyCodeR
|
||||
EnvyCodeR.zip:
|
||||
curl ${ENVYCODE_URL} --location -o EnvyCodeR.zip
|
||||
|
||||
clean:
|
||||
$(MAKE) -C makeicns clean
|
||||
rm -f $(OUTDIR)/MacVim-*.icns
|
||||
rm -f $(OUTDIR)/MacVim-*.icns loadfont.so *.pyc \
|
||||
EnvyCodeR.zip *.ttf *.reg *.txt
|
||||
rm -rf *.egginfo build # Created by setup.py
|
||||
|
||||
@@ -0,0 +1,605 @@
|
||||
from Foundation import *
|
||||
from AppKit import *
|
||||
|
||||
import itertools
|
||||
import math
|
||||
import operator
|
||||
import os
|
||||
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
# Resources
|
||||
DEFAULT_BACKGROUND = '/System/Library/CoreServices/CoreTypes.bundle/' + \
|
||||
'Contents/Resources/GenericDocumentIcon.icns' # might require leopard?
|
||||
|
||||
|
||||
# Cache both images and background renderers globally
|
||||
imageCache = {}
|
||||
bgCache = {}
|
||||
|
||||
|
||||
# Make us not crash
|
||||
# http://www.cocoabuilder.com/archive/message/cocoa/2008/8/6/214964
|
||||
NSApplicationLoad()
|
||||
|
||||
|
||||
class Surface(object):
|
||||
"""Represents a simple bitmapped image."""
|
||||
|
||||
def __init__(self, *p, **kw):
|
||||
if not 'premultiplyAlpha' in kw:
|
||||
kw['premultiplyAlpha'] = True
|
||||
if len(p) == 1 and isinstance(p[0], NSBitmapImageRep):
|
||||
self.bitmapRep = p[0]
|
||||
elif len(p) == 2 and isinstance(p[0], int) and isinstance(p[1], int):
|
||||
format = NSAlphaFirstBitmapFormat
|
||||
if not kw['premultiplyAlpha']:
|
||||
format += NSAlphaNonpremultipliedBitmapFormat
|
||||
self.bitmapRep = NSBitmapImageRep.alloc().initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel_(
|
||||
None, p[0], p[1], 8, 4, True, False, NSDeviceRGBColorSpace,
|
||||
format, 0, 0)
|
||||
|
||||
if not hasattr(self, 'bitmapRep') or not self.bitmapRep:
|
||||
raise Exception('Failed to create surface: ' + str(p))
|
||||
|
||||
def size(self):
|
||||
return map(int, self.bitmapRep.size()) # cocoa returns floats. cocoa ftw
|
||||
|
||||
def data(self):
|
||||
"""Returns data in ARGB order (on intel, at least)."""
|
||||
r = self.bitmapRep
|
||||
if r.bitmapFormat() != (NSAlphaNonpremultipliedBitmapFormat |
|
||||
NSAlphaFirstBitmapFormat) or \
|
||||
r.bitsPerPixel() != 32 or \
|
||||
r.isPlanar() or \
|
||||
r.samplesPerPixel() != 4:
|
||||
raise Exception("Unsupported image format")
|
||||
return self.bitmapRep.bitmapData()
|
||||
|
||||
def save(self, filename):
|
||||
"""Saves image as png file."""
|
||||
self.bitmapRep.representationUsingType_properties_(NSPNGFileType, None) \
|
||||
.writeToFile_atomically_(filename, True)
|
||||
|
||||
def draw(self):
|
||||
self.bitmapRep.draw()
|
||||
|
||||
def context(self):
|
||||
# Note: Cocoa only supports contexts with premultiplied alpha
|
||||
return NSGraphicsContext.graphicsContextWithBitmapImageRep_(self.bitmapRep)
|
||||
|
||||
def copy(self):
|
||||
return Surface(self.bitmapRep.copy())
|
||||
|
||||
|
||||
class Image(object):
|
||||
"""Represents an image that can consist of several Surfaces."""
|
||||
|
||||
def __init__(self, param):
|
||||
if isinstance(param, str):
|
||||
self.image = NSImage.alloc().initWithContentsOfFile_(param)
|
||||
elif isinstance(param, Surface):
|
||||
self.image = NSImage.alloc().initWithSize_( param.size() )
|
||||
self.image.addRepresentation_(param.bitmapRep)
|
||||
|
||||
if not self.image:
|
||||
raise Exception('Failed to load image: ' + str(param))
|
||||
|
||||
def surfaceOfSize(self, w, h):
|
||||
"""Returns an ARGB, non-premultiplied surface of size w*h or throws."""
|
||||
r = None
|
||||
for rep in self.image.representations():
|
||||
# Cocoa reports fraction widths for pngs (wtf?!), so use round()
|
||||
if map(lambda x: int(round(x)), rep.size()) == [w, h]:
|
||||
r = rep
|
||||
break
|
||||
|
||||
# XXX: Resample in this case? That'd make the program easier to use, but
|
||||
# can silently create blurry backgrounds. Since this happens with
|
||||
# the app icon anyways, this might not be a huge deal?
|
||||
if not r:
|
||||
raise Exception('Unsupported size %dx%d', w, h)
|
||||
return Surface(r)
|
||||
|
||||
def blend(self):
|
||||
self.compositeInRect( ((0, 0), self.image.size()) )
|
||||
|
||||
def compositeInRect(self, r, mode=NSCompositeSourceOver):
|
||||
self.image.drawInRect_fromRect_operation_fraction_(r, NSZeroRect,
|
||||
mode, 1.0)
|
||||
|
||||
def sizes(self):
|
||||
s = set()
|
||||
for rep in self.image.representations():
|
||||
s.add(tuple(map(lambda x: int(round(x)), rep.size())))
|
||||
return s
|
||||
|
||||
|
||||
class Context(object):
|
||||
# Tiger has only Python2.3, so we can't use __enter__ / __exit__ for this :-(
|
||||
|
||||
def __init__(self, surface):
|
||||
NSGraphicsContext.saveGraphicsState()
|
||||
c = surface.context()
|
||||
c.setShouldAntialias_(True);
|
||||
c.setImageInterpolation_(NSImageInterpolationHigh);
|
||||
NSGraphicsContext.setCurrentContext_(c)
|
||||
|
||||
def done(self):
|
||||
NSGraphicsContext.restoreGraphicsState()
|
||||
|
||||
|
||||
class SplittableBackground(object):
|
||||
|
||||
def __init__(self, unsplitted, shouldSplit=True):
|
||||
self.unsplitted = unsplitted
|
||||
self.shouldSplit = shouldSplit
|
||||
self.ground = {}
|
||||
self.shadow = {}
|
||||
|
||||
def rawGroundAtSize(self, s):
|
||||
return self.unsplitted.surfaceOfSize(s, s)
|
||||
|
||||
def groundAtSize(self, s):
|
||||
if not self.shouldSplit:
|
||||
return self.rawGroundAtSize(s)
|
||||
self._performSplit(s)
|
||||
return self.ground[s]
|
||||
|
||||
def shadowAtSize(self, s):
|
||||
if not self.shouldSplit:
|
||||
return None
|
||||
self._performSplit(s)
|
||||
return self.shadow[s]
|
||||
|
||||
def _performSplit(self, s):
|
||||
if s in self.ground:
|
||||
assert s in self.shadow
|
||||
return
|
||||
assert s not in self.shadow
|
||||
ground, shadow = splitGenericDocumentIcon(self.unsplitted, s)
|
||||
self.ground[s] = ground
|
||||
self.shadow[s] = shadow
|
||||
|
||||
|
||||
class BackgroundRenderer(object):
|
||||
|
||||
def __init__(self, bg, icon=None, r={}):
|
||||
self.bgRenderer = bg
|
||||
self.icon = icon
|
||||
self.cache = {}
|
||||
self.rect = r
|
||||
|
||||
def drawIcon(self, s):
|
||||
if not self.icon:
|
||||
return
|
||||
|
||||
assert s in [16, 32, 128, 256, 512]
|
||||
a = list(self.rect[s])
|
||||
|
||||
# convert from `flow` coords to cocoa
|
||||
a[2] = -a[2] # mirror y
|
||||
|
||||
w, h = s*a[1], s*a[3]
|
||||
self.icon.compositeInRect( (((s-w)/2 + a[0], (s-h)/2 + a[2]), (w, h)) )
|
||||
|
||||
def drawAtSize(self, s):
|
||||
if not self.icon:
|
||||
# No need to split the background if no icons is interleaved -- take
|
||||
# the faster code path in that case.
|
||||
self.bgRenderer.rawGroundAtSize(s).draw()
|
||||
return
|
||||
|
||||
self.bgRenderer.groundAtSize(s).draw()
|
||||
self.drawIcon(s)
|
||||
if self.bgRenderer.shouldSplit:
|
||||
# shadow needs to be composited, so it needs to be in an image
|
||||
Image(self.bgRenderer.shadowAtSize(s)).blend()
|
||||
|
||||
def backgroundAtSize(self, s):
|
||||
if not s in self.cache:
|
||||
result = Surface(s, s)
|
||||
context = Context(result)
|
||||
self.drawAtSize(s)
|
||||
context.done()
|
||||
self.cache[s] = result
|
||||
return self.cache[s]
|
||||
|
||||
|
||||
def splitGenericDocumentIcon(img, s):
|
||||
"""Takes the generic document icon and splits it into a background and a
|
||||
shadow layer. For the 32x32 and 16x16 variants, the white pixels of the page
|
||||
curl are hardcoded into the otherwise transparent shadow layer."""
|
||||
|
||||
w, h = s, s
|
||||
r = img.surfaceOfSize(w, h)
|
||||
bps = 4*w
|
||||
data = r.data()
|
||||
|
||||
ground = Surface(w, h, premultiplyAlpha=False)
|
||||
shadow = Surface(w, h, premultiplyAlpha=False)
|
||||
|
||||
grounddata = ground.data()
|
||||
shadowdata = shadow.data()
|
||||
|
||||
for y in xrange(h):
|
||||
for x in xrange(w):
|
||||
idx = y*bps + 4*x
|
||||
ia, ir, ig, ib = data[idx:idx + 4]
|
||||
if ia != chr(255):
|
||||
# buffer objects don't support slice assignment :-(
|
||||
grounddata[idx] = ia
|
||||
grounddata[idx + 1] = ir
|
||||
grounddata[idx + 2] = ig
|
||||
grounddata[idx + 3] = ib
|
||||
shadowdata[idx] = chr(0)
|
||||
shadowdata[idx + 1] = chr(0)
|
||||
shadowdata[idx + 2] = chr(0)
|
||||
shadowdata[idx + 3] = chr(0)
|
||||
continue
|
||||
|
||||
assert ir == ig == ib
|
||||
grounddata[idx] = chr(255)
|
||||
grounddata[idx + 1] = chr(255)
|
||||
grounddata[idx + 2] = chr(255)
|
||||
grounddata[idx + 3] = chr(255)
|
||||
shadowdata[idx] = chr(255 - ord(ir))
|
||||
shadowdata[idx + 1] = chr(0)
|
||||
shadowdata[idx + 2] = chr(0)
|
||||
shadowdata[idx + 3] = chr(0)
|
||||
|
||||
# Special-case 16x16 and 32x32 cases: Make some pixels on the fold white.
|
||||
# Ideally, I could make the fold whiteish in all variants, but I can't.
|
||||
whitePix = { 16: [(10, 2), (10, 3), (11, 3), (10, 4), (11, 4), (12, 4)],
|
||||
32: [(21, 4), (21, 5), (22, 5), (21, 6), (22, 6), (23, 6)]}
|
||||
if (w, h) in [(16, 16), (32, 32)]:
|
||||
for x, y in whitePix[w]:
|
||||
idx = y*bps + 4*x
|
||||
shadowdata[idx] = chr(255)
|
||||
shadowdata[idx + 1] = chr(255)
|
||||
shadowdata[idx + 2] = chr(255)
|
||||
shadowdata[idx + 3] = chr(255)
|
||||
|
||||
return ground, shadow
|
||||
|
||||
|
||||
class TextRenderer(object):
|
||||
|
||||
def __init__(self):
|
||||
self.cache = {}
|
||||
|
||||
def attribsAtSize(self, s):
|
||||
if s not in self.cache:
|
||||
self.cache[s] = self._attribsAtSize(s)
|
||||
return self.cache[s]
|
||||
|
||||
def centeredStyle(self):
|
||||
style = NSMutableParagraphStyle.new()
|
||||
style.setParagraphStyle_(NSParagraphStyle.defaultParagraphStyle())
|
||||
style.setAlignment_(NSCenterTextAlignment)
|
||||
return style
|
||||
|
||||
def _attribsAtSize(self, s):
|
||||
# This looks not exactly like the font on Preview.app's document icons,
|
||||
# but I believe that's because Preview's icons are drawn by Photoshop,
|
||||
# and Adobe's font rendering is different from Apple's.
|
||||
fontname = 'LucidaGrande-Bold'
|
||||
|
||||
# Prepare text format
|
||||
fontsizes = { 512: 72.0, 256: 36.0, 128: 18.0, 32: 7.0, 16: 3.0 }
|
||||
# http://developer.apple.com/documentation/Cocoa/Conceptual/AttributedStrings/Articles/standardAttributes.html#//apple_ref/doc/uid/TP40004903
|
||||
attribs = {
|
||||
NSParagraphStyleAttributeName: self.centeredStyle(),
|
||||
NSForegroundColorAttributeName: NSColor.colorWithDeviceWhite_alpha_(
|
||||
0.34, 1),
|
||||
NSFontAttributeName: NSFont.fontWithName_size_(fontname, fontsizes[s])
|
||||
}
|
||||
|
||||
# tighten font a bit for some sizes
|
||||
if s in [256, 512]:
|
||||
attribs[NSKernAttributeName] = -1.0
|
||||
elif s == 32:
|
||||
attribs[NSKernAttributeName] = -0.25
|
||||
|
||||
if not attribs[NSFontAttributeName]:
|
||||
raise Exception('Failed to load font %s' % fontname)
|
||||
return attribs
|
||||
|
||||
def drawTextAtSize(self, text, s):
|
||||
"""Draws text `s` into the current context of size `s`."""
|
||||
|
||||
textRects = {
|
||||
512: ((0, 7), (512, 119)),
|
||||
128: ((0, 6), (128, 26.5)),
|
||||
256: ((0, 7), (256, 57)),
|
||||
16: ((1, 1), (15, 5)),
|
||||
#32: ((1, 1), (31, 9))
|
||||
}
|
||||
|
||||
attribs = self.attribsAtSize(s)
|
||||
text = NSString.stringWithString_(text)
|
||||
if s in [16, 128, 256, 512]:
|
||||
text.drawInRect_withAttributes_(textRects[s], attribs)
|
||||
elif s == 32:
|
||||
# Try to align text on pixel boundary:
|
||||
attribs = attribs.copy()
|
||||
attribs[NSParagraphStyleAttributeName] = \
|
||||
NSParagraphStyle.defaultParagraphStyle()
|
||||
ts = text.sizeWithAttributes_(attribs)
|
||||
text.drawAtPoint_withAttributes_( (math.floor((32.0-ts[0])/2) + 0.5, 1.5),
|
||||
attribs)
|
||||
|
||||
|
||||
class OfficeTextRenderer(TextRenderer):
|
||||
"""Uses Office's LucidaSans font for 32x32.
|
||||
|
||||
This font looks much better for certain strings (e.g. "PDF") but much worse
|
||||
for most others (e.g. "VIM", "JAVA") -- and office fonts are usually not
|
||||
installed. Hence, this class is better not used.
|
||||
"""
|
||||
|
||||
def _attribsAtSize(self, s):
|
||||
self.useOfficeFont = False
|
||||
attribs = TextRenderer._attribsAtSize(self, s)
|
||||
if s == 32:
|
||||
font = NSFont.fontWithName_size_('LucidaSans-Demi', 7.0)
|
||||
if font:
|
||||
attribs[NSFontAttributeName] = font
|
||||
attribs[NSKernAttributeName] = 0
|
||||
self.useOfficeFont = True
|
||||
return attribs
|
||||
|
||||
def drawTextAtSize(self, text, s):
|
||||
attribs = self.attribsAtSize(s)
|
||||
if not self.useOfficeFont or s != 32:
|
||||
TextRenderer.drawTextAtSize(self, text, s)
|
||||
return
|
||||
text = NSString.stringWithString_(text)
|
||||
text.drawInRect_withAttributes_( ((0, 1), (31, 11)), attribs)
|
||||
|
||||
|
||||
def createIcon(s, bg, textRenderer, text):
|
||||
|
||||
# Fill in background
|
||||
output = bg.backgroundAtSize(s).copy()
|
||||
|
||||
# Draw text on top of shadow
|
||||
context = Context(output)
|
||||
if s in text and text[s]:
|
||||
textRenderer.drawTextAtSize(text[s], s)
|
||||
context.done()
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def textDictFromTextList(l):
|
||||
assert 1 <= len(l) <= 3
|
||||
if len(l) == 1:
|
||||
return dict.fromkeys([16, 32, 128, 256, 512], l[0])
|
||||
elif len(l) == 2:
|
||||
return dict(zip([16, 32], 2*[l[1]]) + zip((128, 256, 512), 3*[l[0]]))
|
||||
elif len(l) == 3:
|
||||
return dict([(16, l[2]), (32, l[1])] + zip((128, 256, 512), 3*[l[0]]))
|
||||
|
||||
|
||||
def saveIcns(icons, icnsName, makeIcns='./makeicns'):
|
||||
"""Creates an icns file with several variants.
|
||||
|
||||
Params:
|
||||
icons: A dict that contains icon size as key and Surface as value.
|
||||
Valid keys are 512, 256, 128, 32, 16
|
||||
icnsname: Name of the output file
|
||||
"""
|
||||
# If IconFamily was less buggy, we could wrap it into a python module and
|
||||
# call it directly, which is about a lot faster. However, IconFamily does not
|
||||
# work with NSAlphaNonpremultipliedBitmapFormat correctly, so this has to
|
||||
# wait.
|
||||
#import IconFamily
|
||||
#typeDict = {
|
||||
#16: IconFamily.kSmall32BitData,
|
||||
#32: IconFamily.kLarge32BitData,
|
||||
#128: IconFamily.kThumbnail32BitData,
|
||||
#256: IconFamily.kIconServices256PixelDataARGB,
|
||||
#512: IconFamily.IconServices512PixelDataARGB,
|
||||
#}
|
||||
#maskDict = {
|
||||
#16: IconFamily.kSmall8BitMask,
|
||||
#32: IconFamily.kLarge8BitMask,
|
||||
#128: IconFamily.kThumbnail8BitMask,
|
||||
#}
|
||||
#output = IconFamily.IconFamily.iconFamily()
|
||||
#for s, icon in icons.items():
|
||||
#output.setIconFamilyElement_fromBitmapImageRep_(typeDict[s], icon.bitmapRep)
|
||||
#if s in maskDict:
|
||||
#output.setIconFamilyElement_fromBitmapImageRep_(
|
||||
#maskDict[s], icon.bitmapRep)
|
||||
#output.writeToFile_(icnsName)
|
||||
TMPFILE = 'docerator_tmp_%d.png'
|
||||
try:
|
||||
args = []
|
||||
for s, icon in icons.items():
|
||||
assert s in [512, 256, 128, 32, 16]
|
||||
assert icon.size() == [s, s]
|
||||
icon.save(TMPFILE % s)
|
||||
args.append('-%d %s' % (s, TMPFILE % s))
|
||||
return \
|
||||
os.system('%s %s -out %s' % (makeIcns, ' '.join(args), icnsName)) == 0
|
||||
finally:
|
||||
for s in icons:
|
||||
if os.access(TMPFILE % s, os.F_OK):
|
||||
os.remove(TMPFILE % s)
|
||||
|
||||
|
||||
def getOutname(options):
|
||||
def saneBasename(p):
|
||||
""" '/my/path/to/file.txt' -> 'file' """
|
||||
return os.path.splitext(os.path.basename(p))[0]
|
||||
textPart = 'Generic'
|
||||
if options.text:
|
||||
textPart = options.text.split(',')[0]
|
||||
if options.appicon:
|
||||
base = saneBasename(options.appicon)
|
||||
else:
|
||||
base = saneBasename(getBgName(options))
|
||||
return '%s-%s.icns' % (base, textPart)
|
||||
|
||||
|
||||
def cachedImage(filename):
|
||||
absPath = os.path.abspath(filename)
|
||||
if not absPath in imageCache:
|
||||
imageCache[absPath] = Image(absPath)
|
||||
return imageCache[absPath]
|
||||
|
||||
|
||||
def cachedBackground(img, split):
|
||||
key = (img, split)
|
||||
if not key in bgCache:
|
||||
bgCache[key] = SplittableBackground(img, shouldSplit=split)
|
||||
return bgCache[key]
|
||||
|
||||
|
||||
# taken from running flow on preview
|
||||
defaultRects = {
|
||||
16: (-0.30890000000000001, 0.4919, -1.2968, 0.4743),
|
||||
32: (-0.27810000000000001,
|
||||
0.58930000000000005,
|
||||
-2.2292999999999998,
|
||||
0.57140000000000002),
|
||||
128: (1.1774, 0.56820000000000004, -0.8246, 0.56799999999999995),
|
||||
256: (0.5917, 0.56489999999999996, -1.8994, 0.56499999999999995),
|
||||
512: (0.68700000000000006,
|
||||
0.56530000000000002,
|
||||
-4.2813999999999997,
|
||||
0.56540000000000001)
|
||||
}
|
||||
|
||||
|
||||
def getBgName(options):
|
||||
if not hasattr(options, 'background') \
|
||||
or options.background in ['default-split', 'default-unsplit']:
|
||||
return DEFAULT_BACKGROUND
|
||||
else:
|
||||
return options.background
|
||||
|
||||
|
||||
class IconGenerator(object):
|
||||
def __init__(self, options):
|
||||
if hasattr(options, 'textrenderer') and options.textrenderer:
|
||||
self.textRenderer = options.textrenderer()
|
||||
else:
|
||||
self.textRenderer = TextRenderer()
|
||||
|
||||
# Prepare input images
|
||||
splitBackground = options.background == 'default-split'
|
||||
self.bgIcon = cachedImage(getBgName(options))
|
||||
|
||||
self.testIcon = None
|
||||
if options.appicon:
|
||||
self.testIcon = cachedImage(options.appicon)
|
||||
|
||||
rects = defaultRects.copy()
|
||||
rects[16] = [ 0.0000, 0.5000, -1.0000, 0.5000] # manually, better
|
||||
if hasattr(options, 'rects'):
|
||||
rects.update(options.rects)
|
||||
|
||||
bg = cachedBackground(self.bgIcon, splitBackground)
|
||||
|
||||
if hasattr(options, 'backgroundrenderer') and options.backgroundrenderer:
|
||||
self.bgRenderer = options.backgroundrenderer(bg, self.testIcon, rects)
|
||||
else:
|
||||
self.bgRenderer = BackgroundRenderer(bg, self.testIcon, rects)
|
||||
|
||||
self.testtext = textDictFromTextList(options.text.split(','))
|
||||
|
||||
def createIconAtSize(self, s):
|
||||
return createIcon(s, self.bgRenderer, self.textRenderer, self.testtext)
|
||||
|
||||
|
||||
def iconGenerator(**kwargs):
|
||||
return IconGenerator(optsFromDict(**kwargs))
|
||||
|
||||
|
||||
def makedocicon_opts(options):
|
||||
renderer = IconGenerator(options)
|
||||
|
||||
if hasattr(options, 'sizes') and options.sizes:
|
||||
if isinstance(options.sizes, list):
|
||||
sizes = options.sizes
|
||||
else:
|
||||
sizes = map(int, options.sizes.split(','))
|
||||
else:
|
||||
sizes = renderer.bgIcon.sizes()
|
||||
if renderer.testIcon:
|
||||
sizes = sizes.intersection(renderer.testIcon.sizes())
|
||||
sizes = sorted(map(operator.itemgetter(0), sizes))
|
||||
|
||||
icons = dict([(s, renderer.createIconAtSize(s)) for s in sizes])
|
||||
|
||||
if options.debug:
|
||||
for s, icon in icons.iteritems():
|
||||
icon.save(options.debug % s)
|
||||
|
||||
if hasattr(options, 'outname') and options.outname:
|
||||
outname = options.outname
|
||||
else:
|
||||
outname = getOutname(options)
|
||||
if saveIcns(icons, outname, options.makeicns):
|
||||
print 'Wrote', outname
|
||||
else:
|
||||
print 'Failed to write %s. Make sure makeicns is in your path.' % outname
|
||||
|
||||
|
||||
def optsFromDict(**kwargs):
|
||||
options, _ = getopts().parse_args([]) # get default options
|
||||
for k in kwargs:
|
||||
setattr(options, k, kwargs[k])
|
||||
return options
|
||||
|
||||
|
||||
def makedocicon(**kwargs):
|
||||
makedocicon_opts(optsFromDict(**kwargs))
|
||||
|
||||
|
||||
def makedocicons_opts(options):
|
||||
if not hasattr(options, 'text') or not options.text:
|
||||
options.text = ['']
|
||||
texts = options.text
|
||||
for text in texts:
|
||||
options.text = text
|
||||
makedocicon_opts(options)
|
||||
|
||||
|
||||
def makedocicons(**kwargs):
|
||||
makedocicons_opts(optsFromDict(**kwargs))
|
||||
|
||||
|
||||
def getopts():
|
||||
parser = OptionParser(usage='%prog [options]', version='%prog 1.01')
|
||||
parser.add_option('--background', '--bg', default='default-split',
|
||||
help='Used as background (special values: "default-split" (default), ' \
|
||||
'"default-unsplit").')
|
||||
parser.add_option('--appicon', help='App icon, defaults to no icon.')
|
||||
|
||||
parser.add_option('--text', help='Text on icon. Defaults to empty. '
|
||||
'More than one text is supported, multiple docicons are generated in '
|
||||
'that case.', action='append')
|
||||
parser.add_option('--sizes', help='Sizes of icons. ' \
|
||||
'Defaults to all sizes available in input appicon. Example: "512,128,16"')
|
||||
# XXX(Nico): This has to go
|
||||
parser.add_option('--debug', help='If set, write out pngs for all variants.' \
|
||||
' This needs to look like "debug%d.png".')
|
||||
# XXX(Nico): This has to go once IconFamily is less buggy and can be used
|
||||
# directly
|
||||
parser.add_option('--makeicns', help='Path to makeicns binary',
|
||||
default='./makeicns')
|
||||
return parser
|
||||
|
||||
|
||||
def main():
|
||||
options, args = getopts().parse_args()
|
||||
makedocicons_opts(options)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,65 @@
|
||||
import docerator
|
||||
import unittest
|
||||
|
||||
|
||||
class TextDictFromTextListTest(unittest.TestCase):
|
||||
|
||||
def testBasic(self):
|
||||
|
||||
self.assertEquals({16: 'a', 32: 'a', 128: 'a', 256: 'a', 512: 'a'},
|
||||
docerator.textDictFromTextList(['a']))
|
||||
self.assertEquals({16: 'b', 32: 'b', 128: 'a', 256: 'a', 512: 'a'},
|
||||
docerator.textDictFromTextList(['a', 'b']))
|
||||
self.assertEquals({16: 'c', 32: 'b', 128: 'a', 256: 'a', 512: 'a'},
|
||||
docerator.textDictFromTextList(['a', 'b', 'c']))
|
||||
|
||||
|
||||
class OutnameTest(unittest.TestCase):
|
||||
|
||||
class FakeOptions(object):
|
||||
def __init__(self, **kwargs):
|
||||
for k in kwargs:
|
||||
self.__setattr__(k, kwargs[k])
|
||||
|
||||
def testBasic(self):
|
||||
options = OutnameTest.FakeOptions(
|
||||
appicon = '/Applications/iTunes.app/Contents/Resources/iTunes.icns',
|
||||
text='MP3')
|
||||
self.assertEquals('iTunes-MP3.icns', docerator.getOutname(options))
|
||||
|
||||
def testTextList(self):
|
||||
options = OutnameTest.FakeOptions(
|
||||
appicon = '/Applications/iTunes.app/Contents/Resources/iTunes.icns',
|
||||
text='PYTHON,PY')
|
||||
self.assertEquals('iTunes-PYTHON.icns',
|
||||
docerator.getOutname(options))
|
||||
|
||||
def testEmptyText(self):
|
||||
options = OutnameTest.FakeOptions(
|
||||
appicon = '/Applications/iTunes.app/Contents/Resources/iTunes.icns',
|
||||
text='')
|
||||
self.assertEquals('iTunes-Generic.icns', docerator.getOutname(options))
|
||||
options = OutnameTest.FakeOptions(
|
||||
appicon = '/Applications/iTunes.app/Contents/Resources/iTunes.icns',
|
||||
text=None)
|
||||
self.assertEquals('iTunes-Generic.icns',
|
||||
docerator.getOutname(options))
|
||||
|
||||
def testEmptyIcon(self):
|
||||
options = OutnameTest.FakeOptions(appicon=None, text='MP3')
|
||||
self.assertEquals('GenericDocumentIcon-MP3.icns',
|
||||
docerator.getOutname(options))
|
||||
options = OutnameTest.FakeOptions(appicon=None, text='')
|
||||
self.assertEquals('GenericDocumentIcon-Generic.icns',
|
||||
docerator.getOutname(options))
|
||||
options = OutnameTest.FakeOptions(appicon=None, text='',
|
||||
background='/Applications/Bla/bgicon.icns')
|
||||
self.assertEquals('bgicon-Generic.icns',
|
||||
docerator.getOutname(options))
|
||||
|
||||
|
||||
# XXX(Nico): Look at the doctest module.
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,56 @@
|
||||
// A small python module that registers a font with ATS, given the name of
|
||||
// the font.
|
||||
|
||||
#include <Python/Python.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
static PyObject* loadfont(PyObject* self, PyObject* args) {
|
||||
PyObject* result = Py_False;
|
||||
const char* path = NULL;
|
||||
int ok = PyArg_ParseTuple(args, "s", &path);
|
||||
|
||||
if (ok) {
|
||||
CFStringRef componentPath = CFStringCreateWithCString(kCFAllocatorDefault,
|
||||
path, kCFStringEncodingUTF8);
|
||||
CFURLRef componentURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
|
||||
componentPath, kCFURLPOSIXPathStyle, false);
|
||||
FSRef fsref;
|
||||
|
||||
if (CFURLGetFSRef(componentURL, &fsref)) {
|
||||
OSStatus err = noErr;
|
||||
ATSFontContainerRef fontContainerRef; // we don't deactivate the font
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
err = ATSFontActivateFromFileReference(&fsref,
|
||||
kATSFontContextLocal, kATSFontFormatUnspecified, NULL,
|
||||
kATSOptionFlagsDefault, &fontContainerRef);
|
||||
#else
|
||||
FSSpec fsSpec;
|
||||
FSRef fsRef;
|
||||
if ((err = FSGetCatalogInfo(
|
||||
&fsRef, kFSCatInfoNone, NULL, NULL, &fsSpec, NULL)) == noErr) {
|
||||
err = ATSFontActivateFromFileSpecification(&fsSpec,
|
||||
kATSFontContextLocal, kATSFontFormatUnspecified, NULL,
|
||||
kATSOptionFlagsDefault, &fontContainerRef);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (err == noErr) {
|
||||
result = Py_True;
|
||||
}
|
||||
}
|
||||
CFRelease(componentURL);
|
||||
CFRelease(componentPath);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyMethodDef LoadfontMethods[] = {
|
||||
{ "loadfont", loadfont, METH_VARARGS, "Locally activates font from file." },
|
||||
{ NULL, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC initloadfont(void) {
|
||||
Py_InitModule("loadfont", LoadfontMethods);
|
||||
}
|
||||
+98
-449
@@ -1,31 +1,51 @@
|
||||
# Creates a document icon from an app icon and an optional text.
|
||||
|
||||
# The font is not quite right, use this script to create a document icon
|
||||
# for 'PDF' and compare the D with the D in Preview's pdf.icns
|
||||
# Creates all of MacVim document icons.
|
||||
|
||||
# http://www.macresearch.org/cocoa-scientists-part-xx-python-scriptersmeet-cocoa
|
||||
try:
|
||||
from Foundation import *
|
||||
# Make us independent of sysprefs->appearance->antialias fonts smaller than...
|
||||
# Needs to happen before docerator is imported.
|
||||
from AppKit import NSUserDefaults
|
||||
prefs = NSUserDefaults.standardUserDefaults()
|
||||
prefs.setInteger_forKey_(4, 'AppleAntiAliasingThreshold')
|
||||
|
||||
import docerator
|
||||
|
||||
# Load Envy Code R from a file and register it under its postscript name
|
||||
# Thanks to DamienG for this font (redistributed with permission):
|
||||
# http://damieng.com/blog/2008/05/26/envy-code-r-preview-7-coding-font-released
|
||||
import loadfont
|
||||
loadfont.loadfont('Envy Code R Bold.ttf')
|
||||
|
||||
from Foundation import NSString
|
||||
from AppKit import *
|
||||
|
||||
dont_create = False
|
||||
except:
|
||||
dont_create = True # most likely because we're on tiger
|
||||
NSCompositeSourceOver = 2
|
||||
|
||||
import math
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
# icon types
|
||||
LARGE = 0 # 512, 128, 32, 16; about 96kB
|
||||
SMALL = 1 # 128, 32, 16; about 36kB
|
||||
LINK = 2 # Create link to generic icon; 4kB (== smallest block size on HFS+)
|
||||
|
||||
# path to makeicns binary
|
||||
iconsizes = {
|
||||
SMALL: [128, 32, 16],
|
||||
LARGE: [512, 128, 32, 16],
|
||||
}
|
||||
|
||||
|
||||
# Resources
|
||||
MAKEICNS = 'makeicns/makeicns'
|
||||
APPICON = 'vim-noshadow-512.png'
|
||||
DEFAULT_BACKGROUND = '/System/Library/CoreServices/CoreTypes.bundle/' + \
|
||||
'Contents/Resources/GenericDocumentIcon.icns'
|
||||
|
||||
|
||||
# List of icons to create
|
||||
# XXX: 32x32 variants only support 3-4 letters of text
|
||||
GENERIC_ICON_NAME = 'MacVim-generic'
|
||||
vimIcons = {
|
||||
GENERIC_ICON_NAME: [u'', LARGE],
|
||||
@@ -36,19 +56,19 @@ vimIcons = {
|
||||
'MacVim-c': [u'C', SMALL],
|
||||
'MacVim-m': [u'M', SMALL],
|
||||
'MacVim-mm': [u'MM', SMALL],
|
||||
'MacVim-cpp': [u'C\uff0b\uff0b', SMALL], # fullwidth plusses
|
||||
'MacVim-cpp': [u'C\uff0b\uff0b,C++,C++', SMALL], # fullwidth plusses
|
||||
'MacVim-java': [u'JAVA', SMALL],
|
||||
'MacVim-f': [u'FTRAN', SMALL],
|
||||
'MacVim-html': [u'HTML', SMALL],
|
||||
'MacVim-xml': [u'XML', SMALL],
|
||||
'MacVim-js': [u'JS', SMALL],
|
||||
'MacVim-perl': [u'PERL', SMALL],
|
||||
'MacVim-py': [u'PYTHON', SMALL],
|
||||
'MacVim-perl': [u'PERL,PL', SMALL],
|
||||
'MacVim-py': [u'PYTHON,PY', SMALL],
|
||||
'MacVim-php': [u'PHP', SMALL],
|
||||
'MacVim-rb': [u'RUBY', SMALL],
|
||||
'MacVim-rb': [u'RUBY,RB', SMALL],
|
||||
'MacVim-bash': [u'SH', SMALL],
|
||||
'MacVim-patch': [u'DIFF', SMALL],
|
||||
'MacVim-applescript': [u'\uf8ffSCPT', SMALL], # apple sign
|
||||
'MacVim-applescript': [u'\uf8ffSCPT,\uf8ffS', SMALL], # apple sign
|
||||
'MacVim-as': [u'FLASH', LINK],
|
||||
'MacVim-asp': [u'ASP', LINK],
|
||||
'MacVim-bib': [u'BIB', LINK],
|
||||
@@ -61,8 +81,8 @@ vimIcons = {
|
||||
'MacVim-css': [u'CSS', SMALL],
|
||||
'MacVim-dtd': [u'DTD', LINK],
|
||||
'MacVim-dylan': [u'DYLAN', LINK],
|
||||
'MacVim-erl': [u'ERLANG', SMALL],
|
||||
'MacVim-fscript': [u'FSCPT', SMALL],
|
||||
'MacVim-erl': [u'ERLANG,ERL', SMALL],
|
||||
'MacVim-fscript': [u'FSCPT,FSCR,FS', SMALL],
|
||||
'MacVim-hs': [u'HS', SMALL],
|
||||
'MacVim-inc': [u'INC', LINK],
|
||||
'MacVim-ics': [u'ICS', SMALL],
|
||||
@@ -71,385 +91,24 @@ vimIcons = {
|
||||
'MacVim-bsh': [u'BSH', LINK],
|
||||
'MacVim-properties': [u'PROP', LINK],
|
||||
'MacVim-jsp': [u'JSP', SMALL],
|
||||
'MacVim-lisp': [u'LISP', SMALL],
|
||||
'MacVim-lisp': [u'LISP,LISP,LSP', SMALL],
|
||||
'MacVim-log': [u'LOG', SMALL],
|
||||
'MacVim-wiki': [u'WIKI', SMALL],
|
||||
'MacVim-ps': [u'PS', LINK],
|
||||
#'MacVim-plist': [u'PLIST', SMALL],
|
||||
'MacVim-sch': [u'SCHEME', SMALL],
|
||||
'MacVim-sch': [u'SCHEME,SCM', SMALL],
|
||||
'MacVim-sql': [u'SQL', SMALL],
|
||||
'MacVim-tcl': [u'TCL', SMALL],
|
||||
'MacVim-xsl': [u'XSL', LINK],
|
||||
'MacVim-vcf': [u'VCARD', SMALL],
|
||||
'MacVim-vb': [u'VBASIC', LINK],
|
||||
'MacVim-yaml': [u'YAML', SMALL],
|
||||
'MacVim-vcf': [u'VCARD,VCF', SMALL],
|
||||
'MacVim-vb': [u'VBASIC,VB', LINK],
|
||||
'MacVim-yaml': [u'YAML,YAML,YML', SMALL],
|
||||
'MacVim-gtd': [u'GTD', LINK],
|
||||
'MacVim-markdown': [u'MARK\u2193,M\u2193', LINK], # down arrow
|
||||
'MacVim-rst': [u'RST', LINK],
|
||||
'MacVim-vba': [u'VBA', LINK],
|
||||
}
|
||||
|
||||
shorttext = {
|
||||
u'MacVim-py': u'PY',
|
||||
u'MacVim-rb': u'RB',
|
||||
u'MacVim-perl': u'PL',
|
||||
u'MacVim-applescript': u'\uf8ffS',
|
||||
u'MacVim-erl': u'ERL',
|
||||
u'MacVim-fscript': u'FSCR',
|
||||
u'MacVim-sch': u'SCM',
|
||||
u'MacVim-vcf': u'VCF',
|
||||
u'MacVim-vb': u'VB',
|
||||
}
|
||||
|
||||
|
||||
# Resources
|
||||
BACKGROUND = '/System/Library/CoreServices/CoreTypes.bundle/' + \
|
||||
'Contents/Resources/GenericDocumentIcon.icns' # might require leopard?
|
||||
APPICON = 'vim-noshadow-512.png'
|
||||
#APPICON = 'vim-noshadow-no-v-512.png'
|
||||
|
||||
class Surface(object):
|
||||
"""Represents a simple bitmapped image."""
|
||||
|
||||
def __init__(self, *p, **kw):
|
||||
if not 'premultiplyAlpha' in kw:
|
||||
kw['premultiplyAlpha'] = True
|
||||
if len(p) == 1 and isinstance(p[0], NSBitmapImageRep):
|
||||
self.bitmapRep = p[0]
|
||||
elif len(p) == 2 and isinstance(p[0], int) and isinstance(p[1], int):
|
||||
format = NSAlphaFirstBitmapFormat
|
||||
if not kw['premultiplyAlpha']:
|
||||
format += NSAlphaNonpremultipliedBitmapFormat
|
||||
self.bitmapRep = NSBitmapImageRep.alloc().initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel_(
|
||||
None, p[0], p[1], 8, 4, True, False, NSDeviceRGBColorSpace,
|
||||
format, 0, 0)
|
||||
|
||||
if not hasattr(self, 'bitmapRep') or not self.bitmapRep:
|
||||
raise Exception('Failed to create surface: ' + str(p))
|
||||
|
||||
def size(self):
|
||||
return map(int, self.bitmapRep.size()) # cocoa returns floats. cocoa ftw
|
||||
|
||||
def data(self):
|
||||
"""Returns data in ARGB order (on intel, at least)."""
|
||||
r = self.bitmapRep
|
||||
if r.bitmapFormat() != (NSAlphaNonpremultipliedBitmapFormat |
|
||||
NSAlphaFirstBitmapFormat) or \
|
||||
r.bitsPerPixel() != 32 or \
|
||||
r.isPlanar() or \
|
||||
r.samplesPerPixel() != 4:
|
||||
raise Exception("Unsupported image format")
|
||||
return self.bitmapRep.bitmapData()
|
||||
|
||||
def save(self, filename):
|
||||
"""Saves image as png file."""
|
||||
self.bitmapRep.representationUsingType_properties_(NSPNGFileType, None) \
|
||||
.writeToFile_atomically_(filename, True)
|
||||
|
||||
def draw(self):
|
||||
self.bitmapRep.draw()
|
||||
|
||||
def context(self):
|
||||
# Note: Cocoa only supports contexts with premultiplied alpha
|
||||
return NSGraphicsContext.graphicsContextWithBitmapImageRep_(self.bitmapRep)
|
||||
|
||||
def copy(self):
|
||||
return Surface(self.bitmapRep.copy())
|
||||
|
||||
|
||||
class Image(object):
|
||||
"""Represents an image that can consist of several Surfaces."""
|
||||
|
||||
def __init__(self, param):
|
||||
if isinstance(param, str):
|
||||
self.image = NSImage.alloc().initWithContentsOfFile_(param)
|
||||
elif isinstance(param, Surface):
|
||||
self.image = NSImage.alloc().initWithSize_( param.size() )
|
||||
self.image.addRepresentation_(param.bitmapRep)
|
||||
|
||||
if not self.image:
|
||||
raise Exception('Failed to load image: ' + str(filename))
|
||||
|
||||
def surfaceOfSize(self, w, h):
|
||||
"""Returns an ARGB, non-premultiplied surface of size w*h or throws."""
|
||||
r = None
|
||||
for rep in self.image.representations():
|
||||
if map(int, rep.size()) == [w, h]:
|
||||
r = rep
|
||||
break
|
||||
if not r:
|
||||
raise Exception('Unsupported size %dx%d', w, h)
|
||||
return Surface(r)
|
||||
|
||||
def blend(self):
|
||||
self.compositeInRect( ((0, 0), self.image.size()) )
|
||||
|
||||
def compositeInRect(self, r, mode=NSCompositeSourceOver):
|
||||
self.image.drawInRect_fromRect_operation_fraction_(r, NSZeroRect,
|
||||
mode, 1.0)
|
||||
|
||||
|
||||
class Context(object):
|
||||
# Tiger has only Python2.3, so we can't use __enter__ / __exit__ for this :-(
|
||||
|
||||
def __init__(self, surface):
|
||||
NSGraphicsContext.saveGraphicsState()
|
||||
c = surface.context()
|
||||
c.setShouldAntialias_(True);
|
||||
c.setImageInterpolation_(NSImageInterpolationHigh);
|
||||
NSGraphicsContext.setCurrentContext_(c)
|
||||
|
||||
def done(self):
|
||||
NSGraphicsContext.restoreGraphicsState()
|
||||
|
||||
|
||||
class SplittableBackground(object):
|
||||
|
||||
def __init__(self, unsplitted, shouldSplit=True):
|
||||
self.unsplitted = unsplitted
|
||||
self.shouldSplit = shouldSplit
|
||||
self.ground = {}
|
||||
self.shadow = {}
|
||||
|
||||
def rawGroundAtSize(self, s):
|
||||
return self.unsplitted.surfaceOfSize(s, s)
|
||||
|
||||
def groundAtSize(self, s):
|
||||
if not self.shouldSplit:
|
||||
return self.rawGroundAtSize(s)
|
||||
self._performSplit(s)
|
||||
return self.ground[s]
|
||||
|
||||
def shadowAtSize(self, s):
|
||||
if not self.shouldSplit:
|
||||
return None
|
||||
self._performSplit(s)
|
||||
return self.shadow[s]
|
||||
|
||||
def _performSplit(self, s):
|
||||
if s in self.ground:
|
||||
assert s in self.shadow
|
||||
return
|
||||
assert s not in self.shadow
|
||||
ground, shadow = splitGenericDocumentIcon(self.unsplitted, s)
|
||||
self.ground[s] = ground
|
||||
self.shadow[s] = shadow
|
||||
|
||||
|
||||
class BackgroundRenderer(object):
|
||||
|
||||
def __init__(self, bg, icon=None):
|
||||
self.bgRenderer = bg
|
||||
self.icon = icon
|
||||
self.cache = {}
|
||||
|
||||
def drawIcon(self, s):
|
||||
if not self.icon:
|
||||
return
|
||||
# found by flow program, better than anything i came up with manually before
|
||||
# (except for the 16x16 variant :-( )
|
||||
transforms = {
|
||||
512: [ 0.7049, 0.5653, -4.2432, 0.5656],
|
||||
256: [ 0.5690, 0.5658, -1.9331, 0.5656],
|
||||
128: [ 1.1461, 0.5684, -0.8482, 0.5681],
|
||||
|
||||
32: [-0.2682, 0.5895, -2.2130, 0.5701], # intensity
|
||||
#32: [-0.2731, 0.5898, -2.2262, 0.5729], # rgb (no rmse difference)
|
||||
|
||||
#16: [-0.3033, 0.4909, -1.3235, 0.4790], # program, intensity
|
||||
#16: [-0.3087, 0.4920, -1.2990, 0.4750], # program, rgb mode
|
||||
16: [ 0.0000, 0.5000, -1.0000, 0.5000], # manually, better
|
||||
}
|
||||
|
||||
assert s in [16, 32, 128, 256, 512]
|
||||
a = transforms[s]
|
||||
|
||||
# convert from `flow` coords to cocoa
|
||||
a[2] = -a[2] # mirror y
|
||||
|
||||
w, h = s*a[1], s*a[3]
|
||||
self.icon.compositeInRect( (((s-w)/2 + a[0], (s-h)/2 + a[2]), (w, h)) )
|
||||
|
||||
def drawAtSize(self, s):
|
||||
self.bgRenderer.groundAtSize(s).draw()
|
||||
self.drawIcon(s)
|
||||
if self.bgRenderer.shouldSplit:
|
||||
# shadow needs to be composited, so it needs to be in an image
|
||||
Image(self.bgRenderer.shadowAtSize(s)).blend()
|
||||
|
||||
def backgroundAtSize(self, s):
|
||||
if not s in self.cache:
|
||||
result = Surface(s, s)
|
||||
context = Context(result)
|
||||
self.drawAtSize(s)
|
||||
context.done()
|
||||
self.cache[s] = result
|
||||
return self.cache[s]
|
||||
|
||||
|
||||
def splitGenericDocumentIcon(img, s):
|
||||
"""Takes the generic document icon and splits it into a background and a
|
||||
shadow layer. For the 32x32 and 16x16 variants, the white pixels of the page
|
||||
curl are hardcoded into the otherwise transparent shadow layer."""
|
||||
|
||||
w, h = s, s
|
||||
r = img.surfaceOfSize(w, h)
|
||||
bps = 4*w
|
||||
data = r.data()
|
||||
|
||||
ground = Surface(w, h, premultiplyAlpha=False)
|
||||
shadow = Surface(w, h, premultiplyAlpha=False)
|
||||
|
||||
grounddata = ground.data()
|
||||
shadowdata = shadow.data()
|
||||
|
||||
for y in xrange(h):
|
||||
for x in xrange(w):
|
||||
idx = y*bps + 4*x
|
||||
ia, ir, ig, ib = data[idx:idx + 4]
|
||||
if ia != chr(255):
|
||||
# buffer objects don't support slice assignment :-(
|
||||
grounddata[idx] = ia
|
||||
grounddata[idx + 1] = ir
|
||||
grounddata[idx + 2] = ig
|
||||
grounddata[idx + 3] = ib
|
||||
shadowdata[idx] = chr(0)
|
||||
shadowdata[idx + 1] = chr(0)
|
||||
shadowdata[idx + 2] = chr(0)
|
||||
shadowdata[idx + 3] = chr(0)
|
||||
continue
|
||||
|
||||
assert ir == ig == ib
|
||||
grounddata[idx] = chr(255)
|
||||
grounddata[idx + 1] = chr(255)
|
||||
grounddata[idx + 2] = chr(255)
|
||||
grounddata[idx + 3] = chr(255)
|
||||
shadowdata[idx] = chr(255 - ord(ir))
|
||||
shadowdata[idx + 1] = chr(0)
|
||||
shadowdata[idx + 2] = chr(0)
|
||||
shadowdata[idx + 3] = chr(0)
|
||||
|
||||
# Special-case 16x16 and 32x32 cases: Make some pixels on the fold white.
|
||||
# Ideally, I could make the fold whiteish in all variants, but I can't.
|
||||
whitePix = { 16: [(10, 2), (10, 3), (11, 3), (10, 4), (11, 4), (12, 4)],
|
||||
32: [(21, 4), (21, 5), (22, 5), (21, 6), (22, 6), (23, 6)]}
|
||||
if (w, h) in [(16, 16), (32, 32)]:
|
||||
for x, y in whitePix[w]:
|
||||
idx = y*bps + 4*x
|
||||
shadowdata[idx] = chr(255)
|
||||
shadowdata[idx + 1] = chr(255)
|
||||
shadowdata[idx + 2] = chr(255)
|
||||
shadowdata[idx + 3] = chr(255)
|
||||
|
||||
return ground, shadow
|
||||
|
||||
|
||||
class TextRenderer(object):
|
||||
|
||||
def __init__(self):
|
||||
self.cache = {}
|
||||
|
||||
def attribsAtSize(self, s):
|
||||
if s not in self.cache:
|
||||
self.cache[s] = self._attribsAtSize(s)
|
||||
return self.cache[s]
|
||||
|
||||
def centeredStyle(self):
|
||||
style = NSMutableParagraphStyle.new()
|
||||
style.setParagraphStyle_(NSParagraphStyle.defaultParagraphStyle())
|
||||
style.setAlignment_(NSCenterTextAlignment)
|
||||
return style
|
||||
|
||||
def _attribsAtSize(self, s):
|
||||
# This looks not exactly like the font on Preview.app's document icons,
|
||||
# but I believe that's because Preview's icons are drawn by Photoshop,
|
||||
# and Adobe's font rendering is different from Apple's.
|
||||
fontname = 'LucidaGrande-Bold'
|
||||
|
||||
# Prepare text format
|
||||
fontsizes = { 512: 72.0, 256: 36.0, 128: 18.0, 32: 7.0, 16: 3.0 }
|
||||
# http://developer.apple.com/documentation/Cocoa/Conceptual/AttributedStrings/Articles/standardAttributes.html#//apple_ref/doc/uid/TP40004903
|
||||
attribs = {
|
||||
NSParagraphStyleAttributeName: self.centeredStyle(),
|
||||
NSForegroundColorAttributeName: NSColor.colorWithDeviceWhite_alpha_(
|
||||
0.34, 1),
|
||||
NSFontAttributeName: NSFont.fontWithName_size_(fontname, fontsizes[s])
|
||||
}
|
||||
|
||||
# tighten font a bit for some sizes
|
||||
if s in [256, 512]:
|
||||
attribs[NSKernAttributeName] = -1.0
|
||||
elif s == 32:
|
||||
attribs[NSKernAttributeName] = -0.25
|
||||
|
||||
if not attribs[NSFontAttributeName]:
|
||||
raise Exception('Failed to load font %s' % fontname)
|
||||
return attribs
|
||||
|
||||
def drawTextAtSize(self, text, s):
|
||||
"""Draws text `s` into the current context of size `s`."""
|
||||
|
||||
textRects = {
|
||||
512: ((0, 7), (512, 119)),
|
||||
128: ((0, 6), (128, 26.5)),
|
||||
256: ((0, 7), (256, 57)),
|
||||
16: ((1, 1), (15, 5)),
|
||||
#32: ((1, 1), (31, 9))
|
||||
}
|
||||
|
||||
attribs = self.attribsAtSize(s)
|
||||
text = NSString.stringWithString_(text)
|
||||
if s in [16, 128, 256, 512]:
|
||||
text.drawInRect_withAttributes_(textRects[s], attribs)
|
||||
elif s == 32:
|
||||
# Try to align text on pixel boundary:
|
||||
attribs = attribs.copy()
|
||||
attribs[NSParagraphStyleAttributeName] = \
|
||||
NSParagraphStyle.defaultParagraphStyle()
|
||||
ts = text.sizeWithAttributes_(attribs)
|
||||
text.drawAtPoint_withAttributes_( (math.floor((32.0-ts[0])/2) + 0.5, 1.5),
|
||||
attribs)
|
||||
|
||||
|
||||
class OfficeTextRenderer(TextRenderer):
|
||||
"""Uses Office's LucidaSans font for 32x32.
|
||||
|
||||
This font looks much better for certain strings (e.g. "PDF") but much worse
|
||||
for most others (e.g. "VIM", "JAVA") -- and office fonts are usually not
|
||||
installed. Hence, this class is better not used.
|
||||
"""
|
||||
|
||||
def _attribsAtSize(self, s):
|
||||
self.useOfficeFont = False
|
||||
attribs = TextRenderer._attribsAtSize(self, s)
|
||||
if s == 32:
|
||||
font = NSFont.fontWithName_size_('LucidaSans-Demi', 7.0)
|
||||
if font:
|
||||
attribs[NSFontAttributeName] = font
|
||||
attribs[NSKernAttributeName] = 0
|
||||
self.useOfficeFont = True
|
||||
return attribs
|
||||
|
||||
def drawTextAtSize(self, text, s):
|
||||
attribs = self.attribsAtSize(s)
|
||||
if not self.useOfficeFont or s != 32:
|
||||
TextRenderer.drawTextAtSize(self, text, s)
|
||||
return
|
||||
text = NSString.stringWithString_(text)
|
||||
text.drawInRect_withAttributes_( ((0, 1), (31, 11)), attribs)
|
||||
|
||||
|
||||
def createIcon(s, bg, textRenderer, text, shorttext=None):
|
||||
|
||||
# Fill in background
|
||||
output = bg.backgroundAtSize(s).copy()
|
||||
|
||||
# Draw text on top of shadow
|
||||
context = Context(output)
|
||||
if s in [16, 32] and shorttext:
|
||||
text = shorttext
|
||||
textRenderer.drawTextAtSize(text, s)
|
||||
context.done()
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def createLinks(icons, target):
|
||||
assert len(icons) > 0
|
||||
@@ -460,80 +119,75 @@ def createLinks(icons, target):
|
||||
os.symlink(target, icnsName)
|
||||
|
||||
|
||||
def saveIcns(icons, icnsName, makeIcns='./makeicns'):
|
||||
"""Creates an icns file with several variants.
|
||||
if not dont_create:
|
||||
# define a few classes to render custom 16x16 icons
|
||||
|
||||
Params:
|
||||
icons: A dict that contains icon size as key and Surface as value.
|
||||
Valid keys are 512, 256, 128, 32, 16
|
||||
icnsname: Name of the output file
|
||||
"""
|
||||
# XXX: Figure out how to call ObjC directly from Python, then this doesn't
|
||||
# need to call a different process and do lots of i/o.
|
||||
args = []
|
||||
for s, icon in icons.items():
|
||||
assert s in [512, 256, 128, 32, 16]
|
||||
assert icon.size() == [s, s]
|
||||
icon.save(TMPFILE % s)
|
||||
args.append('-%d %s' % (s, TMPFILE % s))
|
||||
os.system('%s %s -out %s' % (makeIcns, ' '.join(args), icnsName))
|
||||
class NoTextRenderer(docerator.TextRenderer):
|
||||
def drawTextAtSize(self, text, s):
|
||||
if s == 16: return # No text at 16x16
|
||||
docerator.TextRenderer.drawTextAtSize(self, text, s)
|
||||
|
||||
class NoIconRenderer(docerator.BackgroundRenderer):
|
||||
def drawIcon(self, s):
|
||||
if s == 16: return # no "MacVim" icon on the sheet at 16x16
|
||||
docerator.BackgroundRenderer.drawIcon(self, s)
|
||||
|
||||
class SmallTextRenderer(docerator.TextRenderer):
|
||||
def _attribsAtSize(self, s):
|
||||
attribs = docerator.TextRenderer._attribsAtSize(self, s)
|
||||
if s == 16:
|
||||
font = NSFont.fontWithName_size_('EnvyCodeR-Bold', 7.0)
|
||||
assert font
|
||||
attribs[NSFontAttributeName] = font
|
||||
attribs[NSForegroundColorAttributeName] = \
|
||||
NSColor.colorWithDeviceRed_green_blue_alpha_(
|
||||
0/255.0, 82/255.0, 0/255.0, 1)
|
||||
return attribs
|
||||
|
||||
def drawTextAtSize(self, text, s):
|
||||
if s != 16:
|
||||
docerator.TextRenderer.drawTextAtSize(self, text, s)
|
||||
return
|
||||
text = NSString.stringWithString_(text.lower()[0:3]) # at most 3 chars
|
||||
attribs = self.attribsAtSize(s)
|
||||
if len(text) <= 2:
|
||||
attribs[NSKernAttributeName] = 0 # we have some space
|
||||
else:
|
||||
attribs[NSKernAttributeName] = -1 # we need all the room we can get
|
||||
text.drawInRect_withAttributes_( ((1, 2), (15, 11)), attribs)
|
||||
|
||||
|
||||
TMPFILE = 'make_icons_tmp_%d.png'
|
||||
sizes = [512, 128, 32, 16]
|
||||
def main():
|
||||
if dont_create:
|
||||
print "PyObjC not found, only using a stock icon for document icons."
|
||||
# Can't use the constants from docerator in this case
|
||||
import shutil
|
||||
shutil.copyfile(DEFAULT_BACKGROUND, '%s.icns' % GENERIC_ICON_NAME)
|
||||
createLinks([name for name in vimIcons if name != GENERIC_ICON_NAME],
|
||||
'%s.icns' % GENERIC_ICON_NAME)
|
||||
return
|
||||
|
||||
srcdir = os.getcwd()
|
||||
if len(sys.argv) > 1:
|
||||
os.chdir(sys.argv[1])
|
||||
appIcon = os.path.join(srcdir, APPICON)
|
||||
makeIcns = os.path.join(srcdir, MAKEICNS)
|
||||
|
||||
if dont_create:
|
||||
print "PyObjC not found, only using a stock icon for document icons."
|
||||
import shutil
|
||||
shutil.copyfile(BACKGROUND, '%s.icns' % GENERIC_ICON_NAME)
|
||||
createLinks([name for name in vimIcons if name != GENERIC_ICON_NAME],
|
||||
'%s.icns' % GENERIC_ICON_NAME)
|
||||
return
|
||||
# Make us not crash
|
||||
# http://www.cocoabuilder.com/archive/message/cocoa/2008/8/6/214964
|
||||
NSApplicationLoad()
|
||||
|
||||
textRenderer = TextRenderer()
|
||||
#textRenderer = OfficeTextRenderer()
|
||||
|
||||
# Prepare input images
|
||||
bgIcon = Image(BACKGROUND)
|
||||
|
||||
#bg = SplittableBackground(bgIcon, shouldSplit=False)
|
||||
bg = SplittableBackground(bgIcon, shouldSplit=True)
|
||||
|
||||
icon = Image(appIcon)
|
||||
bgRenderer = BackgroundRenderer(bg, icon)
|
||||
|
||||
if not os.access(makeIcns, os.X_OK):
|
||||
print 'Cannot find makeicns at %s', makeIcns
|
||||
return
|
||||
|
||||
# create LARGE and SMALL icons first...
|
||||
for name, t in vimIcons.iteritems():
|
||||
text, size = t
|
||||
if size == LINK: continue
|
||||
print name
|
||||
icnsName = '%s.icns' % name
|
||||
|
||||
if size == SMALL:
|
||||
currSizes = [128, 32, 16]
|
||||
elif size == LARGE:
|
||||
currSizes = [512, 128, 32, 16]
|
||||
|
||||
st = shorttext.get(name)
|
||||
icons = [(s, createIcon(s, bgRenderer, textRenderer, text, shorttext=st))
|
||||
for s in currSizes]
|
||||
icons = dict(icons)
|
||||
saveIcns(icons, '%s.icns' % name, makeIcns)
|
||||
|
||||
del text, size, name, t
|
||||
if name == GENERIC_ICON_NAME:
|
||||
# The generic icon has no text; make the appicon a bit larger
|
||||
docerator.makedocicon(outname='%s.icns' % name, appicon=appIcon,
|
||||
text=text, sizes=iconsizes[size], makeicns=makeIcns,
|
||||
textrenderer=NoTextRenderer, rects={16:(0.0, 0.5533, 0.0, 0.5533)})
|
||||
else:
|
||||
# For the other icons, leave out appicon and render text in Envy Code R
|
||||
docerator.makedocicon(outname='%s.icns' % name, appicon=appIcon,
|
||||
text=text, sizes=iconsizes[size], makeicns=makeIcns,
|
||||
textrenderer=SmallTextRenderer, backgroundrenderer=NoIconRenderer)
|
||||
|
||||
# ...create links later (to make sure the link targets exist)
|
||||
createLinks([name for (name, t) in vimIcons.items() if t[1] == LINK],
|
||||
@@ -541,9 +195,4 @@ def main():
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
finally:
|
||||
for s in sizes:
|
||||
if os.access(TMPFILE % s, os.F_OK):
|
||||
os.remove(TMPFILE % s)
|
||||
|
||||
@@ -54,9 +54,10 @@ void usage() {
|
||||
NSBitmapImageRep* getBitmapImageRepOfSize(NSImage* img, int size) {
|
||||
|
||||
// Don't resample if it's not necessary
|
||||
// XXX: Seems as if this creates problems in some situations, disable this
|
||||
// for now.
|
||||
#if 0
|
||||
// IconFamily does not work correctly with
|
||||
// NSAlphaNonpremultipliedBitmapFormat images, so this has to stay disabled
|
||||
// until IconFamily is fixed (if ever).
|
||||
NSEnumerator* e = [[img representations] objectEnumerator];
|
||||
NSImageRep* ir;
|
||||
while ((ir = [e nextObject])) {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
from distutils.core import setup, Extension
|
||||
|
||||
setup(name="loadfont", version="1.0",
|
||||
ext_modules = [Extension("loadfont", ["loadfont.c"])])
|
||||
|
||||
@@ -40,6 +40,149 @@
|
||||
Sparkle supports updates in zip, tar, tbz, tgz, or dmg format.
|
||||
-->
|
||||
|
||||
<item>
|
||||
<title>Snapshot 48 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 48 released</h1>
|
||||
|
||||
<p> Changes since snapshot 47:
|
||||
<ul>
|
||||
<li> ATSUI clips text to display cell to avoid "bleeding" </li>
|
||||
<li> The pwd is set properly when dropping a folder on the Dock </li>
|
||||
<li> Add Vimball (.vba) as a supported filetype </li>
|
||||
<li> Refactored input code (e.g. can now bind to numeric keypad) </li>
|
||||
<li> Improved IM support (separate keyboard layouts in normal/insert modes using the 'noimd' option, see ":h macvim-international") </li>
|
||||
<li> Draw marked text inline (listed as +xim in ":ver") </li>
|
||||
<li> Add user default MMUseInlineIm (use to disable above feature) </li>
|
||||
<li> Update Vim source and runtime files </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Sat, 15 Aug 2009 00:27 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-48.tbz"
|
||||
length="8212911"
|
||||
sparkle:version="48"
|
||||
sparkle:shortVersionString="7.2"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 47 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 47 released</h1>
|
||||
|
||||
<p> Changes since snapshot 45:
|
||||
<ul>
|
||||
<li> Markdown (Nico Weber) and reStructuredText (Travis Jeffery) are supported file types </li>
|
||||
<li> The forever bouncing Dock icon bug should now really really be fixed (Kazuki Sakamoto) </li>
|
||||
<li> Fixed bug when file name contained decomposed UTF8 characters </li>
|
||||
<li> Quick Look should work for most/all supported filetypes now (although the preview is simple text and is not syntax highlighted) </li>
|
||||
<li> Update the help file </li>
|
||||
<li> 'guifontwide' is updated on Cmd-+/Cmd-- </li>
|
||||
<li> The titles of the next/previous tab menu items now match other apps </li>
|
||||
<li> Add NetBeans support (Kazuki Sakamoto) </li>
|
||||
<li> Add simple logging facility </li>
|
||||
<li> Fix a bug which could cause a crash when a dialog sheet was used </li>
|
||||
<li> Update to latest Vim patches and runtime files </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Fri, 16 Jul 2009 19:43 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-47.tbz"
|
||||
length="8200839"
|
||||
sparkle:version="47"
|
||||
sparkle:shortVersionString="7.2"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 45 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 45 released</h1>
|
||||
|
||||
<p> Changes since snapshot 44:
|
||||
<ul>
|
||||
<li> The toolbar is not hidden by default again (if you prefer having the toolbar hidden, then add the line "set go-=T" to your ~/.gvimrc file) </li>
|
||||
<li> The ATSUI renderer honors the 'guisp' highlighting color </li>
|
||||
<li> Fix the forever bouncing Dock icon bug (Kazuki Sakamoto) </li>
|
||||
<li> Add the "Show Hidden Files" checkbox button to the Save dialog whenever the file browser is expanded </li>
|
||||
<li> Frontend refactoring </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Mon, 13 Apr 2009 19:19 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-45.tbz"
|
||||
length="8135831"
|
||||
sparkle:version="45"
|
||||
sparkle:shortVersionString="7.2"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 44 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 44 released</h1>
|
||||
|
||||
<p> Changes since snapshot 43:
|
||||
<ul>
|
||||
<li> The color table had many erroneous entries which have been corrected (Zvezdan Petkovic) </li>
|
||||
<li> Ctrl+tab works again </li>
|
||||
<li> Tab labels only show file tail by default to make them more legible (reset to default by adding "set guitablabel&" to .gvimrc) </li>
|
||||
<li> The number of columns does not change on ":set go+=rT" </li>
|
||||
<li> Fixed problems with view not maximizing when entering full-screen and the Dock was visible </li>
|
||||
<li> Fix various problems related to having windows on a screen that got unplugged (fixes Issue 162) </li>
|
||||
<li> Latest source code version and runtime files (e.g. the Python syntax file is fixed, fixes Issue 160) </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Sun, 29 Mar 2009 16:56 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-44.tbz"
|
||||
length="8139075"
|
||||
sparkle:version="44"
|
||||
sparkle:shortVersionString="7.2"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 43 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 43 released</h1>
|
||||
|
||||
<p><b>The automatic updating feature is broken in snapshots 39 and 40. If the automatic updating never finishes extracting then you are affected by this bug and will have to upgrade manually. To do so, simply go to the <a href="http://code.google.com/p/macvim/wiki/Snapshot">Snapshot page</a> to download the latest version.</b></p>
|
||||
|
||||
<p> Changes since snapshot 42:
|
||||
<ul>
|
||||
<li> Do inclusive search when opening files (Jonathon Mah) </li>
|
||||
<li> Respect layout prefs when double-clicking an already open file </li>
|
||||
<li> Fix two minor memory leaks </li>
|
||||
<li> Ctrl-] works on German keyboard layout </li>
|
||||
<li> The .viminfo file is written on Cmd-q </li>
|
||||
<li> New 16x16 icons (Nico Weber) </li>
|
||||
<li> Untitled window again opens on reopen event if requested in prefs </li>
|
||||
<li> Fork earlier; fixes bug with 'autochdir', faster startup, "f" no longer supported in 'guioptions' </li>
|
||||
<li> Some other minor bug fixes </li>
|
||||
<li> Use latest runtime files and Vim patches </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Fri, 20 Feb 2009 13:49 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-43.tbz"
|
||||
length="8136440"
|
||||
sparkle:version="43"
|
||||
sparkle:shortVersionString="7.2"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 42 released</title>
|
||||
<description><![CDATA[
|
||||
|
||||
@@ -115,8 +115,21 @@ ifndef MZSCHEME_VER
|
||||
MZSCHEME_VER=205_000
|
||||
endif
|
||||
|
||||
ifndef MZSCHEME_PRECISE_GC
|
||||
MZSCHEME_PRECISE_GC=no
|
||||
endif
|
||||
|
||||
# for version 4.x we need to generate byte-code for Scheme base
|
||||
ifndef MZSCHEME_GENERATE_BASE
|
||||
MZSCHEME_GENERATE_BASE=no
|
||||
endif
|
||||
|
||||
ifeq (no,$(DYNAMIC_MZSCHEME))
|
||||
ifeq (yes,$(MZSCHEME_PRECISE_GC))
|
||||
MZSCHEME_LIB=-lmzsch$(MZSCHEME_VER)
|
||||
else
|
||||
MZSCHEME_LIB = -lmzsch$(MZSCHEME_VER) -lmzgc$(MZSCHEME_VER)
|
||||
endif
|
||||
# the modern MinGW can dynamically link to dlls directly.
|
||||
# point MZSCHEME_DLLS to where you put libmzschXXXXXXX.dll and libgcXXXXXXX.dll
|
||||
ifndef MZSCHEME_DLLS
|
||||
@@ -410,6 +423,13 @@ endif
|
||||
ifdef MZSCHEME
|
||||
OBJ += $(OUTDIR)/if_mzsch.o
|
||||
MZSCHEME_INCL = if_mzsch.h
|
||||
ifeq (yes,$(MZSCHEME_GENERATE_BASE))
|
||||
CFLAGS += -DINCLUDE_MZSCHEME_BASE
|
||||
MZ_EXTRA_DEP += mzscheme_base.c
|
||||
endif
|
||||
ifeq (yes,$(MZSCHEME_PRECISE_GC))
|
||||
CFLAGS += -DMZ_PRECISE_GC
|
||||
endif
|
||||
endif
|
||||
ifdef PYTHON
|
||||
OBJ += $(OUTDIR)/if_python.o
|
||||
@@ -588,6 +608,12 @@ if_perl.c: if_perl.xs typemap
|
||||
$(OUTDIR)/netbeans.o: netbeans.c $(INCL) $(NBDEBUG_INCL) $(NBDEBUG_SRC)
|
||||
$(CC) -c $(CFLAGS) netbeans.c -o $(OUTDIR)/netbeans.o
|
||||
|
||||
$(OUTDIR)/if_mzsch.o: if_mzsch.c $(INCL) if_mzsch.h $(MZ_EXTRA_DEP)
|
||||
$(CC) -c $(CFLAGS) if_mzsch.c -o $(OUTDIR)/if_mzsch.o
|
||||
|
||||
mzscheme_base.c:
|
||||
$(MZSCHEME)/mzc --c-mods mzscheme_base.c ++lib scheme/base
|
||||
|
||||
pathdef.c: $(INCL)
|
||||
ifneq (sh.exe, $(SHELL))
|
||||
@echo creating pathdef.c
|
||||
|
||||
+40
-9
@@ -1,18 +1,18 @@
|
||||
# Makefile for Vim on Win32 (Windows NT/2000/XP/2003 and Windows 95/98/Me)
|
||||
# and Win64, using the Microsoft Visual C++ compilers. Known to work with
|
||||
# VC5, VC6 (VS98), VC7.0 (VS2002), VC7.1 (VS2003), VC8 (VS2005),
|
||||
# and VC9 (VS2008).
|
||||
# VC9 (VS2008), and VC10 (VS2010).
|
||||
#
|
||||
# To build using other Windows compilers, see INSTALLpc.txt
|
||||
#
|
||||
# This makefile can build the console, GUI, OLE-enable, Perl-enabled and
|
||||
# Python-enabled versions of vim for Win32 platforms.
|
||||
# Python-enabled versions of Vim for Win32 platforms.
|
||||
#
|
||||
# The basic command line to build vim is:
|
||||
# The basic command line to build Vim is:
|
||||
#
|
||||
# nmake -f Make_mvc.mak
|
||||
#
|
||||
# This will build the console version of vim with no additional interfaces.
|
||||
# This will build the console version of Vim with no additional interfaces.
|
||||
# To add features, define any of the following:
|
||||
#
|
||||
# !!!! After changing features do "nmake clean" first !!!!
|
||||
@@ -34,6 +34,7 @@
|
||||
# MZSCHEME=[Path to MzScheme directory]
|
||||
# DYNAMIC_MZSCHEME=yes (to load the MzScheme DLLs dynamically)
|
||||
# MZSCHEME_VER=[version, 205_000, ...]
|
||||
# MZSCHEME_DEBUG=no
|
||||
#
|
||||
# Perl interface:
|
||||
# PERL=[Path to Perl directory]
|
||||
@@ -354,6 +355,12 @@ MSVCVER = 9.0
|
||||
!if "$(_NMAKE_VER)" == "9.00.21022.08"
|
||||
MSVCVER = 9.0
|
||||
!endif
|
||||
!if "$(_NMAKE_VER)" == "9.00.30729.01"
|
||||
MSVCVER = 9.0
|
||||
!endif
|
||||
!if "$(_NMAKE_VER)" == "10.00.20506.01"
|
||||
MSVCVER = 10.0
|
||||
!endif
|
||||
!endif
|
||||
|
||||
# Abort bulding VIM if version of VC is unrecognised.
|
||||
@@ -368,7 +375,7 @@ MSVCVER = 9.0
|
||||
!endif
|
||||
|
||||
# Convert processor ID to MVC-compatible number
|
||||
!if ("$(MSVCVER)" != "8.0") && ("$(MSVCVER)" != "9.0")
|
||||
!if ("$(MSVCVER)" != "8.0") && ("$(MSVCVER)" != "9.0") && ("$(MSVCVER)" != "10.0")
|
||||
!if "$(CPUNR)" == "i386"
|
||||
CPUARG = /G3
|
||||
!elseif "$(CPUNR)" == "i486"
|
||||
@@ -401,7 +408,7 @@ OPTFLAG = /O2
|
||||
!else # MAXSPEED
|
||||
OPTFLAG = /Ox
|
||||
!endif
|
||||
!if ("$(MSVCVER)" == "8.0") || ("$(MSVCVER)" == "9.0")
|
||||
!if ("$(MSVCVER)" == "8.0") || ("$(MSVCVER)" == "9.0") || ("$(MSVCVER)" == "10.0")
|
||||
# Use link time code generation if not worried about size
|
||||
!if "$(OPTIMIZE)" != "SPACE"
|
||||
OPTFLAG = $(OPTFLAG) /GL
|
||||
@@ -618,15 +625,37 @@ PYTHON_LIB = $(PYTHON)\libs\python$(PYTHON_VER).lib
|
||||
MZSCHEME_VER = 205_000
|
||||
!endif
|
||||
CFLAGS = $(CFLAGS) -DFEAT_MZSCHEME -I $(MZSCHEME)\include
|
||||
!if EXIST("$(MZSCHEME)\collects\scheme\base.ss")
|
||||
# for MzScheme 4.x we need to include byte code for basic Scheme stuff
|
||||
MZSCHEME_EXTRA_DEP = mzscheme_base.c
|
||||
CFLAGS = $(CFLAGS) -DINCLUDE_MZSCHEME_BASE
|
||||
!endif
|
||||
!if EXIST("$(MZSCHEME)\lib\msvc\libmzsch$(MZSCHEME_VER).lib") \
|
||||
&& !EXIST("$(MZSCHEME)\lib\msvc\libmzgc$(MZSCHEME_VER).lib")
|
||||
!message Building with Precise GC
|
||||
MZSCHEME_PRECISE_GC = yes
|
||||
CFLAGS = $(CFLAGS) -DMZ_PRECISE_GC
|
||||
!endif
|
||||
!if "$(DYNAMIC_MZSCHEME)" == "yes"
|
||||
!if "$(MZSCHEME_PRECISE_GC)" == "yes"
|
||||
!error MzScheme with Precise GC cannot be loaded dynamically
|
||||
!endif
|
||||
!message MzScheme DLLs will be loaded dynamically
|
||||
CFLAGS = $(CFLAGS) -DDYNAMIC_MZSCHEME \
|
||||
-DDYNAMIC_MZSCH_DLL=\"libmzsch$(MZSCHEME_VER).dll\" \
|
||||
-DDYNAMIC_MZGC_DLL=\"libmzgc$(MZSCHEME_VER).dll\"
|
||||
!else
|
||||
!if "$(MZSCHEME_DEBUG)" == "yes"
|
||||
CFLAGS = $(CFLAGS) -DMZSCHEME_FORCE_GC
|
||||
!endif
|
||||
!if "$(MZSCHEME_PRECISE_GC)" == "yes"
|
||||
# Precise GC does not use separate dll
|
||||
MZSCHEME_LIB = $(MZSCHEME)\lib\msvc\libmzsch$(MZSCHEME_VER).lib
|
||||
!else
|
||||
MZSCHEME_LIB = $(MZSCHEME)\lib\msvc\libmzgc$(MZSCHEME_VER).lib \
|
||||
$(MZSCHEME)\lib\msvc\libmzsch$(MZSCHEME_VER).lib
|
||||
!endif
|
||||
!endif
|
||||
MZSCHEME_OBJ = $(OUTDIR)\if_mzsch.obj
|
||||
!endif
|
||||
|
||||
@@ -767,7 +796,7 @@ LINKARGS2 = $(CON_LIB) $(GUI_LIB) $(LIBC) $(OLE_LIB) user32.lib $(SNIFF_LIB) \
|
||||
|
||||
# Report link time code generation progress if used.
|
||||
!ifdef NODEBUG
|
||||
!if ("$(MSVCVER)" == "8.0") || ("$(MSVCVER)" == "9.0")
|
||||
!if ("$(MSVCVER)" == "8.0") || ("$(MSVCVER)" == "9.0") || ("$(MSVCVER)" == "10.0")
|
||||
!if "$(OPTIMIZE)" != "SPACE"
|
||||
LINKARGS1 = $(LINKARGS1) /LTCG:STATUS
|
||||
!endif
|
||||
@@ -927,9 +956,11 @@ $(OUTDIR)/if_perl.obj: $(OUTDIR) if_perl.c $(INCL)
|
||||
$(OUTDIR)/if_perlsfio.obj: $(OUTDIR) if_perlsfio.c $(INCL)
|
||||
$(CC) $(CFLAGS) $(PERL_INC) if_perlsfio.c
|
||||
|
||||
$(OUTDIR)/if_mzsch.obj: $(OUTDIR) if_mzsch.c $(INCL)
|
||||
$(OUTDIR)/if_mzsch.obj: $(OUTDIR) if_mzsch.c $(INCL) $(MZSCHEME_EXTRA_DEP)
|
||||
$(CC) $(CFLAGS) if_mzsch.c \
|
||||
-DMZSCHEME_COLLECTS=\"$(MZSCHEME:\=\\)\\collects\"
|
||||
mzscheme_base.c:
|
||||
$(MZSCHEME)\mzc --c-mods mzscheme_base.c ++lib scheme/base
|
||||
|
||||
$(OUTDIR)/if_python.obj: $(OUTDIR) if_python.c $(INCL)
|
||||
$(CC) $(CFLAGS) $(PYTHON_INC) if_python.c
|
||||
@@ -1009,7 +1040,7 @@ $(OUTDIR)/window.obj: $(OUTDIR) window.c $(INCL)
|
||||
$(OUTDIR)/xpm_w32.obj: $(OUTDIR) xpm_w32.c
|
||||
$(CC) $(CFLAGS) $(XPM_INC) xpm_w32.c
|
||||
|
||||
$(OUTDIR)/vim.res: $(OUTDIR) vim.rc version.h tools.bmp tearoff.bmp \
|
||||
$(OUTDIR)/vim.res: $(OUTDIR) vim.rc gvim.exe.mnf version.h tools.bmp tearoff.bmp \
|
||||
vim.ico vim_error.ico vim_alert.ico vim_info.ico vim_quest.ico
|
||||
$(RC) /l 0x409 /Fo$(OUTDIR)/vim.res $(RCFLAGS) vim.rc
|
||||
|
||||
|
||||
+31
-14
@@ -105,8 +105,8 @@
|
||||
# 4. "make test" {{{1
|
||||
# This is optional. This will run Vim scripts on a number of test
|
||||
# files, and compare the produced output with the expected output.
|
||||
# If all is well, you will get the "ALL DONE" message in the end. See
|
||||
# below (search for "/^test").
|
||||
# If all is well, you will get the "ALL DONE" message in the end. If a
|
||||
# test fails you get "TEST FAILURE". See below (search for "/^test").
|
||||
#
|
||||
# 5. "make install" {{{1
|
||||
# If the new Vim seems to be working OK you can install it and the
|
||||
@@ -533,6 +533,11 @@ CClink = $(CC)
|
||||
#CFLAGS = -g -DDEBUG -Wall -Wshadow -Wmissing-prototypes
|
||||
#CFLAGS = -g -O2 '-DSTARTUPTIME="vimstartup"' -fno-strength-reduce -Wall -Wmissing-prototypes
|
||||
|
||||
# Use this with GCC to check for mistakes, unused arguments, etc.
|
||||
#CFLAGS = -g -Wall -Wextra -Wmissing-prototypes -Wunreachable-code
|
||||
#PYTHON_CFLAGS_EXTRA = -Wno-missing-field-initializers
|
||||
#MZSCHEME_CFLAGS_EXTRA = -Wno-unreachable-code -Wno-unused-parameter
|
||||
|
||||
# EFENCE - Electric-Fence malloc debugging: catches memory accesses beyond
|
||||
# allocated memory (and makes every malloc()/free() very slow).
|
||||
# Electric Fence is free (search ftp sites).
|
||||
@@ -551,7 +556,13 @@ CClink = $(CC)
|
||||
# }}}
|
||||
|
||||
# LINT - for running lint
|
||||
# For standard Unix lint
|
||||
LINT = lint
|
||||
LINT_OPTIONS = -beprxzF
|
||||
# For splint
|
||||
# It doesn't work well, crashes on include files and non-ascii characters.
|
||||
#LINT = splint
|
||||
#LINT_OPTIONS = +unixlib -weak -macrovarprefixexclude -showfunc -linelen 9999
|
||||
|
||||
# PROFILING - Uncomment the next two lines to do profiling with gcc and gprof.
|
||||
# Might not work with GUI or Perl.
|
||||
@@ -1275,16 +1286,16 @@ CPP_DEPEND = $(CC) -I$(srcdir) -M$(CPP_MM) \
|
||||
# This is for cproto 3 patchlevel 8 or below
|
||||
# __inline, __attribute__ and __extension__ are not recognized by cproto
|
||||
# G_IMPLEMENT_INLINES is to avoid functions defined in glib/gutils.h.
|
||||
NO_ATTR = -D__inline= -D__inline__= -DG_IMPLEMENT_INLINES \
|
||||
-D"__attribute__\\(x\\)=" -D"__asm__\\(x\\)=" \
|
||||
-D__extension__= -D__restrict="" \
|
||||
-D__gnuc_va_list=char -D__builtin_va_list=char
|
||||
#NO_ATTR = -D__inline= -D__inline__= -DG_IMPLEMENT_INLINES \
|
||||
# -D"__attribute__\\(x\\)=" -D"__asm__\\(x\\)=" \
|
||||
# -D__extension__= -D__restrict="" \
|
||||
# -D__gnuc_va_list=char -D__builtin_va_list=char
|
||||
|
||||
#
|
||||
# This is for cproto 3 patchlevel 9 or above (currently 4.6)
|
||||
# This is for cproto 3 patchlevel 9 or above (currently 4.6, 4.7g)
|
||||
# __inline and __attribute__ are now recognized by cproto
|
||||
# -D"foo()=" is not supported by all compilers so do not use it
|
||||
# NO_ATTR=
|
||||
NO_ATTR=
|
||||
#
|
||||
# maybe the "/usr/bin/cc -E" has to be adjusted for some systems
|
||||
# This is for cproto 3.5 patchlevel 3:
|
||||
@@ -1448,6 +1459,7 @@ LINT_SRC = $(BASIC_SRC) $(GUI_SRC) $(HANGULIN_SRC) $(PYTHON_SRC) $(TCL_SRC) \
|
||||
$(SNIFF_SRC) $(WORKSHOP_SRC) $(WSDEBUG_SRC) $(NETBEANS_SRC)
|
||||
#LINT_SRC = $(SRC)
|
||||
#LINT_SRC = $(ALL_SRC)
|
||||
#LINT_SRC = $(BASIC_SRC)
|
||||
|
||||
OBJ = \
|
||||
objects/buffer.o \
|
||||
@@ -1753,7 +1765,8 @@ types.vim: $(TAGS_SRC) $(TAGS_INCL)
|
||||
# messages. Don't worry about that.
|
||||
# If there is a real error, there will be a difference between "test.out" and
|
||||
# a "test99.ok" file.
|
||||
# If everything is alright, the final message will be "ALL DONE".
|
||||
# If everything is alright, the final message will be "ALL DONE". If not you
|
||||
# get "TEST FAILURE".
|
||||
#
|
||||
test check:
|
||||
$(MAKE) -f Makefile $(VIMTARGET)
|
||||
@@ -2203,6 +2216,7 @@ clean celan: testclean
|
||||
-rm -f $(TOOLS) auto/osdef.h auto/pathdef.c auto/if_perl.c
|
||||
-rm -f conftest* *~ auto/link.sed
|
||||
-rm -rf $(APPDIR)
|
||||
-rm -rf mzscheme_base.c
|
||||
if test -d $(PODIR); then \
|
||||
cd $(PODIR); $(MAKE) prefix=$(DESTDIR)$(prefix) clean; \
|
||||
fi
|
||||
@@ -2288,12 +2302,12 @@ depend:
|
||||
|
||||
# Run lint. Clean up the *.ln files that are sometimes left behind.
|
||||
lint:
|
||||
lint $(LINT_OPTIONS) $(LINT_CFLAGS) $(LINT_EXTRA) $(LINT_SRC)
|
||||
$(LINT) $(LINT_OPTIONS) $(LINT_CFLAGS) $(LINT_EXTRA) $(LINT_SRC)
|
||||
-rm -f *.ln
|
||||
|
||||
# Check dosinst.c with lint.
|
||||
lintinstall:
|
||||
lint $(LINT_OPTIONS) -DWIN32 -DUNIX_LINT dosinst.c
|
||||
$(LINT) $(LINT_OPTIONS) -DWIN32 -DUNIX_LINT dosinst.c
|
||||
-rm -f dosinst.ln
|
||||
|
||||
###########################################################################
|
||||
@@ -2445,8 +2459,11 @@ objects/if_cscope.o: if_cscope.c
|
||||
objects/if_xcmdsrv.o: if_xcmdsrv.c
|
||||
$(CCC) -o $@ if_xcmdsrv.c
|
||||
|
||||
objects/if_mzsch.o: if_mzsch.c
|
||||
$(CCC) -o $@ if_mzsch.c
|
||||
objects/if_mzsch.o: if_mzsch.c $(MZSCHEME_EXTRA)
|
||||
$(CCC) -o $@ $(MZSCHEME_CFLAGS_EXTRA) if_mzsch.c
|
||||
|
||||
mzscheme_base.c:
|
||||
$(MZSCHEME_MZC) --c-mods mzscheme_base.c ++lib scheme/base
|
||||
|
||||
objects/if_perl.o: auto/if_perl.c
|
||||
$(CCC) -o $@ auto/if_perl.c
|
||||
@@ -2455,7 +2472,7 @@ objects/if_perlsfio.o: if_perlsfio.c
|
||||
$(CCC) -o $@ if_perlsfio.c
|
||||
|
||||
objects/if_python.o: if_python.c
|
||||
$(CCC) -o $@ if_python.c
|
||||
$(CCC) -o $@ $(PYTHON_CFLAGS_EXTRA) if_python.c
|
||||
|
||||
objects/if_ruby.o: if_ruby.c
|
||||
$(CCC) -o $@ if_ruby.c
|
||||
|
||||
+171
-154
@@ -20,20 +20,21 @@ static char THIS_FILE[] = __FILE__;
|
||||
|
||||
static BOOL g_bEnableVim = TRUE; // Vim enabled
|
||||
static BOOL g_bDevStudioEditor = FALSE; // Open file in Dev Studio editor simultaneously
|
||||
static BOOL g_bNewTabs = FALSE;
|
||||
static int g_ChangeDir = CD_NONE; // CD after file open?
|
||||
|
||||
static void VimSetEnableState (BOOL bEnableState);
|
||||
static BOOL VimOpenFile (BSTR& FileName, long LineNr);
|
||||
static DISPID VimGetDispatchId (COleAutomationControl& VimOle, char* Method);
|
||||
static void VimErrDiag (COleAutomationControl& VimOle);
|
||||
static void VimChangeDir (COleAutomationControl& VimOle, DISPID DispatchId, BSTR& FileName);
|
||||
static void DebugMsg (char* Msg, char* Arg = NULL);
|
||||
static void VimSetEnableState(BOOL bEnableState);
|
||||
static BOOL VimOpenFile(BSTR& FileName, long LineNr);
|
||||
static DISPID VimGetDispatchId(COleAutomationControl& VimOle, char* Method);
|
||||
static void VimErrDiag(COleAutomationControl& VimOle);
|
||||
static void VimChangeDir(COleAutomationControl& VimOle, DISPID DispatchId, BSTR& FileName);
|
||||
static void DebugMsg(char* Msg, char* Arg = NULL);
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CCommands
|
||||
|
||||
CCommands::CCommands ()
|
||||
CCommands::CCommands()
|
||||
{
|
||||
// m_pApplication == NULL; M$ Code generation bug!!!
|
||||
m_pApplication = NULL;
|
||||
@@ -41,17 +42,17 @@ CCommands::CCommands ()
|
||||
m_pDebuggerEventsObj = NULL;
|
||||
}
|
||||
|
||||
CCommands::~CCommands ()
|
||||
CCommands::~CCommands()
|
||||
{
|
||||
ASSERT (m_pApplication != NULL);
|
||||
ASSERT(m_pApplication != NULL);
|
||||
if (m_pApplication)
|
||||
{
|
||||
m_pApplication->Release ();
|
||||
m_pApplication->Release();
|
||||
m_pApplication = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CCommands::SetApplicationObject (IApplication * pApplication)
|
||||
void CCommands::SetApplicationObject(IApplication * pApplication)
|
||||
{
|
||||
// This function assumes pApplication has already been AddRef'd
|
||||
// for us, which CDSAddIn did in it's QueryInterface call
|
||||
@@ -61,55 +62,57 @@ void CCommands::SetApplicationObject (IApplication * pApplication)
|
||||
return;
|
||||
|
||||
// Create Application event handlers
|
||||
XApplicationEventsObj::CreateInstance (&m_pApplicationEventsObj);
|
||||
XApplicationEventsObj::CreateInstance(&m_pApplicationEventsObj);
|
||||
if (! m_pApplicationEventsObj)
|
||||
{
|
||||
ReportInternalError ("XApplicationEventsObj::CreateInstance");
|
||||
ReportInternalError("XApplicationEventsObj::CreateInstance");
|
||||
return;
|
||||
}
|
||||
m_pApplicationEventsObj->AddRef ();
|
||||
m_pApplicationEventsObj->Connect (m_pApplication);
|
||||
m_pApplicationEventsObj->AddRef();
|
||||
m_pApplicationEventsObj->Connect(m_pApplication);
|
||||
m_pApplicationEventsObj->m_pCommands = this;
|
||||
|
||||
#ifdef NEVER
|
||||
// Create Debugger event handler
|
||||
CComPtr < IDispatch > pDebugger;
|
||||
if (SUCCEEDED (m_pApplication->get_Debugger (&pDebugger))
|
||||
if (SUCCEEDED(m_pApplication->get_Debugger(&pDebugger))
|
||||
&& pDebugger != NULL)
|
||||
{
|
||||
XDebuggerEventsObj::CreateInstance (&m_pDebuggerEventsObj);
|
||||
m_pDebuggerEventsObj->AddRef ();
|
||||
m_pDebuggerEventsObj->Connect (pDebugger);
|
||||
XDebuggerEventsObj::CreateInstance(&m_pDebuggerEventsObj);
|
||||
m_pDebuggerEventsObj->AddRef();
|
||||
m_pDebuggerEventsObj->Connect(pDebugger);
|
||||
m_pDebuggerEventsObj->m_pCommands = this;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get settings from registry HKEY_CURRENT_USER\Software\Vim\VisVim
|
||||
HKEY hAppKey = GetAppKey ("Vim");
|
||||
HKEY hAppKey = GetAppKey("Vim");
|
||||
if (hAppKey)
|
||||
{
|
||||
HKEY hSectionKey = GetSectionKey (hAppKey, "VisVim");
|
||||
HKEY hSectionKey = GetSectionKey(hAppKey, "VisVim");
|
||||
if (hSectionKey)
|
||||
{
|
||||
g_bEnableVim = GetRegistryInt (hSectionKey, "EnableVim",
|
||||
g_bEnableVim = GetRegistryInt(hSectionKey, "EnableVim",
|
||||
g_bEnableVim);
|
||||
g_bDevStudioEditor = GetRegistryInt(hSectionKey,"DevStudioEditor",
|
||||
g_bDevStudioEditor);
|
||||
g_ChangeDir = GetRegistryInt (hSectionKey, "ChangeDir",
|
||||
g_bDevStudioEditor = GetRegistryInt(hSectionKey,
|
||||
"DevStudioEditor", g_bDevStudioEditor);
|
||||
g_bNewTabs = GetRegistryInt(hSectionKey, "NewTabs",
|
||||
g_bNewTabs);
|
||||
g_ChangeDir = GetRegistryInt(hSectionKey, "ChangeDir",
|
||||
g_ChangeDir);
|
||||
RegCloseKey (hSectionKey);
|
||||
RegCloseKey(hSectionKey);
|
||||
}
|
||||
RegCloseKey (hAppKey);
|
||||
RegCloseKey(hAppKey);
|
||||
}
|
||||
}
|
||||
|
||||
void CCommands::UnadviseFromEvents ()
|
||||
void CCommands::UnadviseFromEvents()
|
||||
{
|
||||
ASSERT (m_pApplicationEventsObj != NULL);
|
||||
ASSERT(m_pApplicationEventsObj != NULL);
|
||||
if (m_pApplicationEventsObj)
|
||||
{
|
||||
m_pApplicationEventsObj->Disconnect (m_pApplication);
|
||||
m_pApplicationEventsObj->Release ();
|
||||
m_pApplicationEventsObj->Disconnect(m_pApplication);
|
||||
m_pApplicationEventsObj->Release();
|
||||
m_pApplicationEventsObj = NULL;
|
||||
}
|
||||
|
||||
@@ -121,10 +124,10 @@ void CCommands::UnadviseFromEvents ()
|
||||
// unadvise from its events (thus the VERIFY_OK below--see
|
||||
// stdafx.h).
|
||||
CComPtr < IDispatch > pDebugger;
|
||||
VERIFY_OK (m_pApplication->get_Debugger (&pDebugger));
|
||||
ASSERT (pDebugger != NULL);
|
||||
m_pDebuggerEventsObj->Disconnect (pDebugger);
|
||||
m_pDebuggerEventsObj->Release ();
|
||||
VERIFY_OK(m_pApplication->get_Debugger(&pDebugger));
|
||||
ASSERT(pDebugger != NULL);
|
||||
m_pDebuggerEventsObj->Disconnect(pDebugger);
|
||||
m_pDebuggerEventsObj->Release();
|
||||
m_pDebuggerEventsObj = NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -136,21 +139,21 @@ void CCommands::UnadviseFromEvents ()
|
||||
|
||||
// Application events
|
||||
|
||||
HRESULT CCommands::XApplicationEvents::BeforeBuildStart ()
|
||||
HRESULT CCommands::XApplicationEvents::BeforeBuildStart()
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCommands::XApplicationEvents::BuildFinish (long nNumErrors, long nNumWarnings)
|
||||
HRESULT CCommands::XApplicationEvents::BuildFinish(long nNumErrors, long nNumWarnings)
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCommands::XApplicationEvents::BeforeApplicationShutDown ()
|
||||
HRESULT CCommands::XApplicationEvents::BeforeApplicationShutDown()
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -158,9 +161,9 @@ HRESULT CCommands::XApplicationEvents::BeforeApplicationShutDown ()
|
||||
// is done.
|
||||
// Vim gets called from here.
|
||||
//
|
||||
HRESULT CCommands::XApplicationEvents::DocumentOpen (IDispatch * theDocument)
|
||||
HRESULT CCommands::XApplicationEvents::DocumentOpen(IDispatch * theDocument)
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
|
||||
if (! g_bEnableVim)
|
||||
// Vim not enabled or empty command line entered
|
||||
@@ -169,7 +172,7 @@ HRESULT CCommands::XApplicationEvents::DocumentOpen (IDispatch * theDocument)
|
||||
// First get the current file name and line number
|
||||
|
||||
// Get the document object
|
||||
CComQIPtr < ITextDocument, &IID_ITextDocument > pDoc (theDocument);
|
||||
CComQIPtr < ITextDocument, &IID_ITextDocument > pDoc(theDocument);
|
||||
if (! pDoc)
|
||||
return S_OK;
|
||||
|
||||
@@ -177,26 +180,26 @@ HRESULT CCommands::XApplicationEvents::DocumentOpen (IDispatch * theDocument)
|
||||
long LineNr = -1;
|
||||
|
||||
// Get the document name
|
||||
if (FAILED (pDoc->get_FullName (&FileName)))
|
||||
if (FAILED(pDoc->get_FullName(&FileName)))
|
||||
return S_OK;
|
||||
|
||||
LPDISPATCH pDispSel;
|
||||
|
||||
// Get a selection object dispatch pointer
|
||||
if (SUCCEEDED (pDoc->get_Selection (&pDispSel)))
|
||||
if (SUCCEEDED(pDoc->get_Selection(&pDispSel)))
|
||||
{
|
||||
// Get the selection object
|
||||
CComQIPtr < ITextSelection, &IID_ITextSelection > pSel (pDispSel);
|
||||
CComQIPtr < ITextSelection, &IID_ITextSelection > pSel(pDispSel);
|
||||
|
||||
if (pSel)
|
||||
// Get the selection line number
|
||||
pSel->get_CurrentLine (&LineNr);
|
||||
pSel->get_CurrentLine(&LineNr);
|
||||
|
||||
pDispSel->Release ();
|
||||
pDispSel->Release();
|
||||
}
|
||||
|
||||
// Open the file in Vim and position to the current line
|
||||
if (VimOpenFile (FileName, LineNr))
|
||||
if (VimOpenFile(FileName, LineNr))
|
||||
{
|
||||
if (! g_bDevStudioEditor)
|
||||
{
|
||||
@@ -204,30 +207,30 @@ HRESULT CCommands::XApplicationEvents::DocumentOpen (IDispatch * theDocument)
|
||||
CComVariant vSaveChanges = dsSaveChangesPrompt;
|
||||
DsSaveStatus Saved;
|
||||
|
||||
pDoc->Close (vSaveChanges, &Saved);
|
||||
pDoc->Close(vSaveChanges, &Saved);
|
||||
}
|
||||
}
|
||||
|
||||
// We're done here
|
||||
SysFreeString (FileName);
|
||||
SysFreeString(FileName);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCommands::XApplicationEvents::BeforeDocumentClose (IDispatch * theDocument)
|
||||
HRESULT CCommands::XApplicationEvents::BeforeDocumentClose(IDispatch * theDocument)
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCommands::XApplicationEvents::DocumentSave (IDispatch * theDocument)
|
||||
HRESULT CCommands::XApplicationEvents::DocumentSave(IDispatch * theDocument)
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCommands::XApplicationEvents::NewDocument (IDispatch * theDocument)
|
||||
HRESULT CCommands::XApplicationEvents::NewDocument(IDispatch * theDocument)
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
|
||||
if (! g_bEnableVim)
|
||||
// Vim not enabled or empty command line entered
|
||||
@@ -235,19 +238,19 @@ HRESULT CCommands::XApplicationEvents::NewDocument (IDispatch * theDocument)
|
||||
|
||||
// First get the current file name and line number
|
||||
|
||||
CComQIPtr < ITextDocument, &IID_ITextDocument > pDoc (theDocument);
|
||||
CComQIPtr < ITextDocument, &IID_ITextDocument > pDoc(theDocument);
|
||||
if (! pDoc)
|
||||
return S_OK;
|
||||
|
||||
BSTR FileName;
|
||||
HRESULT hr;
|
||||
|
||||
hr = pDoc->get_FullName (&FileName);
|
||||
if (FAILED (hr))
|
||||
hr = pDoc->get_FullName(&FileName);
|
||||
if (FAILED(hr))
|
||||
return S_OK;
|
||||
|
||||
// Open the file in Vim and position to the current line
|
||||
if (VimOpenFile (FileName, 0))
|
||||
if (VimOpenFile(FileName, 0))
|
||||
{
|
||||
if (! g_bDevStudioEditor)
|
||||
{
|
||||
@@ -255,49 +258,49 @@ HRESULT CCommands::XApplicationEvents::NewDocument (IDispatch * theDocument)
|
||||
CComVariant vSaveChanges = dsSaveChangesPrompt;
|
||||
DsSaveStatus Saved;
|
||||
|
||||
pDoc->Close (vSaveChanges, &Saved);
|
||||
pDoc->Close(vSaveChanges, &Saved);
|
||||
}
|
||||
}
|
||||
|
||||
SysFreeString (FileName);
|
||||
SysFreeString(FileName);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCommands::XApplicationEvents::WindowActivate (IDispatch * theWindow)
|
||||
HRESULT CCommands::XApplicationEvents::WindowActivate(IDispatch * theWindow)
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCommands::XApplicationEvents::WindowDeactivate (IDispatch * theWindow)
|
||||
HRESULT CCommands::XApplicationEvents::WindowDeactivate(IDispatch * theWindow)
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCommands::XApplicationEvents::WorkspaceOpen ()
|
||||
HRESULT CCommands::XApplicationEvents::WorkspaceOpen()
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCommands::XApplicationEvents::WorkspaceClose ()
|
||||
HRESULT CCommands::XApplicationEvents::WorkspaceClose()
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCommands::XApplicationEvents::NewWorkspace ()
|
||||
HRESULT CCommands::XApplicationEvents::NewWorkspace()
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Debugger event
|
||||
|
||||
HRESULT CCommands::XDebuggerEvents::BreakpointHit (IDispatch * pBreakpoint)
|
||||
HRESULT CCommands::XDebuggerEvents::BreakpointHit(IDispatch * pBreakpoint)
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -308,17 +311,18 @@ HRESULT CCommands::XDebuggerEvents::BreakpointHit (IDispatch * pBreakpoint)
|
||||
class CMainDialog : public CDialog
|
||||
{
|
||||
public:
|
||||
CMainDialog (CWnd * pParent = NULL); // Standard constructor
|
||||
CMainDialog(CWnd * pParent = NULL); // Standard constructor
|
||||
|
||||
//{{AFX_DATA(CMainDialog)
|
||||
enum { IDD = IDD_ADDINMAIN };
|
||||
int m_ChangeDir;
|
||||
BOOL m_bDevStudioEditor;
|
||||
BOOL m_bNewTabs;
|
||||
//}}AFX_DATA
|
||||
|
||||
//{{AFX_VIRTUAL(CMainDialog)
|
||||
protected:
|
||||
virtual void DoDataExchange (CDataExchange * pDX); // DDX/DDV support
|
||||
virtual void DoDataExchange(CDataExchange * pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
protected:
|
||||
@@ -326,100 +330,106 @@ class CMainDialog : public CDialog
|
||||
afx_msg void OnEnable();
|
||||
afx_msg void OnDisable();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP ()
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
CMainDialog::CMainDialog (CWnd * pParent /* =NULL */ )
|
||||
: CDialog (CMainDialog::IDD, pParent)
|
||||
CMainDialog::CMainDialog(CWnd * pParent /* =NULL */ )
|
||||
: CDialog(CMainDialog::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CMainDialog)
|
||||
m_ChangeDir = -1;
|
||||
m_bDevStudioEditor = FALSE;
|
||||
m_bNewTabs = FALSE;
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
void CMainDialog::DoDataExchange (CDataExchange * pDX)
|
||||
void CMainDialog::DoDataExchange(CDataExchange * pDX)
|
||||
{
|
||||
CDialog::DoDataExchange (pDX);
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CMainDialog)
|
||||
DDX_Radio(pDX, IDC_CD_SOURCE_PATH, m_ChangeDir);
|
||||
DDX_Check (pDX, IDC_DEVSTUDIO_EDITOR, m_bDevStudioEditor);
|
||||
DDX_Check(pDX, IDC_DEVSTUDIO_EDITOR, m_bDevStudioEditor);
|
||||
DDX_Check(pDX, IDC_NEW_TABS, m_bNewTabs);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP (CMainDialog, CDialog)
|
||||
BEGIN_MESSAGE_MAP(CMainDialog, CDialog)
|
||||
//{{AFX_MSG_MAP(CMainDialog)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP ()
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CCommands methods
|
||||
|
||||
STDMETHODIMP CCommands::VisVimDialog ()
|
||||
STDMETHODIMP CCommands::VisVimDialog()
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
|
||||
// Use m_pApplication to access the Developer Studio Application
|
||||
// object,
|
||||
// and VERIFY_OK to see error strings in DEBUG builds of your add-in
|
||||
// (see stdafx.h)
|
||||
|
||||
VERIFY_OK (m_pApplication->EnableModeless (VARIANT_FALSE));
|
||||
VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE));
|
||||
|
||||
CMainDialog Dlg;
|
||||
|
||||
Dlg.m_bDevStudioEditor = g_bDevStudioEditor;
|
||||
Dlg.m_bNewTabs = g_bNewTabs;
|
||||
Dlg.m_ChangeDir = g_ChangeDir;
|
||||
if (Dlg.DoModal () == IDOK)
|
||||
if (Dlg.DoModal() == IDOK)
|
||||
{
|
||||
g_bDevStudioEditor = Dlg.m_bDevStudioEditor;
|
||||
g_bNewTabs = Dlg.m_bNewTabs;
|
||||
g_ChangeDir = Dlg.m_ChangeDir;
|
||||
|
||||
// Save settings to registry HKEY_CURRENT_USER\Software\Vim\VisVim
|
||||
HKEY hAppKey = GetAppKey ("Vim");
|
||||
HKEY hAppKey = GetAppKey("Vim");
|
||||
if (hAppKey)
|
||||
{
|
||||
HKEY hSectionKey = GetSectionKey (hAppKey, "VisVim");
|
||||
HKEY hSectionKey = GetSectionKey(hAppKey, "VisVim");
|
||||
if (hSectionKey)
|
||||
{
|
||||
WriteRegistryInt (hSectionKey, "DevStudioEditor",
|
||||
WriteRegistryInt(hSectionKey, "DevStudioEditor",
|
||||
g_bDevStudioEditor);
|
||||
WriteRegistryInt (hSectionKey, "ChangeDir", g_ChangeDir);
|
||||
RegCloseKey (hSectionKey);
|
||||
WriteRegistryInt(hSectionKey, "NewTabs",
|
||||
g_bNewTabs);
|
||||
WriteRegistryInt(hSectionKey, "ChangeDir", g_ChangeDir);
|
||||
RegCloseKey(hSectionKey);
|
||||
}
|
||||
RegCloseKey (hAppKey);
|
||||
RegCloseKey(hAppKey);
|
||||
}
|
||||
}
|
||||
|
||||
VERIFY_OK (m_pApplication->EnableModeless (VARIANT_TRUE));
|
||||
VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCommands::VisVimEnable ()
|
||||
STDMETHODIMP CCommands::VisVimEnable()
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
VimSetEnableState (true);
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
VimSetEnableState(true);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCommands::VisVimDisable ()
|
||||
STDMETHODIMP CCommands::VisVimDisable()
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
VimSetEnableState (false);
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
VimSetEnableState(false);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCommands::VisVimToggle ()
|
||||
STDMETHODIMP CCommands::VisVimToggle()
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
VimSetEnableState (! g_bEnableVim);
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
VimSetEnableState(! g_bEnableVim);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCommands::VisVimLoad ()
|
||||
STDMETHODIMP CCommands::VisVimLoad()
|
||||
{
|
||||
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
|
||||
// Use m_pApplication to access the Developer Studio Application object,
|
||||
// and VERIFY_OK to see error strings in DEBUG builds of your add-in
|
||||
@@ -430,7 +440,7 @@ STDMETHODIMP CCommands::VisVimLoad ()
|
||||
CComPtr < IDispatch > pDispDoc, pDispSel;
|
||||
|
||||
// Get a document object dispatch pointer
|
||||
VERIFY_OK (m_pApplication->get_ActiveDocument (&pDispDoc));
|
||||
VERIFY_OK(m_pApplication->get_ActiveDocument(&pDispDoc));
|
||||
if (! pDispDoc)
|
||||
return S_OK;
|
||||
|
||||
@@ -438,30 +448,30 @@ STDMETHODIMP CCommands::VisVimLoad ()
|
||||
long LineNr = -1;
|
||||
|
||||
// Get the document object
|
||||
CComQIPtr < ITextDocument, &IID_ITextDocument > pDoc (pDispDoc);
|
||||
CComQIPtr < ITextDocument, &IID_ITextDocument > pDoc(pDispDoc);
|
||||
|
||||
if (! pDoc)
|
||||
return S_OK;
|
||||
|
||||
// Get the document name
|
||||
if (FAILED (pDoc->get_FullName (&FileName)))
|
||||
if (FAILED(pDoc->get_FullName(&FileName)))
|
||||
return S_OK;
|
||||
|
||||
// Get a selection object dispatch pointer
|
||||
if (SUCCEEDED (pDoc->get_Selection (&pDispSel)))
|
||||
if (SUCCEEDED(pDoc->get_Selection(&pDispSel)))
|
||||
{
|
||||
// Get the selection object
|
||||
CComQIPtr < ITextSelection, &IID_ITextSelection > pSel (pDispSel);
|
||||
CComQIPtr < ITextSelection, &IID_ITextSelection > pSel(pDispSel);
|
||||
|
||||
if (pSel)
|
||||
// Get the selection line number
|
||||
pSel->get_CurrentLine (&LineNr);
|
||||
pSel->get_CurrentLine(&LineNr);
|
||||
}
|
||||
|
||||
// Open the file in Vim
|
||||
VimOpenFile (FileName, LineNr);
|
||||
VimOpenFile(FileName, LineNr);
|
||||
|
||||
SysFreeString (FileName);
|
||||
SysFreeString(FileName);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -472,16 +482,16 @@ STDMETHODIMP CCommands::VisVimLoad ()
|
||||
|
||||
// Set the enable state and save to registry
|
||||
//
|
||||
static void VimSetEnableState (BOOL bEnableState)
|
||||
static void VimSetEnableState(BOOL bEnableState)
|
||||
{
|
||||
g_bEnableVim = bEnableState;
|
||||
HKEY hAppKey = GetAppKey ("Vim");
|
||||
HKEY hAppKey = GetAppKey("Vim");
|
||||
if (hAppKey)
|
||||
{
|
||||
HKEY hSectionKey = GetSectionKey (hAppKey, "VisVim");
|
||||
HKEY hSectionKey = GetSectionKey(hAppKey, "VisVim");
|
||||
if (hSectionKey)
|
||||
WriteRegistryInt (hSectionKey, "EnableVim", g_bEnableVim);
|
||||
RegCloseKey (hAppKey);
|
||||
WriteRegistryInt(hSectionKey, "EnableVim", g_bEnableVim);
|
||||
RegCloseKey(hAppKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,7 +500,7 @@ static void VimSetEnableState (BOOL bEnableState)
|
||||
// letter.
|
||||
// 'LineNr' must contain a valid line number or 0, e. g. for a new file
|
||||
//
|
||||
static BOOL VimOpenFile (BSTR& FileName, long LineNr)
|
||||
static BOOL VimOpenFile(BSTR& FileName, long LineNr)
|
||||
{
|
||||
|
||||
// OLE automation object for com. with Vim
|
||||
@@ -507,7 +517,7 @@ static BOOL VimOpenFile (BSTR& FileName, long LineNr)
|
||||
// Get a dispatch id for the SendKeys method of Vim;
|
||||
// enables connection to Vim if necessary
|
||||
DISPID DispatchId;
|
||||
DispatchId = VimGetDispatchId (VimOle, "SendKeys");
|
||||
DispatchId = VimGetDispatchId(VimOle, "SendKeys");
|
||||
if (! DispatchId)
|
||||
// OLE error, can't obtain dispatch id
|
||||
goto OleError;
|
||||
@@ -525,20 +535,28 @@ static BOOL VimOpenFile (BSTR& FileName, long LineNr)
|
||||
#ifdef SINGLE_WINDOW
|
||||
// Update the current file in Vim if it has been modified.
|
||||
// Disabled, because it could write the file when you don't want to.
|
||||
sprintf (VimCmd + 2, ":up\n");
|
||||
sprintf(VimCmd + 2, ":up\n");
|
||||
#endif
|
||||
if (! VimOle.Method (DispatchId, "s", TO_OLE_STR_BUF (VimCmd, Buf)))
|
||||
if (! VimOle.Method(DispatchId, "s", TO_OLE_STR_BUF(VimCmd, Buf)))
|
||||
goto OleError;
|
||||
|
||||
// Change Vim working directory to where the file is if desired
|
||||
if (g_ChangeDir != CD_NONE)
|
||||
VimChangeDir (VimOle, DispatchId, FileName);
|
||||
VimChangeDir(VimOle, DispatchId, FileName);
|
||||
|
||||
// Make Vim open the file.
|
||||
// In the filename convert all \ to /, put a \ before a space.
|
||||
sprintf(VimCmd, ":drop ");
|
||||
if (g_bNewTabs)
|
||||
{
|
||||
sprintf(VimCmd, ":tab drop ");
|
||||
s = VimCmd + 11;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(VimCmd, ":drop ");
|
||||
s = VimCmd + 6;
|
||||
}
|
||||
sprintf(FileNameTmp, "%S", (char *)FileName);
|
||||
s = VimCmd + 6;
|
||||
for (p = FileNameTmp; *p != '\0' && s < FileNameTmp + MAX_OLE_STR - 4;
|
||||
++p)
|
||||
if (*p == '\\')
|
||||
@@ -552,20 +570,20 @@ static BOOL VimOpenFile (BSTR& FileName, long LineNr)
|
||||
*s++ = '\n';
|
||||
*s = '\0';
|
||||
|
||||
if (! VimOle.Method (DispatchId, "s", TO_OLE_STR_BUF (VimCmd, Buf)))
|
||||
if (! VimOle.Method(DispatchId, "s", TO_OLE_STR_BUF(VimCmd, Buf)))
|
||||
goto OleError;
|
||||
|
||||
if (LineNr > 0)
|
||||
{
|
||||
// Goto line
|
||||
sprintf (VimCmd, ":%d\n", LineNr);
|
||||
if (! VimOle.Method (DispatchId, "s", TO_OLE_STR_BUF (VimCmd, Buf)))
|
||||
sprintf(VimCmd, ":%d\n", LineNr);
|
||||
if (! VimOle.Method(DispatchId, "s", TO_OLE_STR_BUF(VimCmd, Buf)))
|
||||
goto OleError;
|
||||
}
|
||||
|
||||
// Make Vim come to the foreground
|
||||
if (! VimOle.Method ("SetForeground"))
|
||||
VimOle.ErrDiag ();
|
||||
if (! VimOle.Method("SetForeground"))
|
||||
VimOle.ErrDiag();
|
||||
|
||||
// We're done
|
||||
return true;
|
||||
@@ -573,7 +591,7 @@ static BOOL VimOpenFile (BSTR& FileName, long LineNr)
|
||||
OleError:
|
||||
// There was an OLE error
|
||||
// Check if it's the "unknown class string" error
|
||||
VimErrDiag (VimOle);
|
||||
VimErrDiag(VimOle);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -581,18 +599,18 @@ static BOOL VimOpenFile (BSTR& FileName, long LineNr)
|
||||
// Create the Vim OLE object if necessary
|
||||
// Returns a valid dispatch id or null on error
|
||||
//
|
||||
static DISPID VimGetDispatchId (COleAutomationControl& VimOle, char* Method)
|
||||
static DISPID VimGetDispatchId(COleAutomationControl& VimOle, char* Method)
|
||||
{
|
||||
// Initialize Vim OLE connection if not already done
|
||||
if (! VimOle.IsCreated ())
|
||||
if (! VimOle.IsCreated())
|
||||
{
|
||||
if (! VimOle.CreateObject ("Vim.Application"))
|
||||
if (! VimOle.CreateObject("Vim.Application"))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the dispatch id for the SendKeys method.
|
||||
// By doing this, we are checking if Vim is still there...
|
||||
DISPID DispatchId = VimOle.GetDispatchId ("SendKeys");
|
||||
DISPID DispatchId = VimOle.GetDispatchId("SendKeys");
|
||||
if (! DispatchId)
|
||||
{
|
||||
// We can't get a dispatch id.
|
||||
@@ -604,12 +622,12 @@ static DISPID VimGetDispatchId (COleAutomationControl& VimOle, char* Method)
|
||||
// should not be kept long enough to allow the user to terminate Vim
|
||||
// to avoid memory corruption (why the heck is there no system garbage
|
||||
// collection for those damned OLE memory chunks???).
|
||||
VimOle.DeleteObject ();
|
||||
if (! VimOle.CreateObject ("Vim.Application"))
|
||||
VimOle.DeleteObject();
|
||||
if (! VimOle.CreateObject("Vim.Application"))
|
||||
// If this create fails, it's time for an error msg
|
||||
return NULL;
|
||||
|
||||
if (! (DispatchId = VimOle.GetDispatchId ("SendKeys")))
|
||||
if (! (DispatchId = VimOle.GetDispatchId("SendKeys")))
|
||||
// There is something wrong...
|
||||
return NULL;
|
||||
}
|
||||
@@ -620,20 +638,20 @@ static DISPID VimGetDispatchId (COleAutomationControl& VimOle, char* Method)
|
||||
// Output an error message for an OLE error
|
||||
// Check on the classstring error, which probably means Vim wasn't registered.
|
||||
//
|
||||
static void VimErrDiag (COleAutomationControl& VimOle)
|
||||
static void VimErrDiag(COleAutomationControl& VimOle)
|
||||
{
|
||||
SCODE sc = GetScode (VimOle.GetResult ());
|
||||
SCODE sc = GetScode(VimOle.GetResult());
|
||||
if (sc == CO_E_CLASSSTRING)
|
||||
{
|
||||
char Buf[256];
|
||||
sprintf (Buf, "There is no registered OLE automation server named "
|
||||
sprintf(Buf, "There is no registered OLE automation server named "
|
||||
"\"Vim.Application\".\n"
|
||||
"Use the OLE-enabled version of Vim with VisVim and "
|
||||
"make sure to register Vim by running \"vim -register\".");
|
||||
MessageBox (NULL, Buf, "OLE Error", MB_OK);
|
||||
MessageBox(NULL, Buf, "OLE Error", MB_OK);
|
||||
}
|
||||
else
|
||||
VimOle.ErrDiag ();
|
||||
VimOle.ErrDiag();
|
||||
}
|
||||
|
||||
// Change directory to the directory the file 'FileName' is in or it's parent
|
||||
@@ -644,7 +662,7 @@ static void VimErrDiag (COleAutomationControl& VimOle)
|
||||
// CD_SOURCE_PATH
|
||||
// CD_SOURCE_PARENT
|
||||
//
|
||||
static void VimChangeDir (COleAutomationControl& VimOle, DISPID DispatchId, BSTR& FileName)
|
||||
static void VimChangeDir(COleAutomationControl& VimOle, DISPID DispatchId, BSTR& FileName)
|
||||
{
|
||||
// Do a :cd first
|
||||
|
||||
@@ -655,7 +673,7 @@ static void VimChangeDir (COleAutomationControl& VimOle, DISPID DispatchId, BSTR
|
||||
char DirUnix[_MAX_DIR * 2];
|
||||
char *s, *t;
|
||||
|
||||
_splitpath (StrFileName, Drive, Dir, NULL, NULL);
|
||||
_splitpath(StrFileName, Drive, Dir, NULL, NULL);
|
||||
|
||||
// Convert to Unix path name format, escape spaces.
|
||||
t = DirUnix;
|
||||
@@ -676,19 +694,18 @@ static void VimChangeDir (COleAutomationControl& VimOle, DISPID DispatchId, BSTR
|
||||
OLECHAR Buf[MAX_OLE_STR];
|
||||
char VimCmd[MAX_OLE_STR];
|
||||
|
||||
sprintf (VimCmd, ":cd %s%s%s\n", Drive, DirUnix,
|
||||
sprintf(VimCmd, ":cd %s%s%s\n", Drive, DirUnix,
|
||||
g_ChangeDir == CD_SOURCE_PARENT && DirUnix[1] ? ".." : "");
|
||||
VimOle.Method (DispatchId, "s", TO_OLE_STR_BUF (VimCmd, Buf));
|
||||
VimOle.Method(DispatchId, "s", TO_OLE_STR_BUF(VimCmd, Buf));
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Print out a debug message
|
||||
//
|
||||
static void DebugMsg (char* Msg, char* Arg)
|
||||
static void DebugMsg(char* Msg, char* Arg)
|
||||
{
|
||||
char Buf[400];
|
||||
sprintf (Buf, Msg, Arg);
|
||||
AfxMessageBox (Buf);
|
||||
sprintf(Buf, Msg, Arg);
|
||||
AfxMessageBox(Buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define IDC_CD_SOURCE_PATH 1001
|
||||
#define IDC_CD_SOURCE_PARENT 1002
|
||||
#define IDC_CD_NONE 1003
|
||||
#define IDC_NEW_TABS 1004
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
|
||||
@@ -122,6 +122,9 @@ BEGIN
|
||||
CONTROL "&Open file in DevStudio editor simultaneously",
|
||||
IDC_DEVSTUDIO_EDITOR,"Button",BS_AUTOCHECKBOX | WS_GROUP |
|
||||
WS_TABSTOP,7,7,153,10
|
||||
CONTROL "Open files in new tabs",
|
||||
IDC_NEW_TABS,"Button",BS_AUTOCHECKBOX | WS_GROUP |
|
||||
WS_TABSTOP,7,21,153,10
|
||||
GROUPBOX "Current directory",IDC_STATIC,7,35,164,58,WS_GROUP
|
||||
CONTROL "Set to &source file path",IDC_CD_SOURCE_PATH,"Button",
|
||||
BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,17,49,85,10
|
||||
|
||||
Vendored
+577
-266
File diff suppressed because it is too large
Load Diff
+71
-73
@@ -44,6 +44,7 @@ static int otherfile_buf __ARGS((buf_T *buf, char_u *ffname));
|
||||
#ifdef FEAT_TITLE
|
||||
static int ti_change __ARGS((char_u *str, char_u **last));
|
||||
#endif
|
||||
static int append_arg_number __ARGS((win_T *wp, char_u *buf, int buflen, int add_file));
|
||||
static void free_buffer __ARGS((buf_T *));
|
||||
static void free_buffer_stuff __ARGS((buf_T *buf, int free_options));
|
||||
static void clear_wininfo __ARGS((buf_T *buf));
|
||||
@@ -437,10 +438,6 @@ close_buffer(win, buf, action)
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
if (usingNetbeans)
|
||||
netbeans_file_closed(buf);
|
||||
#endif
|
||||
#ifdef FEAT_ODB_EDITOR
|
||||
odb_buffer_close(buf);
|
||||
#endif
|
||||
@@ -519,12 +516,11 @@ buf_clear_file(buf)
|
||||
* buf_freeall() - free all things allocated for a buffer that are related to
|
||||
* the file.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
buf_freeall(buf, del_buf, wipe_buf)
|
||||
buf_T *buf;
|
||||
int del_buf; /* buffer is going to be deleted */
|
||||
int wipe_buf; /* buffer is going to be wiped out */
|
||||
int del_buf UNUSED; /* buffer is going to be deleted */
|
||||
int wipe_buf UNUSED; /* buffer is going to be wiped out */
|
||||
{
|
||||
#ifdef FEAT_AUTOCMD
|
||||
int is_curbuf = (buf == curbuf);
|
||||
@@ -643,6 +639,10 @@ free_buffer_stuff(buf, free_options)
|
||||
#ifdef FEAT_SIGNS
|
||||
buf_delete_signs(buf); /* delete any signs */
|
||||
#endif
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
if (usingNetbeans)
|
||||
netbeans_file_killed(buf);
|
||||
#endif
|
||||
#ifdef FEAT_LOCALMAP
|
||||
map_clear_int(buf, MAP_ALL_MODES, TRUE, FALSE); /* clear local mappings */
|
||||
map_clear_int(buf, MAP_ALL_MODES, TRUE, TRUE); /* clear local abbrevs */
|
||||
@@ -819,9 +819,6 @@ do_bufdel(command, arg, addr_count, start_bnr, end_bnr, forceit)
|
||||
int bnr; /* buffer number */
|
||||
char_u *p;
|
||||
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
netbeansCloseFile = 1;
|
||||
#endif
|
||||
if (addr_count == 0)
|
||||
{
|
||||
(void)do_buffer(command, DOBUF_CURRENT, FORWARD, 0, forceit);
|
||||
@@ -916,9 +913,6 @@ do_bufdel(command, arg, addr_count, start_bnr, end_bnr, forceit)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
netbeansCloseFile = 0;
|
||||
#endif
|
||||
|
||||
return errormsg;
|
||||
}
|
||||
@@ -1463,13 +1457,13 @@ enter_buffer(buf)
|
||||
|
||||
#ifdef FEAT_KEYMAP
|
||||
if (curbuf->b_kmap_state & KEYMAP_INIT)
|
||||
keymap_init();
|
||||
(void)keymap_init();
|
||||
#endif
|
||||
#ifdef FEAT_SPELL
|
||||
/* May need to set the spell language. Can only do this after the buffer
|
||||
* has been properly setup. */
|
||||
if (!curbuf->b_help && curwin->w_p_spell && *curbuf->b_p_spl != NUL)
|
||||
did_set_spelllang(curbuf);
|
||||
(void)did_set_spelllang(curbuf);
|
||||
#endif
|
||||
|
||||
redraw_later(NOT_VALID);
|
||||
@@ -1687,9 +1681,10 @@ buflist_new(ffname, sfname, lnum, flags)
|
||||
buf->b_fname = buf->b_sfname;
|
||||
#ifdef UNIX
|
||||
if (st.st_dev == (dev_T)-1)
|
||||
buf->b_dev = -1;
|
||||
buf->b_dev_valid = FALSE;
|
||||
else
|
||||
{
|
||||
buf->b_dev_valid = TRUE;
|
||||
buf->b_dev = st.st_dev;
|
||||
buf->b_ino = st.st_ino;
|
||||
}
|
||||
@@ -2034,13 +2029,12 @@ buflist_findname_stat(ffname, stp)
|
||||
* Return fnum of the found buffer.
|
||||
* Return < 0 for error.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
buflist_findpat(pattern, pattern_end, unlisted, diffmode)
|
||||
char_u *pattern;
|
||||
char_u *pattern_end; /* pointer to first char after pattern */
|
||||
int unlisted; /* find unlisted buffers */
|
||||
int diffmode; /* find diff-mode buffers only */
|
||||
int diffmode UNUSED; /* find diff-mode buffers only */
|
||||
{
|
||||
buf_T *buf;
|
||||
regprog_T *prog;
|
||||
@@ -2445,11 +2439,10 @@ wininfo_other_tab_diff(wip)
|
||||
* another tab page.
|
||||
* Returns NULL when there isn't any info.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static wininfo_T *
|
||||
find_wininfo(buf, skip_diff_buffer)
|
||||
buf_T *buf;
|
||||
int skip_diff_buffer;
|
||||
int skip_diff_buffer UNUSED;
|
||||
{
|
||||
wininfo_T *wip;
|
||||
|
||||
@@ -2526,7 +2519,7 @@ buflist_findfpos(buf)
|
||||
buf_T *buf;
|
||||
{
|
||||
wininfo_T *wip;
|
||||
static pos_T no_position = {1, 0};
|
||||
static pos_T no_position = INIT_POS_T(1, 0, 0);
|
||||
|
||||
wip = find_wininfo(buf, FALSE);
|
||||
if (wip != NULL)
|
||||
@@ -2549,7 +2542,6 @@ buflist_findlnum(buf)
|
||||
/*
|
||||
* List all know file names (for :files and :buffers command).
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
buflist_list(eap)
|
||||
exarg_T *eap;
|
||||
@@ -2587,8 +2579,8 @@ buflist_list(eap)
|
||||
{
|
||||
IObuff[len++] = ' ';
|
||||
} while (--i > 0 && len < IOSIZE - 18);
|
||||
vim_snprintf((char *)IObuff + len, IOSIZE - len, _("line %ld"),
|
||||
buf == curbuf ? curwin->w_cursor.lnum
|
||||
vim_snprintf((char *)IObuff + len, (size_t)(IOSIZE - len),
|
||||
_("line %ld"), buf == curbuf ? curwin->w_cursor.lnum
|
||||
: (long)buflist_findlnum(buf));
|
||||
msg_outtrans(IObuff);
|
||||
out_flush(); /* output one line at a time */
|
||||
@@ -2702,9 +2694,10 @@ setfname(buf, ffname, sfname, message)
|
||||
buf->b_fname = buf->b_sfname;
|
||||
#ifdef UNIX
|
||||
if (st.st_dev == (dev_T)-1)
|
||||
buf->b_dev = -1;
|
||||
buf->b_dev_valid = FALSE;
|
||||
else
|
||||
{
|
||||
buf->b_dev_valid = TRUE;
|
||||
buf->b_dev = st.st_dev;
|
||||
buf->b_ino = st.st_ino;
|
||||
}
|
||||
@@ -2898,7 +2891,7 @@ otherfile_buf(buf, ffname
|
||||
/* If no struct stat given, get it now */
|
||||
if (stp == NULL)
|
||||
{
|
||||
if (buf->b_dev < 0 || mch_stat((char *)ffname, &st) < 0)
|
||||
if (!buf->b_dev_valid || mch_stat((char *)ffname, &st) < 0)
|
||||
st.st_dev = (dev_T)-1;
|
||||
stp = &st;
|
||||
}
|
||||
@@ -2935,11 +2928,12 @@ buf_setino(buf)
|
||||
|
||||
if (buf->b_fname != NULL && mch_stat((char *)buf->b_fname, &st) >= 0)
|
||||
{
|
||||
buf->b_dev_valid = TRUE;
|
||||
buf->b_dev = st.st_dev;
|
||||
buf->b_ino = st.st_ino;
|
||||
}
|
||||
else
|
||||
buf->b_dev = -1;
|
||||
buf->b_dev_valid = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2950,7 +2944,7 @@ buf_same_ino(buf, stp)
|
||||
buf_T *buf;
|
||||
struct stat *stp;
|
||||
{
|
||||
return (buf->b_dev >= 0
|
||||
return (buf->b_dev_valid
|
||||
&& stp->st_dev == buf->b_dev
|
||||
&& stp->st_ino == buf->b_ino);
|
||||
}
|
||||
@@ -2977,7 +2971,7 @@ fileinfo(fullname, shorthelp, dont_truncate)
|
||||
|
||||
if (fullname > 1) /* 2 CTRL-G: include buffer number */
|
||||
{
|
||||
sprintf((char *)buffer, "buf %d: ", curbuf->b_fnum);
|
||||
vim_snprintf((char *)buffer, IOSIZE, "buf %d: ", curbuf->b_fnum);
|
||||
p = buffer + STRLEN(buffer);
|
||||
}
|
||||
else
|
||||
@@ -3051,11 +3045,12 @@ fileinfo(fullname, shorthelp, dont_truncate)
|
||||
(long)curbuf->b_ml.ml_line_count,
|
||||
n);
|
||||
validate_virtcol();
|
||||
col_print(buffer + STRLEN(buffer),
|
||||
len = STRLEN(buffer);
|
||||
col_print(buffer + len, IOSIZE - len,
|
||||
(int)curwin->w_cursor.col + 1, (int)curwin->w_virtcol + 1);
|
||||
}
|
||||
|
||||
(void)append_arg_number(curwin, buffer, !shortmess(SHM_FILE), IOSIZE);
|
||||
(void)append_arg_number(curwin, buffer, IOSIZE, !shortmess(SHM_FILE));
|
||||
|
||||
if (dont_truncate)
|
||||
{
|
||||
@@ -3083,15 +3078,16 @@ fileinfo(fullname, shorthelp, dont_truncate)
|
||||
}
|
||||
|
||||
void
|
||||
col_print(buf, col, vcol)
|
||||
col_print(buf, buflen, col, vcol)
|
||||
char_u *buf;
|
||||
size_t buflen;
|
||||
int col;
|
||||
int vcol;
|
||||
{
|
||||
if (col == vcol)
|
||||
sprintf((char *)buf, "%d", col);
|
||||
vim_snprintf((char *)buf, buflen, "%d", col);
|
||||
else
|
||||
sprintf((char *)buf, "%d-%d", col, vcol);
|
||||
vim_snprintf((char *)buf, buflen, "%d-%d", col, vcol);
|
||||
}
|
||||
|
||||
#if defined(FEAT_TITLE) || defined(PROTO)
|
||||
@@ -3208,20 +3204,18 @@ maketitle()
|
||||
if (p == buf + off)
|
||||
/* must be a help buffer */
|
||||
vim_strncpy(buf + off, (char_u *)_("help"),
|
||||
IOSIZE - off - 1);
|
||||
(size_t)(IOSIZE - off - 1));
|
||||
else
|
||||
*p = NUL;
|
||||
|
||||
/* translate unprintable chars */
|
||||
p = transstr(buf + off);
|
||||
vim_strncpy(buf + off, p, IOSIZE - off - 1);
|
||||
vim_strncpy(buf + off, p, (size_t)(IOSIZE - off - 1));
|
||||
vim_free(p);
|
||||
STRCAT(buf, ")");
|
||||
}
|
||||
|
||||
#ifndef FEAT_GUI_MACVIM
|
||||
append_arg_number(curwin, buf, FALSE, IOSIZE);
|
||||
#endif
|
||||
append_arg_number(curwin, buf, IOSIZE, FALSE);
|
||||
|
||||
#if defined(FEAT_CLIENTSERVER)
|
||||
if (serverName != NULL)
|
||||
@@ -3358,14 +3352,13 @@ free_titles()
|
||||
* If maxwidth is not zero, the string will be filled at any middle marker
|
||||
* or truncated if too long, fillchar is used for all whitespace.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar, maxwidth, hltab, tabtab)
|
||||
win_T *wp;
|
||||
char_u *out; /* buffer to write into != NameBuff */
|
||||
size_t outlen; /* length of out[] */
|
||||
char_u *fmt;
|
||||
int use_sandbox; /* "fmt" was set insecurely, use sandbox */
|
||||
int use_sandbox UNUSED; /* "fmt" was set insecurely, use sandbox */
|
||||
int fillchar;
|
||||
int maxwidth;
|
||||
struct stl_hlrec *hltab; /* return: HL attributes (can be NULL) */
|
||||
@@ -3536,7 +3529,7 @@ build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar, maxwidth, hltab, t
|
||||
n = (long)(p - t) - item[groupitem[groupdepth]].maxwid + 1;
|
||||
|
||||
*t = '<';
|
||||
mch_memmove(t + 1, t + n, p - (t + n));
|
||||
mch_memmove(t + 1, t + n, (size_t)(p - (t + n)));
|
||||
p = p - n + 1;
|
||||
#ifdef FEAT_MBYTE
|
||||
/* Fill up space left over by half a double-wide char. */
|
||||
@@ -3566,7 +3559,7 @@ build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar, maxwidth, hltab, t
|
||||
else
|
||||
{
|
||||
/* fill by inserting characters */
|
||||
mch_memmove(t + n - l, t, p - t);
|
||||
mch_memmove(t + n - l, t, (size_t)(p - t));
|
||||
l = n - l;
|
||||
if (p + l >= out + outlen)
|
||||
l = (long)((out + outlen) - p - 1);
|
||||
@@ -3702,7 +3695,7 @@ build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar, maxwidth, hltab, t
|
||||
p = t;
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
sprintf((char *)tmp, "%d", curbuf->b_fnum);
|
||||
vim_snprintf((char *)tmp, sizeof(tmp), "%d", curbuf->b_fnum);
|
||||
set_internal_string_var((char_u *)"actual_curbuf", tmp);
|
||||
|
||||
o_curbuf = curbuf;
|
||||
@@ -3769,13 +3762,13 @@ build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar, maxwidth, hltab, t
|
||||
|
||||
case STL_ALTPERCENT:
|
||||
str = tmp;
|
||||
get_rel_pos(wp, str);
|
||||
get_rel_pos(wp, str, TMPLEN);
|
||||
break;
|
||||
|
||||
case STL_ARGLISTSTAT:
|
||||
fillable = FALSE;
|
||||
tmp[0] = 0;
|
||||
if (append_arg_number(wp, tmp, FALSE, (int)sizeof(tmp)))
|
||||
if (append_arg_number(wp, tmp, (int)sizeof(tmp), FALSE))
|
||||
str = tmp;
|
||||
break;
|
||||
|
||||
@@ -3810,7 +3803,7 @@ build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar, maxwidth, hltab, t
|
||||
case STL_BYTEVAL_X:
|
||||
base = 'X';
|
||||
case STL_BYTEVAL:
|
||||
if (wp->w_cursor.col > STRLEN(linecont))
|
||||
if (wp->w_cursor.col > (colnr_T)STRLEN(linecont))
|
||||
num = 0;
|
||||
else
|
||||
{
|
||||
@@ -3983,7 +3976,7 @@ build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar, maxwidth, hltab, t
|
||||
if (zeropad)
|
||||
*t++ = '0';
|
||||
*t++ = '*';
|
||||
*t++ = nbase == 16 ? base : (nbase == 8 ? 'o' : 'd');
|
||||
*t++ = nbase == 16 ? base : (char_u)(nbase == 8 ? 'o' : 'd');
|
||||
*t = 0;
|
||||
|
||||
for (n = num, l = 1; n >= nbase; n /= nbase)
|
||||
@@ -4176,13 +4169,14 @@ build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar, maxwidth, hltab, t
|
||||
#if defined(FEAT_STL_OPT) || defined(FEAT_CMDL_INFO) \
|
||||
|| defined(FEAT_GUI_TABLINE) || defined(PROTO)
|
||||
/*
|
||||
* Get relative cursor position in window into "str[]", in the form 99%, using
|
||||
* "Top", "Bot" or "All" when appropriate.
|
||||
* Get relative cursor position in window into "buf[buflen]", in the form 99%,
|
||||
* using "Top", "Bot" or "All" when appropriate.
|
||||
*/
|
||||
void
|
||||
get_rel_pos(wp, str)
|
||||
get_rel_pos(wp, buf, buflen)
|
||||
win_T *wp;
|
||||
char_u *str;
|
||||
char_u *buf;
|
||||
int buflen;
|
||||
{
|
||||
long above; /* number of lines above window */
|
||||
long below; /* number of lines below window */
|
||||
@@ -4193,34 +4187,35 @@ get_rel_pos(wp, str)
|
||||
#endif
|
||||
below = wp->w_buffer->b_ml.ml_line_count - wp->w_botline + 1;
|
||||
if (below <= 0)
|
||||
STRCPY(str, above == 0 ? _("All") : _("Bot"));
|
||||
vim_strncpy(buf, (char_u *)(above == 0 ? _("All") : _("Bot")),
|
||||
(size_t)(buflen - 1));
|
||||
else if (above <= 0)
|
||||
STRCPY(str, _("Top"));
|
||||
vim_strncpy(buf, (char_u *)_("Top"), (size_t)(buflen - 1));
|
||||
else
|
||||
sprintf((char *)str, "%2d%%", above > 1000000L
|
||||
vim_snprintf((char *)buf, (size_t)buflen, "%2d%%", above > 1000000L
|
||||
? (int)(above / ((above + below) / 100L))
|
||||
: (int)(above * 100L / (above + below)));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Append (file 2 of 8) to 'buf', if editing more than one file.
|
||||
* Append (file 2 of 8) to "buf[buflen]", if editing more than one file.
|
||||
* Return TRUE if it was appended.
|
||||
*/
|
||||
int
|
||||
append_arg_number(wp, buf, add_file, maxlen)
|
||||
static int
|
||||
append_arg_number(wp, buf, buflen, add_file)
|
||||
win_T *wp;
|
||||
char_u *buf;
|
||||
int buflen;
|
||||
int add_file; /* Add "file" before the arg number */
|
||||
int maxlen; /* maximum nr of chars in buf or zero*/
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
if (ARGCOUNT <= 1) /* nothing to do */
|
||||
return FALSE;
|
||||
|
||||
p = buf + STRLEN(buf); /* go to the end of the buffer */
|
||||
if (maxlen && p - buf + 35 >= maxlen) /* getting too long */
|
||||
p = buf + STRLEN(buf); /* go to the end of the buffer */
|
||||
if (p - buf + 35 >= buflen) /* getting too long */
|
||||
return FALSE;
|
||||
*p++ = ' ';
|
||||
*p++ = '(';
|
||||
@@ -4229,7 +4224,8 @@ append_arg_number(wp, buf, add_file, maxlen)
|
||||
STRCPY(p, "file ");
|
||||
p += 5;
|
||||
}
|
||||
sprintf((char *)p, wp->w_arg_idx_invalid ? "(%d) of %d)"
|
||||
vim_snprintf((char *)p, (size_t)(buflen - (p - buf)),
|
||||
wp->w_arg_idx_invalid ? "(%d) of %d)"
|
||||
: "%d of %d)", wp->w_arg_idx + 1, ARGCOUNT);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -4285,10 +4281,9 @@ fix_fname(fname)
|
||||
* Make "ffname" a full file name, set "sfname" to "ffname" if not NULL.
|
||||
* "ffname" becomes a pointer to allocated memory (or NULL).
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
fname_expand(buf, ffname, sfname)
|
||||
buf_T *buf;
|
||||
buf_T *buf UNUSED;
|
||||
char_u **ffname;
|
||||
char_u **sfname;
|
||||
{
|
||||
@@ -5012,7 +5007,7 @@ read_viminfo_bufferlist(virp, writing)
|
||||
if (tab != NULL)
|
||||
{
|
||||
*tab++ = '\0';
|
||||
col = atoi((char *)tab);
|
||||
col = (colnr_T)atoi((char *)tab);
|
||||
tab = vim_strrchr(xline, '\t');
|
||||
if (tab != NULL)
|
||||
{
|
||||
@@ -5050,6 +5045,7 @@ write_viminfo_bufferlist(fp)
|
||||
#endif
|
||||
char_u *line;
|
||||
int max_buffers;
|
||||
size_t len;
|
||||
|
||||
if (find_viminfo_parameter('%') == NULL)
|
||||
return;
|
||||
@@ -5058,7 +5054,8 @@ write_viminfo_bufferlist(fp)
|
||||
max_buffers = get_viminfo_parameter('%');
|
||||
|
||||
/* Allocate room for the file name, lnum and col. */
|
||||
line = alloc(MAXPATHL + 40);
|
||||
#define LINE_BUF_LEN (MAXPATHL + 40)
|
||||
line = alloc(LINE_BUF_LEN);
|
||||
if (line == NULL)
|
||||
return;
|
||||
|
||||
@@ -5084,7 +5081,8 @@ write_viminfo_bufferlist(fp)
|
||||
break;
|
||||
putc('%', fp);
|
||||
home_replace(NULL, buf->b_ffname, line, MAXPATHL, TRUE);
|
||||
sprintf((char *)line + STRLEN(line), "\t%ld\t%d",
|
||||
len = STRLEN(line);
|
||||
vim_snprintf((char *)line + len, len - LINE_BUF_LEN, "\t%ld\t%d",
|
||||
(long)buf->b_last_cursor.lnum,
|
||||
buf->b_last_cursor.col);
|
||||
viminfo_writestring(fp, line);
|
||||
@@ -5114,7 +5112,8 @@ buf_spname(buf)
|
||||
*/
|
||||
FOR_ALL_TAB_WINDOWS(tp, win)
|
||||
if (win->w_buffer == buf)
|
||||
break;
|
||||
goto win_found;
|
||||
win_found:
|
||||
if (win != NULL && win->w_llist_ref != NULL)
|
||||
return _("[Location List]");
|
||||
else
|
||||
@@ -5241,7 +5240,7 @@ buf_addsign(buf, id, lnum, typenr)
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
linenr_T
|
||||
buf_change_sign_type(buf, markId, typenr)
|
||||
buf_T *buf; /* buffer to store sign in */
|
||||
int markId; /* sign ID */
|
||||
@@ -5258,10 +5257,10 @@ buf_change_sign_type(buf, markId, typenr)
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (linenr_T)0;
|
||||
}
|
||||
|
||||
int_u
|
||||
int
|
||||
buf_getsigntype(buf, lnum, type)
|
||||
buf_T *buf;
|
||||
linenr_T lnum;
|
||||
@@ -5580,11 +5579,10 @@ buf_contents_changed(buf)
|
||||
* this buffer. Call this to wipe out a temp buffer that does not contain any
|
||||
* marks.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
wipe_buffer(buf, aucmd)
|
||||
buf_T *buf;
|
||||
int aucmd; /* When TRUE trigger autocommands. */
|
||||
int aucmd UNUSED; /* When TRUE trigger autocommands. */
|
||||
{
|
||||
if (buf->b_fnum == top_file_num - 1)
|
||||
--top_file_num;
|
||||
|
||||
+13
-14
@@ -17,7 +17,7 @@ static int win_chartabsize __ARGS((win_T *wp, char_u *p, colnr_T col));
|
||||
static int win_nolbr_chartabsize __ARGS((win_T *wp, char_u *s, colnr_T col, int *headp));
|
||||
#endif
|
||||
|
||||
static int nr2hex __ARGS((int c));
|
||||
static unsigned nr2hex __ARGS((unsigned c));
|
||||
|
||||
static int chartab_initialized = FALSE;
|
||||
|
||||
@@ -664,7 +664,7 @@ transchar_hex(buf, c)
|
||||
}
|
||||
#endif
|
||||
buf[++i] = nr2hex((unsigned)c >> 4);
|
||||
buf[++i] = nr2hex(c);
|
||||
buf[++i] = nr2hex((unsigned)c);
|
||||
buf[++i] = '>';
|
||||
buf[++i] = NUL;
|
||||
}
|
||||
@@ -674,9 +674,9 @@ transchar_hex(buf, c)
|
||||
* Lower case letters are used to avoid the confusion of <F1> being 0xf1 or
|
||||
* function key 1.
|
||||
*/
|
||||
static int
|
||||
static unsigned
|
||||
nr2hex(c)
|
||||
int c;
|
||||
unsigned c;
|
||||
{
|
||||
if ((c & 0xf) <= 9)
|
||||
return (c & 0xf) + '0';
|
||||
@@ -884,7 +884,7 @@ vim_iswordc(c)
|
||||
if (c >= 0x100)
|
||||
{
|
||||
if (enc_dbcs != 0)
|
||||
return dbcs_class((unsigned)c >> 8, c & 0xff) >= 2;
|
||||
return dbcs_class((unsigned)c >> 8, (unsigned)(c & 0xff)) >= 2;
|
||||
if (enc_utf8)
|
||||
return utf_class(c) >= 2;
|
||||
}
|
||||
@@ -1026,13 +1026,12 @@ lbr_chartabsize_adv(s, col)
|
||||
* string at start of line. Warning: *headp is only set if it's a non-zero
|
||||
* value, init to 0 before calling.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
win_lbr_chartabsize(wp, s, col, headp)
|
||||
win_T *wp;
|
||||
char_u *s;
|
||||
colnr_T col;
|
||||
int *headp;
|
||||
int *headp UNUSED;
|
||||
{
|
||||
#ifdef FEAT_LINEBREAK
|
||||
int c;
|
||||
@@ -1090,7 +1089,7 @@ win_lbr_chartabsize(wp, s, col, headp)
|
||||
*/
|
||||
numberextra = win_col_off(wp);
|
||||
col2 = col;
|
||||
colmax = W_WIDTH(wp) - numberextra;
|
||||
colmax = (colnr_T)(W_WIDTH(wp) - numberextra);
|
||||
if (col >= colmax)
|
||||
{
|
||||
n = colmax + win_col_off2(wp);
|
||||
@@ -1201,17 +1200,17 @@ in_win_border(wp, vcol)
|
||||
win_T *wp;
|
||||
colnr_T vcol;
|
||||
{
|
||||
colnr_T width1; /* width of first line (after line number) */
|
||||
colnr_T width2; /* width of further lines */
|
||||
int width1; /* width of first line (after line number) */
|
||||
int width2; /* width of further lines */
|
||||
|
||||
#ifdef FEAT_VERTSPLIT
|
||||
if (wp->w_width == 0) /* there is no border */
|
||||
return FALSE;
|
||||
#endif
|
||||
width1 = W_WIDTH(wp) - win_col_off(wp);
|
||||
if (vcol < width1 - 1)
|
||||
if ((int)vcol < width1 - 1)
|
||||
return FALSE;
|
||||
if (vcol == width1 - 1)
|
||||
if ((int)vcol == width1 - 1)
|
||||
return TRUE;
|
||||
width2 = width1 + win_col_off2(wp);
|
||||
return ((vcol - width1) % width2 == width2 - 1);
|
||||
@@ -1396,13 +1395,13 @@ getvvcol(wp, pos, start, cursor, end)
|
||||
# ifdef FEAT_MBYTE
|
||||
/* Cannot put the cursor on part of a wide character. */
|
||||
ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
|
||||
if (pos->col < STRLEN(ptr))
|
||||
if (pos->col < (colnr_T)STRLEN(ptr))
|
||||
{
|
||||
int c = (*mb_ptr2char)(ptr + pos->col);
|
||||
|
||||
if (c != TAB && vim_isprintc(c))
|
||||
{
|
||||
endadd = char2cells(c) - 1;
|
||||
endadd = (colnr_T)(char2cells(c) - 1);
|
||||
if (coladd > endadd) /* past end of line */
|
||||
endadd = 0;
|
||||
else
|
||||
|
||||
@@ -30,12 +30,18 @@
|
||||
/* Define when __DATE__ " " __TIME__ can be used */
|
||||
#undef HAVE_DATE_TIME
|
||||
|
||||
/* Define when __attribute__((unused)) can be used */
|
||||
#undef HAVE_ATTRIBUTE_UNUSED
|
||||
|
||||
/* defined always when using configure */
|
||||
#undef UNIX
|
||||
|
||||
/* Defined to the size of an int */
|
||||
#undef SIZEOF_INT
|
||||
|
||||
/* Define when wchar_t is only 2 bytes. */
|
||||
#undef SMALL_WCHAR_T
|
||||
|
||||
/*
|
||||
* If we cannot trust one of the following from the libraries, we use our
|
||||
* own safe but probably slower vim_memmove().
|
||||
@@ -50,6 +56,9 @@
|
||||
/* Define to empty if the keyword does not work. */
|
||||
#undef const
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
#undef volatile
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef mode_t
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ MZSCHEME_SRC = @MZSCHEME_SRC@
|
||||
MZSCHEME_OBJ = @MZSCHEME_OBJ@
|
||||
MZSCHEME_CFLAGS = @MZSCHEME_CFLAGS@
|
||||
MZSCHEME_PRO = @MZSCHEME_PRO@
|
||||
MZSCHEME_EXTRA = @MZSCHEME_EXTRA@
|
||||
MZSCHEME_MZC = @MZSCHEME_MZC@
|
||||
|
||||
PERL = @vi_cv_path_perl@
|
||||
PERLLIB = @vi_cv_perllib@
|
||||
|
||||
+90
-23
@@ -423,7 +423,7 @@ if test "$enable_mzschemeinterp" = "yes"; then
|
||||
AC_MSG_RESULT("$PLTHOME")
|
||||
vi_cv_path_mzscheme_pfx="$PLTHOME"
|
||||
else
|
||||
AC_MSG_RESULT("not set")
|
||||
AC_MSG_RESULT(not set)
|
||||
dnl -- try to find MzScheme executable
|
||||
AC_PATH_PROG(vi_cv_path_mzscheme, mzscheme)
|
||||
|
||||
@@ -439,14 +439,16 @@ if test "$enable_mzschemeinterp" = "yes"; then
|
||||
if test "X$vi_cv_path_mzscheme" != "X"; then
|
||||
dnl -- find where MzScheme thinks it was installed
|
||||
AC_CACHE_CHECK(MzScheme install prefix,vi_cv_path_mzscheme_pfx,
|
||||
[ vi_cv_path_mzscheme_pfx=`
|
||||
${vi_cv_path_mzscheme} -evm \
|
||||
"(display (simplify-path \
|
||||
dnl different versions of MzScheme differ in command line processing
|
||||
dnl use universal approach
|
||||
echo "(display (simplify-path \
|
||||
(build-path (call-with-values \
|
||||
(lambda () (split-path (find-system-path (quote exec-file)))) \
|
||||
(lambda (base name must-be-dir?) base)) (quote up))))"` ])
|
||||
dnl Remove a trailing slash.
|
||||
vi_cv_path_mzscheme_pfx=`echo "$vi_cv_path_mzscheme_pfx" | sed 's+/$++'`
|
||||
(lambda (base name must-be-dir?) base)) (quote up))))" > mzdirs.scm
|
||||
dnl Remove a trailing slash
|
||||
[ vi_cv_path_mzscheme_pfx=`${vi_cv_path_mzscheme} -r mzdirs.scm | \
|
||||
sed -e 's+/$++'` ])
|
||||
rm -f mzdirs.scm
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -455,16 +457,24 @@ if test "$enable_mzschemeinterp" = "yes"; then
|
||||
if test "X$vi_cv_path_mzscheme_pfx" != "X"; then
|
||||
AC_MSG_CHECKING(if scheme.h can be found in $vi_cv_path_mzscheme_pfx/include)
|
||||
if test -f $vi_cv_path_mzscheme_pfx/include/scheme.h; then
|
||||
AC_MSG_RESULT("yes")
|
||||
SCHEME_INC=${vi_cv_path_mzscheme_pfx}/include
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT("no")
|
||||
AC_MSG_CHECKING(if scheme.h can be found in $vi_cv_path_mzscheme_pfx/plt/include)
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(if scheme.h can be found in $vi_cv_path_mzscheme_pfx/include/plt)
|
||||
if test -f $vi_cv_path_mzscheme_pfx/include/plt/scheme.h; then
|
||||
AC_MSG_RESULT("yes")
|
||||
SCHEME_INC=/plt
|
||||
AC_MSG_RESULT(yes)
|
||||
SCHEME_INC=${vi_cv_path_mzscheme_pfx}/include/plt
|
||||
else
|
||||
AC_MSG_RESULT("no")
|
||||
vi_cv_path_mzscheme_pfx=
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(if scheme.h can be found in /usr/include/plt/)
|
||||
if test -f /usr/include/plt/scheme.h; then
|
||||
AC_MSG_RESULT(yes)
|
||||
SCHEME_INC=/usr/include/plt
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
vi_cv_path_mzscheme_pfx=
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -472,23 +482,38 @@ if test "$enable_mzschemeinterp" = "yes"; then
|
||||
if test "X$vi_cv_path_mzscheme_pfx" != "X"; then
|
||||
if test "x$MACOSX" = "xyes"; then
|
||||
MZSCHEME_LIBS="-framework PLT_MzScheme"
|
||||
elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a"; then
|
||||
MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a"
|
||||
MZSCHEME_CFLAGS="-DMZ_PRECISE_GC"
|
||||
elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
|
||||
MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme.a ${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"
|
||||
else
|
||||
MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme -lmzgc"
|
||||
dnl Using shared objects
|
||||
if test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.so"; then
|
||||
MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme3m"
|
||||
MZSCHEME_CFLAGS="-DMZ_PRECISE_GC"
|
||||
else
|
||||
MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme -lmzgc"
|
||||
fi
|
||||
if test "$GCC" = yes; then
|
||||
dnl Make Vim remember the path to the library. For when it's not in
|
||||
dnl $LD_LIBRARY_PATH.
|
||||
MZSCHEME_LIBS="$MZSCHEME_LIBS -Wl,-rpath -Wl,${vi_cv_path_mzscheme_pfx}/lib"
|
||||
MZSCHEME_LIBS="${MZSCHEME_LIBS} -Wl,-rpath -Wl,${vi_cv_path_mzscheme_pfx}/lib"
|
||||
elif test "`(uname) 2>/dev/null`" = SunOS &&
|
||||
uname -r | grep '^5' >/dev/null; then
|
||||
MZSCHEME_LIBS="$MZSCHEME_LIBS -R ${vi_cv_path_mzscheme_pfx}/lib"
|
||||
MZSCHEME_LIBS="${MZSCHEME_LIBS} -R ${vi_cv_path_mzscheme_pfx}/lib"
|
||||
fi
|
||||
fi
|
||||
if test -d $vi_cv_path_mzscheme_pfx/lib/plt/collects; then
|
||||
SCHEME_COLLECTS=lib/plt/
|
||||
fi
|
||||
MZSCHEME_CFLAGS="-I${vi_cv_path_mzscheme_pfx}/include${SCHEME_INC} \
|
||||
if test -f "${vi_cv_path_mzscheme_pfx}/${SCHEME_COLLECTS}collects/scheme/base.ss" ; then
|
||||
dnl need to generate bytecode for MzScheme base
|
||||
MZSCHEME_EXTRA="mzscheme_base.c"
|
||||
MZSCHEME_CFLAGS="${MZSCHEME_CFLAGS} -DINCLUDE_MZSCHEME_BASE"
|
||||
MZSCHEME_MZC="${vi_cv_path_mzscheme_pfx}/bin/mzc"
|
||||
fi
|
||||
MZSCHEME_CFLAGS="${MZSCHEME_CFLAGS} -I${SCHEME_INC} \
|
||||
-DMZSCHEME_COLLECTS='\"${vi_cv_path_mzscheme_pfx}/${SCHEME_COLLECTS}collects\"'"
|
||||
MZSCHEME_SRC="if_mzsch.c"
|
||||
MZSCHEME_OBJ="objects/if_mzsch.o"
|
||||
@@ -500,6 +525,8 @@ if test "$enable_mzschemeinterp" = "yes"; then
|
||||
AC_SUBST(MZSCHEME_PRO)
|
||||
AC_SUBST(MZSCHEME_LIBS)
|
||||
AC_SUBST(MZSCHEME_CFLAGS)
|
||||
AC_SUBST(MZSCHEME_EXTRA)
|
||||
AC_SUBST(MZSCHEME_MZC)
|
||||
fi
|
||||
|
||||
|
||||
@@ -966,7 +993,13 @@ if test "$enable_rubyinterp" = "yes"; then
|
||||
fi
|
||||
rubyldflags=`$vi_cv_path_ruby -r rbconfig -e 'print Config::CONFIG[["LDFLAGS"]]'`
|
||||
if test "X$rubyldflags" != "X"; then
|
||||
LDFLAGS="$rubyldflags $LDFLAGS"
|
||||
dnl Ruby on Mac OS X 10.5 adds "-arch" flags but these should only
|
||||
dnl be included if requested by passing --with-mac-arch to
|
||||
dnl configure, so strip these flags first (if present)
|
||||
rubyldflags=`echo "$rubyldflags" | sed -e 's/-arch\ ppc//' -e 's/-arch\ i386//'`
|
||||
if test "X$rubyldflags" != "X"; then
|
||||
LDFLAGS="$rubyldflags $LDFLAGS"
|
||||
fi
|
||||
fi
|
||||
RUBY_SRC="if_ruby.c"
|
||||
RUBY_OBJ="objects/if_ruby.o"
|
||||
@@ -1202,6 +1235,28 @@ else
|
||||
|
||||
LDFLAGS="$ac_save_LDFLAGS"
|
||||
|
||||
AC_MSG_CHECKING(size of wchar_t is 2 bytes)
|
||||
AC_CACHE_VAL(ac_cv_small_wchar_t,
|
||||
[AC_TRY_RUN([
|
||||
#include <X11/Xlib.h>
|
||||
#if STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
# include <stddef.h>
|
||||
#endif
|
||||
main()
|
||||
{
|
||||
if (sizeof(wchar_t) <= 2)
|
||||
exit(1);
|
||||
exit(0);
|
||||
}],
|
||||
ac_cv_small_wchar_t="no",
|
||||
ac_cv_small_wchar_t="yes",
|
||||
AC_MSG_ERROR(failed to compile test program))])
|
||||
AC_MSG_RESULT($ac_cv_small_wchar_t)
|
||||
if test "x$ac_cv_small_wchar_t" = "xyes" ; then
|
||||
AC_DEFINE(SMALL_WCHAR_T)
|
||||
fi
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -2103,6 +2158,11 @@ AC_TRY_COMPILE([#include <stdio.h>], [printf("(" __DATE__ " " __TIME__ ")");],
|
||||
AC_MSG_RESULT(yes); AC_DEFINE(HAVE_DATE_TIME),
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
AC_MSG_CHECKING(whether __attribute__((unused)) is allowed)
|
||||
AC_TRY_COMPILE([#include <stdio.h>], [int x __attribute__((unused));],
|
||||
AC_MSG_RESULT(yes); AC_DEFINE(HAVE_ATTRIBUTE_UNUSED),
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_CHECK_HEADER(elf.h, HAS_ELF=1)
|
||||
dnl AC_CHECK_HEADER(dwarf.h, SVR4=1)
|
||||
@@ -2131,7 +2191,7 @@ AC_CHECK_HEADERS(stdarg.h stdlib.h string.h sys/select.h sys/utsname.h \
|
||||
sys/stream.h termios.h libc.h sys/statfs.h \
|
||||
poll.h sys/poll.h pwd.h utime.h sys/param.h libintl.h \
|
||||
libgen.h util/debug.h util/msg18n.h frame.h \
|
||||
sys/acl.h sys/access.h sys/sysctl.h sys/sysinfo.h wchar.h wctype.h)
|
||||
sys/acl.h sys/access.h sys/sysinfo.h wchar.h wctype.h)
|
||||
|
||||
dnl sys/ptem.h depends on sys/stream.h on Solaris
|
||||
AC_CHECK_HEADERS(sys/ptem.h, [], [],
|
||||
@@ -2139,6 +2199,12 @@ AC_CHECK_HEADERS(sys/ptem.h, [], [],
|
||||
# include <sys/stream.h>
|
||||
#endif])
|
||||
|
||||
dnl sys/sysctl.h depends on sys/param.h on OpenBSD
|
||||
AC_CHECK_HEADERS(sys/sysctl.h, [], [],
|
||||
[#if defined HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
#endif])
|
||||
|
||||
|
||||
dnl pthread_np.h may exist but can only be used after including pthread.h
|
||||
AC_MSG_CHECKING([for pthread_np.h])
|
||||
@@ -2184,6 +2250,7 @@ fi
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_PROG_GCC_TRADITIONAL
|
||||
AC_C_CONST
|
||||
AC_C_VOLATILE
|
||||
AC_TYPE_MODE_T
|
||||
AC_TYPE_OFF_T
|
||||
AC_TYPE_PID_T
|
||||
@@ -2905,7 +2972,6 @@ main()
|
||||
AC_MSG_RESULT($ac_cv_sizeof_int)
|
||||
AC_DEFINE_UNQUOTED(SIZEOF_INT, $ac_cv_sizeof_int)
|
||||
|
||||
|
||||
dnl Check for memmove() before bcopy(), makes memmove() be used when both are
|
||||
dnl present, fixes problem with incompatibility between Solaris 2.4 and 2.5.
|
||||
|
||||
@@ -2987,7 +3053,7 @@ dnl Check if X_LOCALE should be defined.
|
||||
if test "$enable_multibyte" = "yes"; then
|
||||
cflags_save=$CFLAGS
|
||||
ldflags_save=$LDFLAGS
|
||||
if test -n "$x_includes" ; then
|
||||
if test "x$x_includes" != "xNONE" ; then
|
||||
CFLAGS="$CFLAGS -I$x_includes"
|
||||
LDFLAGS="$X_LIBS $LDFLAGS -lX11"
|
||||
AC_MSG_CHECKING(whether X_LOCALE needed)
|
||||
@@ -3003,7 +3069,7 @@ fi
|
||||
dnl Link with xpg4, it is said to make Korean locale working
|
||||
AC_CHECK_LIB(xpg4, _xpg4_setrunelocale, [LIBS="$LIBS -lxpg4"],,)
|
||||
|
||||
dnl Check how we can run ctags
|
||||
dnl Check how we can run ctags. Default to "ctags" when nothing works.
|
||||
dnl --version for Exuberant ctags (preferred)
|
||||
dnl Add --fields=+S to get function signatures for omni completion.
|
||||
dnl -t for typedefs (many ctags have this)
|
||||
@@ -3015,6 +3081,7 @@ test -f tags && mv tags tags.save
|
||||
if (eval ctags --version /dev/null | grep Exuberant) < /dev/null 1>&AC_FD_CC 2>&1; then
|
||||
TAGPRG="ctags -I INIT+ --fields=+S"
|
||||
else
|
||||
TAGPRG="ctags"
|
||||
(eval etags /dev/null) < /dev/null 1>&AC_FD_CC 2>&1 && TAGPRG="etags"
|
||||
(eval etags -c /dev/null) < /dev/null 1>&AC_FD_CC 2>&1 && TAGPRG="etags -c"
|
||||
(eval ctags /dev/null) < /dev/null 1>&AC_FD_CC 2>&1 && TAGPRG="ctags"
|
||||
|
||||
+54
-41
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* diff.c: code for diff'ing two or three buffers.
|
||||
* diff.c: code for diff'ing two, three or four buffers.
|
||||
*/
|
||||
|
||||
#include "vim.h"
|
||||
@@ -116,7 +116,7 @@ diff_buf_adjust(win)
|
||||
* Add a buffer to make diffs for.
|
||||
* Call this when a new buffer is being edited in the current window where
|
||||
* 'diff' is set.
|
||||
* Marks the current buffer as being part of the diff and requireing updating.
|
||||
* Marks the current buffer as being part of the diff and requiring updating.
|
||||
* This must be done before any autocmd, because a command may use info
|
||||
* about the screen contents.
|
||||
*/
|
||||
@@ -652,10 +652,9 @@ diff_write(buf, fname)
|
||||
* The buffers are written to a file, also for unmodified buffers (the file
|
||||
* could have been produced by autocommands, e.g. the netrw plugin).
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ex_diffupdate(eap)
|
||||
exarg_T *eap; /* can be NULL, it's not used */
|
||||
exarg_T *eap UNUSED; /* can be NULL */
|
||||
{
|
||||
buf_T *buf;
|
||||
int idx_orig;
|
||||
@@ -827,6 +826,7 @@ diff_file(tmp_orig, tmp_new, tmp_diff)
|
||||
char_u *tmp_diff;
|
||||
{
|
||||
char_u *cmd;
|
||||
size_t len;
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
if (*p_dex != NUL)
|
||||
@@ -835,8 +835,9 @@ diff_file(tmp_orig, tmp_new, tmp_diff)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
cmd = alloc((unsigned)(STRLEN(tmp_orig) + STRLEN(tmp_new)
|
||||
+ STRLEN(tmp_diff) + STRLEN(p_srr) + 27));
|
||||
len = STRLEN(tmp_orig) + STRLEN(tmp_new)
|
||||
+ STRLEN(tmp_diff) + STRLEN(p_srr) + 27;
|
||||
cmd = alloc((unsigned)len);
|
||||
if (cmd != NULL)
|
||||
{
|
||||
/* We don't want $DIFF_OPTIONS to get in the way. */
|
||||
@@ -846,7 +847,7 @@ diff_file(tmp_orig, tmp_new, tmp_diff)
|
||||
/* Build the diff command and execute it. Always use -a, binary
|
||||
* differences are of no use. Ignore errors, diff returns
|
||||
* non-zero when differences have been found. */
|
||||
sprintf((char *)cmd, "diff %s%s%s%s%s %s",
|
||||
vim_snprintf((char *)cmd, len, "diff %s%s%s%s%s %s",
|
||||
diff_a_works == FALSE ? "" : "-a ",
|
||||
#if defined(MSWIN) || defined(MSDOS)
|
||||
diff_bin_works == TRUE ? "--binary " : "",
|
||||
@@ -856,7 +857,7 @@ diff_file(tmp_orig, tmp_new, tmp_diff)
|
||||
(diff_flags & DIFF_IWHITE) ? "-b " : "",
|
||||
(diff_flags & DIFF_ICASE) ? "-i " : "",
|
||||
tmp_orig, tmp_new);
|
||||
append_redir(cmd, p_srr, tmp_diff);
|
||||
append_redir(cmd, (int)len, p_srr, tmp_diff);
|
||||
#ifdef FEAT_AUTOCMD
|
||||
block_autocmds(); /* Avoid ShellCmdPost stuff */
|
||||
#endif
|
||||
@@ -881,6 +882,7 @@ ex_diffpatch(eap)
|
||||
char_u *tmp_orig; /* name of original temp file */
|
||||
char_u *tmp_new; /* name of patched temp file */
|
||||
char_u *buf = NULL;
|
||||
size_t buflen;
|
||||
win_T *old_curwin = curwin;
|
||||
char_u *newname = NULL; /* name of patched file buffer */
|
||||
#ifdef UNIX
|
||||
@@ -891,6 +893,7 @@ ex_diffpatch(eap)
|
||||
char_u *browseFile = NULL;
|
||||
int browse_flag = cmdmod.browse;
|
||||
#endif
|
||||
struct stat st;
|
||||
|
||||
#ifdef FEAT_BROWSE
|
||||
if (cmdmod.browse)
|
||||
@@ -920,16 +923,17 @@ ex_diffpatch(eap)
|
||||
/* Get the absolute path of the patchfile, changing directory below. */
|
||||
fullname = FullName_save(eap->arg, FALSE);
|
||||
#endif
|
||||
buf = alloc((unsigned)(STRLEN(tmp_orig) + (
|
||||
buflen = STRLEN(tmp_orig) + (
|
||||
# ifdef UNIX
|
||||
fullname != NULL ? STRLEN(fullname) :
|
||||
# endif
|
||||
STRLEN(eap->arg)) + STRLEN(tmp_new) + 16));
|
||||
STRLEN(eap->arg)) + STRLEN(tmp_new) + 16;
|
||||
buf = alloc((unsigned)buflen);
|
||||
if (buf == NULL)
|
||||
goto theend;
|
||||
|
||||
#ifdef UNIX
|
||||
/* Temporaraly chdir to /tmp, to avoid patching files in the current
|
||||
/* Temporarily chdir to /tmp, to avoid patching files in the current
|
||||
* directory when the patch file contains more than one patch. When we
|
||||
* have our own temp dir use that instead, it will be cleaned up when we
|
||||
* exit (any .rej files created). Don't change directory if we can't
|
||||
@@ -961,7 +965,8 @@ ex_diffpatch(eap)
|
||||
{
|
||||
/* Build the patch command and execute it. Ignore errors. Switch to
|
||||
* cooked mode to allow the user to respond to prompts. */
|
||||
sprintf((char *)buf, "patch -o %s %s < \"%s\"", tmp_new, tmp_orig,
|
||||
vim_snprintf((char *)buf, buflen, "patch -o %s %s < \"%s\"",
|
||||
tmp_new, tmp_orig,
|
||||
# ifdef UNIX
|
||||
fullname != NULL ? fullname :
|
||||
# endif
|
||||
@@ -995,44 +1000,51 @@ ex_diffpatch(eap)
|
||||
STRCAT(buf, ".rej");
|
||||
mch_remove(buf);
|
||||
|
||||
if (curbuf->b_fname != NULL)
|
||||
/* Only continue if the output file was created. */
|
||||
if (mch_stat((char *)tmp_new, &st) < 0 || st.st_size == 0)
|
||||
EMSG(_("E816: Cannot read patch output"));
|
||||
else
|
||||
{
|
||||
newname = vim_strnsave(curbuf->b_fname,
|
||||
if (curbuf->b_fname != NULL)
|
||||
{
|
||||
newname = vim_strnsave(curbuf->b_fname,
|
||||
(int)(STRLEN(curbuf->b_fname) + 4));
|
||||
if (newname != NULL)
|
||||
STRCAT(newname, ".new");
|
||||
}
|
||||
if (newname != NULL)
|
||||
STRCAT(newname, ".new");
|
||||
}
|
||||
|
||||
#ifdef FEAT_GUI
|
||||
need_mouse_correct = TRUE;
|
||||
need_mouse_correct = TRUE;
|
||||
#endif
|
||||
/* don't use a new tab page, each tab page has its own diffs */
|
||||
cmdmod.tab = 0;
|
||||
/* don't use a new tab page, each tab page has its own diffs */
|
||||
cmdmod.tab = 0;
|
||||
|
||||
if (win_split(0, (diff_flags & DIFF_VERTICAL) ? WSP_VERT : 0) != FAIL)
|
||||
{
|
||||
/* Pretend it was a ":split fname" command */
|
||||
eap->cmdidx = CMD_split;
|
||||
eap->arg = tmp_new;
|
||||
do_exedit(eap, old_curwin);
|
||||
|
||||
if (curwin != old_curwin) /* split must have worked */
|
||||
if (win_split(0, (diff_flags & DIFF_VERTICAL) ? WSP_VERT : 0) != FAIL)
|
||||
{
|
||||
/* Set 'diff', 'scrollbind' on and 'wrap' off. */
|
||||
diff_win_options(curwin, TRUE);
|
||||
diff_win_options(old_curwin, TRUE);
|
||||
/* Pretend it was a ":split fname" command */
|
||||
eap->cmdidx = CMD_split;
|
||||
eap->arg = tmp_new;
|
||||
do_exedit(eap, old_curwin);
|
||||
|
||||
if (newname != NULL)
|
||||
/* check that split worked and editing tmp_new */
|
||||
if (curwin != old_curwin && win_valid(old_curwin))
|
||||
{
|
||||
/* do a ":file filename.new" on the patched buffer */
|
||||
eap->arg = newname;
|
||||
ex_file(eap);
|
||||
/* Set 'diff', 'scrollbind' on and 'wrap' off. */
|
||||
diff_win_options(curwin, TRUE);
|
||||
diff_win_options(old_curwin, TRUE);
|
||||
|
||||
if (newname != NULL)
|
||||
{
|
||||
/* do a ":file filename.new" on the patched buffer */
|
||||
eap->arg = newname;
|
||||
ex_file(eap);
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
/* Do filetype detection with the new name. */
|
||||
if (au_has_group((char_u *)"filetypedetect"))
|
||||
do_cmdline_cmd((char_u *)":doau filetypedetect BufRead");
|
||||
/* Do filetype detection with the new name. */
|
||||
if (au_has_group((char_u *)"filetypedetect"))
|
||||
do_cmdline_cmd((char_u *)":doau filetypedetect BufRead");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1089,10 +1101,9 @@ ex_diffsplit(eap)
|
||||
/*
|
||||
* Set options to show difs for the current window.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ex_diffthis(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
/* Set 'diff', 'scrollbind' on and 'wrap' off. */
|
||||
diff_win_options(curwin, TRUE);
|
||||
@@ -1153,7 +1164,7 @@ ex_diffoff(eap)
|
||||
|
||||
for (wp = firstwin; wp != NULL; wp = wp->w_next)
|
||||
{
|
||||
if (wp == curwin || eap->forceit)
|
||||
if (wp == curwin || (eap->forceit && wp->w_p_diff))
|
||||
{
|
||||
/* Set 'diff', 'scrollbind' off and 'wrap' on. */
|
||||
wp->w_p_diff = FALSE;
|
||||
@@ -2129,6 +2140,8 @@ ex_diffgetput(eap)
|
||||
EMSG2(_("E102: Can't find buffer \"%s\""), eap->arg);
|
||||
return;
|
||||
}
|
||||
if (buf == curbuf)
|
||||
return; /* nothing to do */
|
||||
idx_other = diff_buf_idx(buf);
|
||||
if (idx_other == DB_COUNT)
|
||||
{
|
||||
|
||||
+16
-9
@@ -32,7 +32,7 @@ static int getexactdigraph __ARGS((int, int, int));
|
||||
static void printdigraph __ARGS((digr_T *));
|
||||
|
||||
/* digraphs added by the user */
|
||||
static garray_T user_digraphs = {0, 0, sizeof(digr_T), 10, NULL};
|
||||
static garray_T user_digraphs = {0, 0, (int)sizeof(digr_T), 10, NULL};
|
||||
|
||||
/*
|
||||
* Note: Characters marked with XX are not included literally, because some
|
||||
@@ -2371,10 +2371,10 @@ printdigraph(dp)
|
||||
}
|
||||
else
|
||||
#endif
|
||||
*p++ = dp->result;
|
||||
*p++ = (char_u)dp->result;
|
||||
if (char2cells(dp->result) == 1)
|
||||
*p++ = ' ';
|
||||
sprintf((char *)p, " %3d", dp->result);
|
||||
vim_snprintf((char *)p, sizeof(buf) - (p - buf), " %3d", dp->result);
|
||||
msg_outtrans(buf);
|
||||
}
|
||||
}
|
||||
@@ -2395,7 +2395,10 @@ typedef struct
|
||||
static void keymap_unload __ARGS((void));
|
||||
|
||||
/*
|
||||
* Set up key mapping tables for the 'keymap' option
|
||||
* Set up key mapping tables for the 'keymap' option.
|
||||
* Returns NULL if OK, an error message for failure. This only needs to be
|
||||
* used when setting the option, not later when the value has already been
|
||||
* checked.
|
||||
*/
|
||||
char_u *
|
||||
keymap_init()
|
||||
@@ -2412,25 +2415,29 @@ keymap_init()
|
||||
else
|
||||
{
|
||||
char_u *buf;
|
||||
size_t buflen;
|
||||
|
||||
/* Source the keymap file. It will contain a ":loadkeymap" command
|
||||
* which will call ex_loadkeymap() below. */
|
||||
buf = alloc((unsigned)(STRLEN(curbuf->b_p_keymap)
|
||||
buflen = STRLEN(curbuf->b_p_keymap)
|
||||
# ifdef FEAT_MBYTE
|
||||
+ STRLEN(p_enc)
|
||||
+ STRLEN(p_enc)
|
||||
# endif
|
||||
+ 14));
|
||||
+ 14;
|
||||
buf = alloc((unsigned)buflen);
|
||||
if (buf == NULL)
|
||||
return e_outofmem;
|
||||
|
||||
# ifdef FEAT_MBYTE
|
||||
/* try finding "keymap/'keymap'_'encoding'.vim" in 'runtimepath' */
|
||||
sprintf((char *)buf, "keymap/%s_%s.vim", curbuf->b_p_keymap, p_enc);
|
||||
vim_snprintf((char *)buf, buflen, "keymap/%s_%s.vim",
|
||||
curbuf->b_p_keymap, p_enc);
|
||||
if (source_runtime(buf, FALSE) == FAIL)
|
||||
# endif
|
||||
{
|
||||
/* try finding "keymap/'keymap'.vim" in 'runtimepath' */
|
||||
sprintf((char *)buf, "keymap/%s.vim", curbuf->b_p_keymap);
|
||||
vim_snprintf((char *)buf, buflen, "keymap/%s.vim",
|
||||
curbuf->b_p_keymap);
|
||||
if (source_runtime(buf, FALSE) == FAIL)
|
||||
{
|
||||
vim_free(buf);
|
||||
|
||||
+142
-75
@@ -57,7 +57,7 @@ static char *ctrl_x_msgs[] =
|
||||
N_(" Keyword Local completion (^N^P)"),
|
||||
};
|
||||
|
||||
static char_u e_hitend[] = N_("Hit end of paragraph");
|
||||
static char e_hitend[] = N_("Hit end of paragraph");
|
||||
|
||||
/*
|
||||
* Structure used to store one match for insert completion.
|
||||
@@ -114,6 +114,10 @@ static int compl_restarting = FALSE; /* don't insert match */
|
||||
* FALSE the word to be completed must be located. */
|
||||
static int compl_started = FALSE;
|
||||
|
||||
/* Set when doing something for completion that may call edit() recursively,
|
||||
* which is not allowed. */
|
||||
static int compl_busy = FALSE;
|
||||
|
||||
static int compl_matches = 0;
|
||||
static char_u *compl_pattern = NULL;
|
||||
static int compl_direction = FORWARD;
|
||||
@@ -147,6 +151,7 @@ static void ins_compl_clear __ARGS((void));
|
||||
static int ins_compl_bs __ARGS((void));
|
||||
static void ins_compl_new_leader __ARGS((void));
|
||||
static void ins_compl_addleader __ARGS((int c));
|
||||
static int ins_compl_len __ARGS((void));
|
||||
static void ins_compl_restart __ARGS((void));
|
||||
static void ins_compl_set_original_text __ARGS((char_u *str));
|
||||
static void ins_compl_addfrommatch __ARGS((void));
|
||||
@@ -164,7 +169,7 @@ static int ins_compl_pum_key __ARGS((int c));
|
||||
static int ins_compl_key2count __ARGS((int c));
|
||||
static int ins_compl_use_match __ARGS((int c));
|
||||
static int ins_complete __ARGS((int c));
|
||||
static int quote_meta __ARGS((char_u *dest, char_u *str, int len));
|
||||
static unsigned quote_meta __ARGS((char_u *dest, char_u *str, int len));
|
||||
#endif /* FEAT_INS_EXPAND */
|
||||
|
||||
#define BACKSPACE_CHAR 1
|
||||
@@ -197,7 +202,8 @@ static void replace_pop_ins __ARGS((void));
|
||||
static void mb_replace_pop_ins __ARGS((int cc));
|
||||
#endif
|
||||
static void replace_flush __ARGS((void));
|
||||
static void replace_do_bs __ARGS((void));
|
||||
static void replace_do_bs __ARGS((int limit_col));
|
||||
static int del_char_after_col __ARGS((int limit_col));
|
||||
#ifdef FEAT_CINDENT
|
||||
static int cindent_on __ARGS((void));
|
||||
#endif
|
||||
@@ -304,7 +310,7 @@ edit(cmdchar, startln, count)
|
||||
int c = 0;
|
||||
char_u *ptr;
|
||||
int lastc;
|
||||
colnr_T mincol;
|
||||
int mincol;
|
||||
static linenr_T o_lnum = 0;
|
||||
int i;
|
||||
int did_backspace = TRUE; /* previous char was backspace */
|
||||
@@ -344,7 +350,7 @@ edit(cmdchar, startln, count)
|
||||
|
||||
#ifdef FEAT_INS_EXPAND
|
||||
/* Don't allow recursive insert mode when busy with completion. */
|
||||
if (compl_started || pum_visible())
|
||||
if (compl_started || compl_busy || pum_visible())
|
||||
{
|
||||
EMSG(_(e_secure));
|
||||
return FALSE;
|
||||
@@ -385,7 +391,7 @@ edit(cmdchar, startln, count)
|
||||
if (startln)
|
||||
Insstart.col = 0;
|
||||
}
|
||||
Insstart_textlen = linetabsize(ml_get_curline());
|
||||
Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
|
||||
Insstart_blank_vcol = MAXCOL;
|
||||
if (!did_ai)
|
||||
ai_col = 0;
|
||||
@@ -651,7 +657,7 @@ edit(cmdchar, startln, count)
|
||||
mincol = curwin->w_wcol;
|
||||
validate_cursor_col();
|
||||
|
||||
if ((int)curwin->w_wcol < (int)mincol - curbuf->b_p_ts
|
||||
if ((int)curwin->w_wcol < mincol - curbuf->b_p_ts
|
||||
&& curwin->w_wrow == W_WINROW(curwin)
|
||||
+ curwin->w_height - 1 - p_so
|
||||
&& (curwin->w_cursor.lnum != curwin->w_topline
|
||||
@@ -751,7 +757,7 @@ edit(cmdchar, startln, count)
|
||||
* there is nothing to add, CTRL-L works like CTRL-P then. */
|
||||
if (c == Ctrl_L
|
||||
&& (ctrl_x_mode != CTRL_X_WHOLE_LINE
|
||||
|| STRLEN(compl_shown_match->cp_str)
|
||||
|| (int)STRLEN(compl_shown_match->cp_str)
|
||||
> curwin->w_cursor.col - compl_col))
|
||||
{
|
||||
ins_compl_addfrommatch();
|
||||
@@ -1338,8 +1344,10 @@ doESCkey:
|
||||
goto normalchar;
|
||||
|
||||
docomplete:
|
||||
compl_busy = TRUE;
|
||||
if (ins_complete(c) == FAIL)
|
||||
compl_cont_status = 0;
|
||||
compl_busy = FALSE;
|
||||
break;
|
||||
#endif /* FEAT_INS_EXPAND */
|
||||
|
||||
@@ -1441,10 +1449,9 @@ force_cindent:
|
||||
* Only redraw when there are no characters available. This speeds up
|
||||
* inserting sequences of characters (e.g., for CTRL-R).
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ins_redraw(ready)
|
||||
int ready; /* not busy with something */
|
||||
int ready UNUSED; /* not busy with something */
|
||||
{
|
||||
if (!char_avail())
|
||||
{
|
||||
@@ -1771,7 +1778,7 @@ change_indent(type, amount, round, replaced, call_changed_bytes)
|
||||
* Compute the screen column where the cursor should be.
|
||||
*/
|
||||
vcol = get_indent() - vcol;
|
||||
curwin->w_virtcol = (vcol < 0) ? 0 : vcol;
|
||||
curwin->w_virtcol = (colnr_T)((vcol < 0) ? 0 : vcol);
|
||||
|
||||
/*
|
||||
* Advance the cursor until we reach the right screen column.
|
||||
@@ -1798,9 +1805,9 @@ change_indent(type, amount, round, replaced, call_changed_bytes)
|
||||
*/
|
||||
if (vcol != (int)curwin->w_virtcol)
|
||||
{
|
||||
curwin->w_cursor.col = new_cursor_col;
|
||||
curwin->w_cursor.col = (colnr_T)new_cursor_col;
|
||||
i = (int)curwin->w_virtcol - vcol;
|
||||
ptr = alloc(i + 1);
|
||||
ptr = alloc((unsigned)(i + 1));
|
||||
if (ptr != NULL)
|
||||
{
|
||||
new_cursor_col += i;
|
||||
@@ -1824,7 +1831,7 @@ change_indent(type, amount, round, replaced, call_changed_bytes)
|
||||
if (new_cursor_col <= 0)
|
||||
curwin->w_cursor.col = 0;
|
||||
else
|
||||
curwin->w_cursor.col = new_cursor_col;
|
||||
curwin->w_cursor.col = (colnr_T)new_cursor_col;
|
||||
curwin->w_set_curswant = TRUE;
|
||||
changed_cline_bef_curs();
|
||||
|
||||
@@ -1933,6 +1940,8 @@ truncate_spaces(line)
|
||||
/*
|
||||
* Backspace the cursor until the given column. Handles REPLACE and VREPLACE
|
||||
* modes correctly. May also be used when not in insert mode at all.
|
||||
* Will attempt not to go before "col" even when there is a composing
|
||||
* character.
|
||||
*/
|
||||
void
|
||||
backspace_until_column(col)
|
||||
@@ -1942,13 +1951,49 @@ backspace_until_column(col)
|
||||
{
|
||||
curwin->w_cursor.col--;
|
||||
if (State & REPLACE_FLAG)
|
||||
replace_do_bs();
|
||||
else
|
||||
(void)del_char(FALSE);
|
||||
replace_do_bs(col);
|
||||
else if (!del_char_after_col(col))
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Like del_char(), but make sure not to go before column "limit_col".
|
||||
* Only matters when there are composing characters.
|
||||
* Return TRUE when something was deleted.
|
||||
*/
|
||||
static int
|
||||
del_char_after_col(limit_col)
|
||||
int limit_col UNUSED;
|
||||
{
|
||||
#ifdef FEAT_MBYTE
|
||||
if (enc_utf8 && limit_col >= 0)
|
||||
{
|
||||
colnr_T ecol = curwin->w_cursor.col + 1;
|
||||
|
||||
/* Make sure the cursor is at the start of a character, but
|
||||
* skip forward again when going too far back because of a
|
||||
* composing character. */
|
||||
mb_adjust_cursor();
|
||||
while (curwin->w_cursor.col < (colnr_T)limit_col)
|
||||
{
|
||||
int l = utf_ptr2len(ml_get_cursor());
|
||||
|
||||
if (l == 0) /* end of line */
|
||||
break;
|
||||
curwin->w_cursor.col += l;
|
||||
}
|
||||
if (*ml_get_cursor() == NUL || curwin->w_cursor.col == ecol)
|
||||
return FALSE;
|
||||
del_bytes((long)((int)ecol - curwin->w_cursor.col), FALSE, TRUE);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
(void)del_char(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if defined(FEAT_INS_EXPAND) || defined(PROTO)
|
||||
/*
|
||||
* CTRL-X pressed in Insert mode.
|
||||
@@ -2160,7 +2205,7 @@ ins_compl_add_infercase(str, len, icase, fname, dir, flags)
|
||||
actual_compl_length = compl_length;
|
||||
|
||||
/* Allocate wide character array for the completion and fill it. */
|
||||
wca = (int *)alloc(actual_len * sizeof(int));
|
||||
wca = (int *)alloc((unsigned)(actual_len * sizeof(int)));
|
||||
if (wca != NULL)
|
||||
{
|
||||
p = str;
|
||||
@@ -2418,7 +2463,7 @@ ins_compl_longest_match(match)
|
||||
{
|
||||
had_match = (curwin->w_cursor.col > compl_col);
|
||||
ins_compl_delete();
|
||||
ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
|
||||
ins_bytes(compl_leader + ins_compl_len());
|
||||
ins_redraw(FALSE);
|
||||
|
||||
/* When the match isn't there (to avoid matching itself) remove it
|
||||
@@ -2470,7 +2515,7 @@ ins_compl_longest_match(match)
|
||||
*p = NUL;
|
||||
had_match = (curwin->w_cursor.col > compl_col);
|
||||
ins_compl_delete();
|
||||
ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
|
||||
ins_bytes(compl_leader + ins_compl_len());
|
||||
ins_redraw(FALSE);
|
||||
|
||||
/* When the match isn't there (to avoid matching itself) remove it
|
||||
@@ -2539,7 +2584,7 @@ ins_compl_make_cyclic()
|
||||
*/
|
||||
void
|
||||
set_completion(startcol, list)
|
||||
int startcol;
|
||||
colnr_T startcol;
|
||||
list_T *list;
|
||||
{
|
||||
/* If already doing completions stop it. */
|
||||
@@ -2550,10 +2595,10 @@ set_completion(startcol, list)
|
||||
if (stop_arrow() == FAIL)
|
||||
return;
|
||||
|
||||
if (startcol > (int)curwin->w_cursor.col)
|
||||
if (startcol > curwin->w_cursor.col)
|
||||
startcol = curwin->w_cursor.col;
|
||||
compl_col = startcol;
|
||||
compl_length = curwin->w_cursor.col - startcol;
|
||||
compl_length = (int)curwin->w_cursor.col - (int)startcol;
|
||||
/* compl_pattern doesn't need to be set */
|
||||
compl_orig_text = vim_strnsave(ml_get_curline() + compl_col, compl_length);
|
||||
if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
|
||||
@@ -2819,7 +2864,6 @@ ins_compl_dictionaries(dict_start, pat, flags, thesaurus)
|
||||
regmatch_T regmatch;
|
||||
char_u **files;
|
||||
int count;
|
||||
int i;
|
||||
int save_p_scs;
|
||||
int dir = compl_direction;
|
||||
|
||||
@@ -2851,17 +2895,18 @@ ins_compl_dictionaries(dict_start, pat, flags, thesaurus)
|
||||
if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
|
||||
{
|
||||
char_u *pat_esc = vim_strsave_escaped(pat, (char_u *)"\\");
|
||||
size_t len;
|
||||
|
||||
if (pat_esc == NULL)
|
||||
goto theend;
|
||||
i = (int)STRLEN(pat_esc) + 10;
|
||||
ptr = alloc(i);
|
||||
len = STRLEN(pat_esc) + 10;
|
||||
ptr = alloc((unsigned)len);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
vim_free(pat_esc);
|
||||
goto theend;
|
||||
}
|
||||
vim_snprintf((char *)ptr, i, "^\\s*\\zs\\V%s", pat_esc);
|
||||
vim_snprintf((char *)ptr, len, "^\\s*\\zs\\V%s", pat_esc);
|
||||
regmatch.regprog = vim_regcomp(ptr, RE_MAGIC);
|
||||
vim_free(pat_esc);
|
||||
vim_free(ptr);
|
||||
@@ -2952,7 +2997,7 @@ ins_compl_files(count, files, thesaurus, flags, regmatch, buf, dir)
|
||||
{
|
||||
vim_snprintf((char *)IObuff, IOSIZE,
|
||||
_("Scanning dictionary: %s"), (char *)files[i]);
|
||||
msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
|
||||
(void)msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
|
||||
}
|
||||
|
||||
if (fp != NULL)
|
||||
@@ -3133,6 +3178,7 @@ ins_compl_free()
|
||||
vim_free(match);
|
||||
} while (compl_curr_match != NULL && compl_curr_match != compl_first_match);
|
||||
compl_first_match = compl_curr_match = NULL;
|
||||
compl_shown_match = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3209,7 +3255,7 @@ ins_compl_new_leader()
|
||||
{
|
||||
ins_compl_del_pum();
|
||||
ins_compl_delete();
|
||||
ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
|
||||
ins_bytes(compl_leader + ins_compl_len());
|
||||
compl_used_match = FALSE;
|
||||
|
||||
if (compl_started)
|
||||
@@ -3263,6 +3309,20 @@ ins_compl_new_leader()
|
||||
compl_enter_selects = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the length of the completion, from the completion start column to
|
||||
* the cursor column. Making sure it never goes below zero.
|
||||
*/
|
||||
static int
|
||||
ins_compl_len()
|
||||
{
|
||||
int off = (int)curwin->w_cursor.col - (int)compl_col;
|
||||
|
||||
if (off < 0)
|
||||
return 0;
|
||||
return off;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append one character to the match leader. May reduce the number of
|
||||
* matches.
|
||||
@@ -3292,7 +3352,7 @@ ins_compl_addleader(c)
|
||||
|
||||
vim_free(compl_leader);
|
||||
compl_leader = vim_strnsave(ml_get_curline() + compl_col,
|
||||
curwin->w_cursor.col - compl_col);
|
||||
(int)(curwin->w_cursor.col - compl_col));
|
||||
if (compl_leader != NULL)
|
||||
ins_compl_new_leader();
|
||||
}
|
||||
@@ -3340,7 +3400,7 @@ ins_compl_set_original_text(str)
|
||||
ins_compl_addfrommatch()
|
||||
{
|
||||
char_u *p;
|
||||
int len = curwin->w_cursor.col - compl_col;
|
||||
int len = (int)curwin->w_cursor.col - (int)compl_col;
|
||||
int c;
|
||||
compl_T *cp;
|
||||
|
||||
@@ -3621,10 +3681,9 @@ ins_compl_prep(c)
|
||||
{
|
||||
ins_compl_delete();
|
||||
if (compl_leader != NULL)
|
||||
ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
|
||||
ins_bytes(compl_leader + ins_compl_len());
|
||||
else if (compl_first_match != NULL)
|
||||
ins_bytes(compl_orig_text
|
||||
+ curwin->w_cursor.col - compl_col);
|
||||
ins_bytes(compl_orig_text + ins_compl_len());
|
||||
retval = TRUE;
|
||||
}
|
||||
|
||||
@@ -3907,7 +3966,7 @@ ins_compl_get_exp(ini)
|
||||
: ins_buf->b_sfname == NULL
|
||||
? (char *)ins_buf->b_fname
|
||||
: (char *)ins_buf->b_sfname);
|
||||
msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
|
||||
(void)msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
|
||||
}
|
||||
else if (*e_cpt == NUL)
|
||||
break;
|
||||
@@ -3936,8 +3995,8 @@ ins_compl_get_exp(ini)
|
||||
else if (*e_cpt == ']' || *e_cpt == 't')
|
||||
{
|
||||
type = CTRL_X_TAGS;
|
||||
sprintf((char*)IObuff, _("Scanning tags."));
|
||||
msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
|
||||
vim_snprintf((char *)IObuff, IOSIZE, _("Scanning tags."));
|
||||
(void)msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
|
||||
}
|
||||
else
|
||||
type = -1;
|
||||
@@ -4035,7 +4094,7 @@ ins_compl_get_exp(ini)
|
||||
case CTRL_X_SPELL:
|
||||
#ifdef FEAT_SPELL
|
||||
num_matches = expand_spelling(first_match_pos.lnum,
|
||||
first_match_pos.col, compl_pattern, &matches);
|
||||
compl_pattern, &matches);
|
||||
if (num_matches > 0)
|
||||
ins_compl_add_matches(num_matches, matches, p_ic);
|
||||
#endif
|
||||
@@ -4187,7 +4246,7 @@ ins_compl_get_exp(ini)
|
||||
}
|
||||
|
||||
/* check if compl_curr_match has changed, (e.g. other type of
|
||||
* expansion added somenthing) */
|
||||
* expansion added something) */
|
||||
if (type != 0 && compl_curr_match != old_match)
|
||||
found_new_match = OK;
|
||||
|
||||
@@ -4256,7 +4315,7 @@ ins_compl_delete()
|
||||
static void
|
||||
ins_compl_insert()
|
||||
{
|
||||
ins_bytes(compl_shown_match->cp_str + curwin->w_cursor.col - compl_col);
|
||||
ins_bytes(compl_shown_match->cp_str + ins_compl_len());
|
||||
if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
|
||||
compl_used_match = FALSE;
|
||||
else
|
||||
@@ -4425,7 +4484,7 @@ ins_compl_next(allow_get_expansion, count, insert_match)
|
||||
if (!compl_get_longest || compl_used_match)
|
||||
ins_compl_insert();
|
||||
else
|
||||
ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
|
||||
ins_bytes(compl_leader + ins_compl_len());
|
||||
}
|
||||
else
|
||||
compl_used_match = FALSE;
|
||||
@@ -4688,7 +4747,7 @@ ins_complete(c)
|
||||
}
|
||||
compl_length = curwin->w_cursor.col - (int)compl_col;
|
||||
/* IObuff is used to add a "word from the next line" would we
|
||||
* have enough space? just being paranoic */
|
||||
* have enough space? just being paranoid */
|
||||
#define MIN_SPACE 75
|
||||
if (compl_length > (IOSIZE - MIN_SPACE))
|
||||
{
|
||||
@@ -4745,10 +4804,9 @@ ins_complete(c)
|
||||
{
|
||||
char_u *prefix = (char_u *)"\\<";
|
||||
|
||||
/* we need 3 extra chars, 1 for the NUL and
|
||||
* 2 >= strlen(prefix) -- Acevedo */
|
||||
/* we need up to 2 extra chars for the prefix */
|
||||
compl_pattern = alloc(quote_meta(NULL, line + compl_col,
|
||||
compl_length) + 3);
|
||||
compl_length) + 2);
|
||||
if (compl_pattern == NULL)
|
||||
return FAIL;
|
||||
if (!vim_iswordp(line + compl_col)
|
||||
@@ -4823,7 +4881,7 @@ ins_complete(c)
|
||||
else
|
||||
{
|
||||
compl_pattern = alloc(quote_meta(NULL, line + compl_col,
|
||||
compl_length) + 3);
|
||||
compl_length) + 2);
|
||||
if (compl_pattern == NULL)
|
||||
return FAIL;
|
||||
STRCPY((char *)compl_pattern, "\\<");
|
||||
@@ -4905,7 +4963,7 @@ ins_complete(c)
|
||||
if (col < 0)
|
||||
col = curs_col;
|
||||
compl_col = col;
|
||||
if ((colnr_T)compl_col > curs_col)
|
||||
if (compl_col > curs_col)
|
||||
compl_col = curs_col;
|
||||
|
||||
/* Setup variables for completion. Need to obtain "line" again,
|
||||
@@ -5178,15 +5236,15 @@ ins_complete(c)
|
||||
* a backslash) the metachars, and dest would be NUL terminated.
|
||||
* Returns the length (needed) of dest
|
||||
*/
|
||||
static int
|
||||
static unsigned
|
||||
quote_meta(dest, src, len)
|
||||
char_u *dest;
|
||||
char_u *src;
|
||||
int len;
|
||||
{
|
||||
int m;
|
||||
unsigned m = (unsigned)len + 1; /* one extra for the NUL */
|
||||
|
||||
for (m = len; --len >= 0; src++)
|
||||
for ( ; --len >= 0; src++)
|
||||
{
|
||||
switch (*src)
|
||||
{
|
||||
@@ -6015,7 +6073,7 @@ auto_format(trailblank, prev_line)
|
||||
* in 'formatoptions' and there is a single character before the cursor.
|
||||
* Otherwise the line would be broken and when typing another non-white
|
||||
* next they are not joined back together. */
|
||||
wasatend = (pos.col == STRLEN(old));
|
||||
wasatend = (pos.col == (colnr_T)STRLEN(old));
|
||||
if (*old != NUL && !trailblank && wasatend)
|
||||
{
|
||||
dec_cursor();
|
||||
@@ -6192,7 +6250,7 @@ redo_literal(c)
|
||||
* three digits. */
|
||||
if (VIM_ISDIGIT(c))
|
||||
{
|
||||
sprintf((char *)buf, "%03d", c);
|
||||
vim_snprintf((char *)buf, sizeof(buf), "%03d", c);
|
||||
AppendToRedobuff(buf);
|
||||
}
|
||||
else
|
||||
@@ -6266,7 +6324,7 @@ stop_arrow()
|
||||
ins_need_undo = FALSE;
|
||||
}
|
||||
Insstart = curwin->w_cursor; /* new insertion starts here */
|
||||
Insstart_textlen = linetabsize(ml_get_curline());
|
||||
Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
|
||||
ai_col = 0;
|
||||
#ifdef FEAT_VREPLACE
|
||||
if (State & VREPLACE_FLAG)
|
||||
@@ -6369,13 +6427,17 @@ stop_insert(end_insert_pos, esc)
|
||||
|
||||
/* If we just did an auto-indent, remove the white space from the end
|
||||
* of the line, and put the cursor back.
|
||||
* Do this when ESC was used or moving the cursor up/down. */
|
||||
* Do this when ESC was used or moving the cursor up/down.
|
||||
* Check for the old position still being valid, just in case the text
|
||||
* got changed unexpectedly. */
|
||||
if (did_ai && (esc || (vim_strchr(p_cpo, CPO_INDENT) == NULL
|
||||
&& curwin->w_cursor.lnum != end_insert_pos->lnum)))
|
||||
&& curwin->w_cursor.lnum != end_insert_pos->lnum))
|
||||
&& end_insert_pos->lnum <= curbuf->b_ml.ml_line_count)
|
||||
{
|
||||
pos_T tpos = curwin->w_cursor;
|
||||
|
||||
curwin->w_cursor = *end_insert_pos;
|
||||
check_cursor_col(); /* make sure it is not past the line */
|
||||
for (;;)
|
||||
{
|
||||
if (gchar_cursor() == NUL && curwin->w_cursor.col > 0)
|
||||
@@ -6383,7 +6445,8 @@ stop_insert(end_insert_pos, esc)
|
||||
cc = gchar_cursor();
|
||||
if (!vim_iswhite(cc))
|
||||
break;
|
||||
(void)del_char(TRUE);
|
||||
if (del_char(TRUE) == FAIL)
|
||||
break; /* should not happen */
|
||||
}
|
||||
if (curwin->w_cursor.lnum != tpos.lnum)
|
||||
curwin->w_cursor = tpos;
|
||||
@@ -6395,10 +6458,11 @@ stop_insert(end_insert_pos, esc)
|
||||
* deleted characters. */
|
||||
if (VIsual_active && VIsual.lnum == curwin->w_cursor.lnum)
|
||||
{
|
||||
cc = (int)STRLEN(ml_get_curline());
|
||||
if (VIsual.col > (colnr_T)cc)
|
||||
int len = (int)STRLEN(ml_get_curline());
|
||||
|
||||
if (VIsual.col > len)
|
||||
{
|
||||
VIsual.col = cc;
|
||||
VIsual.col = len;
|
||||
# ifdef FEAT_VIRTUALEDIT
|
||||
VIsual.coladd = 0;
|
||||
# endif
|
||||
@@ -7123,9 +7187,12 @@ replace_flush()
|
||||
* cc == 0: character was inserted, delete it
|
||||
* cc > 0: character was replaced, put cc (first byte of original char) back
|
||||
* and check for more characters to be put back
|
||||
* When "limit_col" is >= 0, don't delete before this column. Matters when
|
||||
* using composing characters, use del_char_after_col() instead of del_char().
|
||||
*/
|
||||
static void
|
||||
replace_do_bs()
|
||||
replace_do_bs(limit_col)
|
||||
int limit_col;
|
||||
{
|
||||
int cc;
|
||||
#ifdef FEAT_VREPLACE
|
||||
@@ -7153,7 +7220,7 @@ replace_do_bs()
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte)
|
||||
{
|
||||
del_char(FALSE);
|
||||
(void)del_char_after_col(limit_col);
|
||||
# ifdef FEAT_VREPLACE
|
||||
if (State & VREPLACE_FLAG)
|
||||
orig_len = (int)STRLEN(ml_get_cursor());
|
||||
@@ -7203,7 +7270,7 @@ replace_do_bs()
|
||||
changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
|
||||
}
|
||||
else if (cc == 0)
|
||||
(void)del_char(FALSE);
|
||||
(void)del_char_after_col(limit_col);
|
||||
}
|
||||
|
||||
#ifdef FEAT_CINDENT
|
||||
@@ -7646,9 +7713,7 @@ ins_reg()
|
||||
*/
|
||||
++no_mapping;
|
||||
regname = plain_vgetc();
|
||||
#ifdef FEAT_LANGMAP
|
||||
LANGMAP_ADJUST(regname, TRUE);
|
||||
#endif
|
||||
if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P)
|
||||
{
|
||||
/* Get a third key for literal register insertion */
|
||||
@@ -7657,9 +7722,7 @@ ins_reg()
|
||||
add_to_showcmd_c(literally);
|
||||
#endif
|
||||
regname = plain_vgetc();
|
||||
#ifdef FEAT_LANGMAP
|
||||
LANGMAP_ADJUST(regname, TRUE);
|
||||
#endif
|
||||
}
|
||||
--no_mapping;
|
||||
|
||||
@@ -8150,7 +8213,7 @@ ins_ctrl_o()
|
||||
/*
|
||||
* If the cursor is on an indent, ^T/^D insert/delete one
|
||||
* shiftwidth. Otherwise ^T/^D behave like a "<<" or ">>".
|
||||
* Always round the indent to 'shiftwith', this is compatible
|
||||
* Always round the indent to 'shiftwidth', this is compatible
|
||||
* with vi. But vi only supports ^T and ^D after an
|
||||
* autoindent, we support it everywhere.
|
||||
*/
|
||||
@@ -8239,7 +8302,7 @@ ins_bs_one(vcolp)
|
||||
* Replace mode */
|
||||
if (curwin->w_cursor.lnum != Insstart.lnum
|
||||
|| curwin->w_cursor.col >= Insstart.col)
|
||||
replace_do_bs();
|
||||
replace_do_bs(-1);
|
||||
}
|
||||
else
|
||||
(void)del_char(FALSE);
|
||||
@@ -8258,6 +8321,7 @@ ins_bs(c, mode, inserted_space_p)
|
||||
linenr_T lnum;
|
||||
int cc;
|
||||
int temp = 0; /* init for GCC */
|
||||
colnr_T save_col;
|
||||
colnr_T mincol;
|
||||
int did_backspace = FALSE;
|
||||
int in_indent;
|
||||
@@ -8415,13 +8479,13 @@ ins_bs(c, mode, inserted_space_p)
|
||||
*/
|
||||
while (cc > 0)
|
||||
{
|
||||
temp = curwin->w_cursor.col;
|
||||
save_col = curwin->w_cursor.col;
|
||||
#ifdef FEAT_MBYTE
|
||||
mb_replace_pop_ins(cc);
|
||||
#else
|
||||
ins_char(cc);
|
||||
#endif
|
||||
curwin->w_cursor.col = temp;
|
||||
curwin->w_cursor.col = save_col;
|
||||
cc = replace_pop();
|
||||
}
|
||||
/* restore the characters that NL replaced */
|
||||
@@ -8453,11 +8517,11 @@ ins_bs(c, mode, inserted_space_p)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
temp = curwin->w_cursor.col;
|
||||
save_col = curwin->w_cursor.col;
|
||||
beginline(BL_WHITE);
|
||||
if (curwin->w_cursor.col < (colnr_T)temp)
|
||||
mincol = curwin->w_cursor.col;
|
||||
curwin->w_cursor.col = temp;
|
||||
curwin->w_cursor.col = save_col;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -8556,7 +8620,7 @@ ins_bs(c, mode, inserted_space_p)
|
||||
break;
|
||||
}
|
||||
if (State & REPLACE_FLAG)
|
||||
replace_do_bs();
|
||||
replace_do_bs(-1);
|
||||
else
|
||||
{
|
||||
#ifdef FEAT_MBYTE
|
||||
@@ -8834,7 +8898,7 @@ ins_left()
|
||||
tpos = curwin->w_cursor;
|
||||
if (oneleft() == OK)
|
||||
{
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
#if defined(FEAT_XIM) && (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM))
|
||||
/* Only call start_arrow() when not busy with preediting, it will
|
||||
* break undo. K_LEFT is inserted in im_correct_cursor(). */
|
||||
if (!im_is_preediting())
|
||||
@@ -8931,7 +8995,10 @@ ins_right()
|
||||
foldOpenCursor();
|
||||
#endif
|
||||
undisplay_dollar();
|
||||
if (gchar_cursor() != NUL || virtual_active()
|
||||
if (gchar_cursor() != NUL
|
||||
#ifdef FEAT_VIRTUALEDIT
|
||||
|| virtual_active()
|
||||
#endif
|
||||
)
|
||||
{
|
||||
start_arrow(&curwin->w_cursor);
|
||||
|
||||
+206
-299
File diff suppressed because it is too large
Load Diff
+325
-90
@@ -43,12 +43,12 @@ static int
|
||||
/*
|
||||
* ":ascii" and "ga".
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
do_ascii(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
int c;
|
||||
int cval;
|
||||
char buf1[20];
|
||||
char buf2[20];
|
||||
char_u buf3[7];
|
||||
@@ -75,6 +75,10 @@ do_ascii(eap)
|
||||
{
|
||||
if (c == NL) /* NUL is stored as NL */
|
||||
c = NUL;
|
||||
if (c == CAR && get_fileformat(curbuf) == EOL_MAC)
|
||||
cval = NL; /* NL is stored as CR */
|
||||
else
|
||||
cval = c;
|
||||
if (vim_isprintc_strict(c) && (c < ' '
|
||||
#ifndef EBCDIC
|
||||
|| c > '~'
|
||||
@@ -82,19 +86,20 @@ do_ascii(eap)
|
||||
))
|
||||
{
|
||||
transchar_nonprint(buf3, c);
|
||||
sprintf(buf1, " <%s>", (char *)buf3);
|
||||
vim_snprintf(buf1, sizeof(buf1), " <%s>", (char *)buf3);
|
||||
}
|
||||
else
|
||||
buf1[0] = NUL;
|
||||
#ifndef EBCDIC
|
||||
if (c >= 0x80)
|
||||
sprintf(buf2, " <M-%s>", transchar(c & 0x7f));
|
||||
vim_snprintf(buf2, sizeof(buf2), " <M-%s>",
|
||||
(char *)transchar(c & 0x7f));
|
||||
else
|
||||
#endif
|
||||
buf2[0] = NUL;
|
||||
vim_snprintf((char *)IObuff, IOSIZE,
|
||||
_("<%s>%s%s %d, Hex %02x, Octal %03o"),
|
||||
transchar(c), buf1, buf2, c, c, c);
|
||||
transchar(c), buf1, buf2, cval, cval, cval);
|
||||
#ifdef FEAT_MBYTE
|
||||
if (enc_utf8)
|
||||
c = cc[ci++];
|
||||
@@ -353,7 +358,7 @@ ex_sort(eap)
|
||||
linenr_T lnum;
|
||||
long maxlen = 0;
|
||||
sorti_T *nrs;
|
||||
size_t count = eap->line2 - eap->line1 + 1;
|
||||
size_t count = (size_t)(eap->line2 - eap->line1 + 1);
|
||||
size_t i;
|
||||
char_u *p;
|
||||
char_u *s;
|
||||
@@ -952,7 +957,7 @@ do_bang(addr_count, eap, forceit, do_in, do_out)
|
||||
}
|
||||
len += (int)STRLEN(prevcmd);
|
||||
}
|
||||
if ((t = alloc(len)) == NULL)
|
||||
if ((t = alloc((unsigned)len)) == NULL)
|
||||
{
|
||||
vim_free(newcmd);
|
||||
return;
|
||||
@@ -1543,7 +1548,7 @@ make_filter_cmd(cmd, itmp, otmp)
|
||||
* redirecting input and/or output.
|
||||
*/
|
||||
if (itmp != NULL || otmp != NULL)
|
||||
sprintf((char *)buf, "(%s)", (char *)cmd);
|
||||
vim_snprintf((char *)buf, len, "(%s)", (char *)cmd);
|
||||
else
|
||||
STRCPY(buf, cmd);
|
||||
if (itmp != NULL)
|
||||
@@ -1592,37 +1597,41 @@ make_filter_cmd(cmd, itmp, otmp)
|
||||
}
|
||||
#endif
|
||||
if (otmp != NULL)
|
||||
append_redir(buf, p_srr, otmp);
|
||||
append_redir(buf, (int)len, p_srr, otmp);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append output redirection for file "fname" to the end of string buffer "buf"
|
||||
* Append output redirection for file "fname" to the end of string buffer
|
||||
* "buf[buflen]"
|
||||
* Works with the 'shellredir' and 'shellpipe' options.
|
||||
* The caller should make sure that there is enough room:
|
||||
* STRLEN(opt) + STRLEN(fname) + 3
|
||||
*/
|
||||
void
|
||||
append_redir(buf, opt, fname)
|
||||
append_redir(buf, buflen, opt, fname)
|
||||
char_u *buf;
|
||||
int buflen;
|
||||
char_u *opt;
|
||||
char_u *fname;
|
||||
{
|
||||
char_u *p;
|
||||
char_u *end;
|
||||
|
||||
buf += STRLEN(buf);
|
||||
end = buf + STRLEN(buf);
|
||||
/* find "%s", skipping "%%" */
|
||||
for (p = opt; (p = vim_strchr(p, '%')) != NULL; ++p)
|
||||
if (p[1] == 's')
|
||||
break;
|
||||
if (p != NULL)
|
||||
{
|
||||
*buf = ' '; /* not really needed? Not with sh, ksh or bash */
|
||||
sprintf((char *)buf + 1, (char *)opt, (char *)fname);
|
||||
*end = ' '; /* not really needed? Not with sh, ksh or bash */
|
||||
vim_snprintf((char *)end + 1, (size_t)(buflen - (end + 1 - buf)),
|
||||
(char *)opt, (char *)fname);
|
||||
}
|
||||
else
|
||||
sprintf((char *)buf,
|
||||
vim_snprintf((char *)end, (size_t)(buflen - (end - buf)),
|
||||
#ifdef FEAT_QUICKFIX
|
||||
# ifndef RISCOS
|
||||
opt != p_sp ? " %s%s" :
|
||||
@@ -1784,7 +1793,7 @@ write_viminfo(file, forceit)
|
||||
* overwrite a user's viminfo file after a "su root", with a
|
||||
* viminfo file that the user can't read.
|
||||
*/
|
||||
st_old.st_dev = 0;
|
||||
st_old.st_dev = (dev_t)0;
|
||||
st_old.st_ino = 0;
|
||||
st_old.st_mode = 0600;
|
||||
if (mch_stat((char *)fname, &st_old) == 0
|
||||
@@ -2246,12 +2255,11 @@ viminfo_readline(virp)
|
||||
*
|
||||
* Return the string in allocated memory (NULL when out of memory).
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
viminfo_readstring(virp, off, convert)
|
||||
vir_T *virp;
|
||||
int off; /* offset for virp->vir_line */
|
||||
int convert; /* convert the string */
|
||||
int convert UNUSED; /* convert the string */
|
||||
{
|
||||
char_u *retval;
|
||||
char_u *s, *d;
|
||||
@@ -2363,10 +2371,9 @@ viminfo_writestring(fd, p)
|
||||
* ^? ^H
|
||||
* not ^? ^?
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
do_fixdel(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
@@ -2385,7 +2392,8 @@ print_line_no_prefix(lnum, use_number, list)
|
||||
|
||||
if (curwin->w_p_nu || use_number)
|
||||
{
|
||||
sprintf((char *)numbuf, "%*ld ", number_width(curwin), (long)lnum);
|
||||
vim_snprintf((char *)numbuf, sizeof(numbuf),
|
||||
"%*ld ", number_width(curwin), (long)lnum);
|
||||
msg_puts_attr(numbuf, hl_attr(HLF_N)); /* Highlight line nrs */
|
||||
}
|
||||
msg_prt_line(ml_get(lnum), list);
|
||||
@@ -2412,8 +2420,8 @@ print_line(lnum, use_number, list)
|
||||
cursor_on(); /* msg_start() switches it off */
|
||||
out_flush();
|
||||
silent_mode = save_silent;
|
||||
info_message = FALSE;
|
||||
}
|
||||
info_message = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2702,7 +2710,12 @@ do_write(eap)
|
||||
if (eap->cmdidx == CMD_saveas)
|
||||
{
|
||||
if (retval == OK)
|
||||
{
|
||||
curbuf->b_p_ro = FALSE;
|
||||
#ifdef FEAT_WINDOWS
|
||||
redraw_tabline = TRUE;
|
||||
#endif
|
||||
}
|
||||
/* Change directories when the 'acd' option is set. */
|
||||
DO_AUTOCHDIR
|
||||
}
|
||||
@@ -2722,7 +2735,6 @@ theend:
|
||||
* May set eap->forceit if a dialog says it's OK to overwrite.
|
||||
* Return OK if it's OK, FAIL if it is not.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
check_overwrite(eap, buf, fname, ffname, other)
|
||||
exarg_T *eap;
|
||||
@@ -3705,7 +3717,7 @@ do_ecmd(fnum, ffname, sfname, eap, newlnum, flags, oldwin)
|
||||
/* If the window options were changed may need to set the spell language.
|
||||
* Can only do this after the buffer has been properly setup. */
|
||||
if (did_get_winopts && curwin->w_p_spell && *curbuf->b_p_spl != NUL)
|
||||
did_set_spelllang(curbuf);
|
||||
(void)did_set_spelllang(curbuf);
|
||||
#endif
|
||||
|
||||
if (command == NULL)
|
||||
@@ -3778,7 +3790,7 @@ do_ecmd(fnum, ffname, sfname, eap, newlnum, flags, oldwin)
|
||||
|
||||
#ifdef FEAT_KEYMAP
|
||||
if (curbuf->b_kmap_state & KEYMAP_INIT)
|
||||
keymap_init();
|
||||
(void)keymap_init();
|
||||
#endif
|
||||
|
||||
--RedrawingDisabled;
|
||||
@@ -4001,6 +4013,9 @@ ex_change(eap)
|
||||
break;
|
||||
ml_delete(eap->line1, FALSE);
|
||||
}
|
||||
|
||||
/* make sure the cursor is not beyond the end of the file now */
|
||||
check_cursor_lnum();
|
||||
deleted_lines_mark(eap->line1, (long)(eap->line2 - lnum));
|
||||
|
||||
/* ":append" on the line above the deleted lines. */
|
||||
@@ -4026,8 +4041,10 @@ ex_z(eap)
|
||||
bigness = curwin->w_height;
|
||||
else if (firstwin == lastwin)
|
||||
bigness = curwin->w_p_scr * 2;
|
||||
#ifdef FEAT_WINDOWS
|
||||
else
|
||||
bigness = curwin->w_height - 3;
|
||||
#endif
|
||||
if (bigness < 1)
|
||||
bigness = 1;
|
||||
|
||||
@@ -4476,7 +4493,7 @@ do_sub(eap)
|
||||
char_u *p1;
|
||||
int did_sub = FALSE;
|
||||
int lastone;
|
||||
unsigned len, needed_len;
|
||||
int len, copy_len, needed_len;
|
||||
long nmatch_tl = 0; /* nr of lines matched below lnum */
|
||||
int do_again; /* do it again after joining lines */
|
||||
int skip_match = FALSE;
|
||||
@@ -4621,6 +4638,8 @@ do_sub(eap)
|
||||
|
||||
if (do_ask)
|
||||
{
|
||||
int typed = 0;
|
||||
|
||||
/* change State to CONFIRM, so that the mouse works
|
||||
* properly */
|
||||
save_State = State;
|
||||
@@ -4659,7 +4678,7 @@ do_sub(eap)
|
||||
resp = getexmodeline('?', NULL, 0);
|
||||
if (resp != NULL)
|
||||
{
|
||||
i = *resp;
|
||||
typed = *resp;
|
||||
vim_free(resp);
|
||||
}
|
||||
}
|
||||
@@ -4711,7 +4730,7 @@ do_sub(eap)
|
||||
#endif
|
||||
++no_mapping; /* don't map this key */
|
||||
++allow_keys; /* allow special keys */
|
||||
i = plain_vgetc();
|
||||
typed = plain_vgetc();
|
||||
--allow_keys;
|
||||
--no_mapping;
|
||||
|
||||
@@ -4722,35 +4741,35 @@ do_sub(eap)
|
||||
}
|
||||
|
||||
need_wait_return = FALSE; /* no hit-return prompt */
|
||||
if (i == 'q' || i == ESC || i == Ctrl_C
|
||||
if (typed == 'q' || typed == ESC || typed == Ctrl_C
|
||||
#ifdef UNIX
|
||||
|| i == intr_char
|
||||
|| typed == intr_char
|
||||
#endif
|
||||
)
|
||||
{
|
||||
got_quit = TRUE;
|
||||
break;
|
||||
}
|
||||
if (i == 'n')
|
||||
if (typed == 'n')
|
||||
break;
|
||||
if (i == 'y')
|
||||
if (typed == 'y')
|
||||
break;
|
||||
if (i == 'l')
|
||||
if (typed == 'l')
|
||||
{
|
||||
/* last: replace and then stop */
|
||||
do_all = FALSE;
|
||||
line2 = lnum;
|
||||
break;
|
||||
}
|
||||
if (i == 'a')
|
||||
if (typed == 'a')
|
||||
{
|
||||
do_ask = FALSE;
|
||||
break;
|
||||
}
|
||||
#ifdef FEAT_INS_EXPAND
|
||||
if (i == Ctrl_E)
|
||||
if (typed == Ctrl_E)
|
||||
scrollup_clamp();
|
||||
else if (i == Ctrl_Y)
|
||||
else if (typed == Ctrl_Y)
|
||||
scrolldown_clamp();
|
||||
#endif
|
||||
}
|
||||
@@ -4761,7 +4780,7 @@ do_sub(eap)
|
||||
if (vim_strchr(p_cpo, CPO_UNDO) != NULL)
|
||||
--no_u_sync;
|
||||
|
||||
if (i == 'n')
|
||||
if (typed == 'n')
|
||||
{
|
||||
/* For a multi-line match, put matchcol at the NUL at
|
||||
* the end of the line and set nmatch to one, so that
|
||||
@@ -4812,9 +4831,9 @@ do_sub(eap)
|
||||
p1 = ml_get(sub_firstlnum + nmatch - 1);
|
||||
nmatch_tl += nmatch - 1;
|
||||
}
|
||||
i = regmatch.startpos[0].col - copycol;
|
||||
needed_len = i + ((unsigned)STRLEN(p1) - regmatch.endpos[0].col)
|
||||
+ sublen + 1;
|
||||
copy_len = regmatch.startpos[0].col - copycol;
|
||||
needed_len = copy_len + ((unsigned)STRLEN(p1)
|
||||
- regmatch.endpos[0].col) + sublen + 1;
|
||||
if (new_start == NULL)
|
||||
{
|
||||
/*
|
||||
@@ -4837,7 +4856,7 @@ do_sub(eap)
|
||||
*/
|
||||
len = (unsigned)STRLEN(new_start);
|
||||
needed_len += len;
|
||||
if (needed_len > new_start_len)
|
||||
if (needed_len > (int)new_start_len)
|
||||
{
|
||||
new_start_len = needed_len + 50;
|
||||
if ((p1 = alloc_check(new_start_len)) == NULL)
|
||||
@@ -4855,8 +4874,8 @@ do_sub(eap)
|
||||
/*
|
||||
* copy the text up to the part that matched
|
||||
*/
|
||||
mch_memmove(new_end, sub_firstline + copycol, (size_t)i);
|
||||
new_end += i;
|
||||
mch_memmove(new_end, sub_firstline + copycol, (size_t)copy_len);
|
||||
new_end += copy_len;
|
||||
|
||||
(void)vim_regsub_multi(®match,
|
||||
sub_firstlnum - regmatch.startpos[0].lnum,
|
||||
@@ -5780,7 +5799,7 @@ find_help_tags(arg, num_matches, matches, keep_lang)
|
||||
* Recognize a few exceptions to the rule. Some strings that contain '*'
|
||||
* with "star". Otherwise '*' is recognized as a wildcard.
|
||||
*/
|
||||
for (i = sizeof(mtable) / sizeof(char *); --i >= 0; )
|
||||
for (i = (int)(sizeof(mtable) / sizeof(char *)); --i >= 0; )
|
||||
if (STRCMP(arg, mtable[i]) == 0)
|
||||
{
|
||||
STRCPY(d, rtable[i]);
|
||||
@@ -6104,10 +6123,9 @@ fix_help_buffer()
|
||||
/*
|
||||
* ":exusage"
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ex_exusage(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
do_cmdline_cmd((char_u *)"help ex-cmd-index");
|
||||
}
|
||||
@@ -6115,10 +6133,9 @@ ex_exusage(eap)
|
||||
/*
|
||||
* ":viusage"
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ex_viusage(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
do_cmdline_cmd((char_u *)"help normal-index");
|
||||
}
|
||||
@@ -6530,7 +6547,46 @@ struct sign
|
||||
static sign_T *first_sign = NULL;
|
||||
static int last_sign_typenr = MAX_TYPENR; /* is decremented */
|
||||
|
||||
static int sign_cmd_idx __ARGS((char_u *begin_cmd, char_u *end_cmd));
|
||||
static void sign_list_defined __ARGS((sign_T *sp));
|
||||
static void sign_undefine __ARGS((sign_T *sp, sign_T *sp_prev));
|
||||
|
||||
static char *cmds[] = {
|
||||
"define",
|
||||
#define SIGNCMD_DEFINE 0
|
||||
"undefine",
|
||||
#define SIGNCMD_UNDEFINE 1
|
||||
"list",
|
||||
#define SIGNCMD_LIST 2
|
||||
"place",
|
||||
#define SIGNCMD_PLACE 3
|
||||
"unplace",
|
||||
#define SIGNCMD_UNPLACE 4
|
||||
"jump",
|
||||
#define SIGNCMD_JUMP 5
|
||||
NULL
|
||||
#define SIGNCMD_LAST 6
|
||||
};
|
||||
|
||||
/*
|
||||
* Find index of a ":sign" subcmd from its name.
|
||||
* "*end_cmd" must be writable.
|
||||
*/
|
||||
static int
|
||||
sign_cmd_idx(begin_cmd, end_cmd)
|
||||
char_u *begin_cmd; /* begin of sign subcmd */
|
||||
char_u *end_cmd; /* just after sign subcmd */
|
||||
{
|
||||
int idx;
|
||||
char save = *end_cmd;
|
||||
|
||||
*end_cmd = NUL;
|
||||
for (idx = 0; ; ++idx)
|
||||
if (cmds[idx] == NULL || STRCMP(begin_cmd, cmds[idx]) == 0)
|
||||
break;
|
||||
*end_cmd = save;
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* ":sign" command
|
||||
@@ -6545,35 +6601,14 @@ ex_sign(eap)
|
||||
sign_T *sp;
|
||||
sign_T *sp_prev;
|
||||
buf_T *buf;
|
||||
static char *cmds[] = {
|
||||
"define",
|
||||
#define SIGNCMD_DEFINE 0
|
||||
"undefine",
|
||||
#define SIGNCMD_UNDEFINE 1
|
||||
"list",
|
||||
#define SIGNCMD_LIST 2
|
||||
"place",
|
||||
#define SIGNCMD_PLACE 3
|
||||
"unplace",
|
||||
#define SIGNCMD_UNPLACE 4
|
||||
"jump",
|
||||
#define SIGNCMD_JUMP 5
|
||||
#define SIGNCMD_LAST 6
|
||||
};
|
||||
|
||||
/* Parse the subcommand. */
|
||||
p = skiptowhite(arg);
|
||||
if (*p != NUL)
|
||||
*p++ = NUL;
|
||||
for (idx = 0; ; ++idx)
|
||||
idx = sign_cmd_idx(arg, p);
|
||||
if (idx == SIGNCMD_LAST)
|
||||
{
|
||||
if (idx == SIGNCMD_LAST)
|
||||
{
|
||||
EMSG2(_("E160: Unknown sign command: %s"), arg);
|
||||
return;
|
||||
}
|
||||
if (STRCMP(arg, cmds[idx]) == 0)
|
||||
break;
|
||||
EMSG2(_("E160: Unknown sign command: %s"), arg);
|
||||
return;
|
||||
}
|
||||
arg = skipwhite(p);
|
||||
|
||||
@@ -6739,24 +6774,8 @@ ex_sign(eap)
|
||||
/* ":sign list {name}" */
|
||||
sign_list_defined(sp);
|
||||
else
|
||||
{
|
||||
/* ":sign undefine {name}" */
|
||||
vim_free(sp->sn_name);
|
||||
vim_free(sp->sn_icon);
|
||||
#ifdef FEAT_SIGN_ICONS
|
||||
if (sp->sn_image != NULL)
|
||||
{
|
||||
out_flush();
|
||||
gui_mch_destroy_sign(sp->sn_image);
|
||||
}
|
||||
#endif
|
||||
vim_free(sp->sn_text);
|
||||
if (sp_prev == NULL)
|
||||
first_sign = sp->sn_next;
|
||||
else
|
||||
sp_prev->sn_next = sp->sn_next;
|
||||
vim_free(sp);
|
||||
}
|
||||
sign_undefine(sp, sp_prev);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -7004,6 +7023,31 @@ sign_list_defined(sp)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Undefine a sign and free its memory.
|
||||
*/
|
||||
static void
|
||||
sign_undefine(sp, sp_prev)
|
||||
sign_T *sp;
|
||||
sign_T *sp_prev;
|
||||
{
|
||||
vim_free(sp->sn_name);
|
||||
vim_free(sp->sn_icon);
|
||||
#ifdef FEAT_SIGN_ICONS
|
||||
if (sp->sn_image != NULL)
|
||||
{
|
||||
out_flush();
|
||||
gui_mch_destroy_sign(sp->sn_image);
|
||||
}
|
||||
#endif
|
||||
vim_free(sp->sn_text);
|
||||
if (sp_prev == NULL)
|
||||
first_sign = sp->sn_next;
|
||||
else
|
||||
sp_prev->sn_next = sp->sn_next;
|
||||
vim_free(sp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get highlighting attribute for sign "typenr".
|
||||
* If "line" is TRUE: line highl, if FALSE: text highl.
|
||||
@@ -7078,6 +7122,197 @@ sign_typenr2name(typenr)
|
||||
return (char_u *)_("[Deleted]");
|
||||
}
|
||||
|
||||
#if defined(EXITFREE) || defined(PROTO)
|
||||
/*
|
||||
* Undefine/free all signs.
|
||||
*/
|
||||
void
|
||||
free_signs()
|
||||
{
|
||||
while (first_sign != NULL)
|
||||
sign_undefine(first_sign, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
|
||||
static enum
|
||||
{
|
||||
EXP_SUBCMD, /* expand :sign sub-commands */
|
||||
EXP_DEFINE, /* expand :sign define {name} args */
|
||||
EXP_PLACE, /* expand :sign place {id} args */
|
||||
EXP_UNPLACE, /* expand :sign unplace" */
|
||||
EXP_SIGN_NAMES /* expand with name of placed signs */
|
||||
} expand_what;
|
||||
|
||||
/*
|
||||
* Function given to ExpandGeneric() to obtain the sign command
|
||||
* expansion.
|
||||
*/
|
||||
char_u *
|
||||
get_sign_name(xp, idx)
|
||||
expand_T *xp UNUSED;
|
||||
int idx;
|
||||
{
|
||||
sign_T *sp;
|
||||
int current_idx;
|
||||
|
||||
switch (expand_what)
|
||||
{
|
||||
case EXP_SUBCMD:
|
||||
return (char_u *)cmds[idx];
|
||||
case EXP_DEFINE:
|
||||
{
|
||||
char *define_arg[] =
|
||||
{
|
||||
"icon=", "linehl=", "text=", "texthl=", NULL
|
||||
};
|
||||
return (char_u *)define_arg[idx];
|
||||
}
|
||||
case EXP_PLACE:
|
||||
{
|
||||
char *place_arg[] =
|
||||
{
|
||||
"line=", "name=", "file=", "buffer=", NULL
|
||||
};
|
||||
return (char_u *)place_arg[idx];
|
||||
}
|
||||
case EXP_UNPLACE:
|
||||
{
|
||||
char *unplace_arg[] = { "file=", "buffer=", NULL };
|
||||
return (char_u *)unplace_arg[idx];
|
||||
}
|
||||
case EXP_SIGN_NAMES:
|
||||
/* Complete with name of signs already defined */
|
||||
current_idx = 0;
|
||||
for (sp = first_sign; sp != NULL; sp = sp->sn_next)
|
||||
if (current_idx++ == idx)
|
||||
return sp->sn_name;
|
||||
return NULL;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle command line completion for :sign command.
|
||||
*/
|
||||
void
|
||||
set_context_in_sign_cmd(xp, arg)
|
||||
expand_T *xp;
|
||||
char_u *arg;
|
||||
{
|
||||
char_u *p;
|
||||
char_u *end_subcmd;
|
||||
char_u *last;
|
||||
int cmd_idx;
|
||||
char_u *begin_subcmd_args;
|
||||
|
||||
/* Default: expand subcommands. */
|
||||
xp->xp_context = EXPAND_SIGN;
|
||||
expand_what = EXP_SUBCMD;
|
||||
xp->xp_pattern = arg;
|
||||
|
||||
end_subcmd = skiptowhite(arg);
|
||||
if (*end_subcmd == NUL)
|
||||
/* expand subcmd name
|
||||
* :sign {subcmd}<CTRL-D>*/
|
||||
return;
|
||||
|
||||
cmd_idx = sign_cmd_idx(arg, end_subcmd);
|
||||
|
||||
/* :sign {subcmd} {subcmd_args}
|
||||
* |
|
||||
* begin_subcmd_args */
|
||||
begin_subcmd_args = skipwhite(end_subcmd);
|
||||
p = skiptowhite(begin_subcmd_args);
|
||||
if (*p == NUL)
|
||||
{
|
||||
/*
|
||||
* Expand first argument of subcmd when possible.
|
||||
* For ":jump {id}" and ":unplace {id}", we could
|
||||
* possibly expand the ids of all signs already placed.
|
||||
*/
|
||||
xp->xp_pattern = begin_subcmd_args;
|
||||
switch (cmd_idx)
|
||||
{
|
||||
case SIGNCMD_LIST:
|
||||
case SIGNCMD_UNDEFINE:
|
||||
/* :sign list <CTRL-D>
|
||||
* :sign undefine <CTRL-D> */
|
||||
expand_what = EXP_SIGN_NAMES;
|
||||
break;
|
||||
default:
|
||||
xp->xp_context = EXPAND_NOTHING;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* expand last argument of subcmd */
|
||||
|
||||
/* :sign define {name} {args}...
|
||||
* |
|
||||
* p */
|
||||
|
||||
/* Loop until reaching last argument. */
|
||||
do
|
||||
{
|
||||
p = skipwhite(p);
|
||||
last = p;
|
||||
p = skiptowhite(p);
|
||||
} while (*p != NUL);
|
||||
|
||||
p = vim_strchr(last, '=');
|
||||
|
||||
/* :sign define {name} {args}... {last}=
|
||||
* | |
|
||||
* last p */
|
||||
if (p == NUL)
|
||||
{
|
||||
/* Expand last argument name (before equal sign). */
|
||||
xp->xp_pattern = last;
|
||||
switch (cmd_idx)
|
||||
{
|
||||
case SIGNCMD_DEFINE:
|
||||
expand_what = EXP_DEFINE;
|
||||
break;
|
||||
case SIGNCMD_PLACE:
|
||||
expand_what = EXP_PLACE;
|
||||
break;
|
||||
case SIGNCMD_JUMP:
|
||||
case SIGNCMD_UNPLACE:
|
||||
expand_what = EXP_UNPLACE;
|
||||
break;
|
||||
default:
|
||||
xp->xp_context = EXPAND_NOTHING;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Expand last argument value (after equal sign). */
|
||||
xp->xp_pattern = p + 1;
|
||||
switch (cmd_idx)
|
||||
{
|
||||
case SIGNCMD_DEFINE:
|
||||
if (STRNCMP(last, "texthl", p - last) == 0 ||
|
||||
STRNCMP(last, "linehl", p - last) == 0)
|
||||
xp->xp_context = EXPAND_HIGHLIGHT;
|
||||
else if (STRNCMP(last, "icon", p - last) == 0)
|
||||
xp->xp_context = EXPAND_FILES;
|
||||
else
|
||||
xp->xp_context = EXPAND_NOTHING;
|
||||
break;
|
||||
case SIGNCMD_PLACE:
|
||||
if (STRNCMP(last, "name", p - last) == 0)
|
||||
expand_what = EXP_SIGN_NAMES;
|
||||
else
|
||||
xp->xp_context = EXPAND_NOTHING;
|
||||
break;
|
||||
default:
|
||||
xp->xp_context = EXPAND_NOTHING;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_GUI) || defined(FEAT_CLIENTSERVER) || defined(PROTO)
|
||||
|
||||
@@ -995,6 +995,8 @@ EX(CMD_unmap, "unmap", ex_unmap,
|
||||
BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
|
||||
EX(CMD_unmenu, "unmenu", ex_menu,
|
||||
BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
|
||||
EX(CMD_unsilent, "unsilent", ex_wrongmodifier,
|
||||
NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
|
||||
EX(CMD_update, "update", ex_update,
|
||||
RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR),
|
||||
EX(CMD_vglobal, "vglobal", ex_global,
|
||||
|
||||
+41
-43
@@ -28,7 +28,8 @@ typedef struct scriptitem_S
|
||||
{
|
||||
char_u *sn_name;
|
||||
# ifdef UNIX
|
||||
int sn_dev;
|
||||
int sn_dev_valid;
|
||||
dev_t sn_dev;
|
||||
ino_t sn_ino;
|
||||
# endif
|
||||
# ifdef FEAT_PROFILE
|
||||
@@ -680,10 +681,9 @@ ex_breakdel(eap)
|
||||
/*
|
||||
* ":breaklist".
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ex_breaklist(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
struct debuggy *bp;
|
||||
int i;
|
||||
@@ -1342,14 +1342,13 @@ autowrite_all()
|
||||
/*
|
||||
* return TRUE if buffer was changed and cannot be abandoned.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
check_changed(buf, checkaw, mult_win, forceit, allbuf)
|
||||
buf_T *buf;
|
||||
int checkaw; /* do autowrite if buffer was changed */
|
||||
int mult_win; /* check also when several wins for the buf */
|
||||
int forceit;
|
||||
int allbuf; /* may write all buffers */
|
||||
int allbuf UNUSED; /* may write all buffers */
|
||||
{
|
||||
if ( !forceit
|
||||
&& bufIsChanged(buf)
|
||||
@@ -1832,12 +1831,11 @@ set_arglist(str)
|
||||
*
|
||||
* Return FAIL for failure, OK otherwise.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
do_arglist(str, what, after)
|
||||
char_u *str;
|
||||
int what;
|
||||
int after; /* 0 means before first one */
|
||||
int what UNUSED;
|
||||
int after UNUSED; /* 0 means before first one */
|
||||
{
|
||||
garray_T new_ga;
|
||||
int exp_count;
|
||||
@@ -2622,11 +2620,10 @@ ex_runtime(eap)
|
||||
|
||||
static void source_callback __ARGS((char_u *fname, void *cookie));
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
source_callback(fname, cookie)
|
||||
char_u *fname;
|
||||
void *cookie;
|
||||
void *cookie UNUSED;
|
||||
{
|
||||
(void)do_source(fname, FALSE, DOSO_NONE);
|
||||
}
|
||||
@@ -2753,10 +2750,9 @@ do_in_runtimepath(name, all, callback, cookie)
|
||||
/*
|
||||
* ":options"
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ex_options(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
cmd_source((char_u *)SYS_OPTWIN_FILE, NULL);
|
||||
}
|
||||
@@ -2915,6 +2911,7 @@ do_source(fname, check_other, is_vimrc)
|
||||
linenr_T save_sourcing_lnum;
|
||||
char_u *p;
|
||||
char_u *fname_exp;
|
||||
char_u *firstline = NULL;
|
||||
int retval = FAIL;
|
||||
#ifdef FEAT_EVAL
|
||||
scid_T save_current_SID;
|
||||
@@ -3065,23 +3062,6 @@ do_source(fname, check_other, is_vimrc)
|
||||
|
||||
cookie.level = ex_nesting_level;
|
||||
#endif
|
||||
#ifdef FEAT_MBYTE
|
||||
cookie.conv.vc_type = CONV_NONE; /* no conversion */
|
||||
|
||||
/* Try reading the first few bytes to check for a UTF-8 BOM. */
|
||||
{
|
||||
char_u buf[3];
|
||||
|
||||
if (fread((char *)buf, sizeof(char_u), (size_t)3, cookie.fp)
|
||||
== (size_t)3
|
||||
&& buf[0] == 0xef && buf[1] == 0xbb && buf[2] == 0xbf)
|
||||
/* Found BOM, setup conversion and skip over it. */
|
||||
convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc);
|
||||
else
|
||||
/* No BOM found, rewind. */
|
||||
fseek(cookie.fp, 0L, SEEK_SET);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Keep the sourcing name/lnum, for recursive calls.
|
||||
@@ -3091,6 +3071,27 @@ do_source(fname, check_other, is_vimrc)
|
||||
save_sourcing_lnum = sourcing_lnum;
|
||||
sourcing_lnum = 0;
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
cookie.conv.vc_type = CONV_NONE; /* no conversion */
|
||||
|
||||
/* Read the first line so we can check for a UTF-8 BOM. */
|
||||
firstline = getsourceline(0, (void *)&cookie, 0);
|
||||
if (firstline != NULL && STRLEN(firstline) >= 3 && firstline[0] == 0xef
|
||||
&& firstline[1] == 0xbb && firstline[2] == 0xbf)
|
||||
{
|
||||
/* Found BOM; setup conversion, skip over BOM and recode the line. */
|
||||
convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc);
|
||||
p = string_convert(&cookie.conv, firstline + 3, NULL);
|
||||
if (p == NULL)
|
||||
p = vim_strsave(firstline + 3);
|
||||
if (p != NULL)
|
||||
{
|
||||
vim_free(firstline);
|
||||
firstline = p;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef STARTUPTIME
|
||||
time_push(&tv_rel, &tv_start);
|
||||
#endif
|
||||
@@ -3122,7 +3123,7 @@ do_source(fname, check_other, is_vimrc)
|
||||
/* Compare dev/ino when possible, it catches symbolic
|
||||
* links. Also compare file names, the inode may change
|
||||
* when the file was edited. */
|
||||
((stat_ok && si->sn_dev != -1)
|
||||
((stat_ok && si->sn_dev_valid)
|
||||
&& (si->sn_dev == st.st_dev
|
||||
&& si->sn_ino == st.st_ino)) ||
|
||||
# endif
|
||||
@@ -3149,11 +3150,12 @@ do_source(fname, check_other, is_vimrc)
|
||||
# ifdef UNIX
|
||||
if (stat_ok)
|
||||
{
|
||||
si->sn_dev_valid = TRUE;
|
||||
si->sn_dev = st.st_dev;
|
||||
si->sn_ino = st.st_ino;
|
||||
}
|
||||
else
|
||||
si->sn_dev = -1;
|
||||
si->sn_dev_valid = FALSE;
|
||||
# endif
|
||||
|
||||
/* Allocate the local script variables to use for this script. */
|
||||
@@ -3184,9 +3186,8 @@ do_source(fname, check_other, is_vimrc)
|
||||
/*
|
||||
* Call do_cmdline, which will call getsourceline() to get the lines.
|
||||
*/
|
||||
do_cmdline(NULL, getsourceline, (void *)&cookie,
|
||||
do_cmdline(firstline, getsourceline, (void *)&cookie,
|
||||
DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT);
|
||||
|
||||
retval = OK;
|
||||
|
||||
#ifdef FEAT_PROFILE
|
||||
@@ -3244,6 +3245,7 @@ almosttheend:
|
||||
#endif
|
||||
fclose(cookie.fp);
|
||||
vim_free(cookie.nextline);
|
||||
vim_free(firstline);
|
||||
#ifdef FEAT_MBYTE
|
||||
convert_setup(&cookie.conv, NULL, NULL);
|
||||
#endif
|
||||
@@ -3258,10 +3260,9 @@ theend:
|
||||
/*
|
||||
* ":scriptnames"
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ex_scriptnames(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -3385,12 +3386,11 @@ fgets_cr(s, n, stream)
|
||||
* Return a pointer to the line in allocated memory.
|
||||
* Return NULL for end-of-file or some error.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
char_u *
|
||||
getsourceline(c, cookie, indent)
|
||||
int c; /* not used */
|
||||
int c UNUSED;
|
||||
void *cookie;
|
||||
int indent; /* not used */
|
||||
int indent UNUSED;
|
||||
{
|
||||
struct source_cookie *sp = (struct source_cookie *)cookie;
|
||||
char_u *line;
|
||||
@@ -3441,7 +3441,7 @@ getsourceline(c, cookie, indent)
|
||||
p = skipwhite(sp->nextline);
|
||||
if (*p != '\\')
|
||||
break;
|
||||
s = alloc((int)(STRLEN(line) + STRLEN(p)));
|
||||
s = alloc((unsigned)(STRLEN(line) + STRLEN(p)));
|
||||
if (s == NULL) /* out of memory */
|
||||
break;
|
||||
STRCPY(s, line);
|
||||
@@ -3717,10 +3717,9 @@ script_line_end()
|
||||
* ":scriptencoding": Set encoding conversion for a sourced script.
|
||||
* Without the multi-byte feature it's simply ignored.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ex_scriptencoding(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
#ifdef FEAT_MBYTE
|
||||
struct source_cookie *sp;
|
||||
@@ -4169,10 +4168,9 @@ ex_language(eap)
|
||||
* Function given to ExpandGeneric() to obtain the possible arguments of the
|
||||
* ":language" command.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
get_lang_arg(xp, idx)
|
||||
expand_T *xp;
|
||||
expand_T *xp UNUSED;
|
||||
int idx;
|
||||
{
|
||||
if (idx == 0)
|
||||
|
||||
+135
-77
@@ -1585,11 +1585,10 @@ free_cmdlines(gap)
|
||||
* If "fgetline" is get_loop_line(), return TRUE if the getline it uses equals
|
||||
* "func". * Otherwise return TRUE when "fgetline" equals "func".
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
getline_equal(fgetline, cookie, func)
|
||||
char_u *(*fgetline) __ARGS((int, void *, int));
|
||||
void *cookie; /* argument for fgetline() */
|
||||
void *cookie UNUSED; /* argument for fgetline() */
|
||||
char_u *(*func) __ARGS((int, void *, int));
|
||||
{
|
||||
#ifdef FEAT_EVAL
|
||||
@@ -1617,10 +1616,9 @@ getline_equal(fgetline, cookie, func)
|
||||
* If "fgetline" is get_loop_line(), return the cookie used by the original
|
||||
* getline function. Otherwise return "cookie".
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void *
|
||||
getline_cookie(fgetline, cookie)
|
||||
char_u *(*fgetline) __ARGS((int, void *, int));
|
||||
char_u *(*fgetline) __ARGS((int, void *, int)) UNUSED;
|
||||
void *cookie; /* argument for fgetline() */
|
||||
{
|
||||
# ifdef FEAT_EVAL
|
||||
@@ -1686,8 +1684,8 @@ do_one_cmd(cmdlinep, sourcing,
|
||||
char_u *errormsg = NULL; /* error message */
|
||||
exarg_T ea; /* Ex command arguments */
|
||||
long verbose_save = -1;
|
||||
int save_msg_scroll = 0;
|
||||
int did_silent = 0;
|
||||
int save_msg_scroll = msg_scroll;
|
||||
int save_msg_silent = -1;
|
||||
int did_esilent = 0;
|
||||
#ifdef HAVE_SANDBOX
|
||||
int did_sandbox = FALSE;
|
||||
@@ -1865,9 +1863,9 @@ do_one_cmd(cmdlinep, sourcing,
|
||||
}
|
||||
if (!checkforcmd(&ea.cmd, "silent", 3))
|
||||
break;
|
||||
++did_silent;
|
||||
if (save_msg_silent == -1)
|
||||
save_msg_silent = msg_silent;
|
||||
++msg_silent;
|
||||
save_msg_scroll = msg_scroll;
|
||||
if (*ea.cmd == '!' && !vim_iswhite(ea.cmd[-1]))
|
||||
{
|
||||
/* ":silent!", but not "silent !cmd" */
|
||||
@@ -1895,6 +1893,13 @@ do_one_cmd(cmdlinep, sourcing,
|
||||
#endif
|
||||
continue;
|
||||
|
||||
case 'u': if (!checkforcmd(&ea.cmd, "unsilent", 3))
|
||||
break;
|
||||
if (save_msg_silent == -1)
|
||||
save_msg_silent = msg_silent;
|
||||
msg_silent = 0;
|
||||
continue;
|
||||
|
||||
case 'v': if (checkforcmd(&ea.cmd, "vertical", 4))
|
||||
{
|
||||
#ifdef FEAT_VERTSPLIT
|
||||
@@ -2693,19 +2698,23 @@ doend:
|
||||
|
||||
cmdmod = save_cmdmod;
|
||||
|
||||
if (did_silent > 0)
|
||||
if (save_msg_silent != -1)
|
||||
{
|
||||
/* messages could be enabled for a serious error, need to check if the
|
||||
* counters don't become negative */
|
||||
msg_silent -= did_silent;
|
||||
if (msg_silent < 0)
|
||||
msg_silent = 0;
|
||||
if (!did_emsg)
|
||||
msg_silent = save_msg_silent;
|
||||
emsg_silent -= did_esilent;
|
||||
if (emsg_silent < 0)
|
||||
emsg_silent = 0;
|
||||
/* Restore msg_scroll, it's set by file I/O commands, even when no
|
||||
* message is actually displayed. */
|
||||
msg_scroll = save_msg_scroll;
|
||||
|
||||
/* "silent reg" or "silent echo x" inside "redir" leaves msg_col
|
||||
* somewhere in the line. Put it back in the first column. */
|
||||
if (redirecting())
|
||||
msg_col = 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SANDBOX
|
||||
@@ -2739,7 +2748,7 @@ checkforcmd(pp, cmd, len)
|
||||
int i;
|
||||
|
||||
for (i = 0; cmd[i] != NUL; ++i)
|
||||
if (cmd[i] != (*pp)[i])
|
||||
if (((char_u *)cmd)[i] != (*pp)[i])
|
||||
break;
|
||||
if (i >= len && !isalpha((*pp)[i]))
|
||||
{
|
||||
@@ -2756,11 +2765,10 @@ checkforcmd(pp, cmd, len)
|
||||
* "full" is set to TRUE if the whole command name matched.
|
||||
* Returns NULL for an ambiguous user command.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static char_u *
|
||||
find_command(eap, full)
|
||||
exarg_T *eap;
|
||||
int *full;
|
||||
int *full UNUSED;
|
||||
{
|
||||
int len;
|
||||
char_u *p;
|
||||
@@ -2805,7 +2813,7 @@ find_command(eap, full)
|
||||
/* Check for ":dl", ":dell", etc. to ":deletel": that's
|
||||
* :delete with the 'l' flag. Same for 'p'. */
|
||||
for (i = 0; i < len; ++i)
|
||||
if (eap->cmd[i] != "delete"[i])
|
||||
if (eap->cmd[i] != ((char_u *)"delete")[i])
|
||||
break;
|
||||
if (i == len - 1)
|
||||
{
|
||||
@@ -2992,6 +3000,7 @@ static struct cmdmod
|
||||
{"silent", 3, FALSE},
|
||||
{"tab", 3, TRUE},
|
||||
{"topleft", 2, FALSE},
|
||||
{"unsilent", 3, FALSE},
|
||||
{"verbose", 4, TRUE},
|
||||
{"vertical", 4, FALSE},
|
||||
};
|
||||
@@ -3009,7 +3018,7 @@ modifier_len(cmd)
|
||||
|
||||
if (VIM_ISDIGIT(*cmd))
|
||||
p = skipwhite(skipdigits(cmd));
|
||||
for (i = 0; i < sizeof(cmdmods) / sizeof(struct cmdmod); ++i)
|
||||
for (i = 0; i < (int)(sizeof(cmdmods) / sizeof(struct cmdmod)); ++i)
|
||||
{
|
||||
for (j = 0; p[j] != NUL; ++j)
|
||||
if (p[j] != cmdmods[i].name[j])
|
||||
@@ -3037,7 +3046,7 @@ cmd_exists(name)
|
||||
char_u *p;
|
||||
|
||||
/* Check command modifiers. */
|
||||
for (i = 0; i < sizeof(cmdmods) / sizeof(struct cmdmod); ++i)
|
||||
for (i = 0; i < (int)(sizeof(cmdmods) / sizeof(struct cmdmod)); ++i)
|
||||
{
|
||||
for (j = 0; name[j] != NUL; ++j)
|
||||
if (name[j] != cmdmods[i].name[j])
|
||||
@@ -3690,6 +3699,18 @@ set_one_cmd_context(xp, buff)
|
||||
case CMD_highlight:
|
||||
set_context_in_highlight_cmd(xp, arg);
|
||||
break;
|
||||
#ifdef FEAT_CSCOPE
|
||||
case CMD_cscope:
|
||||
case CMD_lcscope:
|
||||
case CMD_scscope:
|
||||
set_context_in_cscope_cmd(xp, arg, ea.cmdidx);
|
||||
break;
|
||||
#endif
|
||||
#ifdef FEAT_SIGNS
|
||||
case CMD_sign:
|
||||
set_context_in_sign_cmd(xp, arg);
|
||||
break;
|
||||
#endif
|
||||
#ifdef FEAT_LISTCMDS
|
||||
case CMD_bdelete:
|
||||
case CMD_bwipeout:
|
||||
@@ -3824,7 +3845,7 @@ skip_range(cmd, ctx)
|
||||
char_u *cmd;
|
||||
int *ctx; /* pointer to xp_context or NULL */
|
||||
{
|
||||
int delim;
|
||||
unsigned delim;
|
||||
|
||||
while (vim_strchr((char_u *)" \t0123456789.$%'/?-+,;", *cmd) != NULL)
|
||||
{
|
||||
@@ -5054,10 +5075,9 @@ check_more(message, forceit)
|
||||
/*
|
||||
* Function given to ExpandGeneric() to obtain the list of command names.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
get_command_name(xp, idx)
|
||||
expand_T *xp;
|
||||
expand_T *xp UNUSED;
|
||||
int idx;
|
||||
{
|
||||
if (idx >= (int)CMD_SIZE)
|
||||
@@ -5142,7 +5162,11 @@ uc_add_command(name, name_len, rep, argt, def, flags, compl, compl_arg, force)
|
||||
}
|
||||
|
||||
vim_free(cmd->uc_rep);
|
||||
cmd->uc_rep = 0;
|
||||
cmd->uc_rep = NULL;
|
||||
#if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
|
||||
vim_free(cmd->uc_compl_arg);
|
||||
cmd->uc_compl_arg = NULL;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5201,6 +5225,9 @@ static struct
|
||||
{EXPAND_AUGROUP, "augroup"},
|
||||
{EXPAND_BUFFERS, "buffer"},
|
||||
{EXPAND_COMMANDS, "command"},
|
||||
#if defined(FEAT_CSCOPE)
|
||||
{EXPAND_CSCOPE, "cscope"},
|
||||
#endif
|
||||
#if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
|
||||
{EXPAND_USER_DEFINED, "custom"},
|
||||
{EXPAND_USER_LIST, "customlist"},
|
||||
@@ -5217,6 +5244,9 @@ static struct
|
||||
{EXPAND_MENUS, "menu"},
|
||||
{EXPAND_SETTINGS, "option"},
|
||||
{EXPAND_SHELLCMD, "shellcmd"},
|
||||
#if defined(FEAT_SIGNS)
|
||||
{EXPAND_SIGN, "sign"},
|
||||
#endif
|
||||
{EXPAND_TAGS, "tag"},
|
||||
{EXPAND_TAGS_LISTFILES, "tag_listfiles"},
|
||||
{EXPAND_USER_VARS, "var"},
|
||||
@@ -5500,6 +5530,9 @@ invalid_count:
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* ":command ..."
|
||||
*/
|
||||
static void
|
||||
ex_command(eap)
|
||||
exarg_T *eap;
|
||||
@@ -5561,10 +5594,9 @@ ex_command(eap)
|
||||
* ":comclear"
|
||||
* Clear all user commands, global and for current buffer.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ex_comclear(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
uc_clear(&ucmds);
|
||||
uc_clear(&curbuf->b_ucmds);
|
||||
@@ -5931,7 +5963,8 @@ do_ucmd(eap)
|
||||
char_u *q;
|
||||
|
||||
char_u *start;
|
||||
char_u *end;
|
||||
char_u *end = NULL;
|
||||
char_u *ksp;
|
||||
size_t len, totlen;
|
||||
|
||||
size_t split_len = 0;
|
||||
@@ -5948,16 +5981,51 @@ do_ucmd(eap)
|
||||
|
||||
/*
|
||||
* Replace <> in the command by the arguments.
|
||||
* First round: "buf" is NULL, compute length, allocate "buf".
|
||||
* Second round: copy result into "buf".
|
||||
*/
|
||||
buf = NULL;
|
||||
for (;;)
|
||||
{
|
||||
p = cmd->uc_rep;
|
||||
q = buf;
|
||||
p = cmd->uc_rep; /* source */
|
||||
q = buf; /* destination */
|
||||
totlen = 0;
|
||||
while ((start = vim_strchr(p, '<')) != NULL
|
||||
&& (end = vim_strchr(start + 1, '>')) != NULL)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
start = vim_strchr(p, '<');
|
||||
if (start != NULL)
|
||||
end = vim_strchr(start + 1, '>');
|
||||
if (buf != NULL)
|
||||
{
|
||||
ksp = vim_strchr(p, K_SPECIAL);
|
||||
if (ksp != NULL && (start == NULL || ksp < start || end == NULL)
|
||||
&& ((ksp[1] == KS_SPECIAL && ksp[2] == KE_FILLER)
|
||||
# ifdef FEAT_GUI
|
||||
|| (ksp[1] == KS_EXTRA && ksp[2] == (int)KE_CSI)
|
||||
# endif
|
||||
))
|
||||
{
|
||||
/* K_SPECIAL han been put in the buffer as K_SPECIAL
|
||||
* KS_SPECIAL KE_FILLER, like for mappings, but
|
||||
* do_cmdline() doesn't handle that, so convert it back.
|
||||
* Also change K_SPECIAL KS_EXTRA KE_CSI into CSI. */
|
||||
len = ksp - p;
|
||||
if (len > 0)
|
||||
{
|
||||
mch_memmove(q, p, len);
|
||||
q += len;
|
||||
}
|
||||
*q++ = ksp[1] == KS_SPECIAL ? K_SPECIAL : CSI;
|
||||
p = ksp + 3;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* break if there no <item> is found */
|
||||
if (start == NULL || end == NULL)
|
||||
break;
|
||||
|
||||
/* Include the '>' */
|
||||
++end;
|
||||
|
||||
@@ -6024,10 +6092,9 @@ get_user_command_name(idx)
|
||||
/*
|
||||
* Function given to ExpandGeneric() to obtain the list of user command names.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
get_user_commands(xp, idx)
|
||||
expand_T *xp;
|
||||
expand_T *xp UNUSED;
|
||||
int idx;
|
||||
{
|
||||
if (idx < curbuf->b_ucmds.ga_len)
|
||||
@@ -6042,17 +6109,16 @@ get_user_commands(xp, idx)
|
||||
* Function given to ExpandGeneric() to obtain the list of user command
|
||||
* attributes.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
get_user_cmd_flags(xp, idx)
|
||||
expand_T *xp;
|
||||
expand_T *xp UNUSED;
|
||||
int idx;
|
||||
{
|
||||
static char *user_cmd_flags[] =
|
||||
{"bang", "bar", "buffer", "complete", "count",
|
||||
"nargs", "range", "register"};
|
||||
|
||||
if (idx >= sizeof(user_cmd_flags) / sizeof(user_cmd_flags[0]))
|
||||
if (idx >= (int)(sizeof(user_cmd_flags) / sizeof(user_cmd_flags[0])))
|
||||
return NULL;
|
||||
return (char_u *)user_cmd_flags[idx];
|
||||
}
|
||||
@@ -6060,15 +6126,14 @@ get_user_cmd_flags(xp, idx)
|
||||
/*
|
||||
* Function given to ExpandGeneric() to obtain the list of values for -nargs.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
get_user_cmd_nargs(xp, idx)
|
||||
expand_T *xp;
|
||||
expand_T *xp UNUSED;
|
||||
int idx;
|
||||
{
|
||||
static char *user_cmd_nargs[] = {"0", "1", "*", "?", "+"};
|
||||
|
||||
if (idx >= sizeof(user_cmd_nargs) / sizeof(user_cmd_nargs[0]))
|
||||
if (idx >= (int)(sizeof(user_cmd_nargs) / sizeof(user_cmd_nargs[0])))
|
||||
return NULL;
|
||||
return (char_u *)user_cmd_nargs[idx];
|
||||
}
|
||||
@@ -6076,10 +6141,9 @@ get_user_cmd_nargs(xp, idx)
|
||||
/*
|
||||
* Function given to ExpandGeneric() to obtain the list of values for -complete.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
get_user_cmd_complete(xp, idx)
|
||||
expand_T *xp;
|
||||
expand_T *xp UNUSED;
|
||||
int idx;
|
||||
{
|
||||
return (char_u *)command_complete[idx].name;
|
||||
@@ -6257,10 +6321,9 @@ ex_quit(eap)
|
||||
/*
|
||||
* ":cquit".
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ex_cquit(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
getout(1); /* this does not always pass on the exit code to the Manx
|
||||
compiler. why? */
|
||||
@@ -6702,10 +6765,9 @@ ex_goto(eap)
|
||||
/*
|
||||
* ":shell".
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ex_shell(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
do_shell(NULL, 0);
|
||||
}
|
||||
@@ -7010,10 +7072,9 @@ alist_slash_adjust()
|
||||
/*
|
||||
* ":preserve".
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ex_preserve(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
curbuf->b_flags |= BF_PRESERVED;
|
||||
ml_preserve(curbuf, TRUE);
|
||||
@@ -7245,10 +7306,9 @@ ex_tabmove(eap)
|
||||
/*
|
||||
* :tabs command: List tabs and their contents.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ex_tabs(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
tabpage_T *tp;
|
||||
win_T *wp;
|
||||
@@ -7435,7 +7495,6 @@ ex_edit(eap)
|
||||
/*
|
||||
* ":edit <file>" command and alikes.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
do_exedit(eap, old_curwin)
|
||||
exarg_T *eap;
|
||||
@@ -7648,10 +7707,9 @@ ex_popup(eap)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ex_swapname(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
if (curbuf->b_ml.ml_mfp == NULL || curbuf->b_ml.ml_mfp->mf_fname == NULL)
|
||||
MSG(_("No swap file"));
|
||||
@@ -7664,10 +7722,9 @@ ex_swapname(eap)
|
||||
* offset.
|
||||
* (1998-11-02 16:21:01 R. Edward Ralston <eralston@computer.org>)
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ex_syncbind(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
#ifdef FEAT_SCROLLBIND
|
||||
win_T *wp;
|
||||
@@ -7808,10 +7865,10 @@ ex_read(eap)
|
||||
if (*ml_get(lnum) == NUL && u_savedel(lnum, 1L) == OK)
|
||||
{
|
||||
ml_delete(lnum, FALSE);
|
||||
deleted_lines_mark(lnum, 1L);
|
||||
if (curwin->w_cursor.lnum > 1
|
||||
&& curwin->w_cursor.lnum >= lnum)
|
||||
--curwin->w_cursor.lnum;
|
||||
deleted_lines_mark(lnum, 1L);
|
||||
}
|
||||
}
|
||||
redraw_curbuf_later(VALID);
|
||||
@@ -7827,6 +7884,9 @@ free_cd_dir()
|
||||
{
|
||||
vim_free(prev_dir);
|
||||
prev_dir = NULL;
|
||||
|
||||
vim_free(globaldir);
|
||||
globaldir = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -7849,6 +7909,10 @@ ex_cd(eap)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (allbuf_locked())
|
||||
return;
|
||||
#endif
|
||||
if (vim_strchr(p_cpo, CPO_CHDIR) != NULL && curbufIsChanged()
|
||||
&& !eap->forceit)
|
||||
{
|
||||
@@ -7920,7 +7984,7 @@ ex_cd(eap)
|
||||
shorten_fnames(TRUE);
|
||||
|
||||
/* Echo the new current directory if the command was typed. */
|
||||
if (KeyTyped)
|
||||
if (KeyTyped || p_verbose >= 5)
|
||||
ex_pwd(eap);
|
||||
}
|
||||
vim_free(tofree);
|
||||
@@ -7930,10 +7994,9 @@ ex_cd(eap)
|
||||
/*
|
||||
* ":pwd".
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ex_pwd(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
if (mch_dirname(NameBuff, MAXPATHL) == OK)
|
||||
{
|
||||
@@ -8364,10 +8427,9 @@ ex_bang(eap)
|
||||
/*
|
||||
* ":undo".
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ex_undo(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
if (eap->addr_count == 1) /* :undo 123 */
|
||||
undo_time(eap->line2, FALSE, TRUE);
|
||||
@@ -8378,10 +8440,9 @@ ex_undo(eap)
|
||||
/*
|
||||
* ":redo".
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ex_redo(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
u_redo(1);
|
||||
}
|
||||
@@ -8389,7 +8450,6 @@ ex_redo(eap)
|
||||
/*
|
||||
* ":earlier" and ":later".
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ex_later(eap)
|
||||
exarg_T *eap;
|
||||
@@ -8574,10 +8634,9 @@ ex_redraw(eap)
|
||||
/*
|
||||
* ":redrawstatus": force redraw of status line(s)
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ex_redrawstatus(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
#if defined(FEAT_WINDOWS)
|
||||
int r = RedrawingDisabled;
|
||||
@@ -8654,6 +8713,8 @@ ex_mkrc(eap)
|
||||
}
|
||||
|
||||
#ifdef FEAT_SESSION
|
||||
/* Use the short file name until ":lcd" is used. We also don't use the
|
||||
* short file name when 'acd' is set, that is checked later. */
|
||||
did_lcd = FALSE;
|
||||
|
||||
/* ":mkview" or ":mkview 9": generate file name with 'viewdir' */
|
||||
@@ -8773,7 +8834,7 @@ ex_mkrc(eap)
|
||||
else if (*dirnow != NUL
|
||||
&& (ssop_flags & SSOP_CURDIR) && globaldir != NULL)
|
||||
{
|
||||
if (mch_chdir((char *)globaldir) == OK)
|
||||
if (mch_chdir((char *)globaldir) == 0)
|
||||
shorten_fnames(TRUE);
|
||||
}
|
||||
|
||||
@@ -8838,11 +8899,10 @@ theend:
|
||||
|
||||
#if ((defined(FEAT_SESSION) || defined(FEAT_EVAL)) && defined(vim_mkdir)) \
|
||||
|| defined(PROTO)
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
vim_mkdir_emsg(name, prot)
|
||||
char_u *name;
|
||||
int prot;
|
||||
int prot UNUSED;
|
||||
{
|
||||
if (vim_mkdir(name, prot) != 0)
|
||||
{
|
||||
@@ -9113,10 +9173,9 @@ ex_startinsert(eap)
|
||||
/*
|
||||
* ":stopinsert"
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ex_stopinsert(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
restart_edit = 0;
|
||||
stop_insert_mode = TRUE;
|
||||
@@ -9390,9 +9449,8 @@ find_cmdline_var(src, usedlen)
|
||||
# define SPEC_CLIENT 9
|
||||
#endif
|
||||
};
|
||||
#define SPEC_COUNT (sizeof(spec_str) / sizeof(char *))
|
||||
|
||||
for (i = 0; i < SPEC_COUNT; ++i)
|
||||
for (i = 0; i < (int)(sizeof(spec_str) / sizeof(char *)); ++i)
|
||||
{
|
||||
len = (int)STRLEN(spec_str[i]);
|
||||
if (STRNCMP(src, spec_str[i], len) == 0)
|
||||
@@ -9743,7 +9801,7 @@ arg_all()
|
||||
}
|
||||
|
||||
/* allocate memory */
|
||||
retval = alloc(len + 1);
|
||||
retval = alloc((unsigned)len + 1);
|
||||
if (retval == NULL)
|
||||
break;
|
||||
}
|
||||
@@ -10552,6 +10610,9 @@ ses_fname(fd, buf, flagp)
|
||||
if (buf->b_sfname != NULL
|
||||
&& flagp == &ssop_flags
|
||||
&& (ssop_flags & (SSOP_CURDIR | SSOP_SESDIR))
|
||||
#ifdef FEAT_AUTOCHDIR
|
||||
&& !p_acd
|
||||
#endif
|
||||
&& !did_lcd)
|
||||
name = buf->b_sfname;
|
||||
else
|
||||
@@ -10918,10 +10979,9 @@ ex_setfiletype(eap)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ex_digraphs(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
#ifdef FEAT_DIGRAPHS
|
||||
if (*eap->arg != NUL)
|
||||
@@ -10955,10 +11015,9 @@ ex_set(eap)
|
||||
/*
|
||||
* ":nohlsearch"
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ex_nohlsearch(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
no_hlsearch = TRUE;
|
||||
redraw_all_later(SOME_VALID);
|
||||
@@ -11037,10 +11096,9 @@ ex_match(eap)
|
||||
/*
|
||||
* ":X": Get crypt key
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ex_X(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
(void)get_crypt_key(TRUE, TRUE);
|
||||
}
|
||||
|
||||
+7
-2
@@ -60,7 +60,9 @@ static char_u *get_end_emsg __ARGS((struct condstack *cstack));
|
||||
#else
|
||||
/* Values used for the Vim release. */
|
||||
# define THROW_ON_ERROR TRUE
|
||||
# define THROW_ON_ERROR_TRUE
|
||||
# define THROW_ON_INTERRUPT TRUE
|
||||
# define THROW_ON_INTERRUPT_TRUE
|
||||
#endif
|
||||
|
||||
static void catch_exception __ARGS((except_T *excp));
|
||||
@@ -1320,16 +1322,20 @@ do_throw(cstack)
|
||||
* and reset the did_emsg or got_int flag, so this won't happen again at
|
||||
* the next surrounding try conditional.
|
||||
*/
|
||||
#ifndef THROW_ON_ERROR_TRUE
|
||||
if (did_emsg && !THROW_ON_ERROR)
|
||||
{
|
||||
inactivate_try = TRUE;
|
||||
did_emsg = FALSE;
|
||||
}
|
||||
#endif
|
||||
#ifndef THROW_ON_INTERRUPT_TRUE
|
||||
if (got_int && !THROW_ON_INTERRUPT)
|
||||
{
|
||||
inactivate_try = TRUE;
|
||||
got_int = FALSE;
|
||||
}
|
||||
#endif
|
||||
idx = cleanup_conditionals(cstack, 0, inactivate_try);
|
||||
if (idx >= 0)
|
||||
{
|
||||
@@ -2254,10 +2260,9 @@ rewind_conditionals(cstack, idx, cond_type, cond_level)
|
||||
/*
|
||||
* ":endfunction" when not after a ":function"
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ex_endfunction(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
EMSG(_("E193: :endfunction not inside a function"));
|
||||
}
|
||||
|
||||
+48
-27
@@ -93,7 +93,7 @@ static void draw_cmdline __ARGS((int start, int len));
|
||||
static void save_cmdline __ARGS((struct cmdline_info *ccp));
|
||||
static void restore_cmdline __ARGS((struct cmdline_info *ccp));
|
||||
static int cmdline_paste __ARGS((int regname, int literally, int remcr));
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
#if defined(FEAT_XIM) && (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM))
|
||||
static void redrawcmd_preedit __ARGS((void));
|
||||
#endif
|
||||
#ifdef FEAT_WILDMENU
|
||||
@@ -140,11 +140,10 @@ static int ex_window __ARGS((void));
|
||||
* Return pointer to allocated string if there is a commandline, NULL
|
||||
* otherwise.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
getcmdline(firstc, count, indent)
|
||||
int firstc;
|
||||
long count; /* only used for incremental search */
|
||||
long count UNUSED; /* only used for incremental search */
|
||||
int indent; /* indent for inside conditionals */
|
||||
{
|
||||
int c;
|
||||
@@ -325,7 +324,7 @@ getcmdline(firstc, count, indent)
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_DIGRAPHS
|
||||
do_digraph(-1); /* init digraph typahead */
|
||||
do_digraph(-1); /* init digraph typeahead */
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -2000,8 +1999,8 @@ text_locked_msg()
|
||||
|
||||
#if defined(FEAT_AUTOCMD) || defined(PROTO)
|
||||
/*
|
||||
* Check if "curbuf_lock" is set and return TRUE when it is and give an error
|
||||
* message.
|
||||
* Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is
|
||||
* and give an error message.
|
||||
*/
|
||||
int
|
||||
curbuf_locked()
|
||||
@@ -2011,6 +2010,21 @@ curbuf_locked()
|
||||
EMSG(_("E788: Not allowed to edit another buffer now"));
|
||||
return TRUE;
|
||||
}
|
||||
return allbuf_locked();
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if "allbuf_lock" is set and return TRUE when it is and give an error
|
||||
* message.
|
||||
*/
|
||||
int
|
||||
allbuf_locked()
|
||||
{
|
||||
if (allbuf_lock > 0)
|
||||
{
|
||||
EMSG(_("E811: Not allowed to change buffer information now"));
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
@@ -2098,11 +2112,10 @@ correct_cmdspos(idx, cells)
|
||||
/*
|
||||
* Get an Ex command line for the ":" command.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
char_u *
|
||||
getexline(c, dummy, indent)
|
||||
getexline(c, cookie, indent)
|
||||
int c; /* normally ':', NUL for ":append" */
|
||||
void *dummy; /* cookie not used */
|
||||
void *cookie UNUSED;
|
||||
int indent; /* indent for inside conditionals */
|
||||
{
|
||||
/* When executing a register, remove ':' that's in front of each line. */
|
||||
@@ -2117,12 +2130,11 @@ getexline(c, dummy, indent)
|
||||
* mappings or abbreviations.
|
||||
* Returns a string in allocated memory or NULL.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
char_u *
|
||||
getexmodeline(promptc, dummy, indent)
|
||||
getexmodeline(promptc, cookie, indent)
|
||||
int promptc; /* normally ':', NUL for ":append" and '?' for
|
||||
:s prompt */
|
||||
void *dummy; /* cookie not used */
|
||||
void *cookie UNUSED;
|
||||
int indent; /* indent for inside conditionals */
|
||||
{
|
||||
garray_T line_ga;
|
||||
@@ -2378,7 +2390,8 @@ cmdline_at_end()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(FEAT_XIM) && (defined(FEAT_GUI_GTK))) || defined(PROTO)
|
||||
#if (defined(FEAT_XIM) && (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM))) \
|
||||
|| defined(PROTO)
|
||||
/*
|
||||
* Return the virtual column number at the current cursor position.
|
||||
* This is used by the IM code to obtain the start of the preedit string.
|
||||
@@ -2406,7 +2419,7 @@ cmdline_getvcol_cursor()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
#if defined(FEAT_XIM) && (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM))
|
||||
/*
|
||||
* If part of the command line is an IM preedit string, redraw it with
|
||||
* IM feedback attributes. The cursor position is restored after drawing.
|
||||
@@ -2415,7 +2428,9 @@ cmdline_getvcol_cursor()
|
||||
redrawcmd_preedit()
|
||||
{
|
||||
if ((State & CMDLINE)
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
&& xic != NULL
|
||||
# endif
|
||||
/* && im_get_status() doesn't work when using SCIM */
|
||||
&& !p_imdisable
|
||||
&& im_is_preediting())
|
||||
@@ -2476,7 +2491,7 @@ redrawcmd_preedit()
|
||||
msg_col = old_col;
|
||||
}
|
||||
}
|
||||
#endif /* FEAT_XIM && FEAT_GUI_GTK */
|
||||
#endif /* FEAT_XIM && (FEAT_GUI_GTK || FEAT_GUI_MACVIM) */
|
||||
|
||||
/*
|
||||
* Allocate a new command line buffer.
|
||||
@@ -3199,7 +3214,7 @@ cursorcmd()
|
||||
}
|
||||
|
||||
windgoto(msg_row, msg_col);
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
#if defined(FEAT_XIM) && (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM))
|
||||
redrawcmd_preedit();
|
||||
#endif
|
||||
#ifdef MCH_CURSOR_SHAPE
|
||||
@@ -3817,11 +3832,10 @@ tilde_replace(orig_pat, num_files, files)
|
||||
* Returns EXPAND_NOTHING when the character that triggered expansion should
|
||||
* be inserted like a normal character.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
showmatches(xp, wildmenu)
|
||||
expand_T *xp;
|
||||
int wildmenu;
|
||||
int wildmenu UNUSED;
|
||||
{
|
||||
#define L_SHOWFILE(m) (showtail ? sm_gettail(files_found[m]) : files_found[m])
|
||||
int num_files;
|
||||
@@ -4503,6 +4517,12 @@ ExpandFromContext(xp, pat, num_file, file, options)
|
||||
{EXPAND_EVENTS, get_event_name, TRUE},
|
||||
{EXPAND_AUGROUP, get_augroup_name, TRUE},
|
||||
#endif
|
||||
#ifdef FEAT_CSCOPE
|
||||
{EXPAND_CSCOPE, get_cscope_name, TRUE},
|
||||
#endif
|
||||
#ifdef FEAT_SIGNS
|
||||
{EXPAND_SIGN, get_sign_name, TRUE},
|
||||
#endif
|
||||
#if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
|
||||
&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
|
||||
{EXPAND_LANGUAGE, get_lang_arg, TRUE},
|
||||
@@ -4519,7 +4539,7 @@ ExpandFromContext(xp, pat, num_file, file, options)
|
||||
* right function to do the expansion.
|
||||
*/
|
||||
ret = FAIL;
|
||||
for (i = 0; i < sizeof(tab) / sizeof(struct expgen); ++i)
|
||||
for (i = 0; i < (int)(sizeof(tab) / sizeof(struct expgen)); ++i)
|
||||
if (xp->xp_context == tab[i].context)
|
||||
{
|
||||
if (tab[i].ic)
|
||||
@@ -4860,14 +4880,14 @@ ExpandUserList(xp, num_file, file)
|
||||
/* Loop over the items in the list. */
|
||||
for (li = retlist->lv_first; li != NULL; li = li->li_next)
|
||||
{
|
||||
if (li->li_tv.v_type != VAR_STRING)
|
||||
continue; /* Skip non-string items */
|
||||
if (li->li_tv.v_type != VAR_STRING || li->li_tv.vval.v_string == NULL)
|
||||
continue; /* Skip non-string items and empty strings */
|
||||
|
||||
if (ga_grow(&ga, 1) == FAIL)
|
||||
break;
|
||||
|
||||
((char_u **)ga.ga_data)[ga.ga_len] =
|
||||
vim_strsave(li->li_tv.vval.v_string);
|
||||
vim_strsave(li->li_tv.vval.v_string);
|
||||
++ga.ga_len;
|
||||
}
|
||||
list_unref(retlist);
|
||||
@@ -5671,7 +5691,7 @@ ex_history(eap)
|
||||
histype1 = get_histtype(arg);
|
||||
if (histype1 == -1)
|
||||
{
|
||||
if (STRICMP(arg, "all") == 0)
|
||||
if (STRNICMP(arg, "all", STRLEN(arg)) == 0)
|
||||
{
|
||||
histype1 = 0;
|
||||
histype2 = HIST_COUNT-1;
|
||||
@@ -6050,9 +6070,7 @@ ex_window()
|
||||
# endif
|
||||
return K_IGNORE;
|
||||
}
|
||||
cmdwin_type = ccline.cmdfirstc;
|
||||
if (cmdwin_type == NUL)
|
||||
cmdwin_type = '-';
|
||||
cmdwin_type = get_cmdline_type();
|
||||
|
||||
/* Create the command-line buffer empty. */
|
||||
(void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
|
||||
@@ -6060,6 +6078,9 @@ ex_window()
|
||||
set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
|
||||
set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
|
||||
curbuf->b_p_ma = TRUE;
|
||||
#ifdef FEAT_FOLDING
|
||||
curwin->w_p_fen = FALSE;
|
||||
#endif
|
||||
# ifdef FEAT_RIGHTLEFT
|
||||
curwin->w_p_rl = cmdmsg_rl;
|
||||
cmdmsg_rl = FALSE;
|
||||
@@ -6076,7 +6097,7 @@ ex_window()
|
||||
/* Showing the prompt may have set need_wait_return, reset it. */
|
||||
need_wait_return = FALSE;
|
||||
|
||||
histtype = hist_char2type(ccline.cmdfirstc);
|
||||
histtype = hist_char2type(cmdwin_type);
|
||||
if (histtype == HIST_CMD || histtype == HIST_DEBUG)
|
||||
{
|
||||
if (p_wc == TAB)
|
||||
|
||||
+8
-7
@@ -103,7 +103,8 @@ toF_Xor_X_(c)
|
||||
case F_HE:
|
||||
tempc = _HE;
|
||||
|
||||
if (p_ri && (curwin->w_cursor.col+1 < STRLEN(ml_get_curline())))
|
||||
if (p_ri && (curwin->w_cursor.col + 1
|
||||
< (colnr_T)STRLEN(ml_get_curline())))
|
||||
{
|
||||
inc_cursor();
|
||||
|
||||
@@ -344,7 +345,7 @@ put_curr_and_l_to_X(c)
|
||||
if (curwin->w_p_rl && p_ri)
|
||||
return;
|
||||
|
||||
if ( (curwin->w_cursor.col < STRLEN(ml_get_curline())))
|
||||
if ((curwin->w_cursor.col < (colnr_T)STRLEN(ml_get_curline())))
|
||||
{
|
||||
if ((p_ri && curwin->w_cursor.col) || !p_ri)
|
||||
{
|
||||
@@ -565,7 +566,7 @@ chg_c_to_X_or_X ()
|
||||
|
||||
tempc = gchar_cursor();
|
||||
|
||||
if (curwin->w_cursor.col+1 < STRLEN(ml_get_curline()))
|
||||
if (curwin->w_cursor.col + 1 < (colnr_T)STRLEN(ml_get_curline()))
|
||||
{
|
||||
inc_cursor();
|
||||
|
||||
@@ -594,8 +595,8 @@ chg_l_to_X_orX_ ()
|
||||
{
|
||||
int tempc;
|
||||
|
||||
if (!curwin->w_cursor.col &&
|
||||
(curwin->w_cursor.col+1 == STRLEN(ml_get_curline())))
|
||||
if (curwin->w_cursor.col != 0 &&
|
||||
(curwin->w_cursor.col + 1 == (colnr_T)STRLEN(ml_get_curline())))
|
||||
return;
|
||||
|
||||
if (!curwin->w_cursor.col && p_ri)
|
||||
@@ -663,8 +664,8 @@ chg_l_toXor_X ()
|
||||
{
|
||||
int tempc;
|
||||
|
||||
if (!curwin->w_cursor.col &&
|
||||
(curwin->w_cursor.col+1 == STRLEN(ml_get_curline())))
|
||||
if (curwin->w_cursor.col != 0 &&
|
||||
(curwin->w_cursor.col + 1 == (colnr_T)STRLEN(ml_get_curline())))
|
||||
return;
|
||||
|
||||
if (!curwin->w_cursor.col && p_ri)
|
||||
|
||||
+7
-3
@@ -666,10 +666,13 @@
|
||||
* Both are for Unix and VMS only.
|
||||
*/
|
||||
#ifndef FEAT_XIM
|
||||
# if defined(FEAT_GUI_MACVIM) && defined(FEAT_MBYTE)
|
||||
# define FEAT_XIM
|
||||
# endif
|
||||
/* #define FEAT_XIM */
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_MACVIM)
|
||||
# define USE_XIM 1 /* needed for GTK include files */
|
||||
#endif
|
||||
|
||||
@@ -1200,10 +1203,11 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The Netbeans features currently only work with Motif and GTK and Win32.
|
||||
* The Netbeans features currently only work with Motif, GTK, Win32 and MacVim.
|
||||
* It also requires +listcmds and +eval.
|
||||
*/
|
||||
#if ((!defined(FEAT_GUI_MOTIF) && !defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_W32)) \
|
||||
#if ((!defined(FEAT_GUI_MOTIF) && !defined(FEAT_GUI_GTK) \
|
||||
&& !defined(FEAT_GUI_W32) && !defined(FEAT_GUI_MACVIM)) \
|
||||
|| !defined(FEAT_LISTCMDS) || !defined(FEAT_EVAL)) \
|
||||
&& defined(FEAT_NETBEANS_INTG)
|
||||
# undef FEAT_NETBEANS_INTG
|
||||
|
||||
+364
-120
@@ -69,7 +69,7 @@ static int apply_autocmds_exarg __ARGS((event_T event, char_u *fname, char_u *fn
|
||||
static int au_find_group __ARGS((char_u *name));
|
||||
|
||||
# define AUGROUP_DEFAULT -1 /* default autocmd group */
|
||||
# define AUGROUP_ERROR -2 /* errornouse autocmd group */
|
||||
# define AUGROUP_ERROR -2 /* erroneous autocmd group */
|
||||
# define AUGROUP_ALL -3 /* all autocmd groups */
|
||||
#endif
|
||||
|
||||
@@ -121,6 +121,8 @@ struct bw_info
|
||||
char_u *bw_conv_buf; /* buffer for writing converted chars */
|
||||
int bw_conv_buflen; /* size of bw_conv_buf */
|
||||
int bw_conv_error; /* set for conversion error */
|
||||
linenr_T bw_conv_error_lnum; /* first line with error or zero */
|
||||
linenr_T bw_start_lnum; /* line number at start of buffer */
|
||||
# ifdef USE_ICONV
|
||||
iconv_t bw_iconv_fd; /* descriptor for iconv() or -1 */
|
||||
# endif
|
||||
@@ -132,7 +134,7 @@ static int buf_write_bytes __ARGS((struct bw_info *ip));
|
||||
#ifdef FEAT_MBYTE
|
||||
static linenr_T readfile_linenr __ARGS((linenr_T linecnt, char_u *p, char_u *endp));
|
||||
static int ucs2bytes __ARGS((unsigned c, char_u **pp, int flags));
|
||||
static int same_encoding __ARGS((char_u *a, char_u *b));
|
||||
static int need_conversion __ARGS((char_u *fenc));
|
||||
static int get_fio_flags __ARGS((char_u *ptr));
|
||||
static char_u *check_for_bom __ARGS((char_u *p, long size, int *lenp, int flags));
|
||||
static int make_bom __ARGS((char_u *buf, char_u *name));
|
||||
@@ -144,7 +146,9 @@ static int get_mac_fio_flags __ARGS((char_u *ptr));
|
||||
# endif
|
||||
#endif
|
||||
static int move_lines __ARGS((buf_T *frombuf, buf_T *tobuf));
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
static char *e_auchangedbuf = N_("E812: Autocommands changed buffer or buffer name");
|
||||
#endif
|
||||
|
||||
void
|
||||
filemess(buf, name, s, attr)
|
||||
@@ -295,6 +299,19 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
|
||||
int conv_restlen = 0; /* nr of bytes in conv_rest[] */
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
/* Remember the initial values of curbuf, curbuf->b_ffname and
|
||||
* curbuf->b_fname to detect whether they are altered as a result of
|
||||
* executing nasty autocommands. Also check if "fname" and "sfname"
|
||||
* point to one of these values. */
|
||||
buf_T *old_curbuf = curbuf;
|
||||
char_u *old_b_ffname = curbuf->b_ffname;
|
||||
char_u *old_b_fname = curbuf->b_fname;
|
||||
int using_b_ffname = (fname == curbuf->b_ffname)
|
||||
|| (sfname == curbuf->b_ffname);
|
||||
int using_b_fname = (fname == curbuf->b_fname)
|
||||
|| (sfname == curbuf->b_fname);
|
||||
#endif
|
||||
write_no_eol_lnum = 0; /* in case it was set by the previous read */
|
||||
|
||||
/*
|
||||
@@ -589,7 +606,21 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
|
||||
#ifdef FEAT_QUICKFIX
|
||||
if (!bt_dontwrite(curbuf))
|
||||
#endif
|
||||
{
|
||||
check_need_swap(newfile);
|
||||
#ifdef FEAT_AUTOCMD
|
||||
/* SwapExists autocommand may mess things up */
|
||||
if (curbuf != old_curbuf
|
||||
|| (using_b_ffname
|
||||
&& (old_b_ffname != curbuf->b_ffname))
|
||||
|| (using_b_fname
|
||||
&& (old_b_fname != curbuf->b_fname)))
|
||||
{
|
||||
EMSG(_(e_auchangedbuf));
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (dir_of_file_exists(fname))
|
||||
filemess(curbuf, sfname, (char_u *)_("[New File]"), 0);
|
||||
else
|
||||
@@ -668,9 +699,21 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
|
||||
#endif
|
||||
{
|
||||
check_need_swap(newfile);
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (!read_stdin && (curbuf != old_curbuf
|
||||
|| (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
|
||||
|| (using_b_fname && (old_b_fname != curbuf->b_fname))))
|
||||
{
|
||||
EMSG(_(e_auchangedbuf));
|
||||
if (!read_buffer)
|
||||
close(fd);
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
#ifdef UNIX
|
||||
/* Set swap file protection bits after creating it. */
|
||||
if (swap_mode > 0 && curbuf->b_ml.ml_mfp->mf_fname != NULL)
|
||||
if (swap_mode > 0 && curbuf->b_ml.ml_mfp != NULL
|
||||
&& curbuf->b_ml.ml_mfp->mf_fname != NULL)
|
||||
(void)mch_setperm(curbuf->b_ml.ml_mfp->mf_fname, (long)swap_mode);
|
||||
#endif
|
||||
}
|
||||
@@ -698,7 +741,6 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
|
||||
{
|
||||
int m = msg_scroll;
|
||||
int n = msg_scrolled;
|
||||
buf_T *old_curbuf = curbuf;
|
||||
|
||||
/*
|
||||
* The file must be closed again, the autocommands may want to change
|
||||
@@ -740,8 +782,13 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
|
||||
/*
|
||||
* Don't allow the autocommands to change the current buffer.
|
||||
* Try to re-open the file.
|
||||
*
|
||||
* Don't allow the autocommands to change the buffer name either
|
||||
* (cd for example) if it invalidates fname or sfname.
|
||||
*/
|
||||
if (!read_stdin && (curbuf != old_curbuf
|
||||
|| (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
|
||||
|| (using_b_fname && (old_b_fname != curbuf->b_fname))
|
||||
|| (fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) < 0))
|
||||
{
|
||||
--no_wait_return;
|
||||
@@ -996,13 +1043,12 @@ retry:
|
||||
}
|
||||
|
||||
/*
|
||||
* Conversion is required when the encoding of the file is different
|
||||
* from 'encoding' or 'encoding' is UTF-16, UCS-2 or UCS-4 (requires
|
||||
* conversion to UTF-8).
|
||||
* Conversion may be required when the encoding of the file is different
|
||||
* from 'encoding' or 'encoding' is UTF-16, UCS-2 or UCS-4.
|
||||
*/
|
||||
fio_flags = 0;
|
||||
converted = (*fenc != NUL && !same_encoding(p_enc, fenc));
|
||||
if (converted || enc_unicode != 0)
|
||||
converted = need_conversion(fenc);
|
||||
if (converted)
|
||||
{
|
||||
|
||||
/* "ucs-bom" means we need to check the first bytes of the file
|
||||
@@ -2879,6 +2925,7 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit,
|
||||
linenr_T lnum;
|
||||
long nchars;
|
||||
char_u *errmsg = NULL;
|
||||
int errmsg_allocated = FALSE;
|
||||
char_u *errnum = NULL;
|
||||
char_u *buffer;
|
||||
char_u smallbuf[SMBUFSIZE];
|
||||
@@ -2942,6 +2989,7 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit,
|
||||
/* must init bw_conv_buf and bw_iconv_fd before jumping to "fail" */
|
||||
write_info.bw_conv_buf = NULL;
|
||||
write_info.bw_conv_error = FALSE;
|
||||
write_info.bw_conv_error_lnum = 0;
|
||||
write_info.bw_restlen = 0;
|
||||
# ifdef USE_ICONV
|
||||
write_info.bw_iconv_fd = (iconv_t)-1;
|
||||
@@ -3454,7 +3502,7 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit,
|
||||
if (mch_stat((char *)IObuff, &st) < 0
|
||||
|| st.st_uid != st_old.st_uid
|
||||
|| st.st_gid != st_old.st_gid
|
||||
|| st.st_mode != perm)
|
||||
|| (long)st.st_mode != perm)
|
||||
backup_copy = TRUE;
|
||||
# endif
|
||||
/* Close the file before removing it, on MS-Windows we
|
||||
@@ -3920,10 +3968,9 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit,
|
||||
fenc = buf->b_p_fenc;
|
||||
|
||||
/*
|
||||
* The file needs to be converted when 'fileencoding' is set and
|
||||
* 'fileencoding' differs from 'encoding'.
|
||||
* Check if the file needs to be converted.
|
||||
*/
|
||||
converted = (*fenc != NUL && !same_encoding(p_enc, fenc));
|
||||
converted = need_conversion(fenc);
|
||||
|
||||
/*
|
||||
* Check if UTF-8 to UCS-2/4 or Latin1 conversion needs to be done. Or
|
||||
@@ -4198,6 +4245,7 @@ restore_backup:
|
||||
nchars += write_info.bw_len;
|
||||
}
|
||||
}
|
||||
write_info.bw_start_lnum = start;
|
||||
#endif
|
||||
|
||||
write_info.bw_len = bufsize;
|
||||
@@ -4233,6 +4281,9 @@ restore_backup:
|
||||
nchars += bufsize;
|
||||
s = buffer;
|
||||
len = 0;
|
||||
#ifdef FEAT_MBYTE
|
||||
write_info.bw_start_lnum = lnum;
|
||||
#endif
|
||||
}
|
||||
/* write failed or last line has no EOL: stop here */
|
||||
if (end == 0
|
||||
@@ -4372,7 +4423,7 @@ restore_backup:
|
||||
# endif
|
||||
buf_setino(buf);
|
||||
}
|
||||
else if (buf->b_dev < 0)
|
||||
else if (!buf->b_dev_valid)
|
||||
/* Set the inode when creating a new file. */
|
||||
buf_setino(buf);
|
||||
#endif
|
||||
@@ -4429,7 +4480,17 @@ restore_backup:
|
||||
{
|
||||
#ifdef FEAT_MBYTE
|
||||
if (write_info.bw_conv_error)
|
||||
errmsg = (char_u *)_("E513: write error, conversion failed (make 'fenc' empty to override)");
|
||||
{
|
||||
if (write_info.bw_conv_error_lnum == 0)
|
||||
errmsg = (char_u *)_("E513: write error, conversion failed (make 'fenc' empty to override)");
|
||||
else
|
||||
{
|
||||
errmsg_allocated = TRUE;
|
||||
errmsg = alloc(300);
|
||||
vim_snprintf((char *)errmsg, 300, _("E513: write error, conversion failed in line %ld (make 'fenc' empty to override)"),
|
||||
(long)write_info.bw_conv_error_lnum);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (got_int)
|
||||
@@ -4505,6 +4566,12 @@ restore_backup:
|
||||
{
|
||||
STRCAT(IObuff, _(" CONVERSION ERROR"));
|
||||
c = TRUE;
|
||||
if (write_info.bw_conv_error_lnum != 0)
|
||||
{
|
||||
int l = STRLEN(IObuff);
|
||||
vim_snprintf((char *)IObuff + l, IOSIZE - l, _(" in line %ld;"),
|
||||
(long)write_info.bw_conv_error_lnum);
|
||||
}
|
||||
}
|
||||
else if (notconverted)
|
||||
{
|
||||
@@ -4701,6 +4768,8 @@ nofail:
|
||||
}
|
||||
STRCAT(IObuff, errmsg);
|
||||
emsg(IObuff);
|
||||
if (errmsg_allocated)
|
||||
vim_free(errmsg);
|
||||
|
||||
retval = FAIL;
|
||||
if (end == 0)
|
||||
@@ -4784,6 +4853,8 @@ set_rw_fname(fname, sfname)
|
||||
char_u *sfname;
|
||||
{
|
||||
#ifdef FEAT_AUTOCMD
|
||||
buf_T *buf = curbuf;
|
||||
|
||||
/* It's like the unnamed buffer is deleted.... */
|
||||
if (curbuf->b_p_bl)
|
||||
apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf);
|
||||
@@ -4792,6 +4863,12 @@ set_rw_fname(fname, sfname)
|
||||
if (aborting()) /* autocmds may abort script processing */
|
||||
return FAIL;
|
||||
# endif
|
||||
if (curbuf != buf)
|
||||
{
|
||||
/* We are in another buffer now, don't do the renaming. */
|
||||
EMSG(_(e_auchangedbuf));
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (setfname(curbuf, fname, sfname, FALSE) == OK)
|
||||
@@ -5056,7 +5133,13 @@ buf_write_bytes(ip)
|
||||
c = buf[wlen];
|
||||
}
|
||||
|
||||
ip->bw_conv_error |= ucs2bytes(c, &p, flags);
|
||||
if (ucs2bytes(c, &p, flags) && !ip->bw_conv_error)
|
||||
{
|
||||
ip->bw_conv_error = TRUE;
|
||||
ip->bw_conv_error_lnum = ip->bw_start_lnum;
|
||||
}
|
||||
if (c == NL)
|
||||
++ip->bw_start_lnum;
|
||||
}
|
||||
if (flags & FIO_LATIN1)
|
||||
len = (int)(p - buf);
|
||||
@@ -5248,13 +5331,16 @@ buf_write_bytes(ip)
|
||||
/* Convert with iconv(). */
|
||||
if (ip->bw_restlen > 0)
|
||||
{
|
||||
char *fp;
|
||||
|
||||
/* Need to concatenate the remainder of the previous call and
|
||||
* the bytes of the current call. Use the end of the
|
||||
* conversion buffer for this. */
|
||||
fromlen = len + ip->bw_restlen;
|
||||
from = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
|
||||
mch_memmove((void *)from, ip->bw_rest, (size_t)ip->bw_restlen);
|
||||
mch_memmove((void *)(from + ip->bw_restlen), buf, (size_t)len);
|
||||
fp = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
|
||||
mch_memmove(fp, ip->bw_rest, (size_t)ip->bw_restlen);
|
||||
mch_memmove(fp + ip->bw_restlen, buf, (size_t)len);
|
||||
from = fp;
|
||||
tolen = ip->bw_conv_buflen - fromlen;
|
||||
}
|
||||
else
|
||||
@@ -5334,6 +5420,7 @@ buf_write_bytes(ip)
|
||||
#ifdef FEAT_MBYTE
|
||||
/*
|
||||
* Convert a Unicode character to bytes.
|
||||
* Return TRUE for an error, FALSE when it's OK.
|
||||
*/
|
||||
static int
|
||||
ucs2bytes(c, pp, flags)
|
||||
@@ -5417,20 +5504,37 @@ ucs2bytes(c, pp, flags)
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if "a" and "b" are the same 'encoding'.
|
||||
* Ignores difference between "ansi" and "latin1", "ucs-4" and "ucs-4be", etc.
|
||||
* Return TRUE if file encoding "fenc" requires conversion from or to
|
||||
* 'encoding'.
|
||||
*/
|
||||
static int
|
||||
same_encoding(a, b)
|
||||
char_u *a;
|
||||
char_u *b;
|
||||
need_conversion(fenc)
|
||||
char_u *fenc;
|
||||
{
|
||||
int f;
|
||||
int same_encoding;
|
||||
int enc_flags;
|
||||
int fenc_flags;
|
||||
|
||||
if (STRCMP(a, b) == 0)
|
||||
return TRUE;
|
||||
f = get_fio_flags(a);
|
||||
return (f != 0 && get_fio_flags(b) == f);
|
||||
if (*fenc == NUL || STRCMP(p_enc, fenc) == 0)
|
||||
same_encoding = TRUE;
|
||||
else
|
||||
{
|
||||
/* Ignore difference between "ansi" and "latin1", "ucs-4" and
|
||||
* "ucs-4be", etc. */
|
||||
enc_flags = get_fio_flags(p_enc);
|
||||
fenc_flags = get_fio_flags(fenc);
|
||||
same_encoding = (enc_flags != 0 && fenc_flags == enc_flags);
|
||||
}
|
||||
if (same_encoding)
|
||||
{
|
||||
/* Specified encoding matches with 'encoding'. This requires
|
||||
* conversion when 'encoding' is Unicode but not UTF-8. */
|
||||
return enc_unicode != 0;
|
||||
}
|
||||
|
||||
/* Encodings differ. However, conversion is not needed when 'enc' is any
|
||||
* Unicode encoding and the file is UTF-8. */
|
||||
return !(enc_utf8 && fenc_flags == FIO_UTF8);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5921,7 +6025,7 @@ buf_modname(shortname, fname, ext, prepend_dot)
|
||||
else if (*ext == '.')
|
||||
#endif
|
||||
{
|
||||
if (s - ptr > (size_t)8)
|
||||
if ((size_t)(s - ptr) > (size_t)8)
|
||||
{
|
||||
s = ptr + 8;
|
||||
*s = '\0';
|
||||
@@ -6111,12 +6215,24 @@ vim_rename(from, to)
|
||||
#ifdef HAVE_ACL
|
||||
vim_acl_T acl; /* ACL from original file */
|
||||
#endif
|
||||
#if defined(UNIX) || defined(CASE_INSENSITIVE_FILENAME)
|
||||
int use_tmp_file = FALSE;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When the names are identical, there is nothing to do.
|
||||
* When the names are identical, there is nothing to do. When they refer
|
||||
* to the same file (ignoring case and slash/backslash differences) but
|
||||
* the file name differs we need to go through a temp file.
|
||||
*/
|
||||
if (fnamecmp(from, to) == 0)
|
||||
return 0;
|
||||
{
|
||||
#ifdef CASE_INSENSITIVE_FILENAME
|
||||
if (STRCMP(gettail(from), gettail(to)) != 0)
|
||||
use_tmp_file = TRUE;
|
||||
else
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fail if the "from" file doesn't exist. Avoids that "to" is deleted.
|
||||
@@ -6124,6 +6240,55 @@ vim_rename(from, to)
|
||||
if (mch_stat((char *)from, &st) < 0)
|
||||
return -1;
|
||||
|
||||
#ifdef UNIX
|
||||
{
|
||||
struct stat st_to;
|
||||
|
||||
/* It's possible for the source and destination to be the same file.
|
||||
* This happens when "from" and "to" differ in case and are on a FAT32
|
||||
* filesystem. In that case go through a temp file name. */
|
||||
if (mch_stat((char *)to, &st_to) >= 0
|
||||
&& st.st_dev == st_to.st_dev
|
||||
&& st.st_ino == st_to.st_ino)
|
||||
use_tmp_file = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(UNIX) || defined(CASE_INSENSITIVE_FILENAME)
|
||||
if (use_tmp_file)
|
||||
{
|
||||
char tempname[MAXPATHL + 1];
|
||||
|
||||
/*
|
||||
* Find a name that doesn't exist and is in the same directory.
|
||||
* Rename "from" to "tempname" and then rename "tempname" to "to".
|
||||
*/
|
||||
if (STRLEN(from) >= MAXPATHL - 5)
|
||||
return -1;
|
||||
STRCPY(tempname, from);
|
||||
for (n = 123; n < 99999; ++n)
|
||||
{
|
||||
sprintf((char *)gettail((char_u *)tempname), "%d", n);
|
||||
if (mch_stat(tempname, &st) < 0)
|
||||
{
|
||||
if (mch_rename((char *)from, tempname) == 0)
|
||||
{
|
||||
if (mch_rename(tempname, (char *)to) == 0)
|
||||
return 0;
|
||||
/* Strange, the second step failed. Try moving the
|
||||
* file back and return failure. */
|
||||
mch_rename(tempname, (char *)from);
|
||||
return -1;
|
||||
}
|
||||
/* If it fails for one temp name it will most likely fail
|
||||
* for any temp name, give up. */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Delete the "to" file, this is required on some systems to make the
|
||||
* mch_rename() work, on other systems it makes sure that we don't have
|
||||
@@ -6267,7 +6432,7 @@ check_timestamps(focus)
|
||||
|
||||
if (!stuff_empty() || global_busy || !typebuf_typed()
|
||||
#ifdef FEAT_AUTOCMD
|
||||
|| autocmd_busy || curbuf_lock > 0
|
||||
|| autocmd_busy || curbuf_lock > 0 || allbuf_lock > 0
|
||||
#endif
|
||||
)
|
||||
need_check_timestamps = TRUE; /* check later */
|
||||
@@ -6366,11 +6531,10 @@ move_lines(frombuf, tobuf)
|
||||
* return 2 if a message has been displayed.
|
||||
* return 0 otherwise.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
buf_check_timestamp(buf, focus)
|
||||
buf_T *buf;
|
||||
int focus; /* called for GUI focus event */
|
||||
int focus UNUSED; /* called for GUI focus event */
|
||||
{
|
||||
struct stat st;
|
||||
int stat_res;
|
||||
@@ -6475,8 +6639,10 @@ buf_check_timestamp(buf, focus)
|
||||
set_vim_var_string(VV_FCS_REASON, (char_u *)reason, -1);
|
||||
set_vim_var_string(VV_FCS_CHOICE, (char_u *)"", -1);
|
||||
# endif
|
||||
++allbuf_lock;
|
||||
n = apply_autocmds(EVENT_FILECHANGEDSHELL,
|
||||
buf->b_fname, buf->b_fname, FALSE, buf);
|
||||
--allbuf_lock;
|
||||
busy = FALSE;
|
||||
if (n)
|
||||
{
|
||||
@@ -6524,7 +6690,10 @@ buf_check_timestamp(buf, focus)
|
||||
mesg = _("W16: Warning: Mode of file \"%s\" has changed since editing started");
|
||||
mesg2 = _("See \":help W16\" for more info.");
|
||||
}
|
||||
/* Else: only timestamp changed, ignored */
|
||||
else
|
||||
/* Only timestamp changed, store it to avoid a warning
|
||||
* in check_mtime() later. */
|
||||
buf->b_mtime_read = buf->b_mtime;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6551,6 +6720,11 @@ buf_check_timestamp(buf, focus)
|
||||
tbuf = alloc((unsigned)(STRLEN(path) + STRLEN(mesg)
|
||||
+ STRLEN(mesg2) + 2));
|
||||
sprintf((char *)tbuf, mesg, path);
|
||||
#ifdef FEAT_EVAL
|
||||
/* Set warningmsg here, before the unimportant and output-specific
|
||||
* mesg2 has been appended. */
|
||||
set_vim_var_string(VV_WARNINGMSG, tbuf, -1);
|
||||
#endif
|
||||
#if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
|
||||
if (can_reload)
|
||||
{
|
||||
@@ -6769,10 +6943,11 @@ buf_reload(buf, orig_mode)
|
||||
#endif
|
||||
#ifdef FEAT_FOLDING
|
||||
{
|
||||
win_T *wp;
|
||||
win_T *wp;
|
||||
tabpage_T *tp;
|
||||
|
||||
/* Update folds unless they are defined manually. */
|
||||
FOR_ALL_WINDOWS(wp)
|
||||
FOR_ALL_TAB_WINDOWS(tp, wp)
|
||||
if (wp->w_buffer == curwin->w_buffer
|
||||
&& !foldmethodIsManual(wp))
|
||||
foldUpdateAll(wp);
|
||||
@@ -6790,12 +6965,11 @@ buf_reload(buf, orig_mode)
|
||||
/* Careful: autocommands may have made "buf" invalid! */
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
buf_store_time(buf, st, fname)
|
||||
buf_T *buf;
|
||||
struct stat *st;
|
||||
char_u *fname;
|
||||
char_u *fname UNUSED;
|
||||
{
|
||||
buf->b_mtime = (long)st->st_mtime;
|
||||
buf->b_orig_size = (size_t)st->st_size;
|
||||
@@ -6858,10 +7032,9 @@ vim_deltempdir()
|
||||
* The returned pointer is to allocated memory.
|
||||
* The returned pointer is NULL if no valid name was found.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
vim_tempname(extra_char)
|
||||
int extra_char; /* character to use in the name instead of '?' */
|
||||
int extra_char UNUSED; /* char to use in the name instead of '?' */
|
||||
{
|
||||
#ifdef USE_TMPNAM
|
||||
char_u itmp[L_tmpnam]; /* use tmpnam() */
|
||||
@@ -6890,7 +7063,7 @@ vim_tempname(extra_char)
|
||||
/*
|
||||
* Try the entries in TEMPDIRNAMES to create the temp directory.
|
||||
*/
|
||||
for (i = 0; i < sizeof(tempdirs) / sizeof(char *); ++i)
|
||||
for (i = 0; i < (int)(sizeof(tempdirs) / sizeof(char *)); ++i)
|
||||
{
|
||||
/* expand $TMP, leave room for "/v1100000/999999999" */
|
||||
expand_env((char_u *)tempdirs[i], itmp, TEMPNAMELEN - 20);
|
||||
@@ -8282,7 +8455,7 @@ ex_doautoall(eap)
|
||||
|
||||
/* Execute the modeline settings, but don't set window-local
|
||||
* options if we are using the current window for another buffer. */
|
||||
do_modelines(aco.save_curwin == NULL ? OPT_NOWIN : 0);
|
||||
do_modelines(curwin == aucmd_win ? OPT_NOWIN : 0);
|
||||
|
||||
/* restore the current window */
|
||||
aucmd_restbuf(&aco);
|
||||
@@ -8298,8 +8471,8 @@ ex_doautoall(eap)
|
||||
|
||||
/*
|
||||
* Prepare for executing autocommands for (hidden) buffer "buf".
|
||||
* Search a window for the current buffer. Save the cursor position and
|
||||
* screen offset.
|
||||
* Search for a visible window containing the current buffer. If there isn't
|
||||
* one then use "aucmd_win".
|
||||
* Set "curbuf" and "curwin" to match "buf".
|
||||
* When FEAT_AUTOCMD is not defined another version is used, see below.
|
||||
*/
|
||||
@@ -8309,8 +8482,9 @@ aucmd_prepbuf(aco, buf)
|
||||
buf_T *buf; /* new curbuf */
|
||||
{
|
||||
win_T *win;
|
||||
|
||||
aco->new_curbuf = buf;
|
||||
#ifdef FEAT_WINDOWS
|
||||
int save_ea;
|
||||
#endif
|
||||
|
||||
/* Find a window that is for the new buffer */
|
||||
if (buf == curbuf) /* be quick when buf is curbuf */
|
||||
@@ -8324,42 +8498,67 @@ aucmd_prepbuf(aco, buf)
|
||||
win = NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prefer to use an existing window for the buffer, it has the least side
|
||||
* effects (esp. if "buf" is curbuf).
|
||||
* Otherwise, use curwin for "buf". It might make some items in the
|
||||
* window invalid. At least save the cursor and topline.
|
||||
*/
|
||||
/* Allocate "aucmd_win" when needed. If this fails (out of memory) fall
|
||||
* back to using the current window. */
|
||||
if (win == NULL && aucmd_win == NULL)
|
||||
{
|
||||
win_alloc_aucmd_win();
|
||||
if (aucmd_win == NULL)
|
||||
win = curwin;
|
||||
}
|
||||
if (win == NULL && aucmd_win_used)
|
||||
/* Strange recursive autocommand, fall back to using the current
|
||||
* window. Expect a few side effects... */
|
||||
win = curwin;
|
||||
|
||||
aco->save_curwin = curwin;
|
||||
aco->save_curbuf = curbuf;
|
||||
if (win != NULL)
|
||||
{
|
||||
/* there is a window for "buf", make it the curwin */
|
||||
aco->save_curwin = curwin;
|
||||
/* There is a window for "buf" in the current tab page, make it the
|
||||
* curwin. This is preferred, it has the least side effects (esp. if
|
||||
* "buf" is curbuf). */
|
||||
aco->use_aucmd_win = FALSE;
|
||||
curwin = win;
|
||||
aco->save_buf = win->w_buffer;
|
||||
aco->new_curwin = win;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* there is no window for "buf", use curwin */
|
||||
aco->save_curwin = NULL;
|
||||
aco->save_buf = curbuf;
|
||||
--curbuf->b_nwindows;
|
||||
curwin->w_buffer = buf;
|
||||
/* There is no window for "buf", use "aucmd_win". To minimize the side
|
||||
* effects, insert it in a the current tab page.
|
||||
* Anything related to a window (e.g., setting folds) may have
|
||||
* unexpected results. */
|
||||
aco->use_aucmd_win = TRUE;
|
||||
aucmd_win_used = TRUE;
|
||||
aucmd_win->w_buffer = buf;
|
||||
++buf->b_nwindows;
|
||||
win_init_empty(aucmd_win); /* set cursor and topline to safe values */
|
||||
vim_free(aucmd_win->w_localdir);
|
||||
aucmd_win->w_localdir = NULL;
|
||||
|
||||
/* save cursor and topline, set them to safe values */
|
||||
aco->save_cursor = curwin->w_cursor;
|
||||
curwin->w_cursor.lnum = 1;
|
||||
curwin->w_cursor.col = 0;
|
||||
aco->save_topline = curwin->w_topline;
|
||||
curwin->w_topline = 1;
|
||||
#ifdef FEAT_DIFF
|
||||
aco->save_topfill = curwin->w_topfill;
|
||||
curwin->w_topfill = 0;
|
||||
/* Make sure w_localdir and globaldir are NULL to avoid a chdir() in
|
||||
* win_enter_ext(). */
|
||||
aucmd_win->w_localdir = NULL;
|
||||
aco->globaldir = globaldir;
|
||||
globaldir = NULL;
|
||||
|
||||
|
||||
#ifdef FEAT_WINDOWS
|
||||
/* Split the current window, put the aucmd_win in the upper half.
|
||||
* We don't want the BufEnter or WinEnter autocommands. */
|
||||
block_autocmds();
|
||||
make_snapshot(SNAP_AUCMD_IDX);
|
||||
save_ea = p_ea;
|
||||
p_ea = FALSE;
|
||||
(void)win_split_ins(0, WSP_TOP, aucmd_win, 0);
|
||||
(void)win_comp_pos(); /* recompute window positions */
|
||||
p_ea = save_ea;
|
||||
unblock_autocmds();
|
||||
#endif
|
||||
curwin = aucmd_win;
|
||||
}
|
||||
|
||||
curbuf = buf;
|
||||
aco->new_curwin = curwin;
|
||||
aco->new_curbuf = curbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -8371,21 +8570,92 @@ aucmd_prepbuf(aco, buf)
|
||||
aucmd_restbuf(aco)
|
||||
aco_save_T *aco; /* structure holding saved values */
|
||||
{
|
||||
if (aco->save_curwin != NULL)
|
||||
#ifdef FEAT_WINDOWS
|
||||
int dummy;
|
||||
#endif
|
||||
|
||||
if (aco->use_aucmd_win)
|
||||
{
|
||||
--curbuf->b_nwindows;
|
||||
#ifdef FEAT_WINDOWS
|
||||
/* Find "aucmd_win", it can't be closed, but it may be in another tab
|
||||
* page. Do not trigger autocommands here. */
|
||||
block_autocmds();
|
||||
if (curwin != aucmd_win)
|
||||
{
|
||||
tabpage_T *tp;
|
||||
win_T *wp;
|
||||
|
||||
FOR_ALL_TAB_WINDOWS(tp, wp)
|
||||
{
|
||||
if (wp == aucmd_win)
|
||||
{
|
||||
if (tp != curtab)
|
||||
goto_tabpage_tp(tp);
|
||||
win_goto(aucmd_win);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove the window and frame from the tree of frames. */
|
||||
(void)winframe_remove(curwin, &dummy, NULL);
|
||||
win_remove(curwin, NULL);
|
||||
aucmd_win_used = FALSE;
|
||||
last_status(FALSE); /* may need to remove last status line */
|
||||
restore_snapshot(SNAP_AUCMD_IDX, FALSE);
|
||||
(void)win_comp_pos(); /* recompute window positions */
|
||||
unblock_autocmds();
|
||||
|
||||
if (win_valid(aco->save_curwin))
|
||||
curwin = aco->save_curwin;
|
||||
else
|
||||
/* Hmm, original window disappeared. Just use the first one. */
|
||||
curwin = firstwin;
|
||||
# ifdef FEAT_EVAL
|
||||
vars_clear(&aucmd_win->w_vars.dv_hashtab); /* free all w: variables */
|
||||
# endif
|
||||
#else
|
||||
curwin = aco->save_curwin;
|
||||
#endif
|
||||
curbuf = curwin->w_buffer;
|
||||
|
||||
vim_free(globaldir);
|
||||
globaldir = aco->globaldir;
|
||||
|
||||
/* the buffer contents may have changed */
|
||||
check_cursor();
|
||||
if (curwin->w_topline > curbuf->b_ml.ml_line_count)
|
||||
{
|
||||
curwin->w_topline = curbuf->b_ml.ml_line_count;
|
||||
#ifdef FEAT_DIFF
|
||||
curwin->w_topfill = 0;
|
||||
#endif
|
||||
}
|
||||
#if defined(FEAT_GUI)
|
||||
/* Hide the scrollbars from the aucmd_win and update. */
|
||||
gui_mch_enable_scrollbar(&aucmd_win->w_scrollbars[SBAR_LEFT], FALSE);
|
||||
gui_mch_enable_scrollbar(&aucmd_win->w_scrollbars[SBAR_RIGHT], FALSE);
|
||||
gui_may_update_scrollbars();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* restore curwin */
|
||||
#ifdef FEAT_WINDOWS
|
||||
if (win_valid(aco->save_curwin))
|
||||
#endif
|
||||
{
|
||||
/* restore the buffer which was previously edited by curwin, if
|
||||
* it's still the same window and it's valid */
|
||||
/* Restore the buffer which was previously edited by curwin, if
|
||||
* it was changed, we are still the same window and the buffer is
|
||||
* valid. */
|
||||
if (curwin == aco->new_curwin
|
||||
&& buf_valid(aco->save_buf)
|
||||
&& aco->save_buf->b_ml.ml_mfp != NULL)
|
||||
&& curbuf != aco->new_curbuf
|
||||
&& buf_valid(aco->new_curbuf)
|
||||
&& aco->new_curbuf->b_ml.ml_mfp != NULL)
|
||||
{
|
||||
--curbuf->b_nwindows;
|
||||
curbuf = aco->save_buf;
|
||||
curbuf = aco->new_curbuf;
|
||||
curwin->w_buffer = curbuf;
|
||||
++curbuf->b_nwindows;
|
||||
}
|
||||
@@ -8394,34 +8664,6 @@ aucmd_restbuf(aco)
|
||||
curbuf = curwin->w_buffer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* restore buffer for curwin if it still exists and is loaded */
|
||||
if (buf_valid(aco->save_buf) && aco->save_buf->b_ml.ml_mfp != NULL)
|
||||
{
|
||||
--curbuf->b_nwindows;
|
||||
curbuf = aco->save_buf;
|
||||
curwin->w_buffer = curbuf;
|
||||
++curbuf->b_nwindows;
|
||||
curwin->w_cursor = aco->save_cursor;
|
||||
check_cursor();
|
||||
/* check topline < line_count, in case lines got deleted */
|
||||
if (aco->save_topline <= curbuf->b_ml.ml_line_count)
|
||||
{
|
||||
curwin->w_topline = aco->save_topline;
|
||||
#ifdef FEAT_DIFF
|
||||
curwin->w_topfill = aco->save_topfill;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
curwin->w_topline = curbuf->b_ml.ml_line_count;
|
||||
#ifdef FEAT_DIFF
|
||||
curwin->w_topfill = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int autocmd_nested = FALSE;
|
||||
@@ -8707,9 +8949,11 @@ apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
|
||||
else
|
||||
{
|
||||
sfname = vim_strsave(fname);
|
||||
/* Don't try expanding FileType, Syntax, WindowID or QuickFixCmd* */
|
||||
/* Don't try expanding FileType, Syntax, FuncUndefined, WindowID or
|
||||
* QuickFixCmd* */
|
||||
if (event == EVENT_FILETYPE
|
||||
|| event == EVENT_SYNTAX
|
||||
|| event == EVENT_FUNCUNDEFINED
|
||||
|| event == EVENT_REMOTEREPLY
|
||||
|| event == EVENT_SPELLFILEMISSING
|
||||
|| event == EVENT_QUICKFIXCMDPRE
|
||||
@@ -9008,12 +9252,11 @@ auto_next_pat(apc, stop_at_last)
|
||||
* Called by do_cmdline() to get the next line for ":if".
|
||||
* Returns allocated string, or NULL for end of autocommands.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static char_u *
|
||||
getnextac(c, cookie, indent)
|
||||
int c; /* not used */
|
||||
int c UNUSED;
|
||||
void *cookie;
|
||||
int indent; /* not used */
|
||||
int indent UNUSED;
|
||||
{
|
||||
AutoPatCmd *acp = (AutoPatCmd *)cookie;
|
||||
char_u *retval;
|
||||
@@ -9124,10 +9367,9 @@ has_autocmd(event, sfname, buf)
|
||||
* Function given to ExpandGeneric() to obtain the list of autocommand group
|
||||
* names.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
get_augroup_name(xp, idx)
|
||||
expand_T *xp;
|
||||
expand_T *xp UNUSED;
|
||||
int idx;
|
||||
{
|
||||
if (idx == augroups.ga_len) /* add "END" add the end */
|
||||
@@ -9193,10 +9435,9 @@ set_context_in_autocmd(xp, arg, doautocmd)
|
||||
/*
|
||||
* Function given to ExpandGeneric() to obtain the list of event names.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
get_event_name(xp, idx)
|
||||
expand_T *xp;
|
||||
expand_T *xp UNUSED;
|
||||
int idx;
|
||||
{
|
||||
if (idx < augroups.ga_len) /* First list group names, if wanted */
|
||||
@@ -9337,9 +9578,11 @@ aucmd_prepbuf(aco, buf)
|
||||
aco_save_T *aco; /* structure to save values in */
|
||||
buf_T *buf; /* new curbuf */
|
||||
{
|
||||
aco->save_buf = curbuf;
|
||||
aco->save_curbuf = curbuf;
|
||||
--curbuf->b_nwindows;
|
||||
curbuf = buf;
|
||||
curwin->w_buffer = buf;
|
||||
++curbuf->b_nwindows;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -9350,8 +9593,10 @@ aucmd_prepbuf(aco, buf)
|
||||
aucmd_restbuf(aco)
|
||||
aco_save_T *aco; /* structure holding saved values */
|
||||
{
|
||||
curbuf = aco->save_buf;
|
||||
--curbuf->b_nwindows;
|
||||
curbuf = aco->save_curbuf;
|
||||
curwin->w_buffer = curbuf;
|
||||
++curbuf->b_nwindows;
|
||||
}
|
||||
|
||||
#endif /* FEAT_AUTOCMD */
|
||||
@@ -9508,13 +9753,12 @@ match_file_list(list, sfname, ffname)
|
||||
*
|
||||
* Returns NULL when out of memory.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
file_pat_to_reg_pat(pat, pat_end, allow_dirs, no_bslash)
|
||||
char_u *pat;
|
||||
char_u *pat_end; /* first char after pattern or NULL */
|
||||
char *allow_dirs; /* Result passed back out in here */
|
||||
int no_bslash; /* Don't use a backward slash as pathsep */
|
||||
int no_bslash UNUSED; /* Don't use a backward slash as pathsep */
|
||||
{
|
||||
int size;
|
||||
char_u *endp;
|
||||
|
||||
+12
-6
@@ -740,7 +740,7 @@ deleteFold(start, end, recursive, had_visual)
|
||||
garray_T *found_ga;
|
||||
fold_T *found_fp = NULL;
|
||||
linenr_T found_off = 0;
|
||||
int use_level = FALSE;
|
||||
int use_level;
|
||||
int maybe_small = FALSE;
|
||||
int level = 0;
|
||||
linenr_T lnum = start;
|
||||
@@ -757,6 +757,7 @@ deleteFold(start, end, recursive, had_visual)
|
||||
gap = &curwin->w_folds;
|
||||
found_ga = NULL;
|
||||
lnum_off = 0;
|
||||
use_level = FALSE;
|
||||
for (;;)
|
||||
{
|
||||
if (!foldFind(gap, lnum - lnum_off, &fp))
|
||||
@@ -783,20 +784,21 @@ deleteFold(start, end, recursive, had_visual)
|
||||
else
|
||||
{
|
||||
lnum = found_fp->fd_top + found_fp->fd_len + found_off;
|
||||
did_one = TRUE;
|
||||
|
||||
if (foldmethodIsManual(curwin))
|
||||
deleteFoldEntry(found_ga,
|
||||
(int)(found_fp - (fold_T *)found_ga->ga_data), recursive);
|
||||
else
|
||||
{
|
||||
if (found_fp->fd_top + found_off < first_lnum)
|
||||
first_lnum = found_fp->fd_top;
|
||||
if (lnum > last_lnum)
|
||||
if (first_lnum > found_fp->fd_top + found_off)
|
||||
first_lnum = found_fp->fd_top + found_off;
|
||||
if (last_lnum < lnum)
|
||||
last_lnum = lnum;
|
||||
parseMarker(curwin);
|
||||
if (!did_one)
|
||||
parseMarker(curwin);
|
||||
deleteFoldMarkers(found_fp, recursive, found_off);
|
||||
}
|
||||
did_one = TRUE;
|
||||
|
||||
/* redraw window */
|
||||
changed_window_setting();
|
||||
@@ -811,6 +813,10 @@ deleteFold(start, end, recursive, had_visual)
|
||||
redraw_curbuf_later(INVERTED);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
/* Deleting markers may make cursor column invalid. */
|
||||
check_cursor_col();
|
||||
|
||||
if (last_lnum > 0)
|
||||
changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L);
|
||||
}
|
||||
|
||||
+19
-10
@@ -1309,6 +1309,9 @@ save_typebuf()
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int old_char = -1; /* character put back by vungetc() */
|
||||
static int old_mod_mask; /* mod_mask for ungotten character */
|
||||
|
||||
#if defined(FEAT_EVAL) || defined(FEAT_EX_EXTRA) || defined(PROTO)
|
||||
|
||||
/*
|
||||
@@ -1323,6 +1326,10 @@ save_typeahead(tp)
|
||||
if (!tp->typebuf_valid)
|
||||
typebuf = tp->save_typebuf;
|
||||
|
||||
tp->old_char = old_char;
|
||||
tp->old_mod_mask = old_mod_mask;
|
||||
old_char = -1;
|
||||
|
||||
tp->save_stuffbuff = stuffbuff;
|
||||
stuffbuff.bh_first.b_next = NULL;
|
||||
# ifdef USE_INPUT_BUF
|
||||
@@ -1344,6 +1351,9 @@ restore_typeahead(tp)
|
||||
typebuf = tp->save_typebuf;
|
||||
}
|
||||
|
||||
old_char = tp->old_char;
|
||||
old_mod_mask = tp->old_mod_mask;
|
||||
|
||||
free_buff(&stuffbuff);
|
||||
stuffbuff = tp->save_stuffbuff;
|
||||
# ifdef USE_INPUT_BUF
|
||||
@@ -1499,9 +1509,6 @@ updatescript(c)
|
||||
#define KL_PART_KEY -1 /* keylen value for incomplete key-code */
|
||||
#define KL_PART_MAP -2 /* keylen value for incomplete mapping */
|
||||
|
||||
static int old_char = -1; /* character put back by vungetc() */
|
||||
static int old_mod_mask; /* mod_mask for ungotten character */
|
||||
|
||||
/*
|
||||
* Get the next input character.
|
||||
* Can return a special key or a multi-byte character.
|
||||
@@ -3701,11 +3708,10 @@ get_map_mode(cmdp, forceit)
|
||||
* Clear all mappings or abbreviations.
|
||||
* 'abbr' should be FALSE for mappings, TRUE for abbreviations.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
map_clear(cmdp, arg, forceit, abbr)
|
||||
char_u *cmdp;
|
||||
char_u *arg;
|
||||
char_u *arg UNUSED;
|
||||
int forceit;
|
||||
int abbr;
|
||||
{
|
||||
@@ -3734,13 +3740,12 @@ map_clear(cmdp, arg, forceit, abbr)
|
||||
/*
|
||||
* Clear all mappings in "mode".
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
map_clear_int(buf, mode, local, abbr)
|
||||
buf_T *buf; /* buffer for local mappings */
|
||||
int mode; /* mode in which to delete */
|
||||
int local; /* TRUE for buffer-local mappings */
|
||||
int abbr; /* TRUE for abbreviations */
|
||||
buf_T *buf UNUSED; /* buffer for local mappings */
|
||||
int mode; /* mode in which to delete */
|
||||
int local UNUSED; /* TRUE for buffer-local mappings */
|
||||
int abbr; /* TRUE for abbreviations */
|
||||
{
|
||||
mapblock_T *mp, **mpp;
|
||||
int hash;
|
||||
@@ -3816,7 +3821,11 @@ showmap(mp, local)
|
||||
int len = 1;
|
||||
|
||||
if (msg_didout || msg_silent != 0)
|
||||
{
|
||||
msg_putchar('\n');
|
||||
if (got_int) /* 'q' typed at MORE prompt */
|
||||
return;
|
||||
}
|
||||
if ((mp->m_mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
|
||||
msg_putchar('!'); /* :map! */
|
||||
else if (mp->m_mode & INSERT)
|
||||
|
||||
+32
-13
@@ -482,8 +482,10 @@ EXTERN char *foreground_argument INIT(= NULL);
|
||||
/*
|
||||
* While executing external commands or in Ex mode, should not insert GUI
|
||||
* events in the input buffer: Set hold_gui_events to non-zero.
|
||||
*
|
||||
* volatile because it is used in signal handler sig_sysmouse().
|
||||
*/
|
||||
EXTERN int hold_gui_events INIT(= 0);
|
||||
EXTERN volatile int hold_gui_events INIT(= 0);
|
||||
|
||||
/*
|
||||
* When resizing the shell is postponed, remember the new size, and call
|
||||
@@ -507,6 +509,7 @@ EXTERN VimClipboard clip_plus; /* CLIPBOARD selection in X11 */
|
||||
EXTERN int clip_unnamed INIT(= FALSE);
|
||||
EXTERN int clip_autoselect INIT(= FALSE);
|
||||
EXTERN int clip_autoselectml INIT(= FALSE);
|
||||
EXTERN int clip_html INIT(= FALSE);
|
||||
EXTERN regprog_T *clip_exclude_prog INIT(= NULL);
|
||||
#endif
|
||||
|
||||
@@ -522,7 +525,7 @@ EXTERN win_T *lastwin; /* last window */
|
||||
EXTERN win_T *prevwin INIT(= NULL); /* previous window */
|
||||
# define W_NEXT(wp) ((wp)->w_next)
|
||||
# define FOR_ALL_WINDOWS(wp) for (wp = firstwin; wp != NULL; wp = wp->w_next)
|
||||
#define FOR_ALL_TAB_WINDOWS(tp, wp) \
|
||||
# define FOR_ALL_TAB_WINDOWS(tp, wp) \
|
||||
for ((tp) = first_tabpage; (tp) != NULL; (tp) = (tp)->tp_next) \
|
||||
for ((wp) = ((tp) == curtab) \
|
||||
? firstwin : (tp)->tp_firstwin; (wp); (wp) = (wp)->w_next)
|
||||
@@ -536,6 +539,11 @@ EXTERN win_T *prevwin INIT(= NULL); /* previous window */
|
||||
|
||||
EXTERN win_T *curwin; /* currently active window */
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
EXTERN win_T *aucmd_win; /* window used in aucmd_prepbuf() */
|
||||
EXTERN int aucmd_win_used INIT(= FALSE); /* aucmd_win is being used */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The window layout is kept in a tree of frames. topframe points to the top
|
||||
* of the tree.
|
||||
@@ -597,7 +605,8 @@ EXTERN int exiting INIT(= FALSE);
|
||||
EXTERN int really_exiting INIT(= FALSE);
|
||||
/* TRUE when we are sure to exit, e.g., after
|
||||
* a deadly signal */
|
||||
EXTERN int full_screen INIT(= FALSE);
|
||||
/* volatile because it is used in signal handler deathtrap(). */
|
||||
EXTERN volatile int full_screen INIT(= FALSE);
|
||||
/* TRUE when doing full-screen output
|
||||
* otherwise only writing some messages */
|
||||
|
||||
@@ -616,6 +625,11 @@ EXTERN int textlock INIT(= 0);
|
||||
EXTERN int curbuf_lock INIT(= 0);
|
||||
/* non-zero when the current buffer can't be
|
||||
* changed. Used for FileChangedRO. */
|
||||
EXTERN int allbuf_lock INIT(= 0);
|
||||
/* non-zero when no buffer name can be
|
||||
* changed, no buffer can be deleted and
|
||||
* current directory can't be changed.
|
||||
* Used for SwapExists et al. */
|
||||
#endif
|
||||
#ifdef FEAT_EVAL
|
||||
# define HAVE_SANDBOX
|
||||
@@ -710,7 +724,7 @@ EXTERN int can_si_back INIT(= FALSE);
|
||||
|
||||
EXTERN pos_T saved_cursor /* w_cursor before formatting text. */
|
||||
# ifdef DO_INIT
|
||||
= INIT_POS_T
|
||||
= INIT_POS_T(0, 0, 0)
|
||||
# endif
|
||||
;
|
||||
|
||||
@@ -739,10 +753,12 @@ EXTERN JMP_BUF x_jump_env;
|
||||
*/
|
||||
EXTERN JMP_BUF lc_jump_env; /* argument to SETJMP() */
|
||||
# ifdef SIGHASARG
|
||||
EXTERN int lc_signal; /* catched signal number, 0 when no was signal
|
||||
catched; used for mch_libcall() */
|
||||
/* volatile because it is used in signal handlers. */
|
||||
EXTERN volatile int lc_signal; /* caught signal number, 0 when no was signal
|
||||
caught; used for mch_libcall() */
|
||||
# endif
|
||||
EXTERN int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */
|
||||
/* volatile because it is used in signal handler deathtrap(). */
|
||||
EXTERN volatile int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT)
|
||||
@@ -800,11 +816,14 @@ EXTERN vimconv_T output_conv; /* type of output conversion */
|
||||
*/
|
||||
/* length of char in bytes, including following composing chars */
|
||||
EXTERN int (*mb_ptr2len) __ARGS((char_u *p)) INIT(= latin_ptr2len);
|
||||
/* idem, with limit on string length */
|
||||
EXTERN int (*mb_ptr2len_len) __ARGS((char_u *p, int size)) INIT(= latin_ptr2len_len);
|
||||
/* byte length of char */
|
||||
EXTERN int (*mb_char2len) __ARGS((int c)) INIT(= latin_char2len);
|
||||
/* convert char to bytes, return the length */
|
||||
EXTERN int (*mb_char2bytes) __ARGS((int c, char_u *buf)) INIT(= latin_char2bytes);
|
||||
EXTERN int (*mb_ptr2cells) __ARGS((char_u *p)) INIT(= latin_ptr2cells);
|
||||
EXTERN int (*mb_ptr2cells_len) __ARGS((char_u *p, int size)) INIT(= latin_ptr2cells_len);
|
||||
EXTERN int (*mb_char2cells) __ARGS((int c)) INIT(= latin_char2cells);
|
||||
EXTERN int (*mb_off2cells) __ARGS((unsigned off, unsigned max_off)) INIT(= latin_off2cells);
|
||||
EXTERN int (*mb_ptr2char) __ARGS((char_u *p)) INIT(= latin_ptr2char);
|
||||
@@ -822,10 +841,10 @@ EXTERN int* (*iconv_errno) (void);
|
||||
#endif /* FEAT_MBYTE */
|
||||
|
||||
#ifdef FEAT_XIM
|
||||
# ifdef FEAT_GUI_GTK
|
||||
# if defined(FEAT_GUI_GTK) || defined (FEAT_GUI_MACVIM)
|
||||
# ifdef HAVE_GTK2
|
||||
EXTERN GtkIMContext *xic INIT(= NULL);
|
||||
# else
|
||||
# elif !defined(FEAT_GUI_MACVIM)
|
||||
EXTERN GdkICAttr *xic_attr INIT(= NULL);
|
||||
EXTERN GdkIC *xic INIT(= NULL);
|
||||
EXTERN char *draw_feedback INIT(= NULL);
|
||||
@@ -950,7 +969,7 @@ EXTERN struct buffheader stuffbuff /* stuff buffer */
|
||||
;
|
||||
EXTERN typebuf_T typebuf /* typeahead buffer */
|
||||
#ifdef DO_INIT
|
||||
= {NULL, NULL}
|
||||
= {NULL, NULL, 0, 0, 0, 0, 0, 0, 0}
|
||||
#endif
|
||||
;
|
||||
#ifdef FEAT_EX_EXTRA
|
||||
@@ -986,7 +1005,8 @@ EXTERN int curscript INIT(= 0); /* index in scriptin[] */
|
||||
EXTERN FILE *scriptout INIT(= NULL); /* stream to write script to */
|
||||
EXTERN int read_cmd_fd INIT(= 0); /* fd to read commands from */
|
||||
|
||||
EXTERN int got_int INIT(= FALSE); /* set to TRUE when interrupt
|
||||
/* volatile because it is used in signal handler catch_sigint(). */
|
||||
EXTERN volatile int got_int INIT(= FALSE); /* set to TRUE when interrupt
|
||||
signal occurred */
|
||||
#ifdef USE_TERM_CONSOLE
|
||||
EXTERN int term_console INIT(= FALSE); /* set to TRUE when console used */
|
||||
@@ -1028,7 +1048,7 @@ EXTERN char_u *autocmd_match INIT(= NULL); /* name for <amatch> on cmdline */
|
||||
EXTERN int did_cursorhold INIT(= FALSE); /* set when CursorHold t'gerd */
|
||||
EXTERN pos_T last_cursormoved /* for CursorMoved event */
|
||||
# ifdef DO_INIT
|
||||
= INIT_POS_T
|
||||
= INIT_POS_T(0, 0, 0)
|
||||
# endif
|
||||
;
|
||||
#endif
|
||||
@@ -1342,7 +1362,6 @@ EXTERN garray_T error_ga
|
||||
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
EXTERN char *netbeansArg INIT(= NULL); /* the -nb[:host:port:passwd] arg */
|
||||
EXTERN int netbeansCloseFile INIT(= 0); /* send killed if != 0 */
|
||||
EXTERN int netbeansFireChanges INIT(= 1); /* send buffer changes if != 0 */
|
||||
EXTERN int netbeansForcedQuit INIT(= 0);/* don't write modified files */
|
||||
EXTERN int netbeansReadFile INIT(= 1); /* OK to read from disk if != 0 */
|
||||
|
||||
@@ -58,7 +58,11 @@ static int can_update_cursor = TRUE; /* can display the cursor */
|
||||
gui_start()
|
||||
{
|
||||
char_u *old_term;
|
||||
#if defined(UNIX) && !defined(__BEOS__)
|
||||
#if defined(UNIX) && !defined(__BEOS__) && !defined(MACOS_X)
|
||||
/* By the time we get here Mac OS X will already have forked (it does so
|
||||
* right after scanning the command line) so don't do anything here. This
|
||||
* means that "f" in 'guioptions' cannot be supported.
|
||||
*/
|
||||
# define MAY_FORK
|
||||
int dofork = TRUE;
|
||||
#endif
|
||||
@@ -117,82 +121,10 @@ gui_start()
|
||||
*/
|
||||
if (gui.in_use && dofork)
|
||||
{
|
||||
pid_t pid = -1;
|
||||
|
||||
# if defined MACOS_X
|
||||
int i;
|
||||
|
||||
/* on os x, you have to exec after a fork, otherwise calls to
|
||||
* frameworks will assert (and without corefoundation, you can't start
|
||||
* the gui. what fun.). See CAVEATS at
|
||||
http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/fork.2.html
|
||||
*
|
||||
* Since we have to go through this anyways, we might as well use vfork.
|
||||
* But: then we can't detach from our starting shell, so stick with
|
||||
* fork.
|
||||
*
|
||||
* Kinda sucks to restart vim when doing :gui, so don't fork in that
|
||||
* case (make sure gui.dofork is only set when interpreting argv, not
|
||||
* when doing :gui. Currently, gui.dofork is set to false in ex_gui().
|
||||
*
|
||||
* Also doesn't work well if vim starts cscope (or some other
|
||||
* subprocess I guess), because it's not transferred to the newly
|
||||
* exec'd process, leaving an orphaned process (not a zombie process)
|
||||
* behind. The Right Thing is to kill all our child processes before
|
||||
* calling exec.
|
||||
*/
|
||||
|
||||
/* stolen from http://paste.lisp.org/display/50906 */
|
||||
extern int *_NSGetArgc(void);
|
||||
extern char ***_NSGetArgv(void);
|
||||
|
||||
int argc = *_NSGetArgc();
|
||||
char ** argv = *_NSGetArgv();
|
||||
char * newargv[argc+2];
|
||||
|
||||
newargv[0] = argv[0];
|
||||
|
||||
/*
|
||||
* make sure "-f" is in front of potential "--remote" flags, else
|
||||
* they would consume it.
|
||||
*/
|
||||
newargv[1] = "-f";
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
newargv[i + 1] = argv[i];
|
||||
}
|
||||
newargv[argc+1] = NULL;
|
||||
|
||||
/* shut down all the stuff we just started, just to start
|
||||
* it again from the exec :-\ */
|
||||
prepare_getout();
|
||||
|
||||
pid = fork();
|
||||
switch(pid) {
|
||||
case -1:
|
||||
# ifndef NDEBUG
|
||||
fprintf(stderr, "vim: Mac OS X workaround fork() failed!");
|
||||
# endif
|
||||
_exit(255);
|
||||
case 0:
|
||||
/* Child. */
|
||||
|
||||
/* make sure we survive our shell */
|
||||
setsid();
|
||||
|
||||
/* Restarts the vim process, will not return. */
|
||||
execvp(argv[0], newargv);
|
||||
|
||||
/* if we come here, exec has failed. bail. */
|
||||
_exit(255);
|
||||
default:
|
||||
/* Parent */
|
||||
_exit(0);
|
||||
}
|
||||
# else
|
||||
int pipefd[2]; /* pipe between parent and child */
|
||||
int pipe_error;
|
||||
char dummy;
|
||||
pid_t pid = -1;
|
||||
|
||||
/* Setup a pipe between the child and the parent, so that the parent
|
||||
* knows when the child has done the setsid() call and is allowed to
|
||||
@@ -227,30 +159,27 @@ http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/fork.2.h
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
# if defined(HAVE_SETSID) || defined(HAVE_SETPGID)
|
||||
# if defined(HAVE_SETSID) || defined(HAVE_SETPGID)
|
||||
/*
|
||||
* Change our process group. On some systems/shells a CTRL-C in the
|
||||
* shell where Vim was started would otherwise kill gvim!
|
||||
*/
|
||||
if (pid == 0) /* child */
|
||||
# if defined(HAVE_SETSID)
|
||||
# if defined(HAVE_SETSID)
|
||||
(void)setsid();
|
||||
# else
|
||||
# else
|
||||
(void)setpgid(0, 0);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
if (!pipe_error)
|
||||
{
|
||||
close(pipefd[0]);
|
||||
close(pipefd[1]);
|
||||
}
|
||||
|
||||
|
||||
# if defined(FEAT_GUI_GNOME) && defined(FEAT_SESSION)
|
||||
# if defined(FEAT_GUI_GNOME) && defined(FEAT_SESSION)
|
||||
/* Tell the session manager our new PID */
|
||||
gui_mch_forked();
|
||||
# endif
|
||||
|
||||
# endif
|
||||
}
|
||||
#else
|
||||
@@ -754,11 +683,10 @@ gui_shell_closed()
|
||||
* Return OK when able to set the font. When it failed FAIL is returned and
|
||||
* the fonts are unchanged.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
gui_init_font(font_list, fontset)
|
||||
char_u *font_list;
|
||||
int fontset;
|
||||
int fontset UNUSED;
|
||||
{
|
||||
#define FONTLEN 320
|
||||
char_u font_name[FONTLEN];
|
||||
@@ -1047,7 +975,7 @@ gui_update_cursor(force, clear_selection)
|
||||
guicolor_T fg, bg;
|
||||
|
||||
if (
|
||||
# ifdef HAVE_GTK2
|
||||
# if defined(HAVE_GTK2) && !defined(FEAT_HANGULIN)
|
||||
preedit_get_status()
|
||||
# else
|
||||
im_get_status()
|
||||
@@ -1226,10 +1154,9 @@ gui_position_menu()
|
||||
* Position the various GUI components (text area, menu). The vertical
|
||||
* scrollbars are NOT handled here. See gui_update_scrollbars().
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
gui_position_components(total_width)
|
||||
int total_width;
|
||||
int total_width UNUSED;
|
||||
{
|
||||
int text_area_x;
|
||||
int text_area_y;
|
||||
@@ -1279,7 +1206,7 @@ gui_position_components(total_width)
|
||||
text_area_y,
|
||||
text_area_width,
|
||||
text_area_height
|
||||
#if defined(FEAT_XIM) && !defined(HAVE_GTK2)
|
||||
#if defined(FEAT_XIM) && !(defined(HAVE_GTK2) || defined(FEAT_GUI_MACVIM))
|
||||
+ xim_get_status_area_height()
|
||||
#endif
|
||||
);
|
||||
@@ -1410,7 +1337,7 @@ again:
|
||||
|
||||
gui_update_scrollbars(TRUE);
|
||||
gui_update_cursor(FALSE, TRUE);
|
||||
#if defined(FEAT_XIM) && !defined(HAVE_GTK2)
|
||||
#if defined(FEAT_XIM) && !(defined(HAVE_GTK2) || defined(FEAT_GUI_MACVIM))
|
||||
xim_set_status_area();
|
||||
#endif
|
||||
|
||||
@@ -1463,10 +1390,9 @@ gui_get_shellsize()
|
||||
* If "fit_to_display" is TRUE then the size may be reduced to fit the window
|
||||
* on the screen.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
gui_set_shellsize(mustset, fit_to_display, direction)
|
||||
int mustset; /* set by the user */
|
||||
int mustset UNUSED; /* set by the user */
|
||||
int fit_to_display;
|
||||
int direction; /* RESIZE_HOR, RESIZE_VER */
|
||||
{
|
||||
@@ -3212,10 +3138,9 @@ static int prev_which_scrollbars[3];
|
||||
* If "oldval" is not NULL, "oldval" is the previous value, the new value is
|
||||
* in p_go.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
gui_init_which_components(oldval)
|
||||
char_u *oldval;
|
||||
char_u *oldval UNUSED;
|
||||
{
|
||||
#ifdef FEAT_MENU
|
||||
static int prev_menu_is_active = -1;
|
||||
@@ -3975,6 +3900,21 @@ gui_drag_scrollbar(sb, value, still_dragging)
|
||||
* Scrollbar stuff:
|
||||
*/
|
||||
|
||||
/*
|
||||
* Called when something in the window layout has changed.
|
||||
*/
|
||||
void
|
||||
gui_may_update_scrollbars()
|
||||
{
|
||||
if (gui.in_use && starting == 0)
|
||||
{
|
||||
out_flush();
|
||||
gui_init_which_components(NULL);
|
||||
gui_update_scrollbars(TRUE);
|
||||
}
|
||||
need_mouse_correct = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gui_update_scrollbars(force)
|
||||
int force; /* Force all scrollbars to get updated */
|
||||
@@ -4504,7 +4444,7 @@ gui_do_horiz_scroll()
|
||||
if (curwin->w_p_wrap)
|
||||
return FALSE;
|
||||
|
||||
if (curwin->w_leftcol == scrollbar_value)
|
||||
if ((long_u)curwin->w_leftcol == scrollbar_value)
|
||||
return FALSE;
|
||||
|
||||
curwin->w_leftcol = (colnr_T)scrollbar_value;
|
||||
@@ -4517,7 +4457,7 @@ gui_do_horiz_scroll()
|
||||
&& longest_lnum < curwin->w_botline
|
||||
&& !virtual_active())
|
||||
{
|
||||
if (scrollbar_value > scroll_line_len(curwin->w_cursor.lnum))
|
||||
if (scrollbar_value > (long_u)scroll_line_len(curwin->w_cursor.lnum))
|
||||
{
|
||||
curwin->w_cursor.lnum = longest_lnum;
|
||||
curwin->w_cursor.col = 0;
|
||||
@@ -4763,11 +4703,10 @@ gui_mouse_correct()
|
||||
/*
|
||||
* Find window where the mouse pointer "y" coordinate is in.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static win_T *
|
||||
xy2win(x, y)
|
||||
int x;
|
||||
int y;
|
||||
int x UNUSED;
|
||||
int y UNUSED;
|
||||
{
|
||||
#ifdef FEAT_WINDOWS
|
||||
int row;
|
||||
@@ -4820,6 +4759,8 @@ ex_gui(eap)
|
||||
* Check for "-f" argument: foreground, don't fork.
|
||||
* Also don't fork when started with "gvim -f".
|
||||
* Do fork when using "gui -b".
|
||||
* Note that Mac OS X will never fork on :gui since it can only fork on
|
||||
* startup right after scanning the command line.
|
||||
*/
|
||||
if (arg[0] == '-'
|
||||
&& (arg[1] == 'f' || arg[1] == 'b')
|
||||
@@ -4832,13 +4773,6 @@ ex_gui(eap)
|
||||
{
|
||||
/* Clear the command. Needed for when forking+exiting, to avoid part
|
||||
* of the argument ending up after the shell prompt. */
|
||||
|
||||
#ifdef MACOS_X
|
||||
/* os x doesn't really support fork(), so we can't fork of a gui
|
||||
* in an already running vim. see gui_start() for more details.
|
||||
*/
|
||||
gui.dofork = FALSE;
|
||||
#endif
|
||||
msg_clr_eos_force();
|
||||
gui_start();
|
||||
}
|
||||
@@ -5095,6 +5029,19 @@ gui_do_findrepl(flags, find_text, repl_text, down)
|
||||
char_u *p;
|
||||
regmatch_T regmatch;
|
||||
int save_did_emsg = did_emsg;
|
||||
static int busy = FALSE;
|
||||
|
||||
/* When the screen is being updated we should not change buffers and
|
||||
* windows structures, it may cause freed memory to be used. Also don't
|
||||
* do this recursively (pressing "Find" quickly several times. */
|
||||
if (updating_screen || busy)
|
||||
return FALSE;
|
||||
|
||||
/* refuse replace when text cannot be changed */
|
||||
if ((type == FRD_REPLACE || type == FRD_REPLACEALL) && text_locked())
|
||||
return FALSE;
|
||||
|
||||
busy = TRUE;
|
||||
|
||||
ga_init2(&ga, 1, 100);
|
||||
if (type == FRD_REPLACEALL)
|
||||
@@ -5185,6 +5132,7 @@ gui_do_findrepl(flags, find_text, repl_text, down)
|
||||
}
|
||||
|
||||
vim_free(ga.ga_data);
|
||||
busy = FALSE;
|
||||
return (ga.ga_len > 0);
|
||||
}
|
||||
|
||||
@@ -5226,11 +5174,10 @@ gui_wingoto_xy(x, y)
|
||||
* of dropped files, they will be freed in this function, and caller can't use
|
||||
* fnames after call this function.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
gui_handle_drop(x, y, modifiers, fnames, count)
|
||||
int x;
|
||||
int y;
|
||||
int x UNUSED;
|
||||
int y UNUSED;
|
||||
int_u modifiers;
|
||||
char_u **fnames;
|
||||
int count;
|
||||
|
||||
@@ -495,7 +495,7 @@ typedef struct Gui
|
||||
PhEvent_t *event_buffer;
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_XIM
|
||||
#if defined(FEAT_XIM) && !defined(FEAT_GUI_MACVIM)
|
||||
char *rsrc_input_method;
|
||||
char *rsrc_preedit_type_name;
|
||||
#endif
|
||||
|
||||
+37
-54
@@ -829,7 +829,7 @@ SFsetText(path)
|
||||
text.format = FMT8BIT;
|
||||
|
||||
#ifdef XtNinternational
|
||||
if (_XawTextFormat((TextWidget)selFileField) == XawFmtWide)
|
||||
if ((unsigned long)_XawTextFormat((TextWidget)selFileField) == XawFmtWide)
|
||||
{
|
||||
XawTextReplace(selFileField, (XawTextPosition)0,
|
||||
(XawTextPosition)WcsLen((wchar_t *)&SFtextBuffer[0]), &text);
|
||||
@@ -851,17 +851,15 @@ SFsetText(path)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFbuttonPressList(w, n, event)
|
||||
Widget w;
|
||||
int n;
|
||||
XButtonPressedEvent *event;
|
||||
Widget w UNUSED;
|
||||
int n UNUSED;
|
||||
XButtonPressedEvent *event UNUSED;
|
||||
{
|
||||
SFbuttonPressed = 1;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFbuttonReleaseList(w, n, event)
|
||||
Widget w;
|
||||
@@ -989,11 +987,10 @@ SFcheckFiles(dir)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFdirModTimer(cl, id)
|
||||
XtPointer cl;
|
||||
XtIntervalId *id;
|
||||
XtPointer cl UNUSED;
|
||||
XtIntervalId *id UNUSED;
|
||||
{
|
||||
static int n = -1;
|
||||
static int f = 0;
|
||||
@@ -1596,11 +1593,10 @@ SFscrollTimerInterval()
|
||||
|
||||
static void SFscrollTimer __ARGS((XtPointer p, XtIntervalId *id));
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFscrollTimer(p, id)
|
||||
XtPointer p;
|
||||
XtIntervalId *id;
|
||||
XtIntervalId *id UNUSED;
|
||||
{
|
||||
SFDir *dir;
|
||||
int save;
|
||||
@@ -1695,10 +1691,9 @@ SFnewInvertEntry(n, event)
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFenterList(w, n, event)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
int n;
|
||||
XEnterWindowEvent *event;
|
||||
{
|
||||
@@ -1719,12 +1714,11 @@ SFenterList(w, n, event)
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFleaveList(w, n, event)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
int n;
|
||||
XEvent *event;
|
||||
XEvent *event UNUSED;
|
||||
{
|
||||
if (SFcurrentInvert[n] != -1)
|
||||
{
|
||||
@@ -1733,10 +1727,9 @@ SFleaveList(w, n, event)
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFmotionList(w, n, event)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
int n;
|
||||
XMotionEvent *event;
|
||||
{
|
||||
@@ -1754,7 +1747,6 @@ SFmotionList(w, n, event)
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFvFloatSliderMovedCallback(w, n, fnew)
|
||||
Widget w;
|
||||
@@ -1767,10 +1759,9 @@ SFvFloatSliderMovedCallback(w, n, fnew)
|
||||
SFvSliderMovedCallback(w, (int)(long)n, nw);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFvSliderMovedCallback(w, n, nw)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
int n;
|
||||
int nw;
|
||||
{
|
||||
@@ -1853,10 +1844,9 @@ SFvSliderMovedCallback(w, n, nw)
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFvAreaSelectedCallback(w, n, pnew)
|
||||
Widget w;
|
||||
Widget w;
|
||||
XtPointer n;
|
||||
XtPointer pnew;
|
||||
{
|
||||
@@ -1914,10 +1904,9 @@ SFvAreaSelectedCallback(w, n, pnew)
|
||||
SFvSliderMovedCallback(w, (int)(long)n, nw);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFhSliderMovedCallback(w, n, nw)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
XtPointer n;
|
||||
XtPointer nw;
|
||||
{
|
||||
@@ -1933,10 +1922,9 @@ SFhSliderMovedCallback(w, n, nw)
|
||||
SFdrawList((int)(long)n, SF_DO_NOT_SCROLL);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFhAreaSelectedCallback(w, n, pnew)
|
||||
Widget w;
|
||||
Widget w;
|
||||
XtPointer n;
|
||||
XtPointer pnew;
|
||||
{
|
||||
@@ -1994,11 +1982,10 @@ SFhAreaSelectedCallback(w, n, pnew)
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFpathSliderMovedCallback(w, client_data, nw)
|
||||
Widget w;
|
||||
XtPointer client_data;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data UNUSED;
|
||||
XtPointer nw;
|
||||
{
|
||||
SFDir *dir;
|
||||
@@ -2031,11 +2018,10 @@ SFpathSliderMovedCallback(w, client_data, nw)
|
||||
XawTextSetInsertionPoint(selFileField, pos);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFpathAreaSelectedCallback(w, client_data, pnew)
|
||||
Widget w;
|
||||
XtPointer client_data;
|
||||
XtPointer client_data UNUSED;
|
||||
XtPointer pnew;
|
||||
{
|
||||
int nw = (int)(long)pnew;
|
||||
@@ -2206,13 +2192,12 @@ static char *oneLineTextEditTranslations = "\
|
||||
|
||||
static void SFexposeList __ARGS((Widget w, XtPointer n, XEvent *event, Boolean *cont));
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFexposeList(w, n, event, cont)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
XtPointer n;
|
||||
XEvent *event;
|
||||
Boolean *cont;
|
||||
Boolean *cont UNUSED;
|
||||
{
|
||||
if ((event->type == NoExpose) || event->xexpose.count)
|
||||
return;
|
||||
@@ -2222,13 +2207,12 @@ SFexposeList(w, n, event, cont)
|
||||
|
||||
static void SFmodVerifyCallback __ARGS((Widget w, XtPointer client_data, XEvent *event, Boolean *cont));
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFmodVerifyCallback(w, client_data, event, cont)
|
||||
Widget w;
|
||||
XtPointer client_data;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data UNUSED;
|
||||
XEvent *event;
|
||||
Boolean *cont;
|
||||
Boolean *cont UNUSED;
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
@@ -2241,11 +2225,11 @@ SFmodVerifyCallback(w, client_data, event, cont)
|
||||
|
||||
static void SFokCallback __ARGS((Widget w, XtPointer cl, XtPointer cd));
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFokCallback(w, cl, cd)
|
||||
Widget w;
|
||||
XtPointer cl, cd;
|
||||
Widget w UNUSED;
|
||||
XtPointer cl UNUSED;
|
||||
XtPointer cd UNUSED;
|
||||
{
|
||||
SFstatus = SEL_FILE_OK;
|
||||
}
|
||||
@@ -2258,11 +2242,11 @@ static XtCallbackRec SFokSelect[] =
|
||||
|
||||
static void SFcancelCallback __ARGS((Widget w, XtPointer cl, XtPointer cd));
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFcancelCallback(w, cl, cd)
|
||||
Widget w;
|
||||
XtPointer cl, cd;
|
||||
Widget w UNUSED;
|
||||
XtPointer cl UNUSED;
|
||||
XtPointer cd UNUSED;
|
||||
{
|
||||
SFstatus = SEL_FILE_CANCEL;
|
||||
}
|
||||
@@ -2275,16 +2259,15 @@ static XtCallbackRec SFcancelSelect[] =
|
||||
|
||||
static void SFdismissAction __ARGS((Widget w, XEvent *event, String *params, Cardinal *num_params));
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
SFdismissAction(w, event, params, num_params)
|
||||
Widget w;
|
||||
XEvent *event;
|
||||
String *params;
|
||||
Cardinal *num_params;
|
||||
Widget w UNUSED;
|
||||
XEvent *event;
|
||||
String *params UNUSED;
|
||||
Cardinal *num_params UNUSED;
|
||||
{
|
||||
if (event->type == ClientMessage &&
|
||||
event->xclient.data.l[0] != SFwmDeleteWindow)
|
||||
if (event->type == ClientMessage
|
||||
&& (Atom)event->xclient.data.l[0] != SFwmDeleteWindow)
|
||||
return;
|
||||
|
||||
SFstatus = SEL_FILE_CANCEL;
|
||||
@@ -2703,7 +2686,7 @@ SFcreateWidgets(toplevel, prompt, ok, cancel)
|
||||
SFtextChanged()
|
||||
{
|
||||
#if defined(FEAT_XFONTSET) && defined(XtNinternational)
|
||||
if (_XawTextFormat((TextWidget)selFileField) == XawFmtWide)
|
||||
if ((unsigned long)_XawTextFormat((TextWidget)selFileField) == XawFmtWide)
|
||||
{
|
||||
wchar_t *wcbuf=(wchar_t *)SFtextBuffer;
|
||||
|
||||
@@ -2749,7 +2732,7 @@ SFgetText()
|
||||
#if defined(FEAT_XFONTSET) && defined(XtNinternational)
|
||||
char *buf;
|
||||
|
||||
if (_XawTextFormat((TextWidget)selFileField) == XawFmtWide)
|
||||
if ((unsigned long)_XawTextFormat((TextWidget)selFileField) == XawFmtWide)
|
||||
{
|
||||
wchar_t *wcbuf;
|
||||
int mbslength;
|
||||
|
||||
+34
-45
@@ -198,10 +198,13 @@ ScrollbarClassRec vim_scrollbarClassRec =
|
||||
/* extension */ NULL
|
||||
},
|
||||
{ /* simple fields */
|
||||
/* change_sensitive */ XtInheritChangeSensitive
|
||||
/* change_sensitive */ XtInheritChangeSensitive,
|
||||
#ifndef OLDXAW
|
||||
/* extension */ NULL
|
||||
#endif
|
||||
},
|
||||
{ /* scrollbar fields */
|
||||
/* ignore */ 0
|
||||
/* empty */ 0
|
||||
}
|
||||
};
|
||||
|
||||
@@ -241,7 +244,8 @@ FillArea(sbw, top, bottom, fill, draw_shadow)
|
||||
|
||||
if (bottom <= 0 || bottom <= top)
|
||||
return;
|
||||
if ((sw = sbw->scrollbar.shadow_width) < 0)
|
||||
sw = sbw->scrollbar.shadow_width;
|
||||
if (sw < 0)
|
||||
sw = 0;
|
||||
margin = MARGIN (sbw);
|
||||
floor = sbw->scrollbar.length - margin + 2;
|
||||
@@ -516,13 +520,12 @@ SetDimensions(sbw)
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
Initialize(request, new, args, num_args)
|
||||
Widget request; /* what the client asked for */
|
||||
Widget request UNUSED; /* what the client asked for */
|
||||
Widget new; /* what we're going to give him */
|
||||
ArgList args;
|
||||
Cardinal *num_args;
|
||||
ArgList args UNUSED;
|
||||
Cardinal *num_args UNUSED;
|
||||
{
|
||||
ScrollbarWidget sbw = (ScrollbarWidget) new;
|
||||
|
||||
@@ -556,14 +559,13 @@ Realize(w, valueMask, attributes)
|
||||
(w, valueMask, attributes);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static Boolean
|
||||
SetValues(current, request, desired, args, num_args)
|
||||
Widget current, /* what I am */
|
||||
request, /* what he wants me to be */
|
||||
desired; /* what I will become */
|
||||
ArgList args;
|
||||
Cardinal *num_args;
|
||||
Widget current; /* what I am */
|
||||
Widget request UNUSED; /* what he wants me to be */
|
||||
Widget desired; /* what I will become */
|
||||
ArgList args UNUSED;
|
||||
Cardinal *num_args UNUSED;
|
||||
{
|
||||
ScrollbarWidget sbw = (ScrollbarWidget) current;
|
||||
ScrollbarWidget dsbw = (ScrollbarWidget) desired;
|
||||
@@ -609,7 +611,6 @@ Resize(w)
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
Redisplay(w, event, region)
|
||||
Widget w;
|
||||
@@ -789,11 +790,10 @@ HandleThumb(w, event, params, num_params)
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
RepeatNotify(client_data, idp)
|
||||
XtPointer client_data;
|
||||
XtIntervalId *idp;
|
||||
XtIntervalId *idp UNUSED;
|
||||
{
|
||||
ScrollbarWidget sbw = (ScrollbarWidget) client_data;
|
||||
int call_data;
|
||||
@@ -839,46 +839,42 @@ FloatInRange(num, small, big)
|
||||
return (num < small) ? small : ((num > big) ? big : num);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
ScrollOneLineUp(w, event, params, num_params)
|
||||
Widget w;
|
||||
XEvent *event;
|
||||
String *params;
|
||||
Cardinal *num_params;
|
||||
String *params UNUSED;
|
||||
Cardinal *num_params UNUSED;
|
||||
{
|
||||
ScrollSome(w, event, -ONE_LINE_DATA);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
ScrollOneLineDown(w, event, params, num_params)
|
||||
Widget w;
|
||||
XEvent *event;
|
||||
String *params;
|
||||
Cardinal *num_params;
|
||||
String *params UNUSED;
|
||||
Cardinal *num_params UNUSED;
|
||||
{
|
||||
ScrollSome(w, event, ONE_LINE_DATA);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
ScrollPageDown(w, event, params, num_params)
|
||||
Widget w;
|
||||
XEvent *event;
|
||||
String *params;
|
||||
Cardinal *num_params;
|
||||
String *params UNUSED;
|
||||
Cardinal *num_params UNUSED;
|
||||
{
|
||||
ScrollSome(w, event, ONE_PAGE_DATA);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
ScrollPageUp(w, event, params, num_params)
|
||||
Widget w;
|
||||
XEvent *event;
|
||||
String *params;
|
||||
Cardinal *num_params;
|
||||
String *params UNUSED;
|
||||
Cardinal *num_params UNUSED;
|
||||
{
|
||||
ScrollSome(w, event, -ONE_PAGE_DATA);
|
||||
}
|
||||
@@ -901,13 +897,12 @@ ScrollSome(w, event, call_data)
|
||||
XtCallCallbacks(w, XtNscrollProc, (XtPointer)call_data);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
NotifyScroll(w, event, params, num_params)
|
||||
Widget w;
|
||||
XEvent *event;
|
||||
String *params;
|
||||
Cardinal *num_params;
|
||||
String *params UNUSED;
|
||||
Cardinal *num_params UNUSED;
|
||||
{
|
||||
ScrollbarWidget sbw = (ScrollbarWidget) w;
|
||||
Position x, y, loc;
|
||||
@@ -991,13 +986,12 @@ NotifyScroll(w, event, params, num_params)
|
||||
delay, RepeatNotify, (XtPointer)w);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
EndScroll(w, event, params, num_params)
|
||||
Widget w;
|
||||
XEvent *event; /* unused */
|
||||
String *params; /* unused */
|
||||
Cardinal *num_params; /* unused */
|
||||
XEvent *event UNUSED;
|
||||
String *params UNUSED;
|
||||
Cardinal *num_params UNUSED;
|
||||
{
|
||||
ScrollbarWidget sbw = (ScrollbarWidget) w;
|
||||
|
||||
@@ -1023,13 +1017,12 @@ FractionLoc(sbw, x, y)
|
||||
return PICKLENGTH(sbw, x / width, y / height);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
MoveThumb(w, event, params, num_params)
|
||||
Widget w;
|
||||
XEvent *event;
|
||||
String *params; /* unused */
|
||||
Cardinal *num_params; /* unused */
|
||||
String *params UNUSED;
|
||||
Cardinal *num_params UNUSED;
|
||||
{
|
||||
ScrollbarWidget sbw = (ScrollbarWidget)w;
|
||||
Position x, y;
|
||||
@@ -1069,13 +1062,12 @@ MoveThumb(w, event, params, num_params)
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
NotifyThumb(w, event, params, num_params)
|
||||
Widget w;
|
||||
XEvent *event;
|
||||
String *params; /* unused */
|
||||
Cardinal *num_params; /* unused */
|
||||
String *params UNUSED;
|
||||
Cardinal *num_params UNUSED;
|
||||
{
|
||||
ScrollbarWidget sbw = (ScrollbarWidget)w;
|
||||
/* Use a union to avoid a warning for the weird conversion from float to
|
||||
@@ -1096,7 +1088,6 @@ NotifyThumb(w, event, params, num_params)
|
||||
XtCallCallbacks(w, XtNjumpProc, (XtPointer)&sbw->scrollbar.top);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
AllocTopShadowGC(w)
|
||||
Widget w;
|
||||
@@ -1110,7 +1101,6 @@ AllocTopShadowGC(w)
|
||||
sbw->scrollbar.top_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
AllocBotShadowGC(w)
|
||||
Widget w;
|
||||
@@ -1124,11 +1114,10 @@ AllocBotShadowGC(w)
|
||||
sbw->scrollbar.bot_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
_Xaw3dDrawShadows(gw, event, region, out)
|
||||
Widget gw;
|
||||
XEvent *event;
|
||||
XEvent *event UNUSED;
|
||||
Region region;
|
||||
int out;
|
||||
{
|
||||
|
||||
+29
-44
@@ -86,10 +86,9 @@ static int puller_width = 0;
|
||||
* Scrollbar callback (XtNjumpProc) for when the scrollbar is dragged with the
|
||||
* left or middle mouse button.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
gui_athena_scroll_cb_jump(w, client_data, call_data)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data, call_data;
|
||||
{
|
||||
scrollbar_T *sb, *sb_info;
|
||||
@@ -122,10 +121,9 @@ gui_athena_scroll_cb_jump(w, client_data, call_data)
|
||||
* Scrollbar callback (XtNscrollProc) for paging up or down with the left or
|
||||
* right mouse buttons.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
gui_athena_scroll_cb_scroll(w, client_data, call_data)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data, call_data;
|
||||
{
|
||||
scrollbar_T *sb, *sb_info;
|
||||
@@ -492,7 +490,7 @@ get_toolbar_pixmap(menu, sen)
|
||||
if (menu->icon_builtin || gui_find_bitmap(menu->name, buf, "xpm") == FAIL)
|
||||
{
|
||||
if (menu->iconidx >= 0 && menu->iconidx
|
||||
< (sizeof(built_in_pixmaps) / sizeof(built_in_pixmaps[0])))
|
||||
< (int)(sizeof(built_in_pixmaps) / sizeof(built_in_pixmaps[0])))
|
||||
xpm = built_in_pixmaps[menu->iconidx];
|
||||
else
|
||||
xpm = tb_blank_xpm;
|
||||
@@ -763,7 +761,7 @@ athena_calculate_ins_pos(widget)
|
||||
XtGetValues(XtParent(widget), args, n);
|
||||
|
||||
retval = num_children;
|
||||
for (i = 0; i < num_children; ++i)
|
||||
for (i = 0; i < (int)num_children; ++i)
|
||||
{
|
||||
Widget current = children[i];
|
||||
vimmenu_T *menu = NULL;
|
||||
@@ -780,11 +778,10 @@ athena_calculate_ins_pos(widget)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
gui_mch_add_menu(menu, idx)
|
||||
vimmenu_T *menu;
|
||||
int idx;
|
||||
int idx UNUSED;
|
||||
{
|
||||
char_u *pullright_name;
|
||||
Dimension height, space, border;
|
||||
@@ -869,7 +866,7 @@ gui_mch_add_menu(menu, idx)
|
||||
XtVaGetValues(parent->submenu_id, XtNchildren, &children,
|
||||
XtNnumChildren, &num_children,
|
||||
NULL);
|
||||
for (i = 0; i < num_children; ++i)
|
||||
for (i = 0; i < (int)num_children; ++i)
|
||||
{
|
||||
XtVaSetValues(children[i],
|
||||
XtNrightMargin, puller_width,
|
||||
@@ -913,7 +910,7 @@ gui_athena_menu_has_submenus(id, ignore)
|
||||
XtVaGetValues(id, XtNchildren, &children,
|
||||
XtNnumChildren, &num_children,
|
||||
NULL);
|
||||
for (i = 0; i < num_children; ++i)
|
||||
for (i = 0; i < (int)num_children; ++i)
|
||||
{
|
||||
if (children[i] == ignore)
|
||||
continue;
|
||||
@@ -1175,11 +1172,10 @@ make_pull_name(name)
|
||||
return pname;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
gui_mch_add_menu_item(menu, idx)
|
||||
vimmenu_T *menu;
|
||||
int idx;
|
||||
int idx UNUSED;
|
||||
{
|
||||
vimmenu_T *parent = menu->parent;
|
||||
|
||||
@@ -1444,7 +1440,7 @@ gui_mch_compute_toolbar_height()
|
||||
XtNchildren, &children,
|
||||
XtNnumChildren, &numChildren,
|
||||
NULL);
|
||||
for (i = 0; i < numChildren; i++)
|
||||
for (i = 0; i < (int)numChildren; i++)
|
||||
{
|
||||
whgt = 0;
|
||||
|
||||
@@ -1473,10 +1469,9 @@ gui_mch_get_toolbar_colors(bgp, fgp, bsp, tsp, hsp)
|
||||
#endif
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
gui_mch_toggle_tearoffs(enable)
|
||||
int enable;
|
||||
int enable UNUSED;
|
||||
{
|
||||
/* no tearoff menus */
|
||||
}
|
||||
@@ -1537,7 +1532,7 @@ gui_mch_destroy_menu(menu)
|
||||
else
|
||||
get_left_margin = True;
|
||||
|
||||
for (i = 0; i < num_children; ++i)
|
||||
for (i = 0; i < (int)num_children; ++i)
|
||||
{
|
||||
if (children[i] == menu->id)
|
||||
continue;
|
||||
@@ -1645,11 +1640,10 @@ gui_mch_destroy_menu(menu)
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
gui_athena_menu_timeout(client_data, id)
|
||||
XtPointer client_data;
|
||||
XtIntervalId *id;
|
||||
XtIntervalId *id UNUSED;
|
||||
{
|
||||
Widget w = (Widget)client_data;
|
||||
Widget popup;
|
||||
@@ -1678,12 +1672,11 @@ gui_athena_menu_timeout(client_data, id)
|
||||
*
|
||||
* This is called when XtPopup() is called.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
gui_athena_popup_callback(w, client_data, call_data)
|
||||
Widget w;
|
||||
XtPointer client_data;
|
||||
XtPointer call_data;
|
||||
XtPointer call_data UNUSED;
|
||||
{
|
||||
/* Assumption: XtIsSubclass(XtParent(w),simpleMenuWidgetClass) */
|
||||
vimmenu_T *menu = (vimmenu_T *)client_data;
|
||||
@@ -1711,7 +1704,6 @@ gui_athena_popup_callback(w, client_data, call_data)
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
gui_athena_popdown_submenus_action(w, event, args, nargs)
|
||||
Widget w;
|
||||
@@ -1756,7 +1748,6 @@ has_submenu(widget)
|
||||
return False;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
gui_athena_delayed_arm_action(w, event, args, nargs)
|
||||
Widget w;
|
||||
@@ -1837,7 +1828,6 @@ submenu_widget(widget)
|
||||
* (XtIsSubclass(popup,simpleMenuWidgetClass) == True) */
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
gui_mch_show_popupmenu(menu)
|
||||
vimmenu_T *menu;
|
||||
@@ -2046,15 +2036,14 @@ gui_x11_get_wid()
|
||||
* Put up a file requester.
|
||||
* Returns the selected name in allocated memory, or NULL for Cancel.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
char_u *
|
||||
gui_mch_browse(saving, title, dflt, ext, initdir, filter)
|
||||
int saving; /* select file to write */
|
||||
char_u *title; /* not used (title for the window) */
|
||||
char_u *dflt; /* not used (default name) */
|
||||
char_u *ext; /* not used (extension added) */
|
||||
int saving UNUSED; /* select file to write */
|
||||
char_u *title; /* title for the window */
|
||||
char_u *dflt; /* default name */
|
||||
char_u *ext UNUSED; /* extension added */
|
||||
char_u *initdir; /* initial directory, NULL for current dir */
|
||||
char_u *filter; /* not used (file name filter) */
|
||||
char_u *filter UNUSED; /* file name filter */
|
||||
{
|
||||
Position x, y;
|
||||
char_u dirbuf[MAXPATHL];
|
||||
@@ -2100,13 +2089,12 @@ static void dialog_wm_handler __ARGS((Widget w, XtPointer client_data, XEvent *e
|
||||
* Callback function for the textfield. When CR is hit this works like
|
||||
* hitting the "OK" button, ESC like "Cancel".
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
keyhit_callback(w, client_data, event, cont)
|
||||
Widget w;
|
||||
XtPointer client_data;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data UNUSED;
|
||||
XEvent *event;
|
||||
Boolean *cont;
|
||||
Boolean *cont UNUSED;
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
@@ -2119,12 +2107,11 @@ keyhit_callback(w, client_data, event, cont)
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
butproc(w, client_data, call_data)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data;
|
||||
XtPointer call_data;
|
||||
XtPointer call_data UNUSED;
|
||||
{
|
||||
dialogStatus = (int)(long)client_data + 1;
|
||||
}
|
||||
@@ -2132,27 +2119,25 @@ butproc(w, client_data, call_data)
|
||||
/*
|
||||
* Function called when dialog window closed.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
dialog_wm_handler(w, client_data, event, dum)
|
||||
Widget w;
|
||||
XtPointer client_data;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data UNUSED;
|
||||
XEvent *event;
|
||||
Boolean *dum;
|
||||
Boolean *dum UNUSED;
|
||||
{
|
||||
if (event->type == ClientMessage
|
||||
&& ((XClientMessageEvent *)event)->data.l[0] == dialogatom)
|
||||
&& (Atom)((XClientMessageEvent *)event)->data.l[0] == dialogatom)
|
||||
dialogStatus = 0;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
gui_mch_dialog(type, title, message, buttons, dfltbutton, textfield)
|
||||
int type;
|
||||
int type UNUSED;
|
||||
char_u *title;
|
||||
char_u *message;
|
||||
char_u *buttons;
|
||||
int dfltbutton;
|
||||
int dfltbutton UNUSED;
|
||||
char_u *textfield;
|
||||
{
|
||||
char_u *buts;
|
||||
|
||||
+25
-12
@@ -15,11 +15,10 @@
|
||||
/*
|
||||
* Common code, invoked when the mouse is resting for a moment.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
general_beval_cb(beval, state)
|
||||
BalloonEval *beval;
|
||||
int state;
|
||||
int state UNUSED;
|
||||
{
|
||||
win_T *wp;
|
||||
int col;
|
||||
@@ -551,9 +550,8 @@ target_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
|
||||
return FALSE; /* continue emission */
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static gint
|
||||
mainwin_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
|
||||
mainwin_event_cb(GtkWidget *widget UNUSED, GdkEvent *event, gpointer data)
|
||||
{
|
||||
BalloonEval *beval = (BalloonEval *)data;
|
||||
|
||||
@@ -663,9 +661,10 @@ timeout_cb(gpointer data)
|
||||
return FALSE; /* don't call me again */
|
||||
}
|
||||
|
||||
/*ARGSUSED2*/
|
||||
static gint
|
||||
balloon_expose_event_cb(GtkWidget *widget, GdkEventExpose *event, gpointer data)
|
||||
balloon_expose_event_cb(GtkWidget *widget,
|
||||
GdkEventExpose *event,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
gtk_paint_flat_box(widget->style, widget->window,
|
||||
GTK_STATE_NORMAL, GTK_SHADOW_OUT,
|
||||
@@ -676,7 +675,6 @@ balloon_expose_event_cb(GtkWidget *widget, GdkEventExpose *event, gpointer data)
|
||||
}
|
||||
|
||||
# ifndef HAVE_GTK2
|
||||
/*ARGSUSED2*/
|
||||
static void
|
||||
balloon_draw_cb(GtkWidget *widget, GdkRectangle *area, gpointer data)
|
||||
{
|
||||
@@ -726,13 +724,12 @@ removeEventHandler(beval)
|
||||
/*
|
||||
* The X event handler. All it does is call the real event handler.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
pointerEventEH(w, client_data, event, unused)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data;
|
||||
XEvent *event;
|
||||
Boolean *unused;
|
||||
Boolean *unused UNUSED;
|
||||
{
|
||||
BalloonEval *beval = (BalloonEval *)client_data;
|
||||
pointerEvent(beval, event);
|
||||
@@ -877,11 +874,10 @@ pointerEvent(beval, event)
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
timerRoutine(dx, id)
|
||||
XtPointer dx;
|
||||
XtIntervalId *id;
|
||||
XtIntervalId *id UNUSED;
|
||||
{
|
||||
BalloonEval *beval = (BalloonEval *)dx;
|
||||
|
||||
@@ -1291,6 +1287,23 @@ drawBalloon(beval)
|
||||
XtNy, ty,
|
||||
NULL);
|
||||
#endif
|
||||
/* Set tooltip colors */
|
||||
{
|
||||
Arg args[2];
|
||||
|
||||
#ifdef FEAT_GUI_MOTIF
|
||||
args[0].name = XmNbackground;
|
||||
args[0].value = gui.tooltip_bg_pixel;
|
||||
args[1].name = XmNforeground;
|
||||
args[1].value = gui.tooltip_fg_pixel;
|
||||
#else /* Athena */
|
||||
args[0].name = XtNbackground;
|
||||
args[0].value = gui.tooltip_bg_pixel;
|
||||
args[1].name = XtNforeground;
|
||||
args[1].value = gui.tooltip_fg_pixel;
|
||||
#endif
|
||||
XtSetValues(beval->balloonLabel, &args[0], XtNumber(args));
|
||||
}
|
||||
|
||||
XtPopup(beval->balloonShell, XtGrabNone);
|
||||
|
||||
|
||||
+22
-38
@@ -285,14 +285,14 @@ create_menu_icon(vimmenu_T *menu, GtkIconSize icon_size)
|
||||
return image;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static gint
|
||||
toolbar_button_focus_in_event(GtkWidget *widget, GdkEventFocus *event, gpointer data)
|
||||
toolbar_button_focus_in_event(GtkWidget *widget UNUSED,
|
||||
GdkEventFocus *event UNUSED,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
/* When we're in a GtkPlug, we don't have window focus events, only widget focus.
|
||||
* To emulate stand-alone gvim, if a button gets focus (e.g., <Tab> into GtkPlug)
|
||||
* immediately pass it to mainwin.
|
||||
*/
|
||||
/* When we're in a GtkPlug, we don't have window focus events, only widget
|
||||
* focus. To emulate stand-alone gvim, if a button gets focus (e.g.,
|
||||
* <Tab> into GtkPlug) immediately pass it to mainwin. */
|
||||
if (gtk_socket_id != 0)
|
||||
gtk_widget_grab_focus(gui.drawarea);
|
||||
|
||||
@@ -585,9 +585,8 @@ gui_mch_add_menu(vimmenu_T *menu, int idx)
|
||||
gtk_menu_prepend(GTK_MENU(menu->submenu_id), menu->tearoff_handle);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
menu_item_activate(GtkWidget *widget, gpointer data)
|
||||
menu_item_activate(GtkWidget *widget UNUSED, gpointer data)
|
||||
{
|
||||
gui_menu_cb((vimmenu_T *)data);
|
||||
|
||||
@@ -1202,9 +1201,8 @@ gui_mch_destroy_scrollbar(scrollbar_T *sb)
|
||||
#endif
|
||||
|
||||
#ifndef USE_FILE_CHOOSER
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
browse_ok_cb(GtkWidget *widget, gpointer cbdata)
|
||||
browse_ok_cb(GtkWidget *widget UNUSED, gpointer cbdata)
|
||||
{
|
||||
gui_T *vw = (gui_T *)cbdata;
|
||||
|
||||
@@ -1218,9 +1216,8 @@ browse_ok_cb(GtkWidget *widget, gpointer cbdata)
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
browse_cancel_cb(GtkWidget *widget, gpointer cbdata)
|
||||
browse_cancel_cb(GtkWidget *widget UNUSED, gpointer cbdata)
|
||||
{
|
||||
gui_T *vw = (gui_T *)cbdata;
|
||||
|
||||
@@ -1234,9 +1231,8 @@ browse_cancel_cb(GtkWidget *widget, gpointer cbdata)
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static gboolean
|
||||
browse_destroy_cb(GtkWidget * widget)
|
||||
browse_destroy_cb(GtkWidget *widget UNUSED)
|
||||
{
|
||||
if (gui.browse_fname != NULL)
|
||||
{
|
||||
@@ -1262,14 +1258,13 @@ browse_destroy_cb(GtkWidget * widget)
|
||||
* initdir initial directory, NULL for current dir
|
||||
* filter not used (file name filter)
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
gui_mch_browse(int saving,
|
||||
gui_mch_browse(int saving UNUSED,
|
||||
char_u *title,
|
||||
char_u *dflt,
|
||||
char_u *ext,
|
||||
char_u *ext UNUSED,
|
||||
char_u *initdir,
|
||||
char_u *filter)
|
||||
char_u *filter UNUSED)
|
||||
{
|
||||
#ifdef USE_FILE_CHOOSER
|
||||
GtkWidget *fc;
|
||||
@@ -1377,7 +1372,6 @@ gui_mch_browse(int saving,
|
||||
* dflt default name
|
||||
* initdir initial directory, NULL for current dir
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
gui_mch_browsedir(
|
||||
char_u *title,
|
||||
@@ -1460,7 +1454,6 @@ dlg_destroy(GtkWidget *dlg)
|
||||
}
|
||||
|
||||
# ifdef FEAT_GUI_GNOME
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
gui_gnome_dialog( int type,
|
||||
char_u *title,
|
||||
@@ -1611,7 +1604,6 @@ typedef struct _CancelData
|
||||
GtkWidget *dialog;
|
||||
} CancelData;
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
dlg_button_clicked(GtkWidget * widget, ButtonData *data)
|
||||
{
|
||||
@@ -1622,7 +1614,6 @@ dlg_button_clicked(GtkWidget * widget, ButtonData *data)
|
||||
/*
|
||||
* This makes the Escape key equivalent to the cancel button.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
dlg_key_press_event(GtkWidget *widget, GdkEventKey *event, CancelData *data)
|
||||
{
|
||||
@@ -1655,7 +1646,6 @@ dlg_destroy_cb(int *p)
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
gui_mch_dialog( int type, /* type of dialog */
|
||||
char_u *title, /* title of dialog */
|
||||
@@ -2215,7 +2205,6 @@ typedef struct _DialogInfo
|
||||
GtkDialog *dialog; /* Widget of the dialog */
|
||||
} DialogInfo;
|
||||
|
||||
/*ARGSUSED2*/
|
||||
static gboolean
|
||||
dialog_key_press_event_cb(GtkWidget *widget, GdkEventKey *event, gpointer data)
|
||||
{
|
||||
@@ -2398,14 +2387,13 @@ static int popup_mouse_pos;
|
||||
* Note: The push_in output argument seems to affect scrolling of huge
|
||||
* menus that don't fit on the screen. Leave it at the default for now.
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
static void
|
||||
popup_menu_position_func(GtkMenu *menu,
|
||||
popup_menu_position_func(GtkMenu *menu UNUSED,
|
||||
gint *x, gint *y,
|
||||
# ifdef HAVE_GTK2
|
||||
gboolean *push_in,
|
||||
gboolean *push_in UNUSED,
|
||||
# endif
|
||||
gpointer user_data)
|
||||
gpointer user_data UNUSED)
|
||||
{
|
||||
gdk_window_get_origin(gui.drawarea->window, x, y);
|
||||
|
||||
@@ -2464,13 +2452,12 @@ typedef struct _SharedFindReplace
|
||||
GtkWidget *all; /* 'Replace All' action button */
|
||||
} SharedFindReplace;
|
||||
|
||||
static SharedFindReplace find_widgets = { NULL, };
|
||||
static SharedFindReplace repl_widgets = { NULL, };
|
||||
static SharedFindReplace find_widgets = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
||||
static SharedFindReplace repl_widgets = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
find_key_press_event(
|
||||
GtkWidget *widget,
|
||||
GtkWidget *widget UNUSED,
|
||||
GdkEventKey *event,
|
||||
SharedFindReplace *frdp)
|
||||
{
|
||||
@@ -2962,9 +2949,8 @@ gui_gtk_synch_fonts(void)
|
||||
/*
|
||||
* Callback for actions of the find and replace dialogs
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
find_replace_cb(GtkWidget *widget, gpointer data)
|
||||
find_replace_cb(GtkWidget *widget UNUSED, gpointer data)
|
||||
{
|
||||
int flags;
|
||||
char_u *find_text;
|
||||
@@ -3010,9 +2996,8 @@ find_replace_cb(GtkWidget *widget, gpointer data)
|
||||
}
|
||||
|
||||
/* our usual callback function */
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
entry_activate_cb(GtkWidget *widget, gpointer data)
|
||||
entry_activate_cb(GtkWidget *widget UNUSED, gpointer data)
|
||||
{
|
||||
gtk_widget_grab_focus(GTK_WIDGET(data));
|
||||
}
|
||||
@@ -3055,10 +3040,9 @@ entry_changed_cb(GtkWidget * entry, GtkWidget * dialog)
|
||||
/*
|
||||
* ":helpfind"
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ex_helpfind(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap UNUSED;
|
||||
{
|
||||
/* This will fail when menus are not loaded. Well, it's only for
|
||||
* backwards compatibility anyway. */
|
||||
|
||||
+15
-18
@@ -227,14 +227,14 @@ gtk_form_get_type(void)
|
||||
|
||||
if (!form_type)
|
||||
{
|
||||
GtkTypeInfo form_info =
|
||||
{
|
||||
"GtkForm",
|
||||
sizeof(GtkForm),
|
||||
sizeof(GtkFormClass),
|
||||
(GtkClassInitFunc) gtk_form_class_init,
|
||||
(GtkObjectInitFunc) gtk_form_init
|
||||
};
|
||||
GtkTypeInfo form_info;
|
||||
|
||||
vim_memset(&form_info, 0, sizeof(form_info));
|
||||
form_info.type_name = "GtkForm";
|
||||
form_info.object_size = sizeof(GtkForm);
|
||||
form_info.class_size = sizeof(GtkFormClass);
|
||||
form_info.class_init_func = (GtkClassInitFunc)gtk_form_class_init;
|
||||
form_info.object_init_func = (GtkObjectInitFunc)gtk_form_init;
|
||||
|
||||
form_type = gtk_type_unique(GTK_TYPE_CONTAINER, &form_info);
|
||||
}
|
||||
@@ -611,10 +611,9 @@ gtk_form_remove(GtkContainer *container, GtkWidget *widget)
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED1*/
|
||||
static void
|
||||
gtk_form_forall(GtkContainer *container,
|
||||
gboolean include_internals,
|
||||
gboolean include_internals UNUSED,
|
||||
GtkCallback callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
@@ -786,9 +785,8 @@ gtk_form_position_children(GtkForm *form)
|
||||
* them or discards them, depending on whether we are obscured
|
||||
* or not.
|
||||
*/
|
||||
/*ARGSUSED1*/
|
||||
static GdkFilterReturn
|
||||
gtk_form_filter(GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
|
||||
gtk_form_filter(GdkXEvent *gdk_xevent, GdkEvent *event UNUSED, gpointer data)
|
||||
{
|
||||
XEvent *xevent;
|
||||
GtkForm *form;
|
||||
@@ -821,9 +819,10 @@ gtk_form_filter(GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
|
||||
* there is no corresponding event in GTK, so we have
|
||||
* to get the events from a filter
|
||||
*/
|
||||
/*ARGSUSED1*/
|
||||
static GdkFilterReturn
|
||||
gtk_form_main_filter(GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
|
||||
gtk_form_main_filter(GdkXEvent *gdk_xevent,
|
||||
GdkEvent *event UNUSED,
|
||||
gpointer data)
|
||||
{
|
||||
XEvent *xevent;
|
||||
GtkForm *form;
|
||||
@@ -911,9 +910,8 @@ gtk_form_send_configure(GtkForm *form)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*ARGSUSED0*/
|
||||
static void
|
||||
gtk_form_child_map(GtkWidget *widget, gpointer user_data)
|
||||
gtk_form_child_map(GtkWidget *widget UNUSED, gpointer user_data)
|
||||
{
|
||||
GtkFormChild *child;
|
||||
|
||||
@@ -923,9 +921,8 @@ gtk_form_child_map(GtkWidget *widget, gpointer user_data)
|
||||
gdk_window_show(child->window);
|
||||
}
|
||||
|
||||
/*ARGSUSED0*/
|
||||
static void
|
||||
gtk_form_child_unmap(GtkWidget *widget, gpointer user_data)
|
||||
gtk_form_child_unmap(GtkWidget *widget UNUSED, gpointer user_data)
|
||||
{
|
||||
GtkFormChild *child;
|
||||
|
||||
|
||||
+170
-133
@@ -107,6 +107,7 @@ enum
|
||||
TARGET_UTF8_STRING,
|
||||
TARGET_STRING,
|
||||
TARGET_COMPOUND_TEXT,
|
||||
TARGET_HTML,
|
||||
TARGET_TEXT,
|
||||
TARGET_TEXT_URI_LIST,
|
||||
TARGET_TEXT_PLAIN,
|
||||
@@ -123,6 +124,7 @@ static const GtkTargetEntry selection_targets[] =
|
||||
{VIMENC_ATOM_NAME, 0, TARGET_VIMENC},
|
||||
{VIM_ATOM_NAME, 0, TARGET_VIM},
|
||||
#ifdef FEAT_MBYTE
|
||||
{"text/html", 0, TARGET_HTML},
|
||||
{"UTF8_STRING", 0, TARGET_UTF8_STRING},
|
||||
#endif
|
||||
{"COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT},
|
||||
@@ -140,6 +142,7 @@ static const GtkTargetEntry dnd_targets[] =
|
||||
{
|
||||
{"text/uri-list", 0, TARGET_TEXT_URI_LIST},
|
||||
# ifdef FEAT_MBYTE
|
||||
{"text/html", 0, TARGET_HTML},
|
||||
{"UTF8_STRING", 0, TARGET_UTF8_STRING},
|
||||
# endif
|
||||
{"STRING", 0, TARGET_STRING},
|
||||
@@ -178,6 +181,7 @@ static GdkAtom save_yourself_atom = GDK_NONE;
|
||||
* Atoms used to control/reference X11 selections.
|
||||
*/
|
||||
#ifdef FEAT_MBYTE
|
||||
static GdkAtom html_atom = GDK_NONE;
|
||||
static GdkAtom utf8_string_atom = GDK_NONE;
|
||||
#endif
|
||||
#ifndef HAVE_GTK2
|
||||
@@ -412,6 +416,7 @@ static const char *role_argument = NULL;
|
||||
#endif
|
||||
#if defined(FEAT_GUI_GNOME) && defined(FEAT_SESSION)
|
||||
static const char *restart_command = NULL;
|
||||
static char *abs_restart_command = NULL;
|
||||
#endif
|
||||
static int found_iconic_arg = FALSE;
|
||||
|
||||
@@ -449,8 +454,10 @@ gui_mch_prepare(int *argc, char **argv)
|
||||
char_u buf[MAXPATHL];
|
||||
|
||||
if (mch_FullName((char_u *)argv[0], buf, (int)sizeof(buf), TRUE) == OK)
|
||||
/* Tiny leak; doesn't matter, and usually we don't even get here */
|
||||
restart_command = (char *)vim_strsave(buf);
|
||||
{
|
||||
abs_restart_command = (char *)vim_strsave(buf);
|
||||
restart_command = abs_restart_command;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -611,6 +618,9 @@ gui_mch_prepare(int *argc, char **argv)
|
||||
gui_mch_free_all()
|
||||
{
|
||||
vim_free(gui_argv);
|
||||
#if defined(FEAT_GUI_GNOME) && defined(FEAT_SESSION)
|
||||
vim_free(abs_restart_command);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -619,9 +629,10 @@ gui_mch_free_all()
|
||||
* Doesn't seem possible, since check_copy_area() relies on
|
||||
* this information. --danielk
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static gint
|
||||
visibility_event(GtkWidget *widget, GdkEventVisibility *event, gpointer data)
|
||||
visibility_event(GtkWidget *widget UNUSED,
|
||||
GdkEventVisibility *event,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
gui.visibility = event->state;
|
||||
/*
|
||||
@@ -638,9 +649,10 @@ visibility_event(GtkWidget *widget, GdkEventVisibility *event, gpointer data)
|
||||
/*
|
||||
* Redraw the corresponding portions of the screen.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static gint
|
||||
expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
|
||||
expose_event(GtkWidget *widget UNUSED,
|
||||
GdkEventExpose *event,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
/* Skip this when the GUI isn't set up yet, will redraw later. */
|
||||
if (gui.starting)
|
||||
@@ -668,9 +680,10 @@ expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
|
||||
/*
|
||||
* Handle changes to the "Comm" property
|
||||
*/
|
||||
/*ARGSUSED2*/
|
||||
static gint
|
||||
property_event(GtkWidget *widget, GdkEventProperty *event, gpointer data)
|
||||
property_event(GtkWidget *widget,
|
||||
GdkEventProperty *event,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
if (event->type == GDK_PROPERTY_NOTIFY
|
||||
&& event->state == (int)GDK_PROPERTY_NEW_VALUE
|
||||
@@ -740,9 +753,8 @@ gui_mch_stop_blink(void)
|
||||
blink_state = BLINK_NONE;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static gint
|
||||
blink_cb(gpointer data)
|
||||
blink_cb(gpointer data UNUSED)
|
||||
{
|
||||
if (blink_state == BLINK_ON)
|
||||
{
|
||||
@@ -781,9 +793,10 @@ gui_mch_start_blink(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static gint
|
||||
enter_notify_event(GtkWidget *widget, GdkEventCrossing *event, gpointer data)
|
||||
enter_notify_event(GtkWidget *widget UNUSED,
|
||||
GdkEventCrossing *event UNUSED,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
if (blink_state == BLINK_NONE)
|
||||
gui_mch_start_blink();
|
||||
@@ -795,9 +808,10 @@ enter_notify_event(GtkWidget *widget, GdkEventCrossing *event, gpointer data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static gint
|
||||
leave_notify_event(GtkWidget *widget, GdkEventCrossing *event, gpointer data)
|
||||
leave_notify_event(GtkWidget *widget UNUSED,
|
||||
GdkEventCrossing *event UNUSED,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
if (blink_state != BLINK_NONE)
|
||||
gui_mch_stop_blink();
|
||||
@@ -805,9 +819,10 @@ leave_notify_event(GtkWidget *widget, GdkEventCrossing *event, gpointer data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static gint
|
||||
focus_in_event(GtkWidget *widget, GdkEventFocus *event, gpointer data)
|
||||
focus_in_event(GtkWidget *widget,
|
||||
GdkEventFocus *event UNUSED,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
gui_focus_change(TRUE);
|
||||
|
||||
@@ -826,9 +841,10 @@ focus_in_event(GtkWidget *widget, GdkEventFocus *event, gpointer data)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static gint
|
||||
focus_out_event(GtkWidget *widget, GdkEventFocus *event, gpointer data)
|
||||
focus_out_event(GtkWidget *widget UNUSED,
|
||||
GdkEventFocus *event UNUSED,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
gui_focus_change(FALSE);
|
||||
|
||||
@@ -956,9 +972,10 @@ modifiers_gdk2mouse(guint state)
|
||||
/*
|
||||
* Main keyboard handler:
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static gint
|
||||
key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
|
||||
key_press_event(GtkWidget *widget UNUSED,
|
||||
GdkEventKey *event,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
#ifdef HAVE_GTK2
|
||||
/* 256 bytes is way over the top, but for safety let's reduce it only
|
||||
@@ -1225,9 +1242,10 @@ key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
|
||||
}
|
||||
|
||||
#if defined(FEAT_XIM) && defined(HAVE_GTK2)
|
||||
/*ARGSUSED0*/
|
||||
static gboolean
|
||||
key_release_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
|
||||
key_release_event(GtkWidget *widget UNUSED,
|
||||
GdkEventKey *event,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
/*
|
||||
* GTK+ 2 input methods may do fancy stuff on key release events too.
|
||||
@@ -1243,11 +1261,10 @@ key_release_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
|
||||
* Selection handlers:
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
static gint
|
||||
selection_clear_event(GtkWidget *widget,
|
||||
selection_clear_event(GtkWidget *widget UNUSED,
|
||||
GdkEventSelection *event,
|
||||
gpointer user_data)
|
||||
gpointer user_data UNUSED)
|
||||
{
|
||||
if (event->selection == clip_plus.gtk_sel_atom)
|
||||
clip_lose_selection(&clip_plus);
|
||||
@@ -1265,12 +1282,11 @@ selection_clear_event(GtkWidget *widget,
|
||||
#define RS_FAIL 2 /* selection_received_cb() called and failed */
|
||||
static int received_selection = RS_NONE;
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
selection_received_cb(GtkWidget *widget,
|
||||
selection_received_cb(GtkWidget *widget UNUSED,
|
||||
GtkSelectionData *data,
|
||||
guint time_,
|
||||
gpointer user_data)
|
||||
guint time_ UNUSED,
|
||||
gpointer user_data UNUSED)
|
||||
{
|
||||
VimClipboard *cbd;
|
||||
char_u *text;
|
||||
@@ -1352,6 +1368,24 @@ selection_received_cb(GtkWidget *widget,
|
||||
else
|
||||
text = tmpbuf_utf8;
|
||||
}
|
||||
else if (len >= 2 && text[0] == 0xff && text[1] == 0xfe)
|
||||
{
|
||||
vimconv_T conv;
|
||||
|
||||
/* UTF-16, we get this for HTML */
|
||||
conv.vc_type = CONV_NONE;
|
||||
convert_setup_ext(&conv, (char_u *)"utf-16le", FALSE, p_enc, TRUE);
|
||||
|
||||
if (conv.vc_type != CONV_NONE)
|
||||
{
|
||||
text += 2;
|
||||
len -= 2;
|
||||
tmpbuf = string_convert(&conv, text, &len);
|
||||
convert_setup(&conv, NULL, NULL);
|
||||
}
|
||||
if (tmpbuf != NULL)
|
||||
text = tmpbuf;
|
||||
}
|
||||
}
|
||||
#else /* !HAVE_GTK2 */
|
||||
# ifdef FEAT_MBYTE
|
||||
@@ -1414,13 +1448,12 @@ selection_received_cb(GtkWidget *widget,
|
||||
* Prepare our selection data for passing it to the external selection
|
||||
* client.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
selection_get_cb(GtkWidget *widget,
|
||||
selection_get_cb(GtkWidget *widget UNUSED,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time_,
|
||||
gpointer user_data)
|
||||
guint time_ UNUSED,
|
||||
gpointer user_data UNUSED)
|
||||
{
|
||||
char_u *string;
|
||||
char_u *tmpbuf;
|
||||
@@ -1440,6 +1473,7 @@ selection_get_cb(GtkWidget *widget,
|
||||
|
||||
if (info != (guint)TARGET_STRING
|
||||
#ifdef FEAT_MBYTE
|
||||
&& (!clip_html || info != (guint)TARGET_HTML)
|
||||
&& info != (guint)TARGET_UTF8_STRING
|
||||
&& info != (guint)TARGET_VIMENC
|
||||
#endif
|
||||
@@ -1475,6 +1509,40 @@ selection_get_cb(GtkWidget *widget,
|
||||
}
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
else if (info == (guint)TARGET_HTML)
|
||||
{
|
||||
vimconv_T conv;
|
||||
|
||||
/* Since we get utf-16, we probably should set it as well. */
|
||||
conv.vc_type = CONV_NONE;
|
||||
convert_setup_ext(&conv, p_enc, TRUE, (char_u *)"utf-16le", FALSE);
|
||||
if (conv.vc_type != CONV_NONE)
|
||||
{
|
||||
tmpbuf = string_convert(&conv, string, &length);
|
||||
convert_setup(&conv, NULL, NULL);
|
||||
vim_free(string);
|
||||
string = tmpbuf;
|
||||
}
|
||||
|
||||
/* Prepend the BOM: "fffe" */
|
||||
if (string != NULL)
|
||||
{
|
||||
tmpbuf = alloc(length + 2);
|
||||
tmpbuf[0] = 0xff;
|
||||
tmpbuf[1] = 0xfe;
|
||||
mch_memmove(tmpbuf + 2, string, (size_t)length);
|
||||
vim_free(string);
|
||||
string = tmpbuf;
|
||||
length += 2;
|
||||
|
||||
selection_data->type = selection_data->target;
|
||||
selection_data->format = 16; /* 16 bits per char */
|
||||
gtk_selection_data_set(selection_data, html_atom, 16,
|
||||
string, length);
|
||||
vim_free(string);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (info == (guint)TARGET_VIMENC)
|
||||
{
|
||||
int l = STRLEN(p_enc);
|
||||
@@ -1678,7 +1746,7 @@ process_motion_notify(int x, int y, GdkModifierType state)
|
||||
|
||||
offshoot = dx > dy ? dx : dy;
|
||||
|
||||
/* Make a linearly declaying timer delay with a threshold of 5 at a
|
||||
/* Make a linearly decaying timer delay with a threshold of 5 at a
|
||||
* distance of 127 pixels from the main window.
|
||||
*
|
||||
* One could think endlessly about the most ergonomic variant here.
|
||||
@@ -1707,9 +1775,8 @@ process_motion_notify(int x, int y, GdkModifierType state)
|
||||
/*
|
||||
* Timer used to recognize multiple clicks of the mouse button.
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
static gint
|
||||
motion_repeat_timer_cb(gpointer data)
|
||||
motion_repeat_timer_cb(gpointer data UNUSED)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
@@ -1749,9 +1816,10 @@ motion_repeat_timer_cb(gpointer data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*ARGSUSED2*/
|
||||
static gint
|
||||
motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
|
||||
motion_notify_event(GtkWidget *widget,
|
||||
GdkEventMotion *event,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
if (event->is_hint)
|
||||
{
|
||||
@@ -1777,9 +1845,10 @@ motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
|
||||
* by our own timeout mechanism instead of the one provided by GTK+ itself.
|
||||
* This is due to the way the generic VIM code is recognizing multiple clicks.
|
||||
*/
|
||||
/*ARGSUSED2*/
|
||||
static gint
|
||||
button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
|
||||
button_press_event(GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
int button;
|
||||
int repeated_click = FALSE;
|
||||
@@ -1855,9 +1924,10 @@ button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
|
||||
* GTK+ 2 doesn't handle mouse buttons 4, 5, 6 and 7 the same way as GTK+ 1.
|
||||
* Instead, it abstracts scrolling via the new GdkEventScroll.
|
||||
*/
|
||||
/*ARGSUSED2*/
|
||||
static gboolean
|
||||
scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data)
|
||||
scroll_event(GtkWidget *widget,
|
||||
GdkEventScroll *event,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
int button;
|
||||
int_u vim_modifiers;
|
||||
@@ -1896,9 +1966,10 @@ scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data)
|
||||
#endif /* HAVE_GTK2 */
|
||||
|
||||
|
||||
/*ARGSUSED*/
|
||||
static gint
|
||||
button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
|
||||
button_release_event(GtkWidget *widget UNUSED,
|
||||
GdkEventButton *event,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
int x, y;
|
||||
int_u vim_modifiers;
|
||||
@@ -2100,7 +2171,6 @@ drag_handle_text(GdkDragContext *context,
|
||||
/*
|
||||
* DND receiver.
|
||||
*/
|
||||
/*ARGSUSED2*/
|
||||
static void
|
||||
drag_data_received_cb(GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
@@ -2109,7 +2179,7 @@ drag_data_received_cb(GtkWidget *widget,
|
||||
GtkSelectionData *data,
|
||||
guint info,
|
||||
guint time_,
|
||||
gpointer user_data)
|
||||
gpointer user_data UNUSED)
|
||||
{
|
||||
GdkModifierType state;
|
||||
|
||||
@@ -2143,7 +2213,6 @@ drag_data_received_cb(GtkWidget *widget,
|
||||
* be abandoned and pop up a dialog asking the user for confirmation if
|
||||
* necessary.
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
static void
|
||||
sm_client_check_changed_any(GnomeClient *client,
|
||||
gint key,
|
||||
@@ -2251,7 +2320,6 @@ write_session_file(char_u *filename)
|
||||
* for confirmation if necessary. Save the current editing session and tell
|
||||
* the session manager how to restart Vim.
|
||||
*/
|
||||
/*ARGSUSED1*/
|
||||
static gboolean
|
||||
sm_client_save_yourself(GnomeClient *client,
|
||||
gint phase,
|
||||
@@ -2339,7 +2407,6 @@ sm_client_save_yourself(GnomeClient *client,
|
||||
* here since "save_yourself" has been emitted before (unless serious trouble
|
||||
* is happening).
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
static void
|
||||
sm_client_die(GnomeClient *client, gpointer data)
|
||||
{
|
||||
@@ -2379,10 +2446,9 @@ setup_save_yourself(void)
|
||||
/*
|
||||
* GTK tells us that XSMP needs attention
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static gboolean
|
||||
local_xsmp_handle_requests(source, condition, data)
|
||||
GIOChannel *source;
|
||||
GIOChannel *source UNUSED;
|
||||
GIOCondition condition;
|
||||
gpointer data;
|
||||
{
|
||||
@@ -2480,16 +2546,18 @@ setup_save_yourself(void)
|
||||
* WM_SAVE_YOURSELF hack it actually stores the session... And yes,
|
||||
* it should work with KDE as well.
|
||||
*/
|
||||
/*ARGSUSED1*/
|
||||
static GdkFilterReturn
|
||||
global_event_filter(GdkXEvent *xev, GdkEvent *event, gpointer data)
|
||||
global_event_filter(GdkXEvent *xev,
|
||||
GdkEvent *event UNUSED,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
XEvent *xevent = (XEvent *)xev;
|
||||
|
||||
if (xevent != NULL
|
||||
&& xevent->type == ClientMessage
|
||||
&& xevent->xclient.message_type == GET_X_ATOM(wm_protocols_atom)
|
||||
&& xevent->xclient.data.l[0] == GET_X_ATOM(save_yourself_atom))
|
||||
&& (long_u)xevent->xclient.data.l[0]
|
||||
== GET_X_ATOM(save_yourself_atom))
|
||||
{
|
||||
out_flush();
|
||||
ml_sync_all(FALSE, FALSE); /* preserve all swap files */
|
||||
@@ -2512,7 +2580,6 @@ global_event_filter(GdkXEvent *xev, GdkEvent *event, gpointer data)
|
||||
/*
|
||||
* GDK handler for X ClientMessage events.
|
||||
*/
|
||||
/*ARGSUSED2*/
|
||||
static GdkFilterReturn
|
||||
gdk_wm_protocols_filter(GdkXEvent *xev, GdkEvent *event, gpointer data)
|
||||
{
|
||||
@@ -2558,9 +2625,8 @@ gdk_wm_protocols_filter(GdkXEvent *xev, GdkEvent *event, gpointer data)
|
||||
/*
|
||||
* Setup the window icon & xcmdsrv comm after the main window has been realized.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
mainwin_realize(GtkWidget *widget, gpointer data)
|
||||
mainwin_realize(GtkWidget *widget UNUSED, gpointer data UNUSED)
|
||||
{
|
||||
/* If you get an error message here, you still need to unpack the runtime
|
||||
* archive! */
|
||||
@@ -2712,11 +2778,10 @@ create_blank_pointer(void)
|
||||
}
|
||||
|
||||
#ifdef HAVE_GTK_MULTIHEAD
|
||||
/*ARGSUSED1*/
|
||||
static void
|
||||
mainwin_screen_changed_cb(GtkWidget *widget,
|
||||
GdkScreen *previous_screen,
|
||||
gpointer data)
|
||||
GdkScreen *previous_screen UNUSED,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
if (!gtk_widget_has_screen(widget))
|
||||
return;
|
||||
@@ -2757,9 +2822,8 @@ mainwin_screen_changed_cb(GtkWidget *widget,
|
||||
* Don't try to set any VIM scrollbar sizes anywhere here. I'm relying on the
|
||||
* fact that the main VIM engine doesn't take them into account anywhere.
|
||||
*/
|
||||
/*ARGSUSED1*/
|
||||
static void
|
||||
drawarea_realize_cb(GtkWidget *widget, gpointer data)
|
||||
drawarea_realize_cb(GtkWidget *widget, gpointer data UNUSED)
|
||||
{
|
||||
GtkWidget *sbar;
|
||||
|
||||
@@ -2789,9 +2853,8 @@ drawarea_realize_cb(GtkWidget *widget, gpointer data)
|
||||
/*
|
||||
* Properly clean up on shutdown.
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
static void
|
||||
drawarea_unrealize_cb(GtkWidget *widget, gpointer data)
|
||||
drawarea_unrealize_cb(GtkWidget *widget UNUSED, gpointer data UNUSED)
|
||||
{
|
||||
/* Don't write messages to the GUI anymore */
|
||||
full_screen = FALSE;
|
||||
@@ -2827,11 +2890,10 @@ drawarea_unrealize_cb(GtkWidget *widget, gpointer data)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*ARGSUSED0*/
|
||||
static void
|
||||
drawarea_style_set_cb(GtkWidget *widget,
|
||||
GtkStyle *previous_style,
|
||||
gpointer data)
|
||||
drawarea_style_set_cb(GtkWidget *widget UNUSED,
|
||||
GtkStyle *previous_style UNUSED,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
gui_mch_new_colors();
|
||||
}
|
||||
@@ -2840,9 +2902,10 @@ drawarea_style_set_cb(GtkWidget *widget,
|
||||
* Callback routine for the "delete_event" signal on the toplevel window.
|
||||
* Tries to vim gracefully, or refuses to exit with changed buffers.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static gint
|
||||
delete_event_cb(GtkWidget *widget, GdkEventAny *event, gpointer data)
|
||||
delete_event_cb(GtkWidget *widget UNUSED,
|
||||
GdkEventAny *event UNUSED,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
gui_shell_closed();
|
||||
return TRUE;
|
||||
@@ -2964,7 +3027,7 @@ update_window_manager_hints(int force_width, int force_height)
|
||||
|
||||
/* At start-up, don't try to set the hints until the initial
|
||||
* values have been used (those that dictate our initial size)
|
||||
* Let forced (i.e., correct) values thruogh always.
|
||||
* Let forced (i.e., correct) values through always.
|
||||
*/
|
||||
if (!(force_width && force_height) && init_window_hints_state > 0)
|
||||
{
|
||||
@@ -3142,9 +3205,8 @@ static int clicked_page; /* page clicked in tab line */
|
||||
/*
|
||||
* Handle selecting an item in the tab line popup menu.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
tabline_menu_handler(GtkMenuItem *item, gpointer user_data)
|
||||
tabline_menu_handler(GtkMenuItem *item UNUSED, gpointer user_data)
|
||||
{
|
||||
/* Add the string cmd into input buffer */
|
||||
send_tabline_menu_event(clicked_page, (int)(long)user_data);
|
||||
@@ -3244,13 +3306,12 @@ on_tabline_menu(GtkWidget *widget, GdkEvent *event)
|
||||
/*
|
||||
* Handle selecting one of the tabs.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
on_select_tab(
|
||||
GtkNotebook *notebook,
|
||||
GtkNotebookPage *page,
|
||||
GtkNotebook *notebook UNUSED,
|
||||
GtkNotebookPage *page UNUSED,
|
||||
gint idx,
|
||||
gpointer data)
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
if (!ignore_tabline_evt)
|
||||
{
|
||||
@@ -3460,6 +3521,7 @@ gui_mch_init(void)
|
||||
|
||||
/* Initialise atoms */
|
||||
#ifdef FEAT_MBYTE
|
||||
html_atom = gdk_atom_intern("text/html", FALSE);
|
||||
utf8_string_atom = gdk_atom_intern("UTF8_STRING", FALSE);
|
||||
#endif
|
||||
#ifndef HAVE_GTK2
|
||||
@@ -3784,7 +3846,7 @@ gui_mch_init(void)
|
||||
#endif
|
||||
|
||||
if (gtk_socket_id != 0)
|
||||
/* make sure keybord input can go to the drawarea */
|
||||
/* make sure keyboard input can go to the drawarea */
|
||||
GTK_WIDGET_SET_FLAGS(gui.drawarea, GTK_CAN_FOCUS);
|
||||
|
||||
/*
|
||||
@@ -3922,10 +3984,10 @@ gui_mch_new_colors(void)
|
||||
/*
|
||||
* This signal informs us about the need to rearrange our sub-widgets.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static gint
|
||||
form_configure_event(GtkWidget *widget, GdkEventConfigure *event,
|
||||
gpointer data)
|
||||
form_configure_event(GtkWidget *widget UNUSED,
|
||||
GdkEventConfigure *event,
|
||||
gpointer data UNUSED)
|
||||
{
|
||||
int usable_height = event->height;
|
||||
|
||||
@@ -3948,9 +4010,8 @@ form_configure_event(GtkWidget *widget, GdkEventConfigure *event,
|
||||
* We can't do much more here than to trying to preserve what had been done,
|
||||
* since the window is already inevitably going away.
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
static void
|
||||
mainwin_destroy_cb(GtkObject *object, gpointer data)
|
||||
mainwin_destroy_cb(GtkObject *object UNUSED, gpointer data UNUSED)
|
||||
{
|
||||
/* Don't write messages to the GUI anymore */
|
||||
full_screen = FALSE;
|
||||
@@ -3980,9 +4041,8 @@ mainwin_destroy_cb(GtkObject *object, gpointer data)
|
||||
* scrollbar init.), actually do the standard hinst and stop the timer.
|
||||
* We'll not let the default hints be set while this timer's active.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static gboolean
|
||||
check_startup_plug_hints(gpointer data)
|
||||
check_startup_plug_hints(gpointer data UNUSED)
|
||||
{
|
||||
if (init_window_hints_state == 1)
|
||||
{
|
||||
@@ -4055,7 +4115,7 @@ gui_mch_open(void)
|
||||
Columns = w;
|
||||
if (mask & HeightValue)
|
||||
{
|
||||
if (p_window > h - 1 || !option_was_set((char_u *)"window"))
|
||||
if (p_window > (long)h - 1 || !option_was_set((char_u *)"window"))
|
||||
p_window = h - 1;
|
||||
Rows = h;
|
||||
}
|
||||
@@ -4229,9 +4289,8 @@ gui_mch_open(void)
|
||||
}
|
||||
|
||||
|
||||
/*ARGSUSED0*/
|
||||
void
|
||||
gui_mch_exit(int rc)
|
||||
gui_mch_exit(int rc UNUSED)
|
||||
{
|
||||
if (gui.mainwin != NULL)
|
||||
gtk_widget_destroy(gui.mainwin);
|
||||
@@ -4286,7 +4345,6 @@ static int resize_idle_installed = FALSE;
|
||||
* report the new size through form_configure_event(). That caused the window
|
||||
* layout to be messed up.
|
||||
*/
|
||||
/*ARGSUSED0*/
|
||||
static gboolean
|
||||
force_shell_resize_idle(gpointer data)
|
||||
{
|
||||
@@ -4314,12 +4372,11 @@ force_shell_resize_idle(gpointer data)
|
||||
/*
|
||||
* Set the windows size.
|
||||
*/
|
||||
/*ARGSUSED2*/
|
||||
void
|
||||
gui_mch_set_shellsize(int width, int height,
|
||||
int min_width, int min_height,
|
||||
int base_width, int base_height,
|
||||
int direction)
|
||||
int min_width UNUSED, int min_height UNUSED,
|
||||
int base_width UNUSED, int base_height UNUSED,
|
||||
int direction UNUSED)
|
||||
{
|
||||
#ifndef HAVE_GTK2
|
||||
/* Hack: When the form already is at the desired size, the window might
|
||||
@@ -4413,9 +4470,8 @@ gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
|
||||
}
|
||||
|
||||
#if defined(FEAT_TITLE) || defined(PROTO)
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
gui_mch_settitle(char_u *title, char_u *icon)
|
||||
gui_mch_settitle(char_u *title, char_u *icon UNUSED)
|
||||
{
|
||||
# ifdef HAVE_GTK2
|
||||
if (title != NULL && output_conv.vc_type != CONV_NONE)
|
||||
@@ -4493,7 +4549,6 @@ gui_mch_show_toolbar(int showit)
|
||||
* Get a font structure for highlighting.
|
||||
* "cbdata" is a pointer to the global gui structure.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
font_sel_ok(GtkWidget *wgt, gpointer cbdata)
|
||||
{
|
||||
@@ -4509,7 +4564,6 @@ font_sel_ok(GtkWidget *wgt, gpointer cbdata)
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
font_sel_cancel(GtkWidget *wgt, gpointer cbdata)
|
||||
{
|
||||
@@ -4520,7 +4574,6 @@ font_sel_cancel(GtkWidget *wgt, gpointer cbdata)
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
font_sel_destroy(GtkWidget *wgt, gpointer cbdata)
|
||||
{
|
||||
@@ -4620,7 +4673,6 @@ gui_mch_adjust_charheight(void)
|
||||
/*
|
||||
* Try to load the requested fontset.
|
||||
*/
|
||||
/*ARGSUSED2*/
|
||||
GuiFontset
|
||||
gui_mch_get_fontset(char_u *name, int report_error, int fixed_width)
|
||||
{
|
||||
@@ -4863,7 +4915,7 @@ get_styled_font_variants(char_u * font_name)
|
||||
styled_font[1] = &gui.ital_font;
|
||||
styled_font[2] = &gui.boldital_font;
|
||||
|
||||
/* First free whatever was freviously there. */
|
||||
/* First free whatever was previously there. */
|
||||
for (i = 0; i < 3; ++i)
|
||||
if (*styled_font[i])
|
||||
{
|
||||
@@ -5012,9 +5064,8 @@ ascii_glyph_table_init(void)
|
||||
* Initialize Vim to use the font or fontset with the given name.
|
||||
* Return FAIL if the font could not be loaded, OK otherwise.
|
||||
*/
|
||||
/*ARGSUSED1*/
|
||||
int
|
||||
gui_mch_init_font(char_u *font_name, int fontset)
|
||||
gui_mch_init_font(char_u *font_name, int fontset UNUSED)
|
||||
{
|
||||
#ifdef HAVE_GTK2
|
||||
PangoFontDescription *font_desc;
|
||||
@@ -5326,9 +5377,8 @@ gui_mch_get_font(char_u *name, int report_error)
|
||||
/*
|
||||
* Return the name of font "font" in allocated memory.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
gui_mch_get_fontname(GuiFont font, char_u *name)
|
||||
gui_mch_get_fontname(GuiFont font, char_u *name UNUSED)
|
||||
{
|
||||
# ifdef HAVE_GTK2
|
||||
if (font != NOFONT)
|
||||
@@ -5732,7 +5782,7 @@ draw_under(int flags, int row, int col, int cells)
|
||||
{
|
||||
int i;
|
||||
int offset;
|
||||
const static int val[8] = {1, 0, 0, 0, 1, 2, 2, 2 };
|
||||
static const int val[8] = {1, 0, 0, 0, 1, 2, 2, 2 };
|
||||
int y = FILL_Y(row + 1) - 1;
|
||||
|
||||
/* Undercurl: draw curl at the bottom of the character cell. */
|
||||
@@ -6085,12 +6135,15 @@ gui_mch_draw_string(int row, int col, char_u *s, int len, int flags)
|
||||
# ifdef FEAT_MBYTE
|
||||
if (enc_utf8)
|
||||
{
|
||||
c = utf_ptr2char(p);
|
||||
int pcc[MAX_MCO];
|
||||
|
||||
/* TODO: use the composing characters */
|
||||
c = utfc_ptr2char_len(p, &pcc, len - (p - s));
|
||||
if (c >= 0x10000) /* show chars > 0xffff as ? */
|
||||
c = 0xbf;
|
||||
buf[textlen].byte1 = c >> 8;
|
||||
buf[textlen].byte2 = c;
|
||||
p += utf_ptr2len(p);
|
||||
p += utfc_ptr2len_len(p, len - (p - s));
|
||||
width += utf_char2cells(c);
|
||||
}
|
||||
else
|
||||
@@ -6114,8 +6167,8 @@ gui_mch_draw_string(int row, int col, char_u *s, int len, int flags)
|
||||
if (has_mbyte)
|
||||
{
|
||||
width = 0;
|
||||
for (p = s; p < s + len; p += (*mb_ptr2len)(p))
|
||||
width += (*mb_ptr2cells)(p);
|
||||
for (p = s; p < s + len; p += (*mb_ptr2len_len)(p, len - (p - s)))
|
||||
width += (*mb_ptr2cells_len)(p, len - (p - s));
|
||||
}
|
||||
else
|
||||
# endif
|
||||
@@ -6402,7 +6455,6 @@ input_timer_cb(gpointer data)
|
||||
/*
|
||||
* Callback function, used when data is available on the SNiFF connection.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
sniff_request_cb(
|
||||
gpointer data,
|
||||
@@ -6665,12 +6717,14 @@ clip_mch_request_selection(VimClipboard *cbd)
|
||||
{
|
||||
GdkAtom target;
|
||||
unsigned i;
|
||||
int nbytes;
|
||||
char_u *buffer;
|
||||
time_t start;
|
||||
|
||||
for (i = 0; i < N_SELECTION_TARGETS; ++i)
|
||||
{
|
||||
#ifdef FEAT_MBYTE
|
||||
if (!clip_html && selection_targets[i].info == TARGET_HTML)
|
||||
continue;
|
||||
#endif
|
||||
received_selection = RS_NONE;
|
||||
target = gdk_atom_intern(selection_targets[i].target, FALSE);
|
||||
|
||||
@@ -6690,30 +6744,14 @@ clip_mch_request_selection(VimClipboard *cbd)
|
||||
}
|
||||
|
||||
/* Final fallback position - use the X CUT_BUFFER0 store */
|
||||
nbytes = 0;
|
||||
buffer = (char_u *)XFetchBuffer(GDK_WINDOW_XDISPLAY(gui.mainwin->window),
|
||||
&nbytes, 0);
|
||||
if (nbytes > 0)
|
||||
{
|
||||
/* Got something */
|
||||
clip_yank_selection(MCHAR, buffer, (long)nbytes, cbd);
|
||||
if (p_verbose > 0)
|
||||
{
|
||||
verbose_enter();
|
||||
smsg((char_u *)_("Used CUT_BUFFER0 instead of empty selection"));
|
||||
verbose_leave();
|
||||
}
|
||||
}
|
||||
if (buffer != NULL)
|
||||
XFree(buffer);
|
||||
yank_cut_buffer0(GDK_WINDOW_XDISPLAY(gui.mainwin->window), cbd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disown the selection.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
clip_mch_lose_selection(VimClipboard *cbd)
|
||||
clip_mch_lose_selection(VimClipboard *cbd UNUSED)
|
||||
{
|
||||
/* WEIRD: when using NULL to actually disown the selection, we lose the
|
||||
* selection the first time we own it. */
|
||||
@@ -6741,9 +6779,8 @@ clip_mch_own_selection(VimClipboard *cbd)
|
||||
* Send the current selection to the clipboard. Do nothing for X because we
|
||||
* will fill in the selection only when requested by another app.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
clip_mch_set_selection(VimClipboard *cbd)
|
||||
clip_mch_set_selection(VimClipboard *cbd UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -6950,7 +6987,7 @@ mch_set_mouse_shape(int shape)
|
||||
else
|
||||
id &= ~1; /* they are always even (why?) */
|
||||
}
|
||||
else if (shape < sizeof(mshape_ids) / sizeof(int))
|
||||
else if (shape < (int)(sizeof(mshape_ids) / sizeof(int)))
|
||||
id = mshape_ids[shape];
|
||||
else
|
||||
return;
|
||||
|
||||
+50
-71
@@ -117,10 +117,9 @@ static void gui_motif_scroll_colors __ARGS((Widget id));
|
||||
* Call-back routines.
|
||||
*/
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
scroll_cb(w, client_data, call_data)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data, call_data;
|
||||
{
|
||||
scrollbar_T *sb;
|
||||
@@ -136,11 +135,11 @@ scroll_cb(w, client_data, call_data)
|
||||
}
|
||||
|
||||
#ifdef FEAT_GUI_TABLINE
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
tabline_cb(w, client_data, call_data)
|
||||
Widget w;
|
||||
XtPointer client_data, call_data;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data UNUSED;
|
||||
XtPointer call_data;
|
||||
{
|
||||
XmNotebookCallbackStruct *nptr;
|
||||
|
||||
@@ -149,11 +148,11 @@ tabline_cb(w, client_data, call_data)
|
||||
send_tabline_event(nptr->page_number);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
tabline_button_cb(w, client_data, call_data)
|
||||
Widget w;
|
||||
XtPointer client_data, call_data;
|
||||
XtPointer client_data UNUSED;
|
||||
XtPointer call_data UNUSED;
|
||||
{
|
||||
int cmd, tab_idx;
|
||||
|
||||
@@ -166,11 +165,10 @@ tabline_button_cb(w, client_data, call_data)
|
||||
/*
|
||||
* Tabline single mouse click timeout handler
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
motif_tabline_timer_cb (timed_out, interval_id)
|
||||
XtPointer timed_out;
|
||||
XtIntervalId *interval_id;
|
||||
XtIntervalId *interval_id UNUSED;
|
||||
{
|
||||
*((int *)timed_out) = TRUE;
|
||||
}
|
||||
@@ -203,13 +201,12 @@ tabline_scroller_clicked(scroller_name, event)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
tabline_menu_cb(w, closure, e, continue_dispatch)
|
||||
Widget w;
|
||||
XtPointer closure;
|
||||
XtPointer closure UNUSED;
|
||||
XEvent *e;
|
||||
Boolean *continue_dispatch;
|
||||
Boolean *continue_dispatch UNUSED;
|
||||
{
|
||||
Widget tab_w;
|
||||
XButtonPressedEvent *event;
|
||||
@@ -277,11 +274,10 @@ tabline_menu_cb(w, closure, e, continue_dispatch)
|
||||
XtManageChild(tabLine_menu);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
tabline_balloon_cb(beval, state)
|
||||
BalloonEval *beval;
|
||||
int state;
|
||||
int state UNUSED;
|
||||
{
|
||||
int nr;
|
||||
tabpage_T *tp;
|
||||
@@ -642,13 +638,12 @@ gui_x11_destroy_widgets()
|
||||
#endif
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
gui_mch_set_text_area_pos(x, y, w, h)
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
int x UNUSED;
|
||||
int y UNUSED;
|
||||
int w UNUSED;
|
||||
int h UNUSED;
|
||||
{
|
||||
#ifdef FEAT_TOOLBAR
|
||||
/* Give keyboard focus to the textArea instead of the toolbar. */
|
||||
@@ -1261,7 +1256,7 @@ get_toolbar_pixmap(menu, fname)
|
||||
if (menu->icon_builtin || gui_find_bitmap(menu->name, buf, "xpm") == FAIL)
|
||||
{
|
||||
if (menu->iconidx >= 0 && menu->iconidx
|
||||
< (sizeof(built_in_pixmaps) / sizeof(built_in_pixmaps[0])))
|
||||
< (int)(sizeof(built_in_pixmaps) / sizeof(built_in_pixmaps[0])))
|
||||
xpm = built_in_pixmaps[menu->iconidx];
|
||||
else
|
||||
xpm = tb_blank_xpm;
|
||||
@@ -1716,10 +1711,9 @@ gui_mch_destroy_menu(menu)
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
gui_mch_show_popupmenu(menu)
|
||||
vimmenu_T *menu;
|
||||
vimmenu_T *menu UNUSED;
|
||||
{
|
||||
#ifdef MOTIF_POPUP
|
||||
XmMenuPosition(menu->submenu_id, gui_x11_get_last_mouse_event());
|
||||
@@ -2046,9 +2040,8 @@ do_mnemonic(Widget w, unsigned int keycode)
|
||||
/*
|
||||
* Callback routine for dialog mnemonic processing.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
mnemonic_event(Widget w, XtPointer call_data, XKeyEvent *event)
|
||||
mnemonic_event(Widget w, XtPointer call_data UNUSED, XKeyEvent *event)
|
||||
{
|
||||
do_mnemonic(w, event->keycode);
|
||||
}
|
||||
@@ -2287,13 +2280,12 @@ set_predefined_fontlist(parent, name)
|
||||
* Put up a file requester.
|
||||
* Returns the selected name in allocated memory, or NULL for Cancel.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
char_u *
|
||||
gui_mch_browse(saving, title, dflt, ext, initdir, filter)
|
||||
int saving; /* select file to write */
|
||||
int saving UNUSED; /* select file to write */
|
||||
char_u *title; /* title for the window */
|
||||
char_u *dflt; /* default name */
|
||||
char_u *ext; /* not used (extension added) */
|
||||
char_u *ext UNUSED; /* not used (extension added) */
|
||||
char_u *initdir; /* initial directory, NULL for current dir */
|
||||
char_u *filter; /* file name filter */
|
||||
{
|
||||
@@ -2413,12 +2405,11 @@ gui_mch_browse(saving, title, dflt, ext, initdir, filter)
|
||||
/*
|
||||
* Process callback from Dialog cancel actions.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
DialogCancelCB(w, client_data, call_data)
|
||||
Widget w; /* widget id */
|
||||
XtPointer client_data; /* data from application */
|
||||
XtPointer call_data; /* data from widget class */
|
||||
Widget w UNUSED; /* widget id */
|
||||
XtPointer client_data UNUSED; /* data from application */
|
||||
XtPointer call_data UNUSED; /* data from widget class */
|
||||
{
|
||||
if (browse_fname != NULL)
|
||||
{
|
||||
@@ -2431,12 +2422,11 @@ DialogCancelCB(w, client_data, call_data)
|
||||
/*
|
||||
* Process callback from Dialog actions.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
DialogAcceptCB(w, client_data, call_data)
|
||||
Widget w; /* widget id */
|
||||
XtPointer client_data; /* data from application */
|
||||
XtPointer call_data; /* data from widget class */
|
||||
Widget w UNUSED; /* widget id */
|
||||
XtPointer client_data UNUSED; /* data from application */
|
||||
XtPointer call_data; /* data from widget class */
|
||||
{
|
||||
XmFileSelectionBoxCallbackStruct *fcb;
|
||||
|
||||
@@ -2467,13 +2457,12 @@ static void butproc __ARGS((Widget w, XtPointer client_data, XtPointer call_data
|
||||
* Callback function for the textfield. When CR is hit this works like
|
||||
* hitting the "OK" button, ESC like "Cancel".
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
keyhit_callback(w, client_data, event, cont)
|
||||
Widget w;
|
||||
XtPointer client_data;
|
||||
XtPointer client_data UNUSED;
|
||||
XEvent *event;
|
||||
Boolean *cont;
|
||||
Boolean *cont UNUSED;
|
||||
{
|
||||
char buf[2];
|
||||
KeySym key_sym;
|
||||
@@ -2490,12 +2479,11 @@ keyhit_callback(w, client_data, event, cont)
|
||||
XmTextFieldClearSelection(w, XtLastTimestampProcessed(gui.dpy));
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
butproc(w, client_data, call_data)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data;
|
||||
XtPointer call_data;
|
||||
XtPointer call_data UNUSED;
|
||||
{
|
||||
dialogStatus = (int)(long)client_data + 1;
|
||||
}
|
||||
@@ -2567,10 +2555,9 @@ create_pixmap_label(parent, name, data, args, arg)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
gui_mch_dialog(type, title, message, button_names, dfltbutton, textfield)
|
||||
int type;
|
||||
int type UNUSED;
|
||||
char_u *title;
|
||||
char_u *message;
|
||||
char_u *button_names;
|
||||
@@ -3197,7 +3184,7 @@ gui_mch_compute_toolbar_height()
|
||||
XmNchildren, &children,
|
||||
XmNnumChildren, &numChildren, NULL);
|
||||
borders += tst + tmh;
|
||||
for (i = 0; i < numChildren; i++)
|
||||
for (i = 0; i < (int)numChildren; i++)
|
||||
{
|
||||
whgt = 0;
|
||||
XtVaGetValues(children[i], XmNheight, &whgt, NULL);
|
||||
@@ -3237,13 +3224,12 @@ motif_get_toolbar_colors(bgp, fgp, bsp, tsp, hsp)
|
||||
* I have to use footer help for backwards compatability. Hopefully both will
|
||||
* get implemented and the user will have a choice.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
toolbarbutton_enter_cb(w, client_data, event, cont)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data;
|
||||
XEvent *event;
|
||||
Boolean *cont;
|
||||
XEvent *event UNUSED;
|
||||
Boolean *cont UNUSED;
|
||||
{
|
||||
vimmenu_T *menu = (vimmenu_T *) client_data;
|
||||
|
||||
@@ -3254,13 +3240,12 @@ toolbarbutton_enter_cb(w, client_data, event, cont)
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
toolbarbutton_leave_cb(w, client_data, event, cont)
|
||||
Widget w;
|
||||
XtPointer client_data;
|
||||
XEvent *event;
|
||||
Boolean *cont;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data UNUSED;
|
||||
XEvent *event UNUSED;
|
||||
Boolean *cont UNUSED;
|
||||
{
|
||||
gui_mch_set_footer((char_u *) "");
|
||||
}
|
||||
@@ -3492,10 +3477,9 @@ gui_motif_scroll_colors(id)
|
||||
/*
|
||||
* Set the fontlist for Widget "id" to use gui.menu_fontset or gui.menu_font.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
gui_motif_menu_fontlist(id)
|
||||
Widget id;
|
||||
Widget id UNUSED;
|
||||
{
|
||||
#ifdef FEAT_MENU
|
||||
#ifdef FONTSET_ALWAYS
|
||||
@@ -3566,8 +3550,8 @@ typedef struct _SharedFindReplace
|
||||
Widget cancel;
|
||||
} SharedFindReplace;
|
||||
|
||||
static SharedFindReplace find_widgets = { NULL };
|
||||
static SharedFindReplace repl_widgets = { NULL };
|
||||
static SharedFindReplace find_widgets = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
||||
static SharedFindReplace repl_widgets = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
||||
|
||||
static void find_replace_destroy_callback __ARGS((Widget w, XtPointer client_data, XtPointer call_data));
|
||||
static void find_replace_dismiss_callback __ARGS((Widget w, XtPointer client_data, XtPointer call_data));
|
||||
@@ -3576,12 +3560,11 @@ static void find_replace_callback __ARGS((Widget w, XtPointer client_data, XtPoi
|
||||
static void find_replace_keypress __ARGS((Widget w, SharedFindReplace * frdp, XKeyEvent * event));
|
||||
static void find_replace_dialog_create __ARGS((char_u *entry_text, int do_replace));
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
find_replace_destroy_callback(w, client_data, call_data)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data;
|
||||
XtPointer call_data;
|
||||
XtPointer call_data UNUSED;
|
||||
{
|
||||
SharedFindReplace *cd = (SharedFindReplace *)client_data;
|
||||
|
||||
@@ -3590,12 +3573,11 @@ find_replace_destroy_callback(w, client_data, call_data)
|
||||
cd->dialog = (Widget)0;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
find_replace_dismiss_callback(w, client_data, call_data)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data;
|
||||
XtPointer call_data;
|
||||
XtPointer call_data UNUSED;
|
||||
{
|
||||
SharedFindReplace *cd = (SharedFindReplace *)client_data;
|
||||
|
||||
@@ -3603,22 +3585,20 @@ find_replace_dismiss_callback(w, client_data, call_data)
|
||||
XtUnmanageChild(cd->dialog);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
entry_activate_callback(w, client_data, call_data)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data;
|
||||
XtPointer call_data;
|
||||
XtPointer call_data UNUSED;
|
||||
{
|
||||
XmProcessTraversal((Widget)client_data, XmTRAVERSE_CURRENT);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
find_replace_callback(w, client_data, call_data)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data;
|
||||
XtPointer call_data;
|
||||
XtPointer call_data UNUSED;
|
||||
{
|
||||
long_u flags = (long_u)client_data;
|
||||
char *find_text, *repl_text;
|
||||
@@ -3668,10 +3648,9 @@ find_replace_callback(w, client_data, call_data)
|
||||
XtFree(repl_text);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
find_replace_keypress(w, frdp, event)
|
||||
Widget w;
|
||||
Widget w UNUSED;
|
||||
SharedFindReplace *frdp;
|
||||
XKeyEvent *event;
|
||||
{
|
||||
|
||||
+6
-1
@@ -838,7 +838,12 @@ gui_ph_handle_window_open(
|
||||
static void
|
||||
gui_ph_draw_start( void )
|
||||
{
|
||||
PhGC_t *gc;
|
||||
|
||||
gc = PgGetGC();
|
||||
PgSetRegion( PtWidgetRid( PtFindDisjoint( gui.vimTextArea ) ) );
|
||||
PgClearClippingsCx( gc );
|
||||
PgClearTranslationCx( gc );
|
||||
|
||||
PtWidgetOffset( gui.vimTextArea, &gui_ph_raw_offset );
|
||||
PhTranslatePoint( &gui_ph_raw_offset, PtWidgetPos( gui.vimTextArea, NULL ) );
|
||||
@@ -2970,7 +2975,7 @@ gui_mch_init_font(char_u *vim_font_name, int fontset)
|
||||
if( vim_font_name == NULL )
|
||||
{
|
||||
/* Default font */
|
||||
vim_font_name = "PC Term";
|
||||
vim_font_name = "PC Terminal";
|
||||
}
|
||||
|
||||
if( STRCMP( vim_font_name, "*" ) == 0 )
|
||||
|
||||
+31
-1
@@ -1582,6 +1582,17 @@ gui_mch_init(void)
|
||||
s_findrep_struct.lpstrReplaceWith[0] = NUL;
|
||||
s_findrep_struct.wFindWhatLen = MSWIN_FR_BUFSIZE;
|
||||
s_findrep_struct.wReplaceWithLen = MSWIN_FR_BUFSIZE;
|
||||
# if defined(FEAT_MBYTE) && defined(WIN3264)
|
||||
s_findrep_struct_w.lStructSize = sizeof(s_findrep_struct_w);
|
||||
s_findrep_struct_w.lpstrFindWhat =
|
||||
(LPWSTR)alloc(MSWIN_FR_BUFSIZE * sizeof(WCHAR));
|
||||
s_findrep_struct_w.lpstrFindWhat[0] = NUL;
|
||||
s_findrep_struct_w.lpstrReplaceWith =
|
||||
(LPWSTR)alloc(MSWIN_FR_BUFSIZE * sizeof(WCHAR));
|
||||
s_findrep_struct_w.lpstrReplaceWith[0] = NUL;
|
||||
s_findrep_struct_w.wFindWhatLen = MSWIN_FR_BUFSIZE;
|
||||
s_findrep_struct_w.wReplaceWithLen = MSWIN_FR_BUFSIZE;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
theend:
|
||||
@@ -2938,8 +2949,27 @@ dialog_callback(
|
||||
|
||||
/* If the edit box exists, copy the string. */
|
||||
if (s_textfield != NULL)
|
||||
GetDlgItemText(hwnd, DLG_NONBUTTON_CONTROL + 2,
|
||||
{
|
||||
# if defined(FEAT_MBYTE) && defined(WIN3264)
|
||||
/* If the OS is Windows NT, and 'encoding' differs from active
|
||||
* codepage: use wide function and convert text. */
|
||||
if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT
|
||||
&& enc_codepage >= 0 && (int)GetACP() != enc_codepage)
|
||||
{
|
||||
WCHAR *wp = (WCHAR *)alloc(IOSIZE * sizeof(WCHAR));
|
||||
char_u *p;
|
||||
|
||||
GetDlgItemTextW(hwnd, DLG_NONBUTTON_CONTROL + 2, wp, IOSIZE);
|
||||
p = utf16_to_enc(wp, NULL);
|
||||
vim_strncpy(s_textfield, p, IOSIZE);
|
||||
vim_free(p);
|
||||
vim_free(wp);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
GetDlgItemText(hwnd, DLG_NONBUTTON_CONTROL + 2,
|
||||
s_textfield, IOSIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Need to check for IDOK because if the user just hits Return to
|
||||
|
||||
+88
-4
@@ -153,6 +153,9 @@ static int destroying = FALSE; /* call DestroyWindow() ourselves */
|
||||
#ifdef MSWIN_FIND_REPLACE
|
||||
static UINT s_findrep_msg = 0; /* set in gui_w[16/32].c */
|
||||
static FINDREPLACE s_findrep_struct;
|
||||
# if defined(FEAT_MBYTE) && defined(WIN3264)
|
||||
static FINDREPLACEW s_findrep_struct_w;
|
||||
# endif
|
||||
static HWND s_findrep_hwnd = NULL;
|
||||
static int s_findrep_is_find; /* TRUE for find dialog, FALSE
|
||||
for find/replace dialog */
|
||||
@@ -884,6 +887,45 @@ _OnMenu(
|
||||
#endif
|
||||
|
||||
#ifdef MSWIN_FIND_REPLACE
|
||||
# if defined(FEAT_MBYTE) && defined(WIN3264)
|
||||
/*
|
||||
* copy useful data from structure LPFINDREPLACE to structure LPFINDREPLACEW
|
||||
*/
|
||||
static void
|
||||
findrep_atow(LPFINDREPLACEW lpfrw, LPFINDREPLACE lpfr)
|
||||
{
|
||||
WCHAR *wp;
|
||||
|
||||
lpfrw->hwndOwner = lpfr->hwndOwner;
|
||||
lpfrw->Flags = lpfr->Flags;
|
||||
|
||||
wp = enc_to_utf16(lpfr->lpstrFindWhat, NULL);
|
||||
wcsncpy(lpfrw->lpstrFindWhat, wp, lpfrw->wFindWhatLen - 1);
|
||||
vim_free(wp);
|
||||
|
||||
/* the field "lpstrReplaceWith" doesn't need to be copied */
|
||||
}
|
||||
|
||||
/*
|
||||
* copy useful data from structure LPFINDREPLACEW to structure LPFINDREPLACE
|
||||
*/
|
||||
static void
|
||||
findrep_wtoa(LPFINDREPLACE lpfr, LPFINDREPLACEW lpfrw)
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
lpfr->Flags = lpfrw->Flags;
|
||||
|
||||
p = utf16_to_enc(lpfrw->lpstrFindWhat, NULL);
|
||||
vim_strncpy(lpfr->lpstrFindWhat, p, lpfr->wFindWhatLen - 1);
|
||||
vim_free(p);
|
||||
|
||||
p = utf16_to_enc(lpfrw->lpstrReplaceWith, NULL);
|
||||
vim_strncpy(lpfr->lpstrReplaceWith, p, lpfr->wReplaceWithLen - 1);
|
||||
vim_free(p);
|
||||
}
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Handle a Find/Replace window message.
|
||||
*/
|
||||
@@ -893,6 +935,16 @@ _OnFindRepl(void)
|
||||
int flags = 0;
|
||||
int down;
|
||||
|
||||
# if defined(FEAT_MBYTE) && defined(WIN3264)
|
||||
/* If the OS is Windows NT, and 'encoding' differs from active codepage:
|
||||
* convert text from wide string. */
|
||||
if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT
|
||||
&& enc_codepage >= 0 && (int)GetACP() != enc_codepage)
|
||||
{
|
||||
findrep_wtoa(&s_findrep_struct, &s_findrep_struct_w);
|
||||
}
|
||||
# endif
|
||||
|
||||
if (s_findrep_struct.Flags & FR_DIALOGTERM)
|
||||
/* Give main window the focus back. */
|
||||
(void)SetFocus(s_hwnd);
|
||||
@@ -1663,8 +1715,17 @@ process_message(void)
|
||||
if (msg.message == WM_OLE)
|
||||
{
|
||||
char_u *str = (char_u *)msg.lParam;
|
||||
add_to_input_buf(str, (int)STRLEN(str));
|
||||
vim_free(str);
|
||||
if (str == NULL || *str == NUL)
|
||||
{
|
||||
/* Message can't be ours, forward it. Fixes problem with Ultramon
|
||||
* 3.0.4 */
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
add_to_input_buf(str, (int)STRLEN(str));
|
||||
vim_free(str); /* was allocated in CVim::SendKeys() */
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -2553,7 +2614,19 @@ gui_mch_find_dialog(exarg_T *eap)
|
||||
if (!IsWindow(s_findrep_hwnd))
|
||||
{
|
||||
initialise_findrep(eap->arg);
|
||||
s_findrep_hwnd = FindText((LPFINDREPLACE) &s_findrep_struct);
|
||||
# if defined(FEAT_MBYTE) && defined(WIN3264)
|
||||
/* If the OS is Windows NT, and 'encoding' differs from active
|
||||
* codepage: convert text and use wide function. */
|
||||
if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT
|
||||
&& enc_codepage >= 0 && (int)GetACP() != enc_codepage)
|
||||
{
|
||||
findrep_atow(&s_findrep_struct_w, &s_findrep_struct);
|
||||
s_findrep_hwnd = FindTextW(
|
||||
(LPFINDREPLACEW) &s_findrep_struct_w);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
s_findrep_hwnd = FindText((LPFINDREPLACE) &s_findrep_struct);
|
||||
}
|
||||
|
||||
set_window_title(s_findrep_hwnd,
|
||||
@@ -2578,7 +2651,18 @@ gui_mch_replace_dialog(exarg_T *eap)
|
||||
if (!IsWindow(s_findrep_hwnd))
|
||||
{
|
||||
initialise_findrep(eap->arg);
|
||||
s_findrep_hwnd = ReplaceText((LPFINDREPLACE) &s_findrep_struct);
|
||||
# if defined(FEAT_MBYTE) && defined(WIN3264)
|
||||
if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT
|
||||
&& enc_codepage >= 0 && (int)GetACP() != enc_codepage)
|
||||
{
|
||||
findrep_atow(&s_findrep_struct_w, &s_findrep_struct);
|
||||
s_findrep_hwnd = ReplaceTextW(
|
||||
(LPFINDREPLACEW) &s_findrep_struct_w);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
s_findrep_hwnd = ReplaceText(
|
||||
(LPFINDREPLACE) &s_findrep_struct);
|
||||
}
|
||||
|
||||
set_window_title(s_findrep_hwnd,
|
||||
|
||||
+80
-102
@@ -570,22 +570,20 @@ static char **gui_argv = NULL;
|
||||
* Call-back routines.
|
||||
*/
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
gui_x11_timer_cb(timed_out, interval_id)
|
||||
XtPointer timed_out;
|
||||
XtIntervalId *interval_id;
|
||||
XtIntervalId *interval_id UNUSED;
|
||||
{
|
||||
*((int *)timed_out) = TRUE;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
gui_x11_visibility_cb(w, dud, event, dum)
|
||||
Widget w;
|
||||
XtPointer dud;
|
||||
Widget w UNUSED;
|
||||
XtPointer dud UNUSED;
|
||||
XEvent *event;
|
||||
Boolean *dum;
|
||||
Boolean *dum UNUSED;
|
||||
{
|
||||
if (event->type != VisibilityNotify)
|
||||
return;
|
||||
@@ -603,13 +601,12 @@ gui_x11_visibility_cb(w, dud, event, dum)
|
||||
gui_mch_update();
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
gui_x11_expose_cb(w, dud, event, dum)
|
||||
Widget w;
|
||||
XtPointer dud;
|
||||
Widget w UNUSED;
|
||||
XtPointer dud UNUSED;
|
||||
XEvent *event;
|
||||
Boolean *dum;
|
||||
Boolean *dum UNUSED;
|
||||
{
|
||||
XExposeEvent *gevent;
|
||||
int new_x;
|
||||
@@ -680,13 +677,12 @@ shellRectangle(Widget shell, XRectangle *r)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
gui_x11_resize_window_cb(w, dud, event, dum)
|
||||
Widget w;
|
||||
XtPointer dud;
|
||||
Widget w UNUSED;
|
||||
XtPointer dud UNUSED;
|
||||
XEvent *event;
|
||||
Boolean *dum;
|
||||
Boolean *dum UNUSED;
|
||||
{
|
||||
static int lastWidth, lastHeight;
|
||||
|
||||
@@ -727,35 +723,32 @@ gui_x11_resize_window_cb(w, dud, event, dum)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
gui_x11_focus_change_cb(w, data, event, dum)
|
||||
Widget w;
|
||||
XtPointer data;
|
||||
Widget w UNUSED;
|
||||
XtPointer data UNUSED;
|
||||
XEvent *event;
|
||||
Boolean *dum;
|
||||
Boolean *dum UNUSED;
|
||||
{
|
||||
gui_focus_change(event->type == FocusIn);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
gui_x11_enter_cb(w, data, event, dum)
|
||||
Widget w;
|
||||
XtPointer data;
|
||||
XEvent *event;
|
||||
Boolean *dum;
|
||||
Widget w UNUSED;
|
||||
XtPointer data UNUSED;
|
||||
XEvent *event UNUSED;
|
||||
Boolean *dum UNUSED;
|
||||
{
|
||||
gui_focus_change(TRUE);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
gui_x11_leave_cb(w, data, event, dum)
|
||||
Widget w;
|
||||
XtPointer data;
|
||||
XEvent *event;
|
||||
Boolean *dum;
|
||||
Widget w UNUSED;
|
||||
XtPointer data UNUSED;
|
||||
XEvent *event UNUSED;
|
||||
Boolean *dum UNUSED;
|
||||
{
|
||||
gui_focus_change(FALSE);
|
||||
}
|
||||
@@ -766,13 +759,12 @@ gui_x11_leave_cb(w, data, event, dum)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
gui_x11_key_hit_cb(w, dud, event, dum)
|
||||
Widget w;
|
||||
XtPointer dud;
|
||||
Widget w UNUSED;
|
||||
XtPointer dud UNUSED;
|
||||
XEvent *event;
|
||||
Boolean *dum;
|
||||
Boolean *dum UNUSED;
|
||||
{
|
||||
XKeyPressedEvent *ev_press;
|
||||
#ifdef FEAT_XIM
|
||||
@@ -1078,13 +1070,12 @@ theend:
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
gui_x11_mouse_cb(w, dud, event, dum)
|
||||
Widget w;
|
||||
XtPointer dud;
|
||||
Widget w UNUSED;
|
||||
XtPointer dud UNUSED;
|
||||
XEvent *event;
|
||||
Boolean *dum;
|
||||
Boolean *dum UNUSED;
|
||||
{
|
||||
static XtIntervalId timer = (XtIntervalId)0;
|
||||
static int timed_out = TRUE;
|
||||
@@ -1210,11 +1201,11 @@ gui_mch_prepare(argc, argv)
|
||||
while (arg < *argc)
|
||||
{
|
||||
/* Look for argv[arg] in cmdline_options[] table */
|
||||
for (i = 0; i < XtNumber(cmdline_options); i++)
|
||||
for (i = 0; i < (int)XtNumber(cmdline_options); i++)
|
||||
if (strcmp(argv[arg], cmdline_options[i].option) == 0)
|
||||
break;
|
||||
|
||||
if (i < XtNumber(cmdline_options))
|
||||
if (i < (int)XtNumber(cmdline_options))
|
||||
{
|
||||
/* Remember finding "-rv" or "-reverse" */
|
||||
if (strcmp("-rv", argv[arg]) == 0
|
||||
@@ -1319,12 +1310,11 @@ static XtInputId _xsmp_xtinputid;
|
||||
|
||||
static void local_xsmp_handle_requests __ARGS((XtPointer c, int *s, XtInputId *i));
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
local_xsmp_handle_requests(c, s, i)
|
||||
XtPointer c;
|
||||
int *s;
|
||||
XtInputId *i;
|
||||
XtPointer c UNUSED;
|
||||
int *s UNUSED;
|
||||
XtInputId *i UNUSED;
|
||||
{
|
||||
if (xsmp_handle_requests() == FAIL)
|
||||
XtRemoveInput(_xsmp_xtinputid);
|
||||
@@ -1438,7 +1428,7 @@ gui_mch_init()
|
||||
Columns = w;
|
||||
if (mask & HeightValue)
|
||||
{
|
||||
if (p_window > h - 1 || !option_was_set((char_u *)"window"))
|
||||
if (p_window > (long)h - 1 || !option_was_set((char_u *)"window"))
|
||||
p_window = h - 1;
|
||||
Rows = h;
|
||||
}
|
||||
@@ -1587,6 +1577,8 @@ gui_mch_uninit()
|
||||
XtCloseDisplay(gui.dpy);
|
||||
gui.dpy = NULL;
|
||||
vimShell = (Widget)0;
|
||||
vim_free(gui_argv);
|
||||
gui_argv = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1751,16 +1743,17 @@ gui_init_menu_font()
|
||||
}
|
||||
#endif
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
gui_mch_exit(rc)
|
||||
int rc;
|
||||
int rc UNUSED;
|
||||
{
|
||||
#if 0
|
||||
/* Lesstif gives an error message here, and so does Solaris. The man page
|
||||
* says that this isn't needed when exiting, so just skip it. */
|
||||
XtCloseDisplay(gui.dpy);
|
||||
#endif
|
||||
vim_free(gui_argv);
|
||||
gui_argv = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1795,7 +1788,6 @@ gui_mch_set_winpos(x, y)
|
||||
NULL);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
gui_mch_set_shellsize(width, height, min_width, min_height,
|
||||
base_width, base_height, direction)
|
||||
@@ -1805,7 +1797,7 @@ gui_mch_set_shellsize(width, height, min_width, min_height,
|
||||
int min_height;
|
||||
int base_width;
|
||||
int base_height;
|
||||
int direction;
|
||||
int direction UNUSED;
|
||||
{
|
||||
#ifdef FEAT_XIM
|
||||
height += xim_get_status_area_height(),
|
||||
@@ -1843,11 +1835,10 @@ gui_mch_get_screen_dimensions(screen_w, screen_h)
|
||||
* If "fontset" is TRUE, load the "font_name" as a fontset.
|
||||
* Return FAIL if the font could not be loaded, OK otherwise.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
gui_mch_init_font(font_name, do_fontset)
|
||||
char_u *font_name;
|
||||
int do_fontset;
|
||||
int do_fontset UNUSED;
|
||||
{
|
||||
XFontStruct *font = NULL;
|
||||
|
||||
@@ -2025,10 +2016,9 @@ gui_mch_get_font(name, giveErrorIfMissing)
|
||||
* Return the name of font "font" in allocated memory.
|
||||
* Don't know how to get the actual name, thus use the provided name.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
gui_mch_get_fontname(font, name)
|
||||
GuiFont font;
|
||||
GuiFont font UNUSED;
|
||||
char_u *name;
|
||||
{
|
||||
if (name == NULL)
|
||||
@@ -2517,7 +2507,7 @@ draw_curl(row, col, cells)
|
||||
{
|
||||
int i;
|
||||
int offset;
|
||||
const static int val[8] = {1, 0, 0, 0, 1, 2, 2, 2 };
|
||||
static const int val[8] = {1, 0, 0, 0, 1, 2, 2, 2 };
|
||||
|
||||
XSetForeground(gui.dpy, gui.text_gc, prev_sp_color);
|
||||
for (i = FILL_X(col); i < FILL_X(col + cells); ++i)
|
||||
@@ -2565,8 +2555,10 @@ gui_mch_draw_string(row, col, s, len, flags)
|
||||
# ifdef FEAT_XFONTSET
|
||||
if (current_fontset != NULL)
|
||||
{
|
||||
if (c >= 0x10000 && sizeof(wchar_t) <= 2)
|
||||
# ifdef SMALL_WCHAR_T
|
||||
if (c >= 0x10000)
|
||||
c = 0xbf; /* show chars > 0xffff as ? */
|
||||
# endif
|
||||
((wchar_t *)buf)[wlen] = c;
|
||||
}
|
||||
else
|
||||
@@ -3132,11 +3124,11 @@ gui_mch_draw_menubar()
|
||||
/* Nothing to do in X */
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
gui_x11_menu_cb(w, client_data, call_data)
|
||||
Widget w;
|
||||
XtPointer client_data, call_data;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data;
|
||||
XtPointer call_data UNUSED;
|
||||
{
|
||||
gui_menu_cb((vimmenu_T *)client_data);
|
||||
}
|
||||
@@ -3149,13 +3141,12 @@ gui_x11_menu_cb(w, client_data, call_data)
|
||||
* Function called when window closed. Works like ":qa".
|
||||
* Should put up a requester!
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
gui_x11_wm_protocol_handler(w, client_data, event, dum)
|
||||
Widget w;
|
||||
XtPointer client_data;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data UNUSED;
|
||||
XEvent *event;
|
||||
Boolean *dum;
|
||||
Boolean *dum UNUSED;
|
||||
{
|
||||
/*
|
||||
* Only deal with Client messages.
|
||||
@@ -3168,7 +3159,7 @@ gui_x11_wm_protocol_handler(w, client_data, event, dum)
|
||||
* exit. That can be cancelled though, thus Vim shouldn't exit here.
|
||||
* Just sync our swap files.
|
||||
*/
|
||||
if (((XClientMessageEvent *)event)->data.l[0] ==
|
||||
if ((Atom)((XClientMessageEvent *)event)->data.l[0] ==
|
||||
wm_atoms[SAVE_YOURSELF_IDX])
|
||||
{
|
||||
out_flush();
|
||||
@@ -3181,7 +3172,7 @@ gui_x11_wm_protocol_handler(w, client_data, event, dum)
|
||||
return;
|
||||
}
|
||||
|
||||
if (((XClientMessageEvent *)event)->data.l[0] !=
|
||||
if ((Atom)((XClientMessageEvent *)event)->data.l[0] !=
|
||||
wm_atoms[DELETE_WINDOW_IDX])
|
||||
return;
|
||||
|
||||
@@ -3192,13 +3183,12 @@ gui_x11_wm_protocol_handler(w, client_data, event, dum)
|
||||
/*
|
||||
* Function called when property changed. Check for incoming commands
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
gui_x11_send_event_handler(w, client_data, event, dum)
|
||||
Widget w;
|
||||
XtPointer client_data;
|
||||
Widget w UNUSED;
|
||||
XtPointer client_data UNUSED;
|
||||
XEvent *event;
|
||||
Boolean *dum;
|
||||
Boolean *dum UNUSED;
|
||||
{
|
||||
XPropertyEvent *e = (XPropertyEvent *) event;
|
||||
|
||||
@@ -3273,11 +3263,10 @@ gui_mch_start_blink()
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
gui_x11_blink_cb(timed_out, interval_id)
|
||||
XtPointer timed_out;
|
||||
XtIntervalId *interval_id;
|
||||
XtPointer timed_out UNUSED;
|
||||
XtIntervalId *interval_id UNUSED;
|
||||
{
|
||||
if (blink_state == BLINK_ON)
|
||||
{
|
||||
@@ -3439,47 +3428,37 @@ gui_mch_register_sign(signfile)
|
||||
char_u *signfile;
|
||||
{
|
||||
XpmAttributes attrs;
|
||||
XImage *sign;
|
||||
XImage *sign = NULL;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* Setup the color substitution table.
|
||||
*/
|
||||
sign = NULL;
|
||||
if (signfile[0] != NUL && signfile[0] != '-')
|
||||
{
|
||||
sign = (XImage *)alloc(sizeof(XImage));
|
||||
if (sign != NULL)
|
||||
XpmColorSymbol color[5] =
|
||||
{
|
||||
XpmColorSymbol color[5] =
|
||||
{
|
||||
{"none", NULL, 0},
|
||||
{"iconColor1", NULL, 0},
|
||||
{"bottomShadowColor", NULL, 0},
|
||||
{"topShadowColor", NULL, 0},
|
||||
{"selectColor", NULL, 0}
|
||||
};
|
||||
attrs.valuemask = XpmColorSymbols;
|
||||
attrs.numsymbols = 2;
|
||||
attrs.colorsymbols = color;
|
||||
attrs.colorsymbols[0].pixel = gui.back_pixel;
|
||||
attrs.colorsymbols[1].pixel = gui.norm_pixel;
|
||||
status = XpmReadFileToImage(gui.dpy, (char *)signfile,
|
||||
{"none", NULL, 0},
|
||||
{"iconColor1", NULL, 0},
|
||||
{"bottomShadowColor", NULL, 0},
|
||||
{"topShadowColor", NULL, 0},
|
||||
{"selectColor", NULL, 0}
|
||||
};
|
||||
attrs.valuemask = XpmColorSymbols;
|
||||
attrs.numsymbols = 2;
|
||||
attrs.colorsymbols = color;
|
||||
attrs.colorsymbols[0].pixel = gui.back_pixel;
|
||||
attrs.colorsymbols[1].pixel = gui.norm_pixel;
|
||||
status = XpmReadFileToImage(gui.dpy, (char *)signfile,
|
||||
&sign, NULL, &attrs);
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
/* Sign width is fixed at two columns now.
|
||||
if (sign->width > gui.sign_width)
|
||||
gui.sign_width = sign->width + 8; */
|
||||
}
|
||||
else
|
||||
{
|
||||
vim_free(sign);
|
||||
sign = NULL;
|
||||
EMSG(_(e_signdata));
|
||||
}
|
||||
if (status == 0)
|
||||
{
|
||||
/* Sign width is fixed at two columns now.
|
||||
if (sign->width > gui.sign_width)
|
||||
gui.sign_width = sign->width + 8; */
|
||||
}
|
||||
else
|
||||
EMSG(_(e_signdata));
|
||||
}
|
||||
|
||||
return (void *)sign;
|
||||
@@ -3489,8 +3468,7 @@ gui_mch_register_sign(signfile)
|
||||
gui_mch_destroy_sign(sign)
|
||||
void *sign;
|
||||
{
|
||||
XFree(((XImage *)sign)->data);
|
||||
vim_free(sign);
|
||||
XDestroyImage((XImage*)sign);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user