Compare commits

...

41 Commits

Author SHA1 Message Date
Bjorn Winckler 8cd984a56b Snapshot 48 2009-08-15 01:07:26 +02:00
Bjorn Winckler 650cb7ac61 Remove feat/inline-im from README-repo.txt 2009-08-15 00:21:44 +02:00
Bjorn Winckler ae400c2dbb Add user default MMUseInlineIm
Use inline IM (Vim draws marked text) when on, use old IM drawing code
otherwise.
2009-08-09 21:27:30 +02:00
Bjorn Winckler 507a68ef81 Add support for +xim
Inline marked text editing, underline marked text (even on command
line), etc.
2009-08-09 19:12:10 +02:00
Bjorn Winckler 271ef88821 Add rudimentary inline IM support
Not possible to move cursor in marked text.
2009-08-09 19:11:10 +02:00
Bjorn Winckler 9a248b819d Fix compilation errors on Tiger 2009-08-09 18:38:19 +02:00
Bjorn Winckler 6aeca470b5 Don't remember IM source if ASCII
This fixes a bug where the IM source would be forgotten whenever command
line mode was entered (with 'noimd' set).
2009-08-09 02:28:28 +02:00
Bjorn Winckler 936863de98 Add feat/inline-im to README-repo.txt 2009-08-09 02:20:42 +02:00
Bjorn Winckler d96b64262d Delete feat/input from README-repo.txt 2009-08-09 00:01:22 +02:00
Bjorn Winckler 200d3e5957 Only set ASCII IM source when setting 'noimd'
The layout used in normal mode (IM disabled) no longer changes when IM
is disabled.  It only changes when the 'noimd' option is set.
2009-08-08 23:37:29 +02:00
Bjorn Winckler 4ca28fccbd Merge upstream 2009-07-29 18:26:00 +02:00
vimboss 9c08729d42 updated for version 7.2-245 2009-07-29 16:25:31 +00:00
vimboss 8e0d50c1ed updated for version 7.2-244 2009-07-29 16:06:27 +00:00
vimboss 865619bc65 updated for version 7.2-243 2009-07-29 14:24:36 +00:00
vimboss 3b1a4d48f0 updated for version 7.2-242 2009-07-29 13:42:05 +00:00
vimboss 6c124f1604 updated for version 7.2-241 2009-07-29 10:10:29 +00:00
vimboss 44c21d0863 updated for version 7.2-240 2009-07-29 09:11:15 +00:00
Bjorn Winckler ad1b34005d Add note on improved IM support to the help 2009-07-26 17:02:10 +02:00
Bjorn Winckler 107a1cf7cc Improve IM support for 10.5
When using "set noimd" remember which input source was used in normal
mode separately from the input source used in insert mode.  This way it
is possible to e.g. use a US layout in normal mode and a non-US layout
in insert mode.

The input source used in normal mode must be ASCII capable or it won't
be remembered -- any input source used in insert mode is remembered.

On 10.4 the IM code is unchanged because 10.4 does not support the Text
Input Source Services.
2009-07-25 00:25:32 +02:00
Bjorn Winckler cbe2f307b1 Fix numeric key pad support 2009-07-24 12:42:42 +02:00
Bjorn Winckler 5213b783d7 Refactor keyboard input code
This both cleans up the code as well as improve support for binding to
more key combinations.  The Cocoa key bindings system is effectively
disabled; a custom key binding dictionary is set up in KeyBinding.plist
(so that keyboard navigation works in dialogs).
2009-07-23 18:28:34 +02:00
vimboss c6babee370 updated for version 7.2-239 2009-07-22 14:23:13 +00:00
vimboss b4b97fe905 updated for version 7.2-238 2009-07-22 12:28:17 +00:00
Bjorn Winckler cd37d01770 Add Vimball (vba) as supported filetype 2009-07-22 13:51:30 +02:00
vimboss d8b193e98b updated for version 7.2-237 2009-07-22 11:28:11 +00:00
vimboss 629579e8a0 updated for version 7.2-236 2009-07-22 09:17:23 +00:00
vimboss 9d6d075726 updated for version 7.2-235 2009-07-22 09:04:20 +00:00
Bjorn Winckler 7d6909d353 Set right pwd when dropping a folder on Dock icon
The last path component of the folder that was dropped is no longer
disregarded.
2009-07-21 03:34:15 +02:00
Bjorn Winckler b75c36581f ATSUI clips text to avoid bleeding 2009-07-20 20:13:42 +02:00
Bjorn Winckler ae253a2dad Fix typo in README-repo.txt 2009-07-19 00:29:47 +02:00
Bjorn Winckler 21cced3fc6 Add README-repo.txt file
For the "readme" section on the repo web page.  Pandoc is used to
generate the HTML file.
2009-07-18 21:18:39 +02:00
Bjorn Winckler 29745cf124 Snapshot 47 2009-07-16 20:08:56 +02:00
Bjorn Winckler 699de3c049 Change some logging messages 2009-07-16 14:35:27 +02:00
Bjorn Winckler 5560396666 Dialog sheet animation can no longer cause a crash
Explicitly force the sheet animation to be performed before passing the
result of the sheet on to the backend.  Before this patch the animation
was performed asynchronously and this could lead to a Vim controller
being released at the same time as the animation was being performed
since the animation took place in the default run loop mode.
2009-07-15 00:54:08 +02:00
Bjorn Winckler 8570b5df1f Merge upstream 2009-07-14 21:41:00 +02:00
vimboss 7391be3977 updated for version 7.2-234 2009-07-14 19:40:21 +00:00
vimboss 7068f9086c updated for version 7.2-233 2009-07-14 16:38:36 +00:00
vimboss af2e8b9e3b updated for version 7.2-232 2009-07-14 15:38:41 +00:00
vimboss 7d87f83e26 updated for version 7.2-231 2009-07-14 14:04:54 +00:00
vimboss eb6512ab82 updated for version 7.2-230 2009-07-14 11:44:30 +00:00
vimboss c2d5277fc9 updated for version 7.2-229 2009-07-14 10:20:22 +00:00
56 changed files with 1939 additions and 695 deletions
+8 -1
View File
@@ -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
View File
@@ -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.
+4 -3
View File
@@ -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
View File
@@ -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>
+532
View File
@@ -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>
+57 -3
View File
@@ -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;
}
+1
View File
@@ -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
+15 -1
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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)
+1
View File
@@ -33,6 +33,7 @@
- (void)setMouseShape:(int)shape;
- (void)setAntialias:(BOOL)antialias;
- (void)setImControl:(BOOL)enable;
- (void)activateIm:(BOOL)enable;
//
// MMTextStorage methods
+19 -2
View File
@@ -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:)
+13
View File
@@ -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
View File
@@ -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)
+34 -15
View File
@@ -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
+3 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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!
};
+7 -7
View File
@@ -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)",
+6
View File
@@ -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
+3
View File
@@ -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
+23
View File
@@ -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/
-62
View File
@@ -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
View File
@@ -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];
}
+1
View File
@@ -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],
}
+35 -6
View File
@@ -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>
+4 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+16 -2
View File
@@ -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);
}
+1 -1
View File
@@ -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
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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.
-1
View File
@@ -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)
+6
View File
@@ -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))
+6
View File
@@ -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
+6
View File
@@ -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
View File
@@ -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);
}
-5
View File
@@ -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
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+2
View File
@@ -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
View File
@@ -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);
+1 -1
View File
@@ -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
View File
@@ -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
+34
View File
@@ -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,
/**/