mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-05-28 00:21:57 +02:00
Compare commits
41 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 |
@@ -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
|
||||
|
||||
+27
-5
@@ -1,4 +1,4 @@
|
||||
*gui_mac.txt* For Vim version 7.2. Last change: 2009 Mar 15
|
||||
*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.
|
||||
@@ -625,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.
|
||||
@@ -648,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.
|
||||
|
||||
@@ -3881,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)
|
||||
|
||||
+30
-1
@@ -1158,6 +1158,18 @@
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Vimball Archive</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>vba</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-vba</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
@@ -1189,7 +1201,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>46</string>
|
||||
<string>48</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
@@ -2549,6 +2561,23 @@
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.plain-text</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Vimball Archive</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.vim.vba-file</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>vba</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -159,6 +166,16 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
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,
|
||||
@@ -192,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];
|
||||
@@ -325,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
|
||||
@@ -636,12 +690,12 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (void)removeVimController:(id)controller
|
||||
{
|
||||
ASLogDebug(@"Remove Vim controller pid=%d id=%d",
|
||||
[controller pid], [controller identifier]);
|
||||
ASLogDebug(@"Remove Vim controller pid=%d id=%d (processingFlag=%d)",
|
||||
[controller pid], [controller identifier], processingFlag);
|
||||
|
||||
int idx = [vimControllers indexOfObject:controller];
|
||||
if (NSNotFound == idx) {
|
||||
ASLogWarn(@"Controller at index=%d not found", idx);
|
||||
ASLogDebug(@"Controller not found, probably due to duplicate removal");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ enum { MMMaxCellsPerChar = 2 };
|
||||
- (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
|
||||
|
||||
@@ -329,6 +329,11 @@ defaultLineHeightForFont(NSFont *font)
|
||||
[helper setImControl:enable];
|
||||
}
|
||||
|
||||
- (void)activateIm:(BOOL)enable
|
||||
{
|
||||
[helper activateIm:enable];
|
||||
}
|
||||
|
||||
- (void)keyDown:(NSEvent *)event
|
||||
{
|
||||
[helper keyDown:event];
|
||||
@@ -513,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];
|
||||
@@ -569,6 +575,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
shape:MMInsertionPointVertical
|
||||
fraction:25];
|
||||
}
|
||||
#endif // INCLUDE_OLD_IM_CODE
|
||||
}
|
||||
|
||||
- (BOOL) wantsDefaultClipping
|
||||
@@ -1101,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 };
|
||||
@@ -1150,6 +1162,8 @@ defaultLineHeightForFont(NSFont *font)
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
|
||||
- (void)scrollRect:(NSRect)rect lineCount:(int)count
|
||||
|
||||
@@ -111,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;
|
||||
|
||||
+283
-195
@@ -56,6 +56,9 @@ vimmenu_T *menu_for_descriptor(NSArray *desc);
|
||||
|
||||
static id evalExprCocoa(NSString * expr, NSString ** errstr);
|
||||
|
||||
extern void im_preedit_start_macvim();
|
||||
extern void im_preedit_end_macvim();
|
||||
extern void im_preedit_changed_macvim(char *preedit_string, int cursor_index);
|
||||
|
||||
enum {
|
||||
MMBlinkStateNone = 0,
|
||||
@@ -70,6 +73,81 @@ static NSString *MMSymlinkWarningString =
|
||||
"\ta symlink, then your MacVim.app bundle is incomplete.\n\n";
|
||||
|
||||
|
||||
// Keycodes recognized by Vim (struct taken from gui_x11.c and gui_w48.c)
|
||||
// (The key codes were taken from Carbon/HIToolbox/Events.)
|
||||
static struct specialkey
|
||||
{
|
||||
unsigned key_sym;
|
||||
char_u vim_code0;
|
||||
char_u vim_code1;
|
||||
} special_keys[] =
|
||||
{
|
||||
{0x7e /*kVK_UpArrow*/, 'k', 'u'},
|
||||
{0x7d /*kVK_DownArrow*/, 'k', 'd'},
|
||||
{0x7b /*kVK_LeftArrow*/, 'k', 'l'},
|
||||
{0x7c /*kVK_RightArrow*/, 'k', 'r'},
|
||||
|
||||
{0x7a /*kVK_F1*/, 'k', '1'},
|
||||
{0x78 /*kVK_F2*/, 'k', '2'},
|
||||
{0x63 /*kVK_F3*/, 'k', '3'},
|
||||
{0x76 /*kVK_F4*/, 'k', '4'},
|
||||
{0x60 /*kVK_F5*/, 'k', '5'},
|
||||
{0x61 /*kVK_F6*/, 'k', '6'},
|
||||
{0x62 /*kVK_F7*/, 'k', '7'},
|
||||
{0x64 /*kVK_F8*/, 'k', '8'},
|
||||
{0x65 /*kVK_F9*/, 'k', '9'},
|
||||
{0x6d /*kVK_F10*/, 'k', ';'},
|
||||
|
||||
{0x67 /*kVK_F11*/, 'F', '1'},
|
||||
{0x6f /*kVK_F12*/, 'F', '2'},
|
||||
{0x69 /*kVK_F13*/, 'F', '3'},
|
||||
{0x6b /*kVK_F14*/, 'F', '4'},
|
||||
{0x71 /*kVK_F15*/, 'F', '5'},
|
||||
{0x6a /*kVK_F16*/, 'F', '6'},
|
||||
{0x40 /*kVK_F17*/, 'F', '7'},
|
||||
{0x4f /*kVK_F18*/, 'F', '8'},
|
||||
{0x50 /*kVK_F19*/, 'F', '9'},
|
||||
{0x5a /*kVK_F20*/, 'F', 'A'},
|
||||
|
||||
{0x72 /*kVK_Help*/, '%', '1'},
|
||||
{0x33 /*kVK_Delete*/, 'k', 'b'},
|
||||
{0x75 /*kVK_ForwardDelete*/, 'k', 'D'},
|
||||
{0x73 /*kVK_Home*/, 'k', 'h'},
|
||||
{0x77 /*kVK_End*/, '@', '7'},
|
||||
{0x74 /*kVK_PageUp*/, 'k', 'P'},
|
||||
{0x79 /*kVK_PageDown*/, 'k', 'N'},
|
||||
|
||||
/* Keypad keys: */
|
||||
{0x45 /*kVK_ANSI_KeypadPlus*/, 'K', '6'},
|
||||
{0x4e /*kVK_ANSI_KeypadMinus*/, 'K', '7'},
|
||||
{0x4b /*kVK_ANSI_KeypadDivide*/, 'K', '8'},
|
||||
{0x43 /*kVK_ANSI_KeypadMultiply*/, 'K', '9'},
|
||||
{0x4c /*kVK_ANSI_KeypadEnter*/, 'K', 'A'},
|
||||
{0x41 /*kVK_ANSI_KeypadDecimal*/, 'K', 'B'},
|
||||
{0x47 /*kVK_ANSI_KeypadClear*/, KS_EXTRA, (char_u)KE_KDEL},
|
||||
|
||||
{0x52 /*kVK_ANSI_Keypad0*/, 'K', 'C'},
|
||||
{0x53 /*kVK_ANSI_Keypad1*/, 'K', 'D'},
|
||||
{0x54 /*kVK_ANSI_Keypad2*/, 'K', 'E'},
|
||||
{0x55 /*kVK_ANSI_Keypad3*/, 'K', 'F'},
|
||||
{0x56 /*kVK_ANSI_Keypad4*/, 'K', 'G'},
|
||||
{0x57 /*kVK_ANSI_Keypad5*/, 'K', 'H'},
|
||||
{0x58 /*kVK_ANSI_Keypad6*/, 'K', 'I'},
|
||||
{0x59 /*kVK_ANSI_Keypad7*/, 'K', 'J'},
|
||||
{0x5b /*kVK_ANSI_Keypad8*/, 'K', 'K'},
|
||||
{0x5c /*kVK_ANSI_Keypad9*/, 'K', 'L'},
|
||||
|
||||
/* Keys that we want to be able to use any modifier with: */
|
||||
{0x31 /*kVK_Space*/, ' ', NUL},
|
||||
{0x30 /*kVK_Tab*/, TAB, NUL},
|
||||
{0x35 /*kVK_Escape*/, ESC, NUL},
|
||||
{0x24 /*kVK_Return*/, CAR, NUL},
|
||||
|
||||
/* End of list marker: */
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
|
||||
|
||||
@@ -88,9 +166,13 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
- (void)insertVimStateMessage;
|
||||
- (void)processInputQueue;
|
||||
- (void)handleInputEvent:(int)msgid data:(NSData *)data;
|
||||
+ (NSDictionary *)specialKeys;
|
||||
- (void)handleInsertText:(NSString *)text;
|
||||
- (void)handleKeyDown:(NSString *)key modifiers:(int)mods;
|
||||
- (void)doKeyDown:(NSString *)key
|
||||
keyCode:(unsigned)code
|
||||
modifiers:(int)mods;
|
||||
- (BOOL)handleSpecialKey:(NSString *)key
|
||||
keyCode:(unsigned)code
|
||||
modifiers:(int)mods;
|
||||
- (BOOL)handleMacMetaKey:(int)ikey modifiers:(int)mods;
|
||||
- (void)queueMessage:(int)msgid data:(NSData *)data;
|
||||
- (void)connectionDidDie:(NSNotification *)notification;
|
||||
- (void)blinkTimerFired:(NSTimer *)timer;
|
||||
@@ -108,6 +190,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
- (BOOL)unusedEditor;
|
||||
- (void)redrawScreen;
|
||||
- (void)handleFindReplace:(NSDictionary *)args;
|
||||
- (void)handleMarkedText:(NSData *)data;
|
||||
@end
|
||||
|
||||
|
||||
@@ -346,8 +429,8 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
identifier = [appProxy connectBackend:self pid:pid];
|
||||
return YES;
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
ASLogWarn(@"Exception caught when trying to connect backend: %@", e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"Connect backend failed: reason=%@", ex);
|
||||
}
|
||||
|
||||
return NO;
|
||||
@@ -510,8 +593,8 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
debugStringForMessageQueue(outputQueue));
|
||||
[appProxy processInput:outputQueue forIdentifier:identifier];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
ASLogWarn(@"Exception caught: %@", e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"processInput:forIdentifer failed: reason=%@", ex);
|
||||
if (![connection isValid]) {
|
||||
ASLogNotice(@"Connection is invalid, exit now!");
|
||||
ASLogDebug(@"waitForAck=%d got_int=%d", waitForAck, got_int);
|
||||
@@ -579,8 +662,8 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
debugStringForMessageQueue(outputQueue));
|
||||
[appProxy processInput:outputQueue forIdentifier:identifier];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
ASLogWarn(@"Exception caught when sending CloseWindowMsgID: %@", e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"CloseWindowMsgID send failed: reason=%@", ex);
|
||||
}
|
||||
|
||||
// NOTE: If Cmd-w was pressed to close the window the menu is briefly
|
||||
@@ -702,8 +785,8 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
|
||||
[dialogReturn release]; dialogReturn = nil;
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
ASLogWarn(@"Exception caught: %@", e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"Exception: reason=%@", ex);
|
||||
}
|
||||
|
||||
return (char *)s;
|
||||
@@ -757,8 +840,8 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
|
||||
[dialogReturn release]; dialogReturn = nil;
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
ASLogWarn(@"Exception caught: %@", e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"Exception: reason=%@", ex);
|
||||
}
|
||||
|
||||
return retval;
|
||||
@@ -983,13 +1066,12 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
return INVALCOLOR;
|
||||
}
|
||||
|
||||
- (BOOL)hasSpecialKeyWithValue:(NSString *)value
|
||||
- (BOOL)hasSpecialKeyWithValue:(char_u *)value
|
||||
{
|
||||
NSEnumerator *e = [[MMBackend specialKeys] objectEnumerator];
|
||||
id obj;
|
||||
|
||||
while ((obj = [e nextObject])) {
|
||||
if ([value isEqual:obj])
|
||||
int i;
|
||||
for (i = 0; special_keys[i].key_sym != 0; i++) {
|
||||
if (value[0] == special_keys[i].vim_code0
|
||||
&& value[1] == special_keys[i].vim_code1)
|
||||
return YES;
|
||||
}
|
||||
|
||||
@@ -1038,17 +1120,18 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
|
||||
- (oneway void)processInput:(int)msgid data:(in bycopy NSData *)data
|
||||
{
|
||||
// Look for Cmd-. and Ctrl-C immediately instead of waiting until the input
|
||||
// queue is processed since that only happens in waitForInput: (and Vim
|
||||
// regularly checks for Ctrl-C in between waiting for input).
|
||||
// Look for Ctrl-C immediately instead of waiting until the input queue is
|
||||
// processed since that only happens in waitForInput: (and Vim regularly
|
||||
// checks for Ctrl-C in between waiting for input).
|
||||
// Similarly, TerminateNowMsgID must be checked immediately otherwise code
|
||||
// which waits on the run loop will fail to detect this message (e.g. in
|
||||
// waitForConnectionAcknowledgement).
|
||||
|
||||
if (InsertTextMsgID == msgid && data != nil) {
|
||||
if (KeyDownMsgID == msgid && data != nil) {
|
||||
const void *bytes = [data bytes];
|
||||
bytes += sizeof(int);
|
||||
int len = *((int*)bytes); bytes += sizeof(int);
|
||||
/*unsigned mods = *((unsigned*)bytes);*/ bytes += sizeof(unsigned);
|
||||
/*unsigned code = *((unsigned*)bytes);*/ bytes += sizeof(unsigned);
|
||||
unsigned len = *((unsigned*)bytes); bytes += sizeof(unsigned);
|
||||
if (1 == len) {
|
||||
char_u *str = (char_u*)bytes;
|
||||
if ((str[0] == Ctrl_C && ctrl_c_interrupts) ||
|
||||
@@ -1071,14 +1154,13 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
// Remove all previous instances of this message from the input queue, else
|
||||
// the input queue may fill up as a result of Vim not being able to keep up
|
||||
// with the speed at which new messages are received.
|
||||
// Keyboard input is never dropped, unless the input represents and
|
||||
// Keyboard input is never dropped, unless the input represents an
|
||||
// auto-repeated key.
|
||||
|
||||
BOOL isKeyRepeat = NO;
|
||||
BOOL isKeyboardInput = NO;
|
||||
|
||||
if (data && (InsertTextMsgID == msgid || KeyDownMsgID == msgid ||
|
||||
CmdKeyMsgID == msgid)) {
|
||||
if (data && KeyDownMsgID == msgid) {
|
||||
isKeyboardInput = YES;
|
||||
|
||||
// The lowest bit of the first int is set if this key is a repeat.
|
||||
@@ -1320,8 +1402,8 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
[proxy addInput:string client:self];
|
||||
}
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
ASLogWarn(@"Caught exception: %@", e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"Exception: reason=%@", ex);
|
||||
return NO;
|
||||
}
|
||||
|
||||
@@ -1339,8 +1421,8 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
@try {
|
||||
list = [proxy serverList];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
ASLogWarn(@"Exception caught when listing servers: %@", e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"serverList failed: reason=%@", ex);
|
||||
}
|
||||
} else {
|
||||
EMSG(_("E???: No connection to MacVim, server listing not possible."));
|
||||
@@ -1409,8 +1491,8 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
[client addReply:reply server:self];
|
||||
return YES;
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
ASLogWarn(@"Exception caught: %@", e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"addReply:server: failed: reason=%@", ex);
|
||||
}
|
||||
} else {
|
||||
EMSG2(_("E???: server2client failed; no client with id 0x%x"), port);
|
||||
@@ -1653,24 +1735,21 @@ static void netbeansReadCallback(CFSocketRef s,
|
||||
[q release];
|
||||
}
|
||||
|
||||
|
||||
- (void)handleInputEvent:(int)msgid data:(NSData *)data
|
||||
{
|
||||
if (InsertTextMsgID == msgid || KeyDownMsgID == msgid ||
|
||||
CmdKeyMsgID == msgid) {
|
||||
if (KeyDownMsgID == msgid) {
|
||||
if (!data) return;
|
||||
const void *bytes = [data bytes];
|
||||
int mods = *((int*)bytes); bytes += sizeof(int);
|
||||
int len = *((int*)bytes); bytes += sizeof(int);
|
||||
unsigned mods = *((unsigned*)bytes); bytes += sizeof(unsigned);
|
||||
unsigned code = *((unsigned*)bytes); bytes += sizeof(unsigned);
|
||||
unsigned len = *((unsigned*)bytes); bytes += sizeof(unsigned);
|
||||
NSString *key = [[NSString alloc] initWithBytes:bytes
|
||||
length:len
|
||||
encoding:NSUTF8StringEncoding];
|
||||
mods = eventModifierFlagsToVimModMask(mods);
|
||||
|
||||
if (InsertTextMsgID == msgid)
|
||||
[self handleInsertText:key];
|
||||
else
|
||||
[self handleKeyDown:key modifiers:mods];
|
||||
|
||||
[self doKeyDown:key keyCode:code modifiers:mods];
|
||||
[key release];
|
||||
} else if (ScrollWheelMsgID == msgid) {
|
||||
if (!data) return;
|
||||
@@ -1841,31 +1920,26 @@ static void netbeansReadCallback(CFSocketRef s,
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
messageFromNetbeansMacVim();
|
||||
#endif
|
||||
} else if (SetMarkedTextMsgID == msgid) {
|
||||
[self handleMarkedText:data];
|
||||
} else {
|
||||
ASLogWarn(@"Unknown message received (msgid=%d)", msgid);
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSDictionary *)specialKeys
|
||||
- (void)doKeyDown:(NSString *)key
|
||||
keyCode:(unsigned)code
|
||||
modifiers:(int)mods
|
||||
{
|
||||
static NSDictionary *specialKeys = nil;
|
||||
ASLogDebug(@"key='%@' code=%#x mods=%#x length=%d", key, code, mods,
|
||||
[key length]);
|
||||
if (!key) return;
|
||||
|
||||
if (!specialKeys) {
|
||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
||||
NSString *path = [mainBundle pathForResource:@"SpecialKeys"
|
||||
ofType:@"plist"];
|
||||
specialKeys = [[NSDictionary alloc] initWithContentsOfFile:path];
|
||||
}
|
||||
char_u *str = (char_u*)[key UTF8String];
|
||||
int i, len = [key lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
return specialKeys;
|
||||
}
|
||||
|
||||
- (void)handleInsertText:(NSString *)text
|
||||
{
|
||||
if (!text) return;
|
||||
|
||||
char_u *str = (char_u*)[text UTF8String];
|
||||
int i, len = [text lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
if ([self handleSpecialKey:key keyCode:code modifiers:mods])
|
||||
return;
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
char_u *conv_str = NULL;
|
||||
@@ -1876,13 +1950,34 @@ static void netbeansReadCallback(CFSocketRef s,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mods & MOD_MASK_CMD) {
|
||||
// NOTE: For normal input (non-special, 'macmeta' off) the modifier
|
||||
// flags are already included in the key event. However, the Cmd key
|
||||
// flag is special and must always be added manually. The frontend is
|
||||
// responsible for clearing unnecessary flags when Cmd is held.
|
||||
ASLogDebug(@"add mods=%#x", mods);
|
||||
char_u modChars[3] = { CSI, KS_MODIFIER, mods };
|
||||
add_to_input_buf(modChars, 3);
|
||||
} else if (mods & MOD_MASK_ALT && 1 == len && str[0] < 0x80
|
||||
&& curbuf && curbuf->b_p_mmta) {
|
||||
// HACK! The 'macmeta' is set so we have to handle Alt key presses
|
||||
// separately. Normally Alt key presses are interpreted by the
|
||||
// frontend but now we have to manually set the 8th bit and deal with
|
||||
// UTF-8 conversion.
|
||||
if ([self handleMacMetaKey:str[0] modifiers:mods])
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
ASLogDebug(@"add byte [%d/%d]: %#x", i, len, str[i]);
|
||||
add_to_input_buf(str+i, 1);
|
||||
if (CSI == str[i]) {
|
||||
// NOTE: If the converted string contains the byte CSI, then it
|
||||
// must be followed by the bytes KS_EXTRA, KE_CSI or things
|
||||
// won't work.
|
||||
static char_u extra[2] = { KS_EXTRA, KE_CSI };
|
||||
ASLogDebug(@"add KS_EXTRA, KE_CSI");
|
||||
add_to_input_buf(extra, 2);
|
||||
}
|
||||
}
|
||||
@@ -1893,158 +1988,127 @@ static void netbeansReadCallback(CFSocketRef s,
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)handleKeyDown:(NSString *)key modifiers:(int)mods
|
||||
- (BOOL)handleSpecialKey:(NSString *)key
|
||||
keyCode:(unsigned)code
|
||||
modifiers:(int)mods
|
||||
{
|
||||
// TODO: This code is a horrible mess -- clean up!
|
||||
char_u special[3];
|
||||
char_u modChars[3];
|
||||
char_u *chars = (char_u*)[key UTF8String];
|
||||
int i;
|
||||
for (i = 0; special_keys[i].key_sym != 0; i++) {
|
||||
if (special_keys[i].key_sym == code) {
|
||||
ASLogDebug(@"Special key: %#x", code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (special_keys[i].key_sym == 0)
|
||||
return NO;
|
||||
|
||||
int ikey = special_keys[i].vim_code1 == NUL ? special_keys[i].vim_code0 :
|
||||
TO_SPECIAL(special_keys[i].vim_code0, special_keys[i].vim_code1);
|
||||
ikey = simplify_key(ikey, &mods);
|
||||
if (ikey == CSI)
|
||||
ikey = K_CSI;
|
||||
|
||||
char_u chars[4];
|
||||
int len = 0;
|
||||
|
||||
if (IS_SPECIAL(ikey)) {
|
||||
chars[0] = CSI;
|
||||
chars[1] = K_SECOND(ikey);
|
||||
chars[2] = K_THIRD(ikey);
|
||||
len = 3;
|
||||
} else if (mods & MOD_MASK_ALT && special_keys[i].vim_code1 == 0
|
||||
#ifdef FEAT_MBYTE
|
||||
char_u *conv_str = NULL;
|
||||
&& !enc_dbcs // TODO: ? (taken from gui_gtk_x11.c)
|
||||
#endif
|
||||
int length = [key lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
) {
|
||||
ASLogDebug(@"Alt special=%d", ikey);
|
||||
|
||||
// Special keys (arrow keys, function keys, etc.) are stored in a plist so
|
||||
// that new keys can easily be added.
|
||||
NSString *specialString = [[MMBackend specialKeys]
|
||||
objectForKey:key];
|
||||
if (specialString && [specialString length] > 1) {
|
||||
//ASLogDebug(@"special key: %@", specialString);
|
||||
int ikey = TO_SPECIAL([specialString characterAtIndex:0],
|
||||
[specialString characterAtIndex:1]);
|
||||
|
||||
ikey = simplify_key(ikey, &mods);
|
||||
if (ikey == CSI)
|
||||
ikey = K_CSI;
|
||||
|
||||
special[0] = CSI;
|
||||
special[1] = K_SECOND(ikey);
|
||||
special[2] = K_THIRD(ikey);
|
||||
|
||||
chars = special;
|
||||
length = 3;
|
||||
} else if (1 == length && TAB == chars[0]) {
|
||||
// Tab is a trouble child:
|
||||
// - <Tab> is added to the input buffer as is
|
||||
// - <S-Tab> is translated to, {CSI,'k','B'} (i.e. 'Back-tab')
|
||||
// - <M-Tab> should be 0x80|TAB but this is not valid utf-8 so it needs
|
||||
// to be converted to utf-8
|
||||
// - <S-M-Tab> is translated to <S-Tab> with ALT modifier
|
||||
// - <C-Tab> is reserved by Mac OS X
|
||||
// - <D-Tab> is reserved by Mac OS X
|
||||
chars = special;
|
||||
special[0] = TAB;
|
||||
length = 1;
|
||||
|
||||
if (mods & MOD_MASK_SHIFT) {
|
||||
mods &= ~MOD_MASK_SHIFT;
|
||||
special[0] = CSI;
|
||||
special[1] = K_SECOND(K_S_TAB);
|
||||
special[2] = K_THIRD(K_S_TAB);
|
||||
length = 3;
|
||||
} else if (mods & MOD_MASK_ALT) {
|
||||
int mtab = 0x80 | TAB;
|
||||
// NOTE: The last entries in the special_keys struct when pressed
|
||||
// together with Alt need to be handled separately or they will not
|
||||
// work.
|
||||
// The following code was gleaned from gui_gtk_x11.c.
|
||||
mods &= ~MOD_MASK_ALT;
|
||||
int mkey = 0x80 | ikey;
|
||||
#ifdef FEAT_MBYTE
|
||||
if (enc_utf8) {
|
||||
// Convert to utf-8
|
||||
special[0] = (mtab >> 6) + 0xc0;
|
||||
special[1] = mtab & 0xbf;
|
||||
length = 2;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
special[0] = mtab;
|
||||
length = 1;
|
||||
}
|
||||
mods &= ~MOD_MASK_ALT;
|
||||
}
|
||||
} else if (1 == length && chars[0] < 0x80 && (mods & MOD_MASK_ALT)) {
|
||||
// META key is treated separately. This code was taken from gui_w48.c
|
||||
// and gui_gtk_x11.c.
|
||||
char_u string[7];
|
||||
int ch = simplify_key(chars[0], &mods);
|
||||
|
||||
// Remove the SHIFT modifier for keys where it's already included,
|
||||
// e.g., '(' and '*'
|
||||
if (ch < 0x100 && !isalpha(ch) && isprint(ch))
|
||||
mods &= ~MOD_MASK_SHIFT;
|
||||
|
||||
// Interpret the ALT key as making the key META, include SHIFT, etc.
|
||||
ch = extract_modifiers(ch, &mods);
|
||||
if (ch == CSI)
|
||||
ch = K_CSI;
|
||||
|
||||
int len = 0;
|
||||
if (mods) {
|
||||
string[len++] = CSI;
|
||||
string[len++] = KS_MODIFIER;
|
||||
string[len++] = mods;
|
||||
}
|
||||
|
||||
if (IS_SPECIAL(ch)) {
|
||||
string[len++] = CSI;
|
||||
string[len++] = K_SECOND(ch);
|
||||
string[len++] = K_THIRD(ch);
|
||||
} else {
|
||||
string[len++] = ch;
|
||||
#ifdef FEAT_MBYTE
|
||||
// TODO: What if 'enc' is not "utf-8"?
|
||||
if (enc_utf8 && (ch & 0x80)) { // convert to utf-8
|
||||
string[len++] = ch & 0xbf;
|
||||
string[len-2] = ((unsigned)ch >> 6) + 0xc0;
|
||||
if (string[len-1] == CSI) {
|
||||
string[len++] = KS_EXTRA;
|
||||
string[len++] = (int)KE_CSI;
|
||||
}
|
||||
if (enc_utf8) { // TODO: What about other encodings?
|
||||
// Convert to utf-8
|
||||
chars[0] = (mkey >> 6) + 0xc0;
|
||||
chars[1] = mkey & 0xbf;
|
||||
if (chars[1] == CSI) {
|
||||
// We end up here when ikey == ESC
|
||||
chars[2] = KS_EXTRA;
|
||||
chars[3] = KE_CSI;
|
||||
len = 4;
|
||||
} else {
|
||||
len = 2;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
chars[0] = mkey;
|
||||
len = 1;
|
||||
}
|
||||
|
||||
add_to_input_buf(string, len);
|
||||
return;
|
||||
} else if (length > 0) {
|
||||
unichar c = [key characterAtIndex:0];
|
||||
//ASLogDebug(@"non-special: %@ (hex=%x, mods=%d)", key,
|
||||
// [key characterAtIndex:0], mods);
|
||||
|
||||
// HACK! In most circumstances the Ctrl and Shift modifiers should be
|
||||
// cleared since they are already added to the key by the AppKit.
|
||||
// Unfortunately, the only way to deal with when to clear the modifiers
|
||||
// or not seems to be to have hard-wired rules like this.
|
||||
if ( !((' ' == c) || (0xa0 == c) || (mods & MOD_MASK_CMD)
|
||||
|| 0x9 == c || 0xd == c || ESC == c) ) {
|
||||
mods &= ~MOD_MASK_SHIFT;
|
||||
mods &= ~MOD_MASK_CTRL;
|
||||
//ASLogDebug(@"clear shift ctrl");
|
||||
}
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
if (input_conv.vc_type != CONV_NONE) {
|
||||
conv_str = string_convert(&input_conv, chars, &length);
|
||||
if (conv_str)
|
||||
chars = conv_str;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
ASLogDebug(@"Just ikey=%d", ikey);
|
||||
chars[0] = ikey;
|
||||
len = 1;
|
||||
}
|
||||
|
||||
if (chars && length > 0) {
|
||||
if (len > 0) {
|
||||
if (mods) {
|
||||
//ASLogDebug(@"adding mods: %d", mods);
|
||||
modChars[0] = CSI;
|
||||
modChars[1] = KS_MODIFIER;
|
||||
modChars[2] = mods;
|
||||
ASLogDebug(@"Adding mods to special: %d", mods);
|
||||
char_u modChars[3] = { CSI, KS_MODIFIER, (char_u)mods };
|
||||
add_to_input_buf(modChars, 3);
|
||||
}
|
||||
|
||||
//ASLogDebug(@"add to input buf: 0x%x", chars[0]);
|
||||
// TODO: Check for CSI bytes?
|
||||
add_to_input_buf(chars, length);
|
||||
ASLogDebug(@"Adding special (%d): %x,%x,%x", len,
|
||||
chars[0], chars[1], chars[2]);
|
||||
add_to_input_buf(chars, len);
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)handleMacMetaKey:(int)ikey modifiers:(int)mods
|
||||
{
|
||||
ASLogDebug(@"ikey=%d mods=%d", ikey, mods);
|
||||
|
||||
// This code was taken from gui_w48.c and gui_gtk_x11.c.
|
||||
char_u string[7];
|
||||
int ch = simplify_key(ikey, &mods);
|
||||
|
||||
// Remove the SHIFT modifier for keys where it's already included,
|
||||
// e.g., '(' and '*'
|
||||
if (ch < 0x100 && !isalpha(ch) && isprint(ch))
|
||||
mods &= ~MOD_MASK_SHIFT;
|
||||
|
||||
// Interpret the ALT key as making the key META, include SHIFT, etc.
|
||||
ch = extract_modifiers(ch, &mods);
|
||||
if (ch == CSI)
|
||||
ch = K_CSI;
|
||||
|
||||
int len = 0;
|
||||
if (mods) {
|
||||
string[len++] = CSI;
|
||||
string[len++] = KS_MODIFIER;
|
||||
string[len++] = mods;
|
||||
}
|
||||
|
||||
string[len++] = ch;
|
||||
#ifdef FEAT_MBYTE
|
||||
if (conv_str)
|
||||
vim_free(conv_str);
|
||||
// TODO: What if 'enc' is not "utf-8"?
|
||||
if (enc_utf8 && (ch & 0x80)) { // convert to utf-8
|
||||
string[len++] = ch & 0xbf;
|
||||
string[len-2] = ((unsigned)ch >> 6) + 0xc0;
|
||||
if (string[len-1] == CSI) {
|
||||
string[len++] = KS_EXTRA;
|
||||
string[len++] = (int)KE_CSI;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
add_to_input_buf(string, len);
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)queueMessage:(int)msgid data:(NSData *)data
|
||||
@@ -2417,7 +2481,11 @@ static void netbeansReadCallback(CFSocketRef s,
|
||||
if (openFiles && numFiles > 0 && ![args objectForKey:@"remoteID"]
|
||||
&& (starting || [self unusedEditor]) ) {
|
||||
char_u *s = [[filenames objectAtIndex:0] vimStringSave];
|
||||
vim_chdirfile(s);
|
||||
if (mch_isdir(s)) {
|
||||
mch_chdir((char*)s);
|
||||
} else {
|
||||
vim_chdirfile(s);
|
||||
}
|
||||
vim_free(s);
|
||||
}
|
||||
|
||||
@@ -2700,6 +2768,26 @@ static void netbeansReadCallback(CFSocketRef s,
|
||||
vim_free(replace);
|
||||
}
|
||||
|
||||
|
||||
- (void)handleMarkedText:(NSData *)data
|
||||
{
|
||||
const void *bytes = [data bytes];
|
||||
unsigned pos = *((unsigned*)bytes); bytes += sizeof(unsigned);
|
||||
unsigned len = *((unsigned*)bytes); bytes += sizeof(unsigned);
|
||||
char *chars = (char *)bytes;
|
||||
|
||||
ASLogDebug(@"pos=%d len=%d chars=%s", pos, len, chars);
|
||||
|
||||
if (len == 0) {
|
||||
im_preedit_end_macvim();
|
||||
} else {
|
||||
if (!preedit_get_status())
|
||||
im_preedit_start_macvim();
|
||||
|
||||
im_preedit_changed_macvim(chars, pos);
|
||||
}
|
||||
}
|
||||
|
||||
@end // MMBackend (Private)
|
||||
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
- (void)setMouseShape:(int)shape;
|
||||
- (void)setAntialias:(BOOL)antialias;
|
||||
- (void)setImControl:(BOOL)enable;
|
||||
- (void)activateIm:(BOOL)enable;
|
||||
|
||||
//
|
||||
// MMTextStorage methods
|
||||
|
||||
+19
-2
@@ -312,6 +312,11 @@
|
||||
[helper setImControl:enable];
|
||||
}
|
||||
|
||||
- (void)activateIm:(BOOL)enable
|
||||
{
|
||||
[helper activateIm:enable];
|
||||
}
|
||||
|
||||
- (NSFont *)font
|
||||
{
|
||||
return [(MMTextStorage*)[self textStorage] font];
|
||||
@@ -517,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];
|
||||
@@ -575,6 +581,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // INCLUDE_OLD_IM_CODE
|
||||
|
||||
if (shouldDrawInsertionPoint) {
|
||||
MMTextStorage *ts = (MMTextStorage*)[self textStorage];
|
||||
@@ -584,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])
|
||||
@@ -597,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;
|
||||
@@ -857,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;
|
||||
@@ -41,6 +48,10 @@ enum {
|
||||
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;
|
||||
@@ -83,5 +94,7 @@ enum {
|
||||
- (void)setMarkedRange:(NSRange)range;
|
||||
- (NSRect)firstRectForCharacterRange:(NSRange)range;
|
||||
- (void)setImControl:(BOOL)enable;
|
||||
- (void)activateIm:(BOOL)enable;
|
||||
- (BOOL)useInlineIm;
|
||||
|
||||
@end
|
||||
|
||||
+415
-260
@@ -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,18 +34,39 @@ 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
|
||||
@@ -59,6 +77,17 @@ static float MMDragAreaSize = 73.0f;
|
||||
[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];
|
||||
}
|
||||
|
||||
@@ -83,247 +112,202 @@ static float MMDragAreaSize = 73.0f;
|
||||
|
||||
- (void)keyDown:(NSEvent *)event
|
||||
{
|
||||
//ASLogDebug(@"%@", 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);
|
||||
|
||||
// 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];
|
||||
}
|
||||
|
||||
[self hideMouseCursor];
|
||||
|
||||
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];
|
||||
|
||||
// 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]];
|
||||
[textView setNeedsDisplay:YES];
|
||||
return;
|
||||
}
|
||||
|
||||
int flags = [event modifierFlags];
|
||||
if ((flags & NSControlKeyMask) ||
|
||||
((flags & NSAlternateKeyMask) && (flags & NSFunctionKeyMask))) {
|
||||
BOOL unmodIsPrintable = YES;
|
||||
NSString *unmod = [event charactersIgnoringModifiers];
|
||||
if (unmod && [unmod length] > 0 && [unmod characterAtIndex:0] < 0x20)
|
||||
unmodIsPrintable = NO;
|
||||
|
||||
NSString *chars = [event characters];
|
||||
if ([chars length] == 1 && [chars characterAtIndex:0] < 0x20
|
||||
&& unmodIsPrintable) {
|
||||
// HACK! Send unprintable characters (such as 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:chars];
|
||||
} 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 sendKeyDown:bytes length:len modifiers:flags
|
||||
isARepeat:[event isARepeat]];
|
||||
} else {
|
||||
[textView interpretKeyEvents:[NSArray arrayWithObject:event]];
|
||||
}
|
||||
[currentEvent release];
|
||||
currentEvent = nil;
|
||||
}
|
||||
|
||||
- (void)insertText:(id)string
|
||||
{
|
||||
//ASLogDebug(@"%@", 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];
|
||||
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
int flags = [event modifierFlags] & 0xffff0000U;
|
||||
if ([event type] == NSKeyDown && [event isARepeat])
|
||||
flags |= 1;
|
||||
//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);
|
||||
|
||||
[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
|
||||
{
|
||||
//ASLogDebug(@"%@", 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
|
||||
{
|
||||
//ASLogDebug(@"%@", 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(@"");
|
||||
|
||||
if (imControl)
|
||||
[self checkImState];
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -345,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])
|
||||
@@ -377,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])
|
||||
@@ -396,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];
|
||||
@@ -426,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.
|
||||
@@ -618,6 +614,7 @@ static float MMDragAreaSize = 73.0f;
|
||||
|
||||
- (void)setMarkedTextAttributes:(NSDictionary *)attr
|
||||
{
|
||||
ASLogDebug(@"%@", attr);
|
||||
if (attr != markedTextAttributes) {
|
||||
[markedTextAttributes release];
|
||||
markedTextAttributes = [attr retain];
|
||||
@@ -626,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;
|
||||
|
||||
@@ -667,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];
|
||||
@@ -754,8 +768,99 @@ static float MMDragAreaSize = 73.0f;
|
||||
{
|
||||
// This flag corresponds to the (negation of the) 'imd' option. When
|
||||
// enabled changes to the input method are detected and forwarded to the
|
||||
// backend.
|
||||
// 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
|
||||
@@ -778,76 +883,92 @@ 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 length] > 0 ? [unmodchars characterAtIndex:0] : 0;
|
||||
int len = 0;
|
||||
const char *bytes = 0;
|
||||
int mods = [event modifierFlags];
|
||||
|
||||
//ASLogDebug(@"chars[0]=0x%x unmodchars[0]=0x%x (chars=%@ unmodchars=%@)",
|
||||
// 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];
|
||||
|
||||
//ASLogDebug(@"len=%d chars=0x%x", 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.)
|
||||
@@ -862,6 +983,7 @@ static float MMDragAreaSize = 73.0f;
|
||||
int msgid = state ? ActivatedImMsgID : DeactivatedImMsgID;
|
||||
[[self vimController] sendMessage:msgid data:nil];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)hideMouseCursor
|
||||
@@ -981,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)
|
||||
|
||||
@@ -348,8 +348,9 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
@try {
|
||||
[backendProxy processInput:msgid data:data];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
ASLogWarn(@"Exception caught during DO call: %@", e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"processInput:data: failed: pid=%d id=%d msg=%s reason=%@",
|
||||
pid, identifier, MessageStrings[msgid], ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,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];
|
||||
@@ -410,7 +413,8 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
ASLogDebug(@"eval(%@)=%@", expr, eval);
|
||||
}
|
||||
@catch (NSException *ex) {
|
||||
ASLogWarn(@"Exception caught: %@", ex);
|
||||
ASLogNotice(@"evaluateExpression: failed: pid=%d id=%d reason=%@",
|
||||
pid, identifier, ex);
|
||||
}
|
||||
|
||||
return eval;
|
||||
@@ -426,7 +430,8 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
errorString:errstr];
|
||||
ASLogDebug(@"eval(%@)=%@", expr, eval);
|
||||
} @catch (NSException *ex) {
|
||||
ASLogWarn(@"Exception caught: %@", ex);
|
||||
ASLogNotice(@"evaluateExpressionCocoa: failed: pid=%d id=%d reason=%@",
|
||||
pid, identifier, ex);
|
||||
*errstr = [ex reason];
|
||||
}
|
||||
|
||||
@@ -464,7 +469,7 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
[windowController processInputQueueDidFinish];
|
||||
}
|
||||
@catch (NSException *ex) {
|
||||
ASLogWarn(@"Caught exception (pid=%d): %@", pid, ex);
|
||||
ASLogNotice(@"Exception: pid=%d id=%d reason=%@", pid, identifier, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -802,11 +807,9 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
flags:[[dict objectForKey:@"flags"] intValue]];
|
||||
}
|
||||
} else if (ActivateKeyScriptMsgID == msgid) {
|
||||
// NOTE: The IM code is delegated to the frontend since calling it in
|
||||
// the backend caused weird bugs (second dock icon appearing etc.).
|
||||
KeyScript(smKeySysScript);
|
||||
[[[windowController vimView] textView] activateIm:YES];
|
||||
} else if (DeactivateKeyScriptMsgID == msgid) {
|
||||
KeyScript(smKeyRoman);
|
||||
[[[windowController vimView] textView] activateIm:NO];
|
||||
} else if (EnableImControlMsgID == msgid) {
|
||||
[[[windowController vimView] textView] setImControl:YES];
|
||||
} else if (DisableImControlMsgID == msgid) {
|
||||
@@ -830,9 +833,15 @@ 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
|
||||
// so that we can be fairly certain that Vim doesn't think the dialog box
|
||||
@@ -850,8 +859,8 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
[[NSDocumentController sharedDocumentController]
|
||||
noteNewRecentFilePath:path];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
ASLogWarn(@"Exception caught: %@", e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"Exception: pid=%d id=%d reason=%@", pid, identifier, ex);
|
||||
}
|
||||
@finally {
|
||||
[conn setRequestTimeout:oldTimeout];
|
||||
@@ -873,11 +882,19 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
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) {
|
||||
ASLogWarn(@"Exception caught: %@", e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"setDialogReturn: failed: pid=%d id=%d reason=%@",
|
||||
pid, identifier, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1259,6 +1276,8 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
- (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
|
||||
|
||||
@@ -122,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;
|
||||
@@ -998,8 +995,9 @@
|
||||
@try {
|
||||
reply = [backendProxy starRegisterToPasteboard:pb];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
ASLogWarn(@"Caught exception: \"%@\"", e);
|
||||
@catch (NSException *ex) {
|
||||
ASLogNotice(@"starRegisterToPasteboard: failed: pid=%d reason=%@",
|
||||
[vimController pid], ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -103,9 +103,7 @@ extern char *MessageStrings[];
|
||||
|
||||
enum {
|
||||
OpenWindowMsgID = 1, // NOTE: FIRST IN ENUM MUST BE 1
|
||||
InsertTextMsgID,
|
||||
KeyDownMsgID,
|
||||
CmdKeyMsgID,
|
||||
BatchDrawMsgID,
|
||||
SelectTabMsgID,
|
||||
CloseTabMsgID,
|
||||
@@ -179,6 +177,7 @@ enum {
|
||||
BrowseForFileMsgID,
|
||||
ShowDialogMsgID,
|
||||
NetBeansMsgID,
|
||||
SetMarkedTextMsgID,
|
||||
LastMsgID // NOTE: MUST BE LAST MESSAGE IN ENUM!
|
||||
};
|
||||
|
||||
@@ -294,6 +293,9 @@ 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.
|
||||
@@ -345,3 +347,4 @@ void ASLInit();
|
||||
#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__)
|
||||
|
||||
+1
-2
@@ -18,9 +18,7 @@ char *MessageStrings[] =
|
||||
{
|
||||
"INVALID MESSAGE ID",
|
||||
"OpenWindowMsgID",
|
||||
"InsertTextMsgID",
|
||||
"KeyDownMsgID",
|
||||
"CmdKeyMsgID",
|
||||
"BatchDrawMsgID",
|
||||
"SelectTabMsgID",
|
||||
"CloseTabMsgID",
|
||||
@@ -94,6 +92,7 @@ char *MessageStrings[] =
|
||||
"BrowseForFileMsgID",
|
||||
"ShowDialogMsgID",
|
||||
"NetBeansMsgID",
|
||||
"SetMarkedTextMsgID",
|
||||
"END OF MESSAGE IDs" // NOTE: Must be last!
|
||||
};
|
||||
|
||||
|
||||
@@ -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 = 46;
|
||||
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 = 46;
|
||||
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 = 46;
|
||||
CURRENT_PROJECT_VERSION = 48;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#import "MacVim.h"
|
||||
|
||||
|
||||
// TODO: Remove this when the inline IM code has been tested
|
||||
#define INCLUDE_OLD_IM_CODE
|
||||
|
||||
|
||||
// NSUserDefaults keys
|
||||
extern NSString *MMTabMinWidthKey;
|
||||
@@ -47,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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
+1
-15
@@ -1589,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];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ vimIcons = {
|
||||
'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],
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -41,9 +41,37 @@
|
||||
-->
|
||||
|
||||
<item>
|
||||
<title>Snapshot 46 released</title>
|
||||
<title>Snapshot 48 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 46 released</h1>
|
||||
<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>
|
||||
@@ -56,15 +84,16 @@
|
||||
<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, 10 Jul 2009 23:50 CET</pubDate>
|
||||
<pubDate>Fri, 16 Jul 2009 19:43 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-46.tbz"
|
||||
length="8198862"
|
||||
sparkle:version="46"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-47.tbz"
|
||||
length="8200839"
|
||||
sparkle:version="47"
|
||||
sparkle:shortVersionString="7.2"
|
||||
/>
|
||||
</item>
|
||||
|
||||
Vendored
+4
-1
@@ -5780,7 +5780,10 @@ $as_echo "$rubyhdrdir" >&6; }
|
||||
fi
|
||||
rubyldflags=`$vi_cv_path_ruby -r rbconfig -e 'print Config::CONFIG["LDFLAGS"]'`
|
||||
if test "X$rubyldflags" != "X"; then
|
||||
LDFLAGS="$rubyldflags $LDFLAGS"
|
||||
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"
|
||||
|
||||
+7
-1
@@ -993,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"
|
||||
|
||||
+34
-26
@@ -893,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)
|
||||
@@ -999,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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -8898,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())
|
||||
|
||||
+8
-5
@@ -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
|
||||
@@ -2390,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.
|
||||
@@ -2418,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.
|
||||
@@ -2427,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())
|
||||
@@ -2488,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.
|
||||
@@ -3211,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
|
||||
|
||||
+4
-1
@@ -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
|
||||
|
||||
|
||||
+91
-23
@@ -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));
|
||||
@@ -1041,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
|
||||
@@ -2924,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];
|
||||
@@ -2987,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;
|
||||
@@ -3965,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
|
||||
@@ -4243,6 +4245,7 @@ restore_backup:
|
||||
nchars += write_info.bw_len;
|
||||
}
|
||||
}
|
||||
write_info.bw_start_lnum = start;
|
||||
#endif
|
||||
|
||||
write_info.bw_len = bufsize;
|
||||
@@ -4278,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
|
||||
@@ -4474,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)
|
||||
@@ -4550,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)
|
||||
{
|
||||
@@ -4746,6 +4768,8 @@ nofail:
|
||||
}
|
||||
STRCAT(IObuff, errmsg);
|
||||
emsg(IObuff);
|
||||
if (errmsg_allocated)
|
||||
vim_free(errmsg);
|
||||
|
||||
retval = FAIL;
|
||||
if (end == 0)
|
||||
@@ -5109,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);
|
||||
@@ -5390,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)
|
||||
@@ -5473,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);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -8458,6 +8506,10 @@ aucmd_prepbuf(aco, buf)
|
||||
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;
|
||||
@@ -8466,6 +8518,7 @@ aucmd_prepbuf(aco, buf)
|
||||
/* 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;
|
||||
}
|
||||
else
|
||||
@@ -8474,9 +8527,20 @@ aucmd_prepbuf(aco, buf)
|
||||
* 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;
|
||||
|
||||
/* 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.
|
||||
@@ -8510,7 +8574,7 @@ aucmd_restbuf(aco)
|
||||
int dummy;
|
||||
#endif
|
||||
|
||||
if (aco->new_curwin == aucmd_win)
|
||||
if (aco->use_aucmd_win)
|
||||
{
|
||||
--curbuf->b_nwindows;
|
||||
#ifdef FEAT_WINDOWS
|
||||
@@ -8537,6 +8601,7 @@ aucmd_restbuf(aco)
|
||||
/* 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 */
|
||||
@@ -8555,6 +8620,9 @@ aucmd_restbuf(aco)
|
||||
#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)
|
||||
@@ -8579,7 +8647,7 @@ aucmd_restbuf(aco)
|
||||
#endif
|
||||
{
|
||||
/* Restore the buffer which was previously edited by curwin, if
|
||||
* it was chagned, we are still the same window and the buffer is
|
||||
* it was changed, we are still the same window and the buffer is
|
||||
* valid. */
|
||||
if (curwin == aco->new_curwin
|
||||
&& curbuf != aco->new_curbuf
|
||||
|
||||
+5
-7
@@ -3708,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;
|
||||
{
|
||||
@@ -3741,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;
|
||||
|
||||
+3
-2
@@ -541,6 +541,7 @@ 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
|
||||
|
||||
/*
|
||||
@@ -840,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);
|
||||
|
||||
@@ -1206,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
|
||||
);
|
||||
@@ -1337,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
|
||||
|
||||
@@ -5029,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)
|
||||
@@ -5119,6 +5132,7 @@ gui_do_findrepl(flags, find_text, repl_text, down)
|
||||
}
|
||||
|
||||
vim_free(ga.ga_data);
|
||||
busy = FALSE;
|
||||
return (ga.ga_len > 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -720,9 +720,11 @@ ex_perl(eap)
|
||||
#ifdef HAVE_SANDBOX
|
||||
if (sandbox)
|
||||
{
|
||||
# ifndef MAKE_TEST /* avoid a warning for unreachable code */
|
||||
if ((safe = perl_get_sv( "VIM::safe", FALSE )) == NULL || !SvTRUE(safe))
|
||||
EMSG(_("E299: Perl evaluation forbidden in sandbox without the Safe module"));
|
||||
else
|
||||
# endif
|
||||
{
|
||||
PUSHMARK(SP);
|
||||
XPUSHs(safe);
|
||||
|
||||
+64
-4
@@ -3517,7 +3517,14 @@ iconv_end()
|
||||
|
||||
#if defined(FEAT_XIM) || defined(PROTO)
|
||||
|
||||
# ifdef FEAT_GUI_GTK
|
||||
# ifdef FEAT_GUI_MACVIM
|
||||
typedef int GtkIMContext;
|
||||
typedef int * gpointer;
|
||||
typedef char gchar;
|
||||
# define g_return_if_fail(x) if (!(x)) return;
|
||||
# endif
|
||||
|
||||
# if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM)
|
||||
static int xim_has_preediting INIT(= FALSE); /* IM current status */
|
||||
|
||||
/*
|
||||
@@ -3535,7 +3542,7 @@ init_preedit_start_col(void)
|
||||
}
|
||||
# endif
|
||||
|
||||
# if defined(HAVE_GTK2) && !defined(PROTO)
|
||||
# if (defined(HAVE_GTK2) || defined(FEAT_GUI_MACVIM)) && !defined(PROTO)
|
||||
|
||||
static int im_is_active = FALSE; /* IM is enabled for current mode */
|
||||
static int preedit_is_active = FALSE;
|
||||
@@ -3543,9 +3550,12 @@ static int im_preedit_cursor = 0; /* cursor offset in characters */
|
||||
static int im_preedit_trailing = 0; /* number of characters after cursor */
|
||||
|
||||
static unsigned long im_commit_handler_id = 0;
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
static unsigned int im_activatekey_keyval = GDK_VoidSymbol;
|
||||
static unsigned int im_activatekey_state = 0;
|
||||
# endif
|
||||
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
void
|
||||
im_set_active(int active)
|
||||
{
|
||||
@@ -3557,10 +3567,12 @@ im_set_active(int active)
|
||||
if (im_is_active != was_active)
|
||||
xim_reset();
|
||||
}
|
||||
# endif
|
||||
|
||||
void
|
||||
xim_set_focus(int focus)
|
||||
{
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
if (xic != NULL)
|
||||
{
|
||||
if (focus)
|
||||
@@ -3568,8 +3580,10 @@ xim_set_focus(int focus)
|
||||
else
|
||||
gtk_im_context_focus_out(xic);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
void
|
||||
im_set_position(int row, int col)
|
||||
{
|
||||
@@ -3585,6 +3599,7 @@ im_set_position(int row, int col)
|
||||
gtk_im_context_set_cursor_location(xic, &area);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
# if 0 || defined(PROTO) /* apparently only used in gui_x11.c */
|
||||
void
|
||||
@@ -3609,8 +3624,10 @@ im_add_to_input(char_u *str, int len)
|
||||
if (input_conv.vc_type != CONV_NONE)
|
||||
vim_free(str);
|
||||
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
if (p_mh) /* blank out the pointer if necessary */
|
||||
gui_mch_mousehide(TRUE);
|
||||
# endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3651,8 +3668,10 @@ im_correct_cursor(int num_move_back)
|
||||
add_to_input_buf(backkey, (int)sizeof(backkey));
|
||||
}
|
||||
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
static int xim_expected_char = NUL;
|
||||
static int xim_ignored_char = FALSE;
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Update the mode and cursor while in an IM callback.
|
||||
@@ -3670,6 +3689,7 @@ im_show_info(void)
|
||||
out_flush();
|
||||
}
|
||||
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
/*
|
||||
* Callback invoked when the user finished preediting.
|
||||
* Put the final string into the input buffer.
|
||||
@@ -3759,12 +3779,18 @@ im_commit_cb(GtkIMContext *context UNUSED,
|
||||
if (gtk_main_level() > 0)
|
||||
gtk_main_quit();
|
||||
}
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Callback invoked after start to the preedit.
|
||||
*/
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
static void
|
||||
im_preedit_start_cb(GtkIMContext *context UNUSED, gpointer data UNUSED)
|
||||
# else
|
||||
void
|
||||
im_preedit_start_macvim()
|
||||
# endif
|
||||
{
|
||||
#ifdef XIM_DEBUG
|
||||
xim_log("im_preedit_start_cb()\n");
|
||||
@@ -3779,8 +3805,13 @@ im_preedit_start_cb(GtkIMContext *context UNUSED, gpointer data UNUSED)
|
||||
/*
|
||||
* Callback invoked after end to the preedit.
|
||||
*/
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
static void
|
||||
im_preedit_end_cb(GtkIMContext *context UNUSED, gpointer data UNUSED)
|
||||
# else
|
||||
void
|
||||
im_preedit_end_macvim()
|
||||
# endif
|
||||
{
|
||||
#ifdef XIM_DEBUG
|
||||
xim_log("im_preedit_end_cb()\n");
|
||||
@@ -3839,19 +3870,28 @@ im_preedit_end_cb(GtkIMContext *context UNUSED, gpointer data UNUSED)
|
||||
* remaining input from within the "retrieve_surrounding" signal handler, this
|
||||
* might not be necessary. Gotta ask on vim-dev for opinions.
|
||||
*/
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
static void
|
||||
im_preedit_changed_cb(GtkIMContext *context, gpointer data UNUSED)
|
||||
# else
|
||||
void
|
||||
im_preedit_changed_macvim(char *preedit_string, int cursor_index)
|
||||
# endif
|
||||
{
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
char *preedit_string = NULL;
|
||||
int cursor_index = 0;
|
||||
# endif
|
||||
int num_move_back = 0;
|
||||
char_u *str;
|
||||
char_u *p;
|
||||
int i;
|
||||
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
gtk_im_context_get_preedit_string(context,
|
||||
&preedit_string, NULL,
|
||||
&cursor_index);
|
||||
# endif
|
||||
|
||||
#ifdef XIM_DEBUG
|
||||
xim_log("im_preedit_changed_cb(): %s\n", preedit_string);
|
||||
@@ -3921,12 +3961,15 @@ im_preedit_changed_cb(GtkIMContext *context, gpointer data UNUSED)
|
||||
im_correct_cursor(num_move_back);
|
||||
}
|
||||
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
g_free(preedit_string);
|
||||
|
||||
if (gtk_main_level() > 0)
|
||||
gtk_main_quit();
|
||||
# endif
|
||||
}
|
||||
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
/*
|
||||
* Translate the Pango attributes at iter to Vim highlighting attributes.
|
||||
* Ignore attributes not supported by Vim highlighting. This shouldn't have
|
||||
@@ -3965,6 +4008,7 @@ translate_pango_attributes(PangoAttrIterator *iter)
|
||||
|
||||
return char_attr;
|
||||
}
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Retrieve the highlighting attributes at column col in the preedit string.
|
||||
@@ -3973,6 +4017,7 @@ translate_pango_attributes(PangoAttrIterator *iter)
|
||||
int
|
||||
im_get_feedback_attr(int col)
|
||||
{
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
char *preedit_string = NULL;
|
||||
PangoAttrList *attr_list = NULL;
|
||||
int char_attr = -1;
|
||||
@@ -4017,6 +4062,9 @@ im_get_feedback_attr(int col)
|
||||
g_free(preedit_string);
|
||||
|
||||
return char_attr;
|
||||
# else
|
||||
return HL_UNDERLINE;
|
||||
# endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4026,6 +4074,7 @@ xim_init(void)
|
||||
xim_log("xim_init()\n");
|
||||
#endif
|
||||
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
g_return_if_fail(gui.drawarea != NULL);
|
||||
g_return_if_fail(gui.drawarea->window != NULL);
|
||||
|
||||
@@ -4042,6 +4091,7 @@ xim_init(void)
|
||||
G_CALLBACK(&im_preedit_end_cb), NULL);
|
||||
|
||||
gtk_im_context_set_client_window(xic, gui.drawarea->window);
|
||||
# endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4051,18 +4101,21 @@ im_shutdown(void)
|
||||
xim_log("im_shutdown()\n");
|
||||
#endif
|
||||
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
if (xic != NULL)
|
||||
{
|
||||
gtk_im_context_focus_out(xic);
|
||||
g_object_unref(xic);
|
||||
xic = NULL;
|
||||
}
|
||||
# endif
|
||||
im_is_active = FALSE;
|
||||
im_commit_handler_id = 0;
|
||||
preedit_start_col = MAXCOL;
|
||||
xim_has_preediting = FALSE;
|
||||
}
|
||||
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
/*
|
||||
* Convert the string argument to keyval and state for GdkEventKey.
|
||||
* If str is valid return TRUE, otherwise FALSE.
|
||||
@@ -4168,10 +4221,12 @@ im_synthesize_keypress(unsigned int keyval, unsigned int state)
|
||||
g_free(event);
|
||||
# endif
|
||||
}
|
||||
# endif // FEAT_GUI_MACVIM
|
||||
|
||||
void
|
||||
xim_reset(void)
|
||||
{
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
if (xic != NULL)
|
||||
{
|
||||
/*
|
||||
@@ -4229,11 +4284,13 @@ xim_reset(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
preedit_start_col = MAXCOL;
|
||||
xim_has_preediting = FALSE;
|
||||
}
|
||||
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
int
|
||||
xim_queue_key_press_event(GdkEventKey *event, int down)
|
||||
{
|
||||
@@ -4363,12 +4420,15 @@ xim_queue_key_press_event(GdkEventKey *event, int down)
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
int
|
||||
im_get_status(void)
|
||||
{
|
||||
return im_is_active;
|
||||
}
|
||||
# endif
|
||||
|
||||
# else /* !HAVE_GTK2 */
|
||||
|
||||
@@ -5808,7 +5868,7 @@ im_get_status()
|
||||
|
||||
# endif /* !HAVE_GTK2 */
|
||||
|
||||
# if defined(HAVE_GTK2) || defined(PROTO)
|
||||
# if (defined(HAVE_GTK2) || defined(FEAT_GUI_MACVIM)) || defined(PROTO)
|
||||
int
|
||||
preedit_get_status(void)
|
||||
{
|
||||
@@ -5816,7 +5876,7 @@ preedit_get_status(void)
|
||||
}
|
||||
# endif
|
||||
|
||||
# if defined(FEAT_GUI_GTK) || defined(PROTO)
|
||||
# if (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM)) || defined(PROTO)
|
||||
int
|
||||
im_is_preediting()
|
||||
{
|
||||
|
||||
+21
-6
@@ -2473,7 +2473,7 @@ skip_to_option_part(p)
|
||||
void
|
||||
changed()
|
||||
{
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
#if defined(FEAT_XIM) && (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM))
|
||||
/* The text of the preediting area is inserted, but this doesn't
|
||||
* mean a change of the buffer yet. That is delayed until the
|
||||
* text is committed. (this means preedit becomes empty) */
|
||||
@@ -3276,6 +3276,7 @@ prompt_for_number(mouse_used)
|
||||
cmdline_row = msg_row - 1;
|
||||
need_wait_return = FALSE;
|
||||
msg_didany = FALSE;
|
||||
msg_didout = FALSE;
|
||||
}
|
||||
else
|
||||
cmdline_row = save_cmdline_row;
|
||||
@@ -8533,11 +8534,25 @@ match_suffix(fname)
|
||||
for (setsuf = p_su; *setsuf; )
|
||||
{
|
||||
setsuflen = copy_option_part(&setsuf, suf_buf, MAXSUFLEN, ".,");
|
||||
if (fnamelen >= setsuflen
|
||||
&& fnamencmp(suf_buf, fname + fnamelen - setsuflen,
|
||||
(size_t)setsuflen) == 0)
|
||||
break;
|
||||
setsuflen = 0;
|
||||
if (setsuflen == 0)
|
||||
{
|
||||
char_u *tail = gettail(fname);
|
||||
|
||||
/* empty entry: match name without a '.' */
|
||||
if (vim_strchr(tail, '.') == NULL)
|
||||
{
|
||||
setsuflen = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fnamelen >= setsuflen
|
||||
&& fnamencmp(suf_buf, fname + fnamelen - setsuflen,
|
||||
(size_t)setsuflen) == 0)
|
||||
break;
|
||||
setsuflen = 0;
|
||||
}
|
||||
}
|
||||
return (setsuflen != 0);
|
||||
}
|
||||
|
||||
+42
-4
@@ -409,8 +409,9 @@ struct vimoption
|
||||
#define P_NUM 0x02 /* the option is numeric */
|
||||
#define P_STRING 0x04 /* the option is a string */
|
||||
#define P_ALLOCED 0x08 /* the string option is in allocated memory,
|
||||
must use vim_free() when assigning new
|
||||
value. Not set if default is the same. */
|
||||
must use free_string_option() when
|
||||
assigning new value. Not set if default is
|
||||
the same. */
|
||||
#define P_EXPAND 0x10 /* environment expansion. NOTE: P_EXPAND can
|
||||
never be used for local or hidden options! */
|
||||
#define P_NODEFAULT 0x40 /* don't set to default value */
|
||||
@@ -7275,6 +7276,14 @@ set_bool_option(opt_idx, varp, value, opt_flags)
|
||||
compatible_set();
|
||||
}
|
||||
|
||||
/* 'list', 'number' */
|
||||
else if ((int *)varp == &curwin->w_p_list
|
||||
|| (int *)varp == &curwin->w_p_nu)
|
||||
{
|
||||
if (curwin->w_curswant != MAXCOL)
|
||||
curwin->w_set_curswant = TRUE;
|
||||
}
|
||||
|
||||
else if ((int *)varp == &curbuf->b_p_ro)
|
||||
{
|
||||
/* when 'readonly' is reset globally, also reset readonlymode */
|
||||
@@ -7763,6 +7772,14 @@ set_bool_option(opt_idx, varp, value, opt_flags)
|
||||
curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
|
||||
# endif
|
||||
}
|
||||
if (curwin->w_curswant != MAXCOL)
|
||||
curwin->w_set_curswant = TRUE;
|
||||
}
|
||||
|
||||
else if ((int *)varp == &p_arshape)
|
||||
{
|
||||
if (curwin->w_curswant != MAXCOL)
|
||||
curwin->w_set_curswant = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -7773,8 +7790,7 @@ set_bool_option(opt_idx, varp, value, opt_flags)
|
||||
options[opt_idx].flags |= P_WAS_SET;
|
||||
|
||||
comp_col(); /* in case 'ruler' or 'showcmd' changed */
|
||||
if (curwin->w_curswant != MAXCOL)
|
||||
curwin->w_set_curswant = TRUE; /* in case 'list' changed */
|
||||
|
||||
check_redraw(options[opt_idx].flags);
|
||||
|
||||
return NULL;
|
||||
@@ -9059,6 +9075,28 @@ free_termoptions()
|
||||
clear_termcodes();
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the string for one term option, if it was allocated.
|
||||
* Set the string to empty_option and clear allocated flag.
|
||||
* "var" points to the option value.
|
||||
*/
|
||||
void
|
||||
free_one_termoption(var)
|
||||
char_u *var;
|
||||
{
|
||||
struct vimoption *p;
|
||||
|
||||
for (p = &options[0]; p->fullname != NULL; p++)
|
||||
if (p->var == var)
|
||||
{
|
||||
if (p->flags & P_ALLOCED)
|
||||
free_string_option(*(char_u **)(p->var));
|
||||
*(char_u **)(p->var) = empty_option;
|
||||
p->flags &= ~P_ALLOCED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the terminal option defaults to the current value.
|
||||
* Used after setting the terminal name.
|
||||
|
||||
@@ -291,7 +291,6 @@
|
||||
# define HAVE_SETENV
|
||||
# define HAVE_RENAME
|
||||
# endif
|
||||
# define mch_chdir(s) chdir(s)
|
||||
#endif
|
||||
|
||||
#if defined(MACOS_X) && !defined(HAVE_CONFIG_H)
|
||||
|
||||
@@ -2039,6 +2039,12 @@ mch_chdir(char *path)
|
||||
{
|
||||
if (path[0] == NUL) /* just checking... */
|
||||
return 0;
|
||||
if (p_verbose >= 5)
|
||||
{
|
||||
verbose_enter();
|
||||
smsg((char_u *)"chdir(%s)", path);
|
||||
verbose_leave();
|
||||
}
|
||||
if (path[1] == ':') /* has a drive name */
|
||||
{
|
||||
if (change_drive(TOLOWER_ASC(path[0]) - 'a' + 1))
|
||||
|
||||
@@ -653,6 +653,12 @@ mch_chdir(char *path)
|
||||
if (path[0] == NUL) /* just checking... */
|
||||
return -1;
|
||||
|
||||
if (p_verbose >= 5)
|
||||
{
|
||||
verbose_enter();
|
||||
smsg((char_u *)"chdir(%s)", path);
|
||||
verbose_leave();
|
||||
}
|
||||
if (isalpha(path[0]) && path[1] == ':') /* has a drive name */
|
||||
{
|
||||
/* If we can change to the drive, skip that part of the path. If we
|
||||
|
||||
@@ -1203,6 +1203,12 @@ mch_chdir(dir)
|
||||
int retval;
|
||||
char_u *new_dir;
|
||||
|
||||
if (p_verbose >= 5)
|
||||
{
|
||||
verbose_enter();
|
||||
smsg((char_u *)"chdir(%s)", dir);
|
||||
verbose_leave();
|
||||
}
|
||||
length = strlen(dir);
|
||||
if (dir[length - 1] != '.')
|
||||
return chdir(dir); /* No trailing dots - nothing to do. */
|
||||
|
||||
+30
-7
@@ -319,6 +319,23 @@ static struct signalinfo
|
||||
{-1, "Unknown!", FALSE}
|
||||
};
|
||||
|
||||
int
|
||||
mch_chdir(path)
|
||||
char *path;
|
||||
{
|
||||
if (p_verbose >= 5)
|
||||
{
|
||||
verbose_enter();
|
||||
smsg((char_u *)"chdir(%s)", path);
|
||||
verbose_leave();
|
||||
}
|
||||
# ifdef VMS
|
||||
return chdir(vms_fixfilename(path));
|
||||
# else
|
||||
return chdir(path);
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Write s[len] to the screen.
|
||||
*/
|
||||
@@ -1138,10 +1155,10 @@ mch_suspend()
|
||||
* to happen).
|
||||
*/
|
||||
{
|
||||
long wait;
|
||||
for (wait = 0; !sigcont_received && wait <= 3L; wait++)
|
||||
long wait_time;
|
||||
for (wait_time = 0; !sigcont_received && wait_time <= 3L; wait_time++)
|
||||
/* Loop is not entered most of the time */
|
||||
mch_delay(wait, FALSE);
|
||||
mch_delay(wait_time, FALSE);
|
||||
}
|
||||
# endif
|
||||
|
||||
@@ -1717,9 +1734,9 @@ get_x11_icon(test_only)
|
||||
if (oldicon == NULL && !test_only)
|
||||
{
|
||||
if (STRNCMP(T_NAME, "builtin_", 8) == 0)
|
||||
oldicon = T_NAME + 8;
|
||||
oldicon = vim_strsave(T_NAME + 8);
|
||||
else
|
||||
oldicon = T_NAME;
|
||||
oldicon = vim_strsave(T_NAME);
|
||||
}
|
||||
|
||||
return retval;
|
||||
@@ -1922,9 +1939,9 @@ get_x11_icon(test_only)
|
||||
if (!test_only)
|
||||
{
|
||||
if (STRNCMP(T_NAME, "builtin_", 8) == 0)
|
||||
oldicon = T_NAME + 8;
|
||||
oldicon = vim_strsave(T_NAME + 8);
|
||||
else
|
||||
oldicon = T_NAME;
|
||||
oldicon = vim_strsave(T_NAME);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2426,6 +2443,12 @@ mch_FullName(fname, buf, len, force)
|
||||
#ifdef HAVE_FCHDIR
|
||||
if (fd >= 0)
|
||||
{
|
||||
if (p_verbose >= 5)
|
||||
{
|
||||
verbose_enter();
|
||||
MSG("fchdir() to previous dir");
|
||||
verbose_leave();
|
||||
}
|
||||
l = fchdir(fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
@@ -482,11 +482,6 @@ typedef struct dsc$descriptor DESC;
|
||||
# else
|
||||
int mch_rename __ARGS((const char *src, const char *dest));
|
||||
# endif
|
||||
# ifdef VMS
|
||||
# define mch_chdir(s) chdir(vms_fixfilename(s))
|
||||
# else
|
||||
# define mch_chdir(s) chdir(s)
|
||||
# endif
|
||||
# ifndef VMS
|
||||
# ifdef __MVS__
|
||||
/* on OS390 Unix getenv() doesn't return a pointer to persistent
|
||||
|
||||
@@ -29,6 +29,7 @@ int makeset __ARGS((FILE *fd, int opt_flags, int local_only));
|
||||
int makefoldset __ARGS((FILE *fd));
|
||||
void clear_termoptions __ARGS((void));
|
||||
void free_termoptions __ARGS((void));
|
||||
void free_one_termoption __ARGS((char_u *var));
|
||||
void set_term_defaults __ARGS((void));
|
||||
void comp_col __ARGS((void));
|
||||
char_u *get_equalprg __ARGS((void));
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* os_unix.c */
|
||||
int mch_chdir __ARGS((char *path));
|
||||
void mch_write __ARGS((char_u *s, int len));
|
||||
int mch_inchar __ARGS((char_u *buf, int maxlen, long wtime, int tb_change_cnt));
|
||||
int mch_char_avail __ARGS((void));
|
||||
|
||||
+16
-7
@@ -2695,7 +2695,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
#endif
|
||||
#define WL_LINE WL_SBR + 1 /* text in the line */
|
||||
int draw_state = WL_START; /* what to draw next */
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
#if defined(FEAT_XIM) && (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM))
|
||||
int feedback_col = 0;
|
||||
int feedback_old_attr = -1;
|
||||
#endif
|
||||
@@ -4254,12 +4254,15 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
&& !attr_pri)
|
||||
char_attr = extra_attr;
|
||||
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
#if defined(FEAT_XIM) && (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM))
|
||||
/* XIM don't send preedit_start and preedit_end, but they send
|
||||
* preedit_changed and commit. Thus Vim can't set "im_is_active", use
|
||||
* im_is_preediting() here. */
|
||||
if (xic != NULL
|
||||
&& lnum == wp->w_cursor.lnum
|
||||
if (
|
||||
# ifndef FEAT_GUI_MACVIM
|
||||
xic != NULL &&
|
||||
# endif
|
||||
lnum == wp->w_cursor.lnum
|
||||
&& (State & INSERT)
|
||||
&& !p_imdisable
|
||||
&& im_is_preediting()
|
||||
@@ -7467,6 +7470,10 @@ retry:
|
||||
*/
|
||||
FOR_ALL_TAB_WINDOWS(tp, wp)
|
||||
win_free_lsize(wp);
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (aucmd_win != NULL)
|
||||
win_free_lsize(aucmd_win);
|
||||
#endif
|
||||
|
||||
new_ScreenLines = (schar_T *)lalloc((long_u)(
|
||||
(Rows + 1) * Columns * sizeof(schar_T)), FALSE);
|
||||
@@ -7504,7 +7511,8 @@ retry:
|
||||
}
|
||||
}
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (aucmd_win != NULL && win_alloc_lines(aucmd_win) == FAIL)
|
||||
if (aucmd_win != NULL && aucmd_win->w_lines == NULL
|
||||
&& win_alloc_lines(aucmd_win) == FAIL)
|
||||
outofmem = TRUE;
|
||||
#endif
|
||||
#ifdef FEAT_WINDOWS
|
||||
@@ -8968,14 +8976,15 @@ showmode()
|
||||
&& curbuf->b_p_iminsert == B_IMODE_IM)
|
||||
# else
|
||||
if (
|
||||
# ifdef HAVE_GTK2
|
||||
# if defined(HAVE_GTK2) || defined(FEAT_GUI_MACVIM)
|
||||
preedit_get_status()
|
||||
# else
|
||||
im_get_status()
|
||||
# endif
|
||||
)
|
||||
# endif
|
||||
# ifdef HAVE_GTK2 /* most of the time, it's not XIM being used */
|
||||
# if defined(HAVE_GTK2) || defined(FEAT_GUI_MACVIM)
|
||||
/* most of the time, it's not XIM being used */
|
||||
MSG_PUTS_ATTR(" IM", attr);
|
||||
# else
|
||||
MSG_PUTS_ATTR(" XIM", attr);
|
||||
|
||||
+6
-2
@@ -10252,6 +10252,7 @@ spell_suggest(count)
|
||||
int limit;
|
||||
int selected = count;
|
||||
int badlen = 0;
|
||||
int msg_scroll_save = msg_scroll;
|
||||
|
||||
if (no_spell_checking(curwin))
|
||||
return;
|
||||
@@ -10416,7 +10417,9 @@ spell_suggest(count)
|
||||
selected = prompt_for_number(&mouse_used);
|
||||
if (mouse_used)
|
||||
selected -= lines_left;
|
||||
lines_left = Rows; /* avoid more prompt */
|
||||
lines_left = Rows; /* avoid more prompt */
|
||||
/* don't delay for 'smd' in normal_cmd() */
|
||||
msg_scroll = msg_scroll_save;
|
||||
}
|
||||
|
||||
if (selected > 0 && selected <= sug.su_ga.ga_len && u_save_cursor() == OK)
|
||||
@@ -10441,7 +10444,8 @@ spell_suggest(count)
|
||||
}
|
||||
|
||||
/* Replace the word. */
|
||||
p = alloc((unsigned)STRLEN(line) - stp->st_orglen + stp->st_wordlen + 1);
|
||||
p = alloc((unsigned)STRLEN(line) - stp->st_orglen
|
||||
+ stp->st_wordlen + 1);
|
||||
if (p != NULL)
|
||||
{
|
||||
c = (int)(sug.su_badptr - line);
|
||||
|
||||
@@ -2303,9 +2303,11 @@ typedef struct
|
||||
{
|
||||
buf_T *save_curbuf; /* saved curbuf */
|
||||
#ifdef FEAT_AUTOCMD
|
||||
int use_aucmd_win; /* using aucmd_win */
|
||||
win_T *save_curwin; /* saved curwin */
|
||||
win_T *new_curwin; /* new curwin */
|
||||
buf_T *new_curbuf; /* new curbuf */
|
||||
char_u *globaldir; /* saved value of globaldir */
|
||||
#endif
|
||||
} aco_save_T;
|
||||
|
||||
|
||||
+1
-1
@@ -2881,7 +2881,7 @@ ttest(pairs)
|
||||
|
||||
/* if 'Sb' and 'AB' are not defined, reset "Co" */
|
||||
if (*T_CSB == NUL && *T_CAB == NUL)
|
||||
T_CCO = empty_option;
|
||||
free_one_termoption(T_CCO);
|
||||
|
||||
/* Set 'weirdinvert' according to value of 't_xs' */
|
||||
p_wiv = (*T_XS != NUL);
|
||||
|
||||
@@ -3173,7 +3173,7 @@ im_save_status(psave)
|
||||
* And don't save when the GUI is running but our window doesn't have
|
||||
* input focus (e.g., when a find dialog is open). */
|
||||
if (!p_imdisable && KeyTyped && !KeyStuffed
|
||||
# ifdef FEAT_XIM
|
||||
# if defined(FEAT_XIM) && !defined(FEAT_GUI_MACVIM)
|
||||
&& xic != NULL
|
||||
# endif
|
||||
# ifdef FEAT_GUI
|
||||
|
||||
+1
-1
@@ -1390,7 +1390,7 @@ u_sync(force)
|
||||
/* Skip it when already synced or syncing is disabled. */
|
||||
if (curbuf->b_u_synced || (!force && no_u_sync > 0))
|
||||
return;
|
||||
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|
||||
#if defined(FEAT_XIM) && (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MACVIM))
|
||||
if (im_is_preediting())
|
||||
return; /* XIM is busy, don't break an undo sequence */
|
||||
#endif
|
||||
|
||||
@@ -691,6 +691,40 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
245,
|
||||
/**/
|
||||
244,
|
||||
/**/
|
||||
243,
|
||||
/**/
|
||||
242,
|
||||
/**/
|
||||
241,
|
||||
/**/
|
||||
240,
|
||||
/**/
|
||||
239,
|
||||
/**/
|
||||
238,
|
||||
/**/
|
||||
237,
|
||||
/**/
|
||||
236,
|
||||
/**/
|
||||
235,
|
||||
/**/
|
||||
234,
|
||||
/**/
|
||||
233,
|
||||
/**/
|
||||
232,
|
||||
/**/
|
||||
231,
|
||||
/**/
|
||||
230,
|
||||
/**/
|
||||
229,
|
||||
/**/
|
||||
228,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user