mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-05-28 00:21:57 +02:00
Compare commits
140 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 07831f45b2 | |||
| 9a69ad0d62 | |||
| be6ecb5d92 | |||
| 138be9d567 | |||
| 0430474168 | |||
| 0f1ee64746 | |||
| d08cc220fd | |||
| 04d9ab21b0 | |||
| 9c7523e944 | |||
| 030d0d07ec | |||
| 0578f14843 | |||
| 11274e43c4 | |||
| ebfad47ec6 | |||
| 48e6f325d6 | |||
| e899e2dfc7 | |||
| 1bc466c774 | |||
| f08c899208 | |||
| 31bd050607 | |||
| 2e6fb2ea53 | |||
| 862da53932 | |||
| 15763286bd | |||
| fed823a238 | |||
| 5d5176aabf | |||
| 19468d3117 | |||
| 0402b6b5c4 | |||
| b6932fb3ae | |||
| 22695b7f3b | |||
| bc8b62f3d9 | |||
| bd542602dd | |||
| e5159c3b6a | |||
| b36829bcaa | |||
| 07c344444b | |||
| bafcc3365d | |||
| 41ca0e5508 | |||
| 246dfc17f4 | |||
| 9aae3ba3cc | |||
| 0a54dd7370 | |||
| 6e8e20588d | |||
| 296634f40e | |||
| 13d45e4ff9 | |||
| 3e314dee6e | |||
| 779811f241 | |||
| 22017e1410 | |||
| af8ea2cc11 | |||
| ac3b778ddb | |||
| 1de2bc973a | |||
| cdb8dc17ca | |||
| b11e6ca3c9 | |||
| 69c366f7ed | |||
| 7792c4e8ab | |||
| 3910f20697 | |||
| 472eda54f6 | |||
| c09ef35588 | |||
| bf90097520 | |||
| 3292e01a82 | |||
| ba210fdada | |||
| 2d57fac276 | |||
| 4868c3cb85 | |||
| d38abe1843 | |||
| 045cef0a51 | |||
| 560504f7ba | |||
| 4ba3129468 | |||
| 98cc0fee24 | |||
| 26349fc938 | |||
| fb5cf175af | |||
| 0243a624be | |||
| 96433d48a1 | |||
| e5ecb34260 | |||
| 60fd59ea55 | |||
| 8afb077865 | |||
| eef4ba19a6 | |||
| 8574b2152c | |||
| 52b5ee23fc | |||
| d97c301011 | |||
| 343bd24d2e | |||
| a58654a6b0 | |||
| af62299744 | |||
| 60cd2a75c1 | |||
| 2ef7f8c8a0 | |||
| f2282b0096 | |||
| 90c663f76b | |||
| 5d748c8f27 | |||
| b8ac483bf8 | |||
| b884eef376 | |||
| 49cb3f99b8 | |||
| 9f83b2360b | |||
| 88b58bbd9f | |||
| dee796111a | |||
| 8ab6c75d08 | |||
| 3d8abd2669 | |||
| 12bec6e4ef | |||
| d26a1b2aad | |||
| 68799a3f7b | |||
| 164caf3832 | |||
| fa28669748 | |||
| 2fefb81d43 | |||
| 9d568fc7c9 | |||
| 0e6bfe9367 | |||
| 042108b0ad | |||
| 8ee6c93248 | |||
| 3f9f756149 | |||
| f6a5f65011 | |||
| f6e817e253 | |||
| bf22f09010 | |||
| 41c734a1aa | |||
| 65b46aa438 | |||
| 55790c5bb1 | |||
| 160b3ddb75 | |||
| 4bbbab9e56 | |||
| 548238236c | |||
| 1f27812ec0 | |||
| 1b21020c55 | |||
| d6fb745d7b | |||
| b5d1a8c5ba | |||
| 2e80f981c6 | |||
| 43d56b9b31 | |||
| d3b99588e3 | |||
| 80e4ddf501 | |||
| 143c782109 | |||
| a9dce2fa3d | |||
| bd394ba7b4 | |||
| 17b0feb45b | |||
| 9265b87738 | |||
| 84a3908488 | |||
| da50fc7107 | |||
| a2f006b7a5 | |||
| ff477a8d27 | |||
| ef149aa134 | |||
| a6907b971a | |||
| a8b5c51adf | |||
| ee5a7d0bb7 | |||
| dd78d32dd4 | |||
| 1190edd343 | |||
| 0a00f8f69f | |||
| b5b2678f9d | |||
| 1b133a3190 | |||
| 5e1defcf44 | |||
| 0f6e98e9fc | |||
| ed474b1614 | |||
| 518615feff |
@@ -18,5 +18,6 @@ src/auto/pathdef.c
|
||||
src/config.log
|
||||
src/config.status
|
||||
src/objects
|
||||
src/po/*.mo
|
||||
src/tags
|
||||
src/xxd/xxd
|
||||
|
||||
@@ -193,6 +193,7 @@ SRC_UNIX = \
|
||||
src/vim_icon.xbm \
|
||||
src/vim_mask.xbm \
|
||||
src/vimtutor \
|
||||
src/gvimtutor \
|
||||
src/which.sh \
|
||||
src/workshop.c \
|
||||
src/workshop.h \
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
" MacVim colorscheme
|
||||
"
|
||||
" Maintainer: Bjorn Winckler <bjorn.winckler@gmail.com>
|
||||
" Last Change: 2007 Nov 17
|
||||
" Last Change: 2008 May 9
|
||||
"
|
||||
" This is the default MacVim color scheme. It supports both light and dark
|
||||
" backgrounds (see :h 'background').
|
||||
@@ -50,7 +50,11 @@ hi TabLineFill gui=reverse
|
||||
hi TabLineSel gui=bold
|
||||
hi Title gui=bold guifg=DeepSkyBlue3
|
||||
hi VertSplit gui=NONE guifg=DarkSlateGray guibg=Gray90
|
||||
hi Visual guibg=MacSelectedTextBackgroundColor
|
||||
if has("gui_macvim")
|
||||
hi Visual guibg=MacSelectedTextBackgroundColor
|
||||
else
|
||||
hi Visual guibg=#72F7FF
|
||||
endif
|
||||
hi WarningMsg guifg=Firebrick2
|
||||
|
||||
" Syntax items (`:he group-name` -- more groups are available, these are just
|
||||
@@ -79,7 +83,7 @@ if &background == "dark"
|
||||
hi DiffChange guibg=MediumPurple4
|
||||
hi DiffDelete gui=bold guifg=White guibg=SlateBlue
|
||||
hi DiffText gui=NONE guifg=White guibg=SteelBlue
|
||||
hi LineNr guifg=#350A5B guibg=Grey5
|
||||
hi LineNr guifg=#552A7B guibg=Grey5
|
||||
hi MatchParen guifg=White guibg=Magenta
|
||||
hi Normal guifg=Grey50 guibg=Grey10
|
||||
hi Search guibg=Blue4 guifg=NONE
|
||||
@@ -101,7 +105,11 @@ else
|
||||
hi DiffText gui=NONE guibg=Gold
|
||||
hi LineNr guifg=#888888 guibg=#E6E6E6
|
||||
hi MatchParen guifg=White guibg=MediumPurple1
|
||||
hi Normal gui=NONE guifg=MacTextColor guibg=MacTextBackgroundColor
|
||||
if has("gui_macvim")
|
||||
hi Normal gui=NONE guifg=MacTextColor guibg=MacTextBackgroundColor
|
||||
else
|
||||
hi Normal gui=NONE guifg=Black guibg=White
|
||||
endif
|
||||
hi Search guibg=CadetBlue1 guifg=NONE
|
||||
hi Statement gui=bold guifg=Maroon guibg=NONE
|
||||
hi Todo gui=NONE guifg=DarkGreen guibg=PaleGreen1
|
||||
@@ -115,7 +123,7 @@ endif
|
||||
" Change the selection color on focus change (but only if the "macvim"
|
||||
" colorscheme is active).
|
||||
"
|
||||
if !exists("s:augroups_defined")
|
||||
if has("gui_macvim") && !exists("s:augroups_defined")
|
||||
au FocusLost * if exists("colors_name") && colors_name == "macvim" | hi Visual guibg=MacSecondarySelectedControlColor | endif
|
||||
au FocusGained * if exists("colors_name") && colors_name == "macvim" | hi Visual guibg=MacSelectedTextBackgroundColor | endif
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*eval.txt* For Vim version 7.1. Last change: 2008 Jan 11
|
||||
*eval.txt* For Vim version 7.1. Last change: 2008 Feb 20
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -1638,6 +1638,7 @@ getline( {lnum}) String line {lnum} of current buffer
|
||||
getline( {lnum}, {end}) List lines {lnum} to {end} of current buffer
|
||||
getloclist({nr}) List list of location list items
|
||||
getmatches() List list of current matches
|
||||
getpid() Number process ID of Vim
|
||||
getpos( {expr}) List position of cursor, mark, etc.
|
||||
getqflist() List list of quickfix items
|
||||
getreg( [{regname} [, 1]]) String contents of register
|
||||
@@ -3833,6 +3834,10 @@ nr2char({expr}) *nr2char()*
|
||||
characters. nr2char(0) is a real NUL and terminates the
|
||||
string, thus results in an empty string.
|
||||
|
||||
*getpid()*
|
||||
getpid() Return a Number which is the process ID of the Vim process.
|
||||
On Unix this is a unique number. On MS-DOS it's always zero.
|
||||
|
||||
*getpos()*
|
||||
getpos({expr}) Get the position for {expr}. For possible values of {expr}
|
||||
see |line()|.
|
||||
@@ -4523,6 +4528,9 @@ setpos({expr}, {list})
|
||||
character. E.g., a position within a <Tab> or after the last
|
||||
character.
|
||||
|
||||
Returns 0 when the position could be set, -1 otherwise.
|
||||
An error message is given if {expr} is invalid.
|
||||
|
||||
Also see |getpos()|
|
||||
|
||||
This does not restore the preferred column for moving
|
||||
|
||||
+126
-53
@@ -1,4 +1,4 @@
|
||||
*gui_mac.txt* For Vim version 7.1. Last change: 2008 Feb 05
|
||||
*gui_mac.txt* For Vim version 7.1. Last change: 2008 May 25
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bjorn Winckler
|
||||
@@ -34,9 +34,10 @@ on the MacVim project page >
|
||||
or by posting to the vim_mac mailing list *vim_mac* >
|
||||
http://groups.google.com/group/vim_mac
|
||||
|
||||
Remember to keep checking the project page for new snapshots. (If you
|
||||
downloaded this copy from somewhere else, you might want to go there now to
|
||||
make sure that you have got the latest version.)
|
||||
Remember to keep checking the project page for new snapshots or use the
|
||||
automatic updating feature which can be enabled in the preferences pane. (If
|
||||
you downloaded this copy from somewhere else, you might want to go there now
|
||||
to make sure that you have got the latest version.)
|
||||
|
||||
==============================================================================
|
||||
1. MacVim differences *macvim-differences*
|
||||
@@ -123,7 +124,28 @@ strings like "((3) of 2)" to appear in the window title.
|
||||
|
||||
*macvim-options*
|
||||
These are the non-standard options that MacVim supports:
|
||||
'fullscreen' 'toolbariconsize' 'transparency'
|
||||
'fullscreen' 'fuoptions' 'toolbariconsize' 'transparency' 'antialias'
|
||||
|
||||
*macvim-find*
|
||||
Whenever you search for something in Vim (e.g. using "/") the search query is
|
||||
copied to the OS X "Find Pasteboard". The idea is that if you search for
|
||||
something and switch to another application, then you can hit <D-g> (or <D-G>)
|
||||
to repeat the search in the new app. The same feature works if you search in
|
||||
some app, switch to MacVim and hit <D-g>.
|
||||
|
||||
Note that the command |n| is not the same as <D-g>. The former will repeat
|
||||
the last search made in Vim, whereas the latter searches for the string on the
|
||||
OS X Find Pasteboard using the action findNext: (see |:macaction|).
|
||||
|
||||
The <D-g> key equivalent is a great way to bring a search from one window to
|
||||
another in MacVim. Simply search for something in one window (using "/") then
|
||||
switch to another (e.g. with <D-`>) and hit <D-g> and the search will be
|
||||
repeated in the new window.
|
||||
|
||||
*macvim-backspace* *macvim-delete*
|
||||
The 'backspace' option is set in the system vimrc to make the delete key
|
||||
behave in a more familiar way to new users. If you dislike this non-default
|
||||
behaviour, then add the line "set backspace&" to your "~/.vimrc" file.
|
||||
|
||||
==============================================================================
|
||||
2. Starting MacVim *macvim-start*
|
||||
@@ -203,7 +225,11 @@ as general information regarding Mac OS X user defaults.
|
||||
Here is a list of relevant dictionary entries:
|
||||
|
||||
KEY VALUE ~
|
||||
MMAtsuiRenderer enable ATSUI renderer [bool]
|
||||
MMCellWidthMultiplier width of a normal glyph in em units [float]
|
||||
MMDialogsTrackPwd open/save dialogs track the Vim pwd [bool]
|
||||
MMLoginShellArgument login shell parameter [string]
|
||||
MMLoginShellCommand which shell to use to launch Vim [string]
|
||||
MMNoFontSubstitution disable automatic font substitution [bool]
|
||||
MMTabMaxWidth maximum width of a tab [int]
|
||||
MMTabMinWidth minimum width of a tab [int]
|
||||
@@ -214,6 +240,7 @@ MMTextInsetRight text area offset in pixels [int]
|
||||
MMTextInsetTop text area offset in pixels [int]
|
||||
MMTexturedWindow use brushed metal window (Tiger only) [bool]
|
||||
MMTranslateCtrlClick interpret ctrl-click as right-click [bool]
|
||||
MMZoomBoth zoom button maximizes both directions [bool]
|
||||
|
||||
As an example, if you have more than one mouse button and would wish to free
|
||||
up Ctrl-click so you can bind it to something else, then the appropriate
|
||||
@@ -223,6 +250,23 @@ command is: >
|
||||
If you wish to restore all user defaults to their starting values, open
|
||||
Terminal and type: >
|
||||
defaults delete org.vim.MacVim
|
||||
<
|
||||
*macvim-login-shell*
|
||||
Applications opened from the Finder do not automatically source the user's
|
||||
environment variables (which are typically set in .profile or .bashrc). This
|
||||
presents a problem when using |:!| to execute commands in the shell since e.g.
|
||||
$PATH might not be set properly. To work around this problem MacVim can start
|
||||
new Vim processes via a login shell so that all environment variables are set.
|
||||
|
||||
By default MacVim uses the $SHELL environment variable to determine which
|
||||
shell to use (if $SHELL is not set "/bin/bash" is used). It is possible to
|
||||
override this choice by setting the user default MMLoginShellCommand to the
|
||||
shell that should be used (e.g. "/bin/tcsh"). MacVim tries to make the shell
|
||||
a login shell by prepending argv[0] with a dash. If you use an exotic shell
|
||||
and need to pass it a parameter to make it a login shell then you can set the
|
||||
user default MMLoginShellArgument (e.g. to "-l"). Finally, if the "bash"
|
||||
shell is used, then "-l" is automatically added as an argument. To override
|
||||
this behaviour set MMLoginShellArgument to "--".
|
||||
|
||||
==============================================================================
|
||||
4. Special colors *macvim-colors*
|
||||
@@ -272,50 +316,79 @@ than the default?) then post them to |vim_mac|.
|
||||
==============================================================================
|
||||
5. Menus *macvim-menus*
|
||||
|
||||
*:macm* *:macmenukey*
|
||||
MacVim has a special way of binding keys to menu items that differs from other
|
||||
Vim GUI ports. A menu binding is called a "key equivalent" in Mac OS X
|
||||
terminology, this is displayed on the right side of a menu item. The
|
||||
":macmenukey" command is used to set the key equivalent of a menu item. This
|
||||
command takes two parameters, the first names the menu item to bind to, the
|
||||
second gives the key combination. For example: >
|
||||
:macmenukey File.New\ Tab <D-t>
|
||||
This sets the key equivalent of the "New Tab" menu item under the "File" menu
|
||||
to Cmd+t.
|
||||
Menus in Mac OS X behave slightly different from other platforms. For that
|
||||
reason two new commands have been added to Vim. To understand what these
|
||||
commands do you must first understand how menus work on OS X.
|
||||
|
||||
Note that key equivalents:
|
||||
* must contain the Cmd modifier flag (<D-...>)
|
||||
* take precedence over normal mappings made with ":map"
|
||||
* can only be modified during startup (e.g. in .gvimrc)
|
||||
Each entry in a menu is called a "menu item". With each menu item is
|
||||
associated: a title, a key equivalent and an action message. When a menu is
|
||||
displayed the title is shown on the left and the key equivalent (if any) is
|
||||
shown on the right. Key equivalents enable you to access a menu item using
|
||||
the keyboard instead of having to use the mouse. When a menu item is clicked
|
||||
it will send it's associated action message. Actions can be used to instruct
|
||||
MacVim to paste some text (paste:), open a new window (newWindow:), etc.
|
||||
Certain actions are standard throughout OS X which is why MacVim must be able
|
||||
to set these for each menu item. (E.g. the menu item "Edit.Paste" must be
|
||||
bound to the action "paste:" otherwise pasting won't work in dialogs since
|
||||
that is the action that instructs them to paste something.)
|
||||
|
||||
It is possible to reset a key equivalent by calling :macmenukey with a menu
|
||||
name but no key. This is so that the default key equivalents can be reset in
|
||||
"~/.gvimrc". For example, if you would like to free up <D-s> (which is the
|
||||
key equivalent of "File.Save") then add the following line to "~/.gvimrc": >
|
||||
macmenukey File.Save
|
||||
Now you can use :map to bind <D-s> to whatever you like.
|
||||
Menus are configured using the |:macmenu| command and the |:macaction| command
|
||||
can be used to send action messages.
|
||||
|
||||
It is not necessary to reset a key equivalent if all you want to do is to
|
||||
change the key equivalent of a menu item. For example, say you want to use
|
||||
<D-M-Right> as the key equivalent for "Next Tab", then add the following line
|
||||
to "~/.gvimrc": >
|
||||
macmenukey Window.Next\ Tab <D-M-Right>
|
||||
<
|
||||
*:maca* *:macaction*
|
||||
It is typical for menu items in Cocoa applications to bind to Objective-C
|
||||
selectors. To support this, MacVim introduces the ":macaction" command. This
|
||||
command takes the name of an action message as its only parameter. (An action
|
||||
message is an Objective-C message with "void" return type and a single
|
||||
parameter of type "id".) For example, the "New Window" menu item on the
|
||||
"File" menu is created in the following manner: >
|
||||
:an 10.290 File.New\ Window :macaction newWindow:<CR>
|
||||
:maca[ction] {action:} Send the message "action:" to the first responder.
|
||||
The list of allowed actions can be seen by typing
|
||||
:maca <C-d>
|
||||
An attempt to send an action not listed here will
|
||||
result in an error. This list is specified in a
|
||||
property list file called |Actions.plist|.
|
||||
|
||||
Note 1: A menu item which is bound to ":macaction" will automatically be bound
|
||||
to that action in all modes (as if ":an" was used). It is not possible to
|
||||
bind to ":macaction" in one mode only.
|
||||
Note 2: The action is "nil-targeted", which means it is passed down the first
|
||||
responder chain.
|
||||
*:macm* *:macmenu*
|
||||
:mac[menu] {menu} {key}={arg} ...
|
||||
Set Mac specific properties for {menu}. The
|
||||
properties that can be set are:
|
||||
action the action this menu sends
|
||||
alt "yes" if alternate of previous menu
|
||||
key the key equivalent of this menu
|
||||
This command must be used in a startup file, for
|
||||
example in "~/.gvimrc". It has no effect otherwise.
|
||||
|
||||
For convenience, a menu with "action=name:" which is
|
||||
bound to <Nop> will act as if bound to
|
||||
":maca name:<CR>". Thus, if "Menu.Item" is given by
|
||||
:an Menu.Item <Nop>
|
||||
:macm Menu.Item action=name:
|
||||
then ":emenu Menu.Item" is equivalent to
|
||||
":maca name:".
|
||||
|
||||
The key equivalent is specified with the <D-..>
|
||||
syntax. Note that key equivalents must contain the
|
||||
Cmd modifier flag (<D-...>), and they take precedence
|
||||
over normal mappings.
|
||||
Use the syntax "key=<nop>" to clear the key equivalent
|
||||
of a menu. This can be used to free up a key
|
||||
combination that is set in the system gvimrc so that
|
||||
it may be mapped to using ":map".
|
||||
|
||||
Recognised values of "alt" are "0", "no", "1", and
|
||||
"yes". The default is "no". An alternate menu must
|
||||
have the same key equivalent as the previous menu,
|
||||
except the modifier flags must differ. The alternate
|
||||
menu is by default hidden and only shows up when the
|
||||
modifier is held down.
|
||||
|
||||
Here are some examples on how to use these commands:
|
||||
|
||||
1. Create a menu item with title "New Window" under the "File" menu, with key
|
||||
equivalent Cmd-n, which opens a new window when selected: >
|
||||
:an 10.290 File.New\ Window <Nop>
|
||||
:macm File.New\ Window action=newWindow: key=<D-n>
|
||||
2. Change the key equivalent to cycle through tabs to Cmd-Left/Right: >
|
||||
:macm Window.Previous\ Tab key=<D-Left>
|
||||
:macm Window.Next\ Tab key=<D-Right>
|
||||
3. Create a mapping in normal mode which closes the current tab/window: >
|
||||
:map <C-w> :maca performClose:<CR>
|
||||
>
|
||||
*Actions.plist*
|
||||
Some action messages would not be suitable to call from within Vim, so there
|
||||
is a dictionary called "Actions.plist" (in the Resources folder of the
|
||||
@@ -323,27 +396,26 @@ application bundle) which contains all actions that may be called. The key in
|
||||
this dictionary is the name of the action message (case sensitive), the value
|
||||
is not used.
|
||||
|
||||
Hint: The |:macaction| command supports command-line completion so you can
|
||||
enter ":maca<Space><C-d>" to see a list of all available actions.
|
||||
|
||||
Here is a random assortment of actions from Actions.plist which might be
|
||||
useful.
|
||||
useful.
|
||||
|
||||
Action Description ~
|
||||
findNext: Search forward using the "Find Pasteboard"
|
||||
findPrevious: Search backward using the "Find Pasteboard"
|
||||
fontSizeDown: Decrease font size
|
||||
fontSizeUp: Increase font size
|
||||
newWindow: Open a new (empty) window
|
||||
orderFrontCharacterPalette: Show the the "Special Characters" dialog
|
||||
orderFrontFontPanel: Show the Font panel
|
||||
orderFrontPreferencePanel: Show the Preferences panel
|
||||
performClose: Close tab/window
|
||||
performZoom: Zoom window (same as clicking the green blob)
|
||||
selectNextWindow: Select next window (similar to <D-`>)
|
||||
selectPreviousWindow: Select previous window (similar to <S-D-`>)
|
||||
|
||||
As an example, to map <C-z> to performZoom: you could do something like this: >
|
||||
:map <silent> <C-z> :macaction performZoom:<CR>
|
||||
A better way to map to performZoom: would be to set the key equivalent of the
|
||||
menu item "Window.Zoom" to the above action. This can be done by adding the
|
||||
following line to "~/.gvimrc": >
|
||||
macmenukey Window.Zoom <D-C-z>
|
||||
(Note that key equivalents must contain the 'D' flag.)
|
||||
|
||||
==============================================================================
|
||||
6. Toolbar *macvim-toolbar*
|
||||
|
||||
@@ -482,7 +554,8 @@ Scenario: ~
|
||||
When you click the (green) zoom button you want the window to maximize
|
||||
horizontally as well as vertically.
|
||||
Solution: ~
|
||||
Hold down Cmd and click the zoom button.
|
||||
Hold down Cmd and click the zoom button. If you prefer this to be the default
|
||||
action, then set the user default MMZoomBoth (see |macvim-prefs|).
|
||||
|
||||
Scenario: ~
|
||||
Typing feels sluggish when the cursor is just before a right bracket (i.e. ')',
|
||||
|
||||
@@ -1289,7 +1289,7 @@ The commands are sorted on the non-optional part of their name.
|
||||
|:move| :m[ove] move lines
|
||||
|:mark| :ma[rk] set a mark
|
||||
|:macation| :maca[ction] send action message
|
||||
|:macmenukey| :macm[eyequiv] set key equivalent for menu item
|
||||
|:macmenu| :macm[enu] set Mac specific properties for menu item
|
||||
|:make| :mak[e] execute external command 'makeprg' and parse
|
||||
error messages
|
||||
|:map| :map show or enter a mapping
|
||||
|
||||
+80
-18
@@ -1,4 +1,4 @@
|
||||
*options.txt* For Vim version 7.1. Last change: 2007 Aug 10
|
||||
*options.txt* For Vim version 7.1. Last change: 2008 Feb 24
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -666,17 +666,21 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
Standard Annex #11 (http://www.unicode.org/reports/tr11).
|
||||
|
||||
*'antialias'* *'anti'* *'noantialias'* *'noanti'*
|
||||
'antialias' 'anti' boolean (default: off)
|
||||
'antialias' 'anti' boolean (default off, on for MacVim)
|
||||
global
|
||||
{not in Vi}
|
||||
{only available when compiled with Carbon GUI enabled
|
||||
on Mac OS X}
|
||||
This option only has an effect in the Carbon GUI version of Vim on Mac
|
||||
OS X v10.2 or later. When on, Vim will use smooth ("antialiased")
|
||||
fonts, which can be easier to read at certain sizes on certain
|
||||
displays. Setting this option can sometimes cause problems if
|
||||
'guifont' is set to its default (empty string).
|
||||
Note: Antialiasing is handled automatically on MacVim.
|
||||
{only available when compiled with GUI enabled on
|
||||
Mac OS X}
|
||||
This option only has an effect in the GUI version of Vim on Mac OS X
|
||||
v10.2 or later. When on, Vim will use smooth ("antialiased") fonts,
|
||||
which can be easier to read at certain sizes on certain displays.
|
||||
|
||||
Setting this option in the Carbon version can sometimes cause problems
|
||||
if 'guifont' is set to its default (empty string).
|
||||
|
||||
Support for this option is not flawless in MacVim. In particular,
|
||||
Monaco always seems to render not antialiased for point sizes up
|
||||
to 10. The ATSUI renderer has better antialias support.
|
||||
|
||||
*'autochdir'* *'acd'* *'noautochdir'* *'noacd'*
|
||||
'autochdir' 'acd' boolean (default off)
|
||||
@@ -3046,16 +3050,74 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
'fullscreen' 'fu' boolean (default off)
|
||||
global
|
||||
{not in Vi}
|
||||
{only available in the MacVim GUI}
|
||||
When this option is set, the whole screen is covered by vim. Screen
|
||||
{only in MacVim GUI}
|
||||
When this option is set, the whole screen is covered by Vim. Screen
|
||||
decorations drawn by the operating system (such as the dock or the
|
||||
menu bar) are hidden. Most of vim's window chrome is hidden as well
|
||||
(e.g. toolbar, title bar). The tab bar and scroll bars remains visible.
|
||||
|
||||
Most of the screen is black, only a 'columns' x 'lines' part of the
|
||||
screen is covered by the actual vim control. The control is centered.
|
||||
menu bar) are hidden. Most of Vim's window chrome is hidden as well
|
||||
(e.g. toolbar, title bar). The tab bar and scroll bars remain visible.
|
||||
Updates to the window position are ignored in fullscreen mode.
|
||||
|
||||
See 'fuoptions' for how Vim resizes and colors the background when
|
||||
entering and leaving fullscreen mode.
|
||||
|
||||
XXX: Add fuenter/fuleave autocommands? You might want to display
|
||||
a NERDTree or a Tlist only in fullscreen for example. Then again, this
|
||||
could probably be in a sizechanged autocommand that triggers if the
|
||||
size is above a certain threshold.
|
||||
XXX: Think about how 'fullscreen' and 'transparency' should interact.
|
||||
|
||||
*'fuoptions'* *'fuopt'*
|
||||
'fuoptions' 'fuopt' string (default "maxvert")
|
||||
global
|
||||
{not in Vi}
|
||||
{only in MacVim GUI}
|
||||
In fullscreen mode, most of the screen is black, only a part of the
|
||||
screen is covered by the actual Vim control. The control is centered.
|
||||
This option controls the size of the Vim control as well as the color
|
||||
of the unused screen area.
|
||||
value effect ~
|
||||
maxvert When entering fullscreen, 'lines' is set to the maximum number
|
||||
of lines fitting on the screen in fullscreen mode. When
|
||||
leaving fullscreen, if 'lines' is still equal to the maximized
|
||||
number of lines, it is restored to the value it had before
|
||||
entering fullscreen.
|
||||
maxhorz When entering fullscreen, 'columns' is set to the maximum number
|
||||
of columns fitting on the screen in fullscreen mode. When
|
||||
leaving fullscreen, if 'columns' is still equal to the maximized
|
||||
number of columns, it is restored to the value it had before
|
||||
entering fullscreen.
|
||||
background:color
|
||||
When entering fullscreen, 'color' defines the color of the part
|
||||
of the screen that is not occupied by the Vim control. If
|
||||
'color' is an 8-digit hexadecimal number preceded by '#',
|
||||
it is interpreted as an explicit color value '#aarrggbb', with
|
||||
one byte each for the alpha, red, green, and blue values.
|
||||
Otherwise, 'color' is interpreted as a highlight group name,
|
||||
and the fullscreen background is filled with that highlight
|
||||
group's background color, as defined by the current color
|
||||
scheme.
|
||||
|
||||
Examples:
|
||||
Don't change size of Vim when entering fullscreen: >
|
||||
:set fuoptions=
|
||||
< Maximize Vim when entering fullscreen: >
|
||||
:set fuoptions=maxvert,maxhorz
|
||||
< Maximize Vim only vertically when entering fullscreen, and color the
|
||||
background dark blue: >
|
||||
:set fuoptions=maxvert,background:#FF003042
|
||||
< Don't change the size of Vim when entering fullscreen, and color the
|
||||
background like the current text background: >
|
||||
:set fuoptions=background:Normal
|
||||
<
|
||||
XXX: what if the font size is changed? you probably never want to
|
||||
restore the old 'lines' or 'columns' in that case.
|
||||
XXX: Each time the Vim window resizes (for example due to font size
|
||||
changes, re-maximize Vim to fullscreen?)
|
||||
XXX: The approach doesn't restore vertical Vim size if fu is entered
|
||||
without tabs and leaves with tabs (or the other way round).
|
||||
|
||||
|
||||
|
||||
*'gdefault'* *'gd'* *'nogdefault'* *'nogd'*
|
||||
'gdefault' 'gd' boolean (default off)
|
||||
global
|
||||
@@ -4906,7 +4968,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
|autocmd-osfiletypes|
|
||||
|
||||
*'paragraphs'* *'para'*
|
||||
'paragraphs' 'para' string (default "IPLPPPQPP LIpplpipbp")
|
||||
'paragraphs' 'para' string (default "IPLPPPQPP TPHPLIPpLpItpplpipbp")
|
||||
global
|
||||
Specifies the nroff macros that separate paragraphs. These are pairs
|
||||
of two letters (see |object-motions|).
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*os_mac.txt* For Vim version 7.1. Last change: 2006 Apr 30
|
||||
*os_mac.txt* For Vim version 7.1. Last change: 2008 May 19
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar et al.
|
||||
@@ -6,9 +6,13 @@
|
||||
|
||||
*mac* *Mac* *macintosh* *Macintosh*
|
||||
|
||||
This file documents the particularities of the Macintosh version of Vim.
|
||||
This file documents the particularities of the Mac version of Vim. It was
|
||||
written with the older Carbon version of Vim in mind. If you are using the
|
||||
newer MacVim.app then please go to |macvim|. Some of the information here
|
||||
does not apply to MacVim.app.
|
||||
|
||||
NOTE: This file is a bit outdated. You might find more useful info here:
|
||||
NOTE: This file is a bit outdated. You might find more useful info on the old
|
||||
Carbon version of Vim here:
|
||||
http://macvim.org/
|
||||
|
||||
1. Filename Convention |mac-filename|
|
||||
|
||||
@@ -697,6 +697,7 @@ Short explanation of each option: *option-list*
|
||||
'formatexpr' 'fex' expression used with "gq" command
|
||||
'fsync' 'fs' whether to invoke fsync() after file write
|
||||
'fullscreen' 'fu' let vim cover the whole screen (MacVim only)
|
||||
'fuoptions' 'fuopt' controls how 'fullscreen' behaves (MacVim only)
|
||||
'gdefault' 'gd' the ":substitute" flag 'g' is default on
|
||||
'grepformat' 'gfm' format of 'grepprg' output
|
||||
'grepprg' 'gp' program to use for ":grep"
|
||||
|
||||
@@ -766,7 +766,8 @@ accordingly. Vim proceeds in this order:
|
||||
Note that this file is ALWAYS read in 'compatible' mode, since the
|
||||
automatic resetting of 'compatible' is only done later. Add a ":set
|
||||
nocp" command if you like.
|
||||
For the Macintosh the $VIMRUNTIME/macmap.vim is read.
|
||||
For the Macintosh the $VIMRUNTIME/macmap.vim is read (not on
|
||||
MacVim.app, this only applies to the older Carbon version).
|
||||
|
||||
*VIMINIT* *.vimrc* *_vimrc* *EXINIT* *.exrc* *_exrc*
|
||||
c. Four places are searched for initializations. The first that exists
|
||||
|
||||
@@ -1177,6 +1177,8 @@ goes from 2.2 to 2.3. (Gordon Prieur)
|
||||
|
||||
Mac: When starting up Vim will load the $VIMRUNTIME/macmap.vim script to
|
||||
define default command-key mappings. (mostly by Benji Fisher)
|
||||
This only applies to the older Carbon version of Vim, MacVim.app does not
|
||||
source this file.
|
||||
|
||||
Mac: Add the selection type to the clipboard, so that Block, line and
|
||||
character selections can be used between two Vims. (Eckehard Berns)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
vimtutor \- the Vim tutor
|
||||
.SH SYNOPSIS
|
||||
.br
|
||||
.B vimtutor [language]
|
||||
.B vimtutor [-g] [language]
|
||||
.SH DESCRIPTION
|
||||
.B Vimtutor
|
||||
starts the
|
||||
@@ -18,6 +18,9 @@ is useful for people that want to learn their first
|
||||
.B Vim
|
||||
commands.
|
||||
.PP
|
||||
The optional argument -g starts vimtutor with gvim rather than vim, if the
|
||||
GUI version of vim is available, or falls back to Vim if gvim is not found.
|
||||
.PP
|
||||
The optional [language] argument is the two-letter name of a language, like
|
||||
"it" or "es".
|
||||
If the [language] argument is missing, the language of the current locale will
|
||||
|
||||
+9
-3
@@ -1,7 +1,7 @@
|
||||
" Vim support file to switch on loading indent files for file types
|
||||
"
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2005 Mar 28
|
||||
" Last Change: 2008 Feb 22
|
||||
|
||||
if exists("did_indent_on")
|
||||
finish
|
||||
@@ -15,11 +15,17 @@ augroup filetypeindent
|
||||
exe b:undo_indent
|
||||
unlet! b:undo_indent b:did_indent
|
||||
endif
|
||||
if expand("<amatch>") != ""
|
||||
let s = expand("<amatch>")
|
||||
if s != ""
|
||||
if exists("b:did_indent")
|
||||
unlet b:did_indent
|
||||
endif
|
||||
runtime! indent/<amatch>.vim
|
||||
|
||||
" When there is a dot it is used to separate filetype names. Thus for
|
||||
" "aaa.bbb" load "indent/aaa.vim" and then "indent/bbb.vim".
|
||||
for name in split(s, '\.')
|
||||
exe 'runtime! indent/' . name . '.vim'
|
||||
endfor
|
||||
endif
|
||||
endfunc
|
||||
augroup END
|
||||
|
||||
@@ -617,6 +617,8 @@ if has("gui")
|
||||
call append("$", " \tset transparency=" . &transp)
|
||||
call append("$", "fullscreen\tdisplay vim in fullscreen mode")
|
||||
call <SID>BinOptionG("fullscreen", &fullscreen)
|
||||
call append("$", "fuoptions\tcontrol how fullscreen mode should behave")
|
||||
call <SID>OptionG("fuoptions", &fuoptions)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
" Vim plugin for showing matching parens
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2008 Jan 06
|
||||
" Last Change: 2008 Feb 27
|
||||
|
||||
" Exit quickly when:
|
||||
" - this plugin was already loaded (or disabled)
|
||||
@@ -34,7 +34,8 @@ function! s:Highlight_Matching_Pair()
|
||||
endif
|
||||
|
||||
" Avoid that we remove the popup menu.
|
||||
if pumvisible()
|
||||
" Return when there are no colors (looks like the cursor jumps).
|
||||
if pumvisible() || (&t_Co < 8 && !has("gui_running"))
|
||||
return
|
||||
endif
|
||||
|
||||
@@ -60,39 +61,13 @@ function! s:Highlight_Matching_Pair()
|
||||
endif
|
||||
|
||||
" Figure out the arguments for searchpairpos().
|
||||
" Restrict the search to visible lines with "stopline".
|
||||
" And avoid searching very far (e.g., for closed folds and long lines)
|
||||
" The "viewable" variables give a range in which we can scroll while keeping
|
||||
" the cursor at the same position
|
||||
" adjustedScrolloff accounts for very large numbers of scrolloff
|
||||
let adjustedScrolloff = min([&scrolloff, (line('w$') - line('w0')) / 2])
|
||||
let bottom_viewable = min([line('$'), c_lnum + &lines - adjustedScrolloff - 2])
|
||||
let top_viewable = max([1, c_lnum-&lines+adjustedScrolloff + 2])
|
||||
" one of these stoplines will be adjusted below, but the current values are
|
||||
" minimal boundaries within the current window
|
||||
let stoplinebottom = line('w$')
|
||||
let stoplinetop = line('w0')
|
||||
if i % 2 == 0
|
||||
let s_flags = 'nW'
|
||||
let c2 = plist[i + 1]
|
||||
if has("byte_offset") && has("syntax_items") && &smc > 0
|
||||
let stopbyte = min([line2byte("$"), line2byte(".") + col(".") + &smc * 2])
|
||||
let stopline = min([bottom_viewable, byte2line(stopbyte)])
|
||||
else
|
||||
let stopline = min([bottom_viewable, c_lnum + 100])
|
||||
endif
|
||||
let stoplinebottom = stopline
|
||||
else
|
||||
let s_flags = 'nbW'
|
||||
let c2 = c
|
||||
let c = plist[i - 1]
|
||||
if has("byte_offset") && has("syntax_items") && &smc > 0
|
||||
let stopbyte = max([1, line2byte(".") + col(".") - &smc * 2])
|
||||
let stopline = max([top_viewable, byte2line(stopbyte)])
|
||||
else
|
||||
let stopline = max([top_viewable, c_lnum - 100])
|
||||
endif
|
||||
let stoplinetop = stopline
|
||||
endif
|
||||
if c == '['
|
||||
let c = '\['
|
||||
@@ -111,10 +86,47 @@ function! s:Highlight_Matching_Pair()
|
||||
\ '=~? "string\\|character\\|singlequote\\|comment"'
|
||||
execute 'if' s_skip '| let s_skip = 0 | endif'
|
||||
|
||||
" Limit the search to lines visible in the window.
|
||||
let stoplinebottom = line('w$')
|
||||
let stoplinetop = line('w0')
|
||||
if i % 2 == 0
|
||||
let stopline = stoplinebottom
|
||||
else
|
||||
let stopline = stoplinetop
|
||||
endif
|
||||
|
||||
try
|
||||
" Limit the search time to 500 msec to avoid a hang on very long lines.
|
||||
let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline, 500)
|
||||
" Limit the search time to 300 msec to avoid a hang on very long lines.
|
||||
" This fails when a timeout is not supported.
|
||||
let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline, 300)
|
||||
catch /E118/
|
||||
" Can't use the timeout, restrict the stopline a bit more to avoid taking
|
||||
" a long time on closed folds and long lines.
|
||||
" The "viewable" variables give a range in which we can scroll while
|
||||
" keeping the cursor at the same position.
|
||||
" adjustedScrolloff accounts for very large numbers of scrolloff.
|
||||
let adjustedScrolloff = min([&scrolloff, (line('w$') - line('w0')) / 2])
|
||||
let bottom_viewable = min([line('$'), c_lnum + &lines - adjustedScrolloff - 2])
|
||||
let top_viewable = max([1, c_lnum-&lines+adjustedScrolloff + 2])
|
||||
" one of these stoplines will be adjusted below, but the current values are
|
||||
" minimal boundaries within the current window
|
||||
if i % 2 == 0
|
||||
if has("byte_offset") && has("syntax_items") && &smc > 0
|
||||
let stopbyte = min([line2byte("$"), line2byte(".") + col(".") + &smc * 2])
|
||||
let stopline = min([bottom_viewable, byte2line(stopbyte)])
|
||||
else
|
||||
let stopline = min([bottom_viewable, c_lnum + 100])
|
||||
endif
|
||||
let stoplinebottom = stopline
|
||||
else
|
||||
if has("byte_offset") && has("syntax_items") && &smc > 0
|
||||
let stopbyte = max([1, line2byte(".") + col(".") - &smc * 2])
|
||||
let stopline = max([top_viewable, byte2line(stopbyte)])
|
||||
else
|
||||
let stopline = max([top_viewable, c_lnum - 100])
|
||||
endif
|
||||
let stoplinetop = stopline
|
||||
endif
|
||||
let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline)
|
||||
endtry
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ gvimext.dll: gvimext.obj \
|
||||
gvimext.obj: gvimext.h
|
||||
|
||||
.cpp.obj:
|
||||
$(cc) $(cflags) -DFEAT_GETTEXT $(cvarsdll) $*.cpp
|
||||
$(cc) $(cflags) -DFEAT_GETTEXT $(cvarsmt) $*.cpp
|
||||
|
||||
gvimext.res: gvimext.rc
|
||||
$(rc) $(rcflags) $(rcvars) gvimext.rc
|
||||
|
||||
+10
-3
@@ -82,9 +82,8 @@ To compile and debug Vim with the VC2003 Toolkit, you will also need
|
||||
|ms-platform-sdk|, |dotnet-1.1-redist|, |dotnet-1.1-sdk|,
|
||||
and |windbg-download|.
|
||||
|
||||
It's easier to download Visual C++ 2005 Express Edition, |msvc-2005-express|.
|
||||
The advantage of the VC 2003 Toolkit is that it will be freely available
|
||||
long after VC 2005 Express Edition stops being free in November 2006.
|
||||
It's easier to download Visual C++ 2008 Express Edition, |msvc-2008-express|,
|
||||
which is freely available in perpetuity.
|
||||
|
||||
The free Code::Blocks IDE works with the VC2003 Toolkit, as described at
|
||||
http://wiki.codeblocks.org/index.php?title=Integrating_Microsoft_Visual_Toolkit_2003_with_Code::Blocks_IDE
|
||||
@@ -152,6 +151,14 @@ Instructions for integrating the Platform SDK into VC Express:
|
||||
http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/default.aspx
|
||||
|
||||
|
||||
Visual C++ 2008 Express Edition *msvc-2008-express*
|
||||
-------------------------------
|
||||
|
||||
Visual C++ 2008 Express Edition can be downloaded for free from:
|
||||
http://msdn2.microsoft.com/en-us/express/default.aspx
|
||||
This includes the IDE and the debugger. You can build Vim with Make_mvc.mak.
|
||||
|
||||
|
||||
2. MinGW
|
||||
========
|
||||
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
<?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">
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>addNewTab:</key>
|
||||
<string></string>
|
||||
<key>arrangeInFront:</key>
|
||||
<string></string>
|
||||
<key>clearRecentDocuments:</key>
|
||||
<string></string>
|
||||
<key>copy:</key>
|
||||
<string></string>
|
||||
<key>cut:</key>
|
||||
<string></string>
|
||||
<key>fileOpen:</key>
|
||||
<string></string>
|
||||
<key>findNext:</key>
|
||||
@@ -24,24 +30,36 @@
|
||||
<string></string>
|
||||
<key>newWindow:</key>
|
||||
<string></string>
|
||||
<key>openWebsite:</key>
|
||||
<string></string>
|
||||
<key>orderFrontCharacterPalette:</key>
|
||||
<string></string>
|
||||
<key>orderFrontFontPanel:</key>
|
||||
<string></string>
|
||||
<key>orderFrontPreferencePanel:</key>
|
||||
<string></string>
|
||||
<key>paste:</key>
|
||||
<string></string>
|
||||
<key>performClose:</key>
|
||||
<string></string>
|
||||
<key>performMiniaturize:</key>
|
||||
<string></string>
|
||||
<key>performZoom:</key>
|
||||
<string></string>
|
||||
<key>recentFilesDummy:</key>
|
||||
<string></string>
|
||||
<key>redo:</key>
|
||||
<string></string>
|
||||
<key>selectAll:</key>
|
||||
<string></string>
|
||||
<key>selectNextWindow:</key>
|
||||
<string></string>
|
||||
<key>selectPreviousWindow:</key>
|
||||
<string></string>
|
||||
<key>terminate:</key>
|
||||
<string></string>
|
||||
<key>undo:</key>
|
||||
<string></string>
|
||||
<key>unhide:</key>
|
||||
<string></string>
|
||||
<key>unhideAllApplications:</key>
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/* vi:set ts=8 sts=4 sw=4 ft=objc:
|
||||
*
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
*
|
||||
* Do ":help uganda" in Vim to read copying and usage conditions.
|
||||
* Do ":help credits" in Vim to see a list of people who contributed.
|
||||
* See README.txt for an overview of the Vim source code.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Security/Authorization.h>
|
||||
|
||||
|
||||
@interface AuthorizedShellCommand : NSObject {
|
||||
|
||||
NSArray *commands;
|
||||
|
||||
AuthorizationRef authorizationRef;
|
||||
|
||||
}
|
||||
|
||||
// Pass an array of dictionaries. Each dictionary has to have the following
|
||||
// keys:
|
||||
//
|
||||
// * MMCommand: The command to execute, an NSString (e.g. @"/usr/bin/rm").
|
||||
// * MMArguments: An array of NSStrings, the arguments that are passed to
|
||||
// the command.
|
||||
//
|
||||
- (AuthorizedShellCommand *)initWithCommands:(NSArray *)theCommands;
|
||||
|
||||
// Runs the command passed in the constructor.
|
||||
- (OSStatus)run;
|
||||
|
||||
// This pops up the permission dialog. Called by run.
|
||||
- (OSStatus)askUserForPermission;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
extern NSString *MMCommand;
|
||||
extern NSString *MMArguments;
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
/* vi:set ts=8 sts=4 sw=4 ft=objc:
|
||||
*
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
*
|
||||
* Do ":help uganda" in Vim to read copying and usage conditions.
|
||||
* Do ":help credits" in Vim to see a list of people who contributed.
|
||||
* See README.txt for an overview of the Vim source code.
|
||||
*/
|
||||
/*
|
||||
* AuthorizedCommand
|
||||
*
|
||||
* Runs a set of shell commands which may require authorization. Displays a
|
||||
* gui dialog to ask the user for authorized access.
|
||||
*/
|
||||
|
||||
#import "AuthorizedShellCommand.h"
|
||||
|
||||
#import <Security/AuthorizationTags.h>
|
||||
|
||||
@implementation AuthorizedShellCommand
|
||||
|
||||
- (AuthorizedShellCommand *)initWithCommands:(NSArray *)theCommands
|
||||
{
|
||||
if (![super init])
|
||||
return nil;
|
||||
|
||||
commands = [theCommands retain];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[super dealloc];
|
||||
[commands release];
|
||||
}
|
||||
|
||||
- (OSStatus)run
|
||||
{
|
||||
OSStatus err;
|
||||
int i;
|
||||
const char** arguments = NULL;
|
||||
AuthorizationFlags flags = kAuthorizationFlagDefaults;
|
||||
|
||||
err = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
|
||||
flags, &authorizationRef);
|
||||
if (err != errAuthorizationSuccess)
|
||||
return err;
|
||||
|
||||
if ((err = [self askUserForPermission]) != errAuthorizationSuccess) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
NSEnumerator* myIterator = [commands objectEnumerator];
|
||||
NSDictionary* currCommand;
|
||||
|
||||
while (currCommand = [myIterator nextObject])
|
||||
{
|
||||
/* do something useful with currCommand */
|
||||
FILE *ioPipe = NULL;
|
||||
char junk[256];
|
||||
|
||||
const char* toolPath = [[currCommand objectForKey:MMCommand] UTF8String];
|
||||
NSArray* argumentStrings = [currCommand objectForKey:MMArguments];
|
||||
arguments = (const char**)malloc(
|
||||
([argumentStrings count] + 1) * sizeof(char*));
|
||||
|
||||
for (i = 0; i < [argumentStrings count]; ++i) {
|
||||
arguments[i] = [[argumentStrings objectAtIndex:i] UTF8String];
|
||||
}
|
||||
arguments[i] = NULL;
|
||||
|
||||
err = AuthorizationExecuteWithPrivileges (authorizationRef, toolPath,
|
||||
kAuthorizationFlagDefaults, (char*const*)arguments, &ioPipe);
|
||||
if (err != errAuthorizationSuccess)
|
||||
goto cleanup;
|
||||
|
||||
#if 0
|
||||
// We use the pipe to signal us when the command has completed
|
||||
char *p;
|
||||
do {
|
||||
p = fgets(junk, sizeof(junk), ioPipe);
|
||||
} while (p);
|
||||
#else
|
||||
for(;;)
|
||||
{
|
||||
int bytesRead = read (fileno (ioPipe),
|
||||
junk, sizeof (junk));
|
||||
if (bytesRead < 1) break;
|
||||
write (fileno (stdout), junk, bytesRead);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (arguments != NULL) {
|
||||
free(arguments);
|
||||
arguments = NULL;
|
||||
}
|
||||
fclose(ioPipe);
|
||||
}
|
||||
|
||||
|
||||
|
||||
cleanup:
|
||||
AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);
|
||||
authorizationRef = 0;
|
||||
|
||||
if (arguments != NULL)
|
||||
free(arguments);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
- (OSStatus)askUserForPermission
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(authorizationRef != 0);
|
||||
|
||||
// The documentation for AuthorizationItem says that `value` should be
|
||||
// the path to the full posix path for kAuthorizationRightExecute. But
|
||||
// the installer sample "Calling a Privileged Installer" sets it to NULL.
|
||||
// Gotta love Apple's documentation.
|
||||
//
|
||||
// If you don't set `value` correctly, you'll get an
|
||||
// `errAuthorizationToolEnvironmentError` when you try to execute the
|
||||
// command.
|
||||
AuthorizationItem* authItems =
|
||||
malloc([commands count] * sizeof(AuthorizationItem));
|
||||
for (i = 0; i < [commands count]; ++i) {
|
||||
authItems[i].name = kAuthorizationRightExecute;
|
||||
authItems[i].value = (void*)
|
||||
[[[commands objectAtIndex:i] objectForKey:MMCommand] UTF8String];
|
||||
authItems[i].valueLength = strlen(authItems[i].value);
|
||||
authItems[i].flags = 0;
|
||||
}
|
||||
|
||||
AuthorizationRights rights = {
|
||||
[commands count], authItems
|
||||
};
|
||||
|
||||
OSStatus err = AuthorizationCopyRights(authorizationRef, &rights, NULL,
|
||||
kAuthorizationFlagInteractionAllowed |
|
||||
kAuthorizationFlagPreAuthorize |
|
||||
kAuthorizationFlagExtendRights
|
||||
, NULL);
|
||||
|
||||
free(authItems);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NSString *MMCommand = @"MMCommand";
|
||||
NSString *MMArguments = @"MMArguments";
|
||||
|
||||
+21
-15
@@ -1,32 +1,34 @@
|
||||
{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf440
|
||||
{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;\f2\fswiss\fcharset77 Helvetica-Oblique;
|
||||
}
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
|
||||
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\vieww9000\viewh8400\viewkind0
|
||||
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
|
||||
|
||||
\f0\b\fs24 \cf0 VIM - Vi IMproved
|
||||
\f1\b0 \
|
||||
\b0 \
|
||||
|
||||
\f2\i Bram Moolenaar et al.
|
||||
\f1\i0 \
|
||||
\i Bram Moolenaar et al.
|
||||
\i0 \
|
||||
\
|
||||
|
||||
\f0\b MacVim GUI\
|
||||
\b MacVim GUI\
|
||||
|
||||
\f2\i\b0 Bj\'9arn Winckler\
|
||||
\i\b0 Bj\'f6rn Winckler\
|
||||
|
||||
\f1\i0 \
|
||||
\i0 \
|
||||
with the help of:\
|
||||
|
||||
\f2\i Nico Weber (full-screen editing, Sparkle support, ...)\
|
||||
George Harker (transparency, ...)\
|
||||
\i Nico Weber\
|
||||
George Harker\
|
||||
Jjgod Jiang\
|
||||
Tim Allen\
|
||||
Chris Willmore\
|
||||
Ben Schmidt\
|
||||
Scott Renfro\
|
||||
Enno L\'fcbbers\
|
||||
|
||||
\f1\i0 \
|
||||
...and many others who have helped by reporting bugs or otherwise.\
|
||||
\i0 \
|
||||
...and many others who have helped by reporting bugs etc.\
|
||||
\
|
||||
\
|
||||
Thank you to {\field{\*\fldinst{HYPERLINK "http://www.positivespinmedia.com"}}{\fldrslt Positive Spin Media}} for the PSMTabBarControl Framework.\
|
||||
@@ -35,6 +37,10 @@ Toolbar icons from {\field{\*\fldinst{HYPERLINK "http://svn.gnome.org/viewvc/gno
|
||||
\
|
||||
Vim icons made by {\field{\*\fldinst{HYPERLINK "http://www.cs.princeton.edu/~mtwebb/vim_icon/vim_icons.html"}}{\fldrslt Matthew Webb}}.\
|
||||
\
|
||||
The default font in MacVim, DejaVu Sans Mono, is based on the Bitstream Vera\'aa and Arev fonts. Bitstream Vera\'aa is \'a9 2003 by Bitstream, Inc. Arev is \'a9 2006 by Tavmjong Bah. The DejaVu changes to these fonts are in the public domain.\
|
||||
The default font in MacVim, DejaVu Sans Mono, is based on the Bitstream Vera\'99 and Arev fonts. Bitstream Vera\'99 is \'a9 2003 by Bitstream, Inc. Arev is \'a9 2006 by Tavmjong Bah. The DejaVu changes to these fonts are in the public domain.\
|
||||
\
|
||||
Thanks to Andy Matuschak for {\field{\*\fldinst{HYPERLINK "http://sparkle.andymatuschak.org/"}}{\fldrslt Sparkle}}.}
|
||||
Thanks to Andy Matuschak for {\field{\*\fldinst{HYPERLINK "http://sparkle.andymatuschak.org/"}}{\fldrslt Sparkle}}.\
|
||||
\
|
||||
Thanks to Dave Batton for {\field{\*\fldinst{HYPERLINK "http://www.mere-mortal-software.com/blog/details.php?d=2007-03-11&c=show"}}{\fldrslt DBPrefsWindowController}}.\
|
||||
\
|
||||
Thanks to Allan Odgaard for making the "Edit in TextMate" input manager source code available, and also to Chris Eidhof and Eelco Lempsink for modifying it so that it could be used with any ODB capable editor.}
|
||||
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// DBPrefsWindowController.h
|
||||
//
|
||||
// Created by Dave Batton
|
||||
// http://www.Mere-Mortal-Software.com/blog/
|
||||
//
|
||||
// Documentation for this class is available here:
|
||||
// http://www.mere-mortal-software.com/blog/details.php?d=2007-03-11
|
||||
//
|
||||
// Copyright 2007. Some rights reserved.
|
||||
// This work is licensed under a Creative Commons license:
|
||||
// http://creativecommons.org/licenses/by/3.0/
|
||||
//
|
||||
// 11 March 2007 : Initial 1.0 release
|
||||
// 15 March 2007 : Version 1.1
|
||||
// Resizing is now handled along with the cross-fade by
|
||||
// the NSViewAnimation routine.
|
||||
// Cut the fade time in half to speed up the window resize.
|
||||
// -setupToolbar is now called each time the window opens so
|
||||
// you can configure it differently each time if you want.
|
||||
// Holding down the shift key will now slow down the animation.
|
||||
// This can be disabled by using the new -setShiftSlowsAnimation:
|
||||
// method.
|
||||
// 23 March 2007 : Version 1.1.1
|
||||
// The initial first responder now gets set when the view is
|
||||
// swapped so that the user can tab to the objects displayed
|
||||
// in the window.
|
||||
// Also added a work-around to Cocoa's insistance on drawing
|
||||
// a focus ring around the first toolbar icon when going from
|
||||
// a view with a focusable item to a view without a focusable item.
|
||||
//
|
||||
// 31 May 2007 : Version 1.1.2
|
||||
// The window's title bar and toolbar heights are now calculated at
|
||||
// runtime, rather than being hard-coded.
|
||||
// Fixed a redraw problem and a window placement problem associated
|
||||
// with large preference windows.
|
||||
// Added some code to supress compiler warnings from unused parameters.
|
||||
// Fixed a couple of objects that weren't being properly released.
|
||||
//
|
||||
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface DBPrefsWindowController : NSWindowController {
|
||||
NSMutableArray *toolbarIdentifiers;
|
||||
NSMutableDictionary *toolbarViews;
|
||||
NSMutableDictionary *toolbarItems;
|
||||
|
||||
BOOL _crossFade;
|
||||
BOOL _shiftSlowsAnimation;
|
||||
|
||||
NSView *contentSubview;
|
||||
NSViewAnimation *viewAnimation;
|
||||
|
||||
NSString *currentPaneIdentifier;
|
||||
}
|
||||
|
||||
|
||||
+ (DBPrefsWindowController *)sharedPrefsWindowController;
|
||||
+ (NSString *)nibName;
|
||||
|
||||
- (void)setupToolbar;
|
||||
- (void)addView:(NSView *)view label:(NSString *)label;
|
||||
- (void)addView:(NSView *)view label:(NSString *)label image:(NSImage *)image;
|
||||
|
||||
- (BOOL)crossFade;
|
||||
- (void)setCrossFade:(BOOL)fade;
|
||||
- (BOOL)shiftSlowsAnimation;
|
||||
- (void)setShiftSlowsAnimation:(BOOL)slows;
|
||||
|
||||
- (void)displayViewForIdentifier:(NSString *)identifier animate:(BOOL)animate;
|
||||
- (void)crossFadeView:(NSView *)oldView withView:(NSView *)newView;
|
||||
- (NSRect)frameForView:(NSView *)view;
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,431 @@
|
||||
//
|
||||
// DBPrefsWindowController.m
|
||||
//
|
||||
|
||||
#import "DBPrefsWindowController.h"
|
||||
|
||||
|
||||
static DBPrefsWindowController *_sharedPrefsWindowController = nil;
|
||||
|
||||
|
||||
@implementation DBPrefsWindowController
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Class Methods
|
||||
|
||||
|
||||
+ (DBPrefsWindowController *)sharedPrefsWindowController
|
||||
{
|
||||
if (!_sharedPrefsWindowController) {
|
||||
_sharedPrefsWindowController = [[self alloc] initWithWindowNibName:[self nibName]];
|
||||
}
|
||||
return _sharedPrefsWindowController;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+ (NSString *)nibName
|
||||
// Subclasses can override this to use a nib with a different name.
|
||||
{
|
||||
return @"Preferences";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Setup & Teardown
|
||||
|
||||
|
||||
- (id)initWithWindow:(NSWindow *)window
|
||||
// -initWithWindow: is the designated initializer for NSWindowController.
|
||||
{
|
||||
self = [super initWithWindow:nil];
|
||||
if (self != nil) {
|
||||
// Set up an array and some dictionaries to keep track
|
||||
// of the views we'll be displaying.
|
||||
toolbarIdentifiers = [[NSMutableArray alloc] init];
|
||||
toolbarViews = [[NSMutableDictionary alloc] init];
|
||||
toolbarItems = [[NSMutableDictionary alloc] init];
|
||||
|
||||
// Set up an NSViewAnimation to animate the transitions.
|
||||
viewAnimation = [[NSViewAnimation alloc] init];
|
||||
[viewAnimation setAnimationBlockingMode:NSAnimationNonblocking];
|
||||
[viewAnimation setAnimationCurve:NSAnimationEaseInOut];
|
||||
[viewAnimation setDelegate:self];
|
||||
|
||||
[self setCrossFade:YES];
|
||||
[self setShiftSlowsAnimation:YES];
|
||||
}
|
||||
return self;
|
||||
|
||||
(void)window; // To prevent compiler warnings.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)windowDidLoad
|
||||
{
|
||||
// Create a new window to display the preference views.
|
||||
// If the developer attached a window to this controller
|
||||
// in Interface Builder, it gets replaced with this one.
|
||||
NSPanel *window = [[[NSPanel alloc] initWithContentRect:NSMakeRect(0,0,1000,1000)
|
||||
styleMask:(NSTitledWindowMask |
|
||||
NSClosableWindowMask)
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:YES] autorelease];
|
||||
[window setHidesOnDeactivate:NO];
|
||||
[self setWindow:window];
|
||||
contentSubview = [[[NSView alloc] initWithFrame:[[[self window] contentView] frame]] autorelease];
|
||||
[contentSubview setAutoresizingMask:(NSViewMinYMargin | NSViewWidthSizable)];
|
||||
[[[self window] contentView] addSubview:contentSubview];
|
||||
[[self window] setShowsToolbarButton:NO];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void) dealloc {
|
||||
[toolbarIdentifiers release];
|
||||
[toolbarViews release];
|
||||
[toolbarItems release];
|
||||
[viewAnimation release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Configuration
|
||||
|
||||
|
||||
- (void)setupToolbar
|
||||
{
|
||||
// Subclasses must override this method to add items to the
|
||||
// toolbar by calling -addView:label: or -addView:label:image:.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)addView:(NSView *)view label:(NSString *)label
|
||||
{
|
||||
[self addView:view
|
||||
label:label
|
||||
image:[NSImage imageNamed:label]];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)addView:(NSView *)view label:(NSString *)label image:(NSImage *)image
|
||||
{
|
||||
NSAssert (view != nil,
|
||||
@"Attempted to add a nil view when calling -addView:label:image:.");
|
||||
|
||||
NSString *identifier = [[label copy] autorelease];
|
||||
|
||||
[toolbarIdentifiers addObject:identifier];
|
||||
[toolbarViews setObject:view forKey:identifier];
|
||||
|
||||
NSToolbarItem *item = [[[NSToolbarItem alloc] initWithItemIdentifier:identifier] autorelease];
|
||||
[item setLabel:label];
|
||||
[item setImage:image];
|
||||
[item setTarget:self];
|
||||
[item setAction:@selector(toggleActivePreferenceView:)];
|
||||
|
||||
[toolbarItems setObject:item forKey:identifier];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Accessor Methods
|
||||
|
||||
|
||||
- (BOOL)crossFade
|
||||
{
|
||||
return _crossFade;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)setCrossFade:(BOOL)fade
|
||||
{
|
||||
_crossFade = fade;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (BOOL)shiftSlowsAnimation
|
||||
{
|
||||
return _shiftSlowsAnimation;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)setShiftSlowsAnimation:(BOOL)slows
|
||||
{
|
||||
_shiftSlowsAnimation = slows;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (NSString *)currentPaneIdentifier
|
||||
// Subclasses can override this to persist the current preference pane.
|
||||
{
|
||||
return currentPaneIdentifier;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)setCurrentPaneIdentifier:(NSString *)identifier
|
||||
// Subclasses can override this to persist the current preference pane.
|
||||
{
|
||||
currentPaneIdentifier = identifier;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Overriding Methods
|
||||
|
||||
|
||||
- (IBAction)showWindow:(id)sender
|
||||
{
|
||||
// This forces the resources in the nib to load.
|
||||
(void)[self window];
|
||||
|
||||
// Clear the last setup and get a fresh one.
|
||||
[toolbarIdentifiers removeAllObjects];
|
||||
[toolbarViews removeAllObjects];
|
||||
[toolbarItems removeAllObjects];
|
||||
[self setupToolbar];
|
||||
|
||||
NSAssert (([toolbarIdentifiers count] > 0),
|
||||
@"No items were added to the toolbar in -setupToolbar.");
|
||||
|
||||
if ([[self window] toolbar] == nil) {
|
||||
NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"DBPreferencesToolbar"];
|
||||
[toolbar setAllowsUserCustomization:NO];
|
||||
[toolbar setAutosavesConfiguration:NO];
|
||||
[toolbar setSizeMode:NSToolbarSizeModeDefault];
|
||||
[toolbar setDisplayMode:NSToolbarDisplayModeIconAndLabel];
|
||||
[toolbar setDelegate:self];
|
||||
[[self window] setToolbar:toolbar];
|
||||
[toolbar release];
|
||||
}
|
||||
|
||||
if ([toolbarItems objectForKey:[self currentPaneIdentifier]] == nil) {
|
||||
[self setCurrentPaneIdentifier:[toolbarIdentifiers objectAtIndex:0]];
|
||||
}
|
||||
[[[self window] toolbar]
|
||||
setSelectedItemIdentifier:[self currentPaneIdentifier]];
|
||||
[self displayViewForIdentifier:[self currentPaneIdentifier] animate:NO];
|
||||
|
||||
[[self window] center];
|
||||
|
||||
[super showWindow:sender];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Toolbar
|
||||
|
||||
|
||||
- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
|
||||
{
|
||||
return toolbarIdentifiers;
|
||||
|
||||
(void)toolbar;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
|
||||
{
|
||||
return toolbarIdentifiers;
|
||||
|
||||
(void)toolbar;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
|
||||
{
|
||||
return toolbarIdentifiers;
|
||||
(void)toolbar;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)identifier willBeInsertedIntoToolbar:(BOOL)willBeInserted
|
||||
{
|
||||
return [toolbarItems objectForKey:identifier];
|
||||
(void)toolbar;
|
||||
(void)willBeInserted;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)toggleActivePreferenceView:(NSToolbarItem *)toolbarItem
|
||||
{
|
||||
[self displayViewForIdentifier:[toolbarItem itemIdentifier] animate:YES];
|
||||
[self setCurrentPaneIdentifier:[toolbarItem itemIdentifier]];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)displayViewForIdentifier:(NSString *)identifier animate:(BOOL)animate
|
||||
{
|
||||
// Find the view we want to display.
|
||||
NSView *newView = [toolbarViews objectForKey:identifier];
|
||||
|
||||
// See if there are any visible views.
|
||||
NSView *oldView = nil;
|
||||
if ([[contentSubview subviews] count] > 0) {
|
||||
// Get a list of all of the views in the window. Usually at this
|
||||
// point there is just one visible view. But if the last fade
|
||||
// hasn't finished, we need to get rid of it now before we move on.
|
||||
NSEnumerator *subviewsEnum = [[contentSubview subviews] reverseObjectEnumerator];
|
||||
|
||||
// The first one (last one added) is our visible view.
|
||||
oldView = [subviewsEnum nextObject];
|
||||
|
||||
// Remove any others.
|
||||
NSView *reallyOldView = nil;
|
||||
while ((reallyOldView = [subviewsEnum nextObject]) != nil) {
|
||||
[reallyOldView removeFromSuperviewWithoutNeedingDisplay];
|
||||
}
|
||||
}
|
||||
|
||||
if (![newView isEqualTo:oldView]) {
|
||||
NSRect frame = [newView bounds];
|
||||
frame.origin.y = NSHeight([contentSubview frame]) - NSHeight([newView bounds]);
|
||||
[newView setFrame:frame];
|
||||
[contentSubview addSubview:newView];
|
||||
[[self window] setInitialFirstResponder:newView];
|
||||
|
||||
if (animate && [self crossFade])
|
||||
[self crossFadeView:oldView withView:newView];
|
||||
else {
|
||||
[oldView removeFromSuperviewWithoutNeedingDisplay];
|
||||
[newView setHidden:NO];
|
||||
[[self window] setFrame:[self frameForView:newView] display:YES animate:animate];
|
||||
}
|
||||
|
||||
[[self window] setTitle:[[toolbarItems objectForKey:identifier] label]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Cross-Fading Methods
|
||||
|
||||
|
||||
- (void)crossFadeView:(NSView *)oldView withView:(NSView *)newView
|
||||
{
|
||||
[viewAnimation stopAnimation];
|
||||
|
||||
if ([self shiftSlowsAnimation] && [[[self window] currentEvent] modifierFlags] & NSShiftKeyMask)
|
||||
[viewAnimation setDuration:1.25];
|
||||
else
|
||||
[viewAnimation setDuration:0.25];
|
||||
|
||||
NSDictionary *fadeOutDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
oldView, NSViewAnimationTargetKey,
|
||||
NSViewAnimationFadeOutEffect, NSViewAnimationEffectKey,
|
||||
nil];
|
||||
|
||||
NSDictionary *fadeInDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
newView, NSViewAnimationTargetKey,
|
||||
NSViewAnimationFadeInEffect, NSViewAnimationEffectKey,
|
||||
nil];
|
||||
|
||||
NSDictionary *resizeDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[self window], NSViewAnimationTargetKey,
|
||||
[NSValue valueWithRect:[[self window] frame]], NSViewAnimationStartFrameKey,
|
||||
[NSValue valueWithRect:[self frameForView:newView]], NSViewAnimationEndFrameKey,
|
||||
nil];
|
||||
|
||||
NSArray *animationArray = [NSArray arrayWithObjects:
|
||||
fadeOutDictionary,
|
||||
fadeInDictionary,
|
||||
resizeDictionary,
|
||||
nil];
|
||||
|
||||
[viewAnimation setViewAnimations:animationArray];
|
||||
[viewAnimation startAnimation];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)animationDidEnd:(NSAnimation *)animation
|
||||
{
|
||||
NSView *subview;
|
||||
|
||||
// Get a list of all of the views in the window. Hopefully
|
||||
// at this point there are two. One is visible and one is hidden.
|
||||
NSEnumerator *subviewsEnum = [[contentSubview subviews] reverseObjectEnumerator];
|
||||
|
||||
// This is our visible view. Just get past it.
|
||||
subview = [subviewsEnum nextObject];
|
||||
|
||||
// Remove everything else. There should be just one, but
|
||||
// if the user does a lot of fast clicking, we might have
|
||||
// more than one to remove.
|
||||
while ((subview = [subviewsEnum nextObject]) != nil) {
|
||||
[subview removeFromSuperviewWithoutNeedingDisplay];
|
||||
}
|
||||
|
||||
// This is a work-around that prevents the first
|
||||
// toolbar icon from becoming highlighted.
|
||||
[[self window] makeFirstResponder:nil];
|
||||
|
||||
(void)animation;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (NSRect)frameForView:(NSView *)view
|
||||
// Calculate the window size for the new view.
|
||||
{
|
||||
NSRect windowFrame = [[self window] frame];
|
||||
NSRect contentRect = [[self window] contentRectForFrameRect:windowFrame];
|
||||
float windowTitleAndToolbarHeight = NSHeight(windowFrame) - NSHeight(contentRect);
|
||||
|
||||
windowFrame.size.height = NSHeight([view frame]) + windowTitleAndToolbarHeight;
|
||||
windowFrame.size.width = NSWidth([view frame]);
|
||||
windowFrame.origin.y = NSMaxY([[self window] frame]) - NSHeight(windowFrame);
|
||||
|
||||
return windowFrame;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@end
|
||||
+57
-11
@@ -1,11 +1,57 @@
|
||||
{
|
||||
IBClasses = (
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{
|
||||
CLASS = MMPreferenceController;
|
||||
LANGUAGE = ObjC;
|
||||
SUPERCLASS = NSWindowController;
|
||||
}
|
||||
);
|
||||
IBVersion = 1;
|
||||
}
|
||||
<?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>
|
||||
<key>IBClasses</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>ACTIONS</key>
|
||||
<dict>
|
||||
<key>installOdb</key>
|
||||
<string>id</string>
|
||||
<key>uninstallOdb</key>
|
||||
<string>id</string>
|
||||
</dict>
|
||||
<key>CLASS</key>
|
||||
<string>MMPreferenceController</string>
|
||||
<key>LANGUAGE</key>
|
||||
<string>ObjC</string>
|
||||
<key>OUTLETS</key>
|
||||
<dict>
|
||||
<key>editors</key>
|
||||
<string>NSPopUpButton</string>
|
||||
<key>generalPreferences</key>
|
||||
<string>NSView</string>
|
||||
<key>installOdbButton</key>
|
||||
<string>NSButton</string>
|
||||
<key>integrationPreferences</key>
|
||||
<string>NSView</string>
|
||||
<key>obdBundleVersionLabel</key>
|
||||
<string>NSTextField</string>
|
||||
<key>uninstallOdbButton</key>
|
||||
<string>NSButton</string>
|
||||
</dict>
|
||||
<key>SUPERCLASS</key>
|
||||
<string>DBPrefsWindowController</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CLASS</key>
|
||||
<string>FirstResponder</string>
|
||||
<key>LANGUAGE</key>
|
||||
<string>ObjC</string>
|
||||
<key>SUPERCLASS</key>
|
||||
<string>NSObject</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CLASS</key>
|
||||
<string>DBPrefsWindowController</string>
|
||||
<key>LANGUAGE</key>
|
||||
<string>ObjC</string>
|
||||
<key>SUPERCLASS</key>
|
||||
<string>NSWindowController</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>IBVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
+11
-21
@@ -1,31 +1,21 @@
|
||||
<?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">
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>69 14 356 240 0 0 1024 746 </string>
|
||||
<key>IBFramework Version</key>
|
||||
<string>489.0</string>
|
||||
<key>IBGroupedObjects</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<array>
|
||||
<string>79</string>
|
||||
<string>40</string>
|
||||
</array>
|
||||
<key>2</key>
|
||||
<array>
|
||||
<string>71</string>
|
||||
<string>37</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>IBLastGroupID</key>
|
||||
<string>3</string>
|
||||
<string>629</string>
|
||||
<key>IBLastKnownRelativeProjectPath</key>
|
||||
<string>../../MacVim.xcodeproj</string>
|
||||
<key>IBOldestOS</key>
|
||||
<integer>5</integer>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>5</integer>
|
||||
<integer>191</integer>
|
||||
<integer>115</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>8S165</string>
|
||||
<string>9C31</string>
|
||||
<key>targetFramework</key>
|
||||
<string>IBCocoaFramework</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
+16
-1
@@ -484,6 +484,21 @@
|
||||
<string>com.sun.java-class</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>patch</string>
|
||||
<string>diff</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>doc-bm</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Patch File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSIsAppleDefaultForType</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
@@ -530,7 +545,7 @@
|
||||
<key>CFBundleSignature</key>
|
||||
<string>VIMM</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>21</string>
|
||||
<string>28</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1010 B |
@@ -16,10 +16,13 @@
|
||||
|
||||
|
||||
@interface MMAppController : NSObject <MMAppProtocol> {
|
||||
NSConnection *connection;
|
||||
NSMutableArray *vimControllers;
|
||||
NSString *openSelectionString;
|
||||
ATSFontContainerRef fontContainerRef;
|
||||
NSMutableDictionary *pidArguments;
|
||||
|
||||
NSMenuItem *recentFilesMenuItem;
|
||||
}
|
||||
|
||||
- (void)removeVimController:(id)controller;
|
||||
@@ -31,5 +34,6 @@
|
||||
- (IBAction)fontSizeUp:(id)sender;
|
||||
- (IBAction)fontSizeDown:(id)sender;
|
||||
- (IBAction)orderFrontPreferencePanel:(id)sender;
|
||||
- (IBAction)openWebsite:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
+227
-80
@@ -30,6 +30,7 @@
|
||||
#import "MMVimController.h"
|
||||
#import "MMWindowController.h"
|
||||
#import "MMPreferenceController.h"
|
||||
#import <unistd.h>
|
||||
|
||||
|
||||
#define MM_HANDLE_XCODE_MOD_EVENT 0
|
||||
@@ -40,6 +41,8 @@
|
||||
static NSTimeInterval MMRequestTimeout = 5;
|
||||
static NSTimeInterval MMReplyTimeout = 5;
|
||||
|
||||
static NSString *MMWebsiteString = @"http://code.google.com/p/macvim/";
|
||||
|
||||
|
||||
#pragma options align=mac68k
|
||||
typedef struct
|
||||
@@ -54,6 +57,9 @@ typedef struct
|
||||
#pragma options align=reset
|
||||
|
||||
|
||||
static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
|
||||
|
||||
@interface MMAppController (MMServices)
|
||||
- (void)openSelection:(NSPasteboard *)pboard userData:(NSString *)userData
|
||||
error:(NSString **)error;
|
||||
@@ -115,6 +121,10 @@ typedef struct
|
||||
[NSNumber numberWithInt:MMUntitledWindowAlways],
|
||||
MMUntitledWindowKey,
|
||||
[NSNumber numberWithBool:NO], MMTexturedWindowKey,
|
||||
[NSNumber numberWithBool:NO], MMZoomBothKey,
|
||||
@"", MMLoginShellCommandKey,
|
||||
@"", MMLoginShellArgumentKey,
|
||||
[NSNumber numberWithBool:YES], MMDialogsTrackPwdKey,
|
||||
nil];
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
|
||||
@@ -131,24 +141,30 @@ typedef struct
|
||||
vimControllers = [NSMutableArray new];
|
||||
pidArguments = [NSMutableDictionary new];
|
||||
|
||||
// NOTE: Do not use the default connection since the Logitech Control
|
||||
// Center (LCC) input manager steals and this would cause MacVim to
|
||||
// never open any windows. (This is a bug in LCC but since they are
|
||||
// unlikely to fix it, we graciously give them the default connection.)
|
||||
connection = [[NSConnection alloc] initWithReceivePort:[NSPort port]
|
||||
sendPort:nil];
|
||||
[connection setRootObject:self];
|
||||
[connection setRequestTimeout:MMRequestTimeout];
|
||||
[connection setReplyTimeout:MMReplyTimeout];
|
||||
|
||||
// NOTE: When the user is resizing the window the AppKit puts the run
|
||||
// loop in event tracking mode. Unless the connection listens to
|
||||
// request in this mode, live resizing won't work.
|
||||
[connection addRequestMode:NSEventTrackingRunLoopMode];
|
||||
|
||||
// NOTE! If the name of the connection changes here it must also be
|
||||
// updated in MMBackend.m.
|
||||
NSConnection *connection = [NSConnection defaultConnection];
|
||||
NSString *name = [NSString stringWithFormat:@"%@-connection",
|
||||
[[NSBundle mainBundle] bundleIdentifier]];
|
||||
//NSLog(@"Registering connection with name '%@'", name);
|
||||
if ([connection registerName:name]) {
|
||||
[connection setRequestTimeout:MMRequestTimeout];
|
||||
[connection setReplyTimeout:MMReplyTimeout];
|
||||
[connection setRootObject:self];
|
||||
|
||||
// NOTE: When the user is resizing the window the AppKit puts the
|
||||
// run loop in event tracking mode. Unless the connection listens
|
||||
// to request in this mode, live resizing won't work.
|
||||
[connection addRequestMode:NSEventTrackingRunLoopMode];
|
||||
} else {
|
||||
NSLog(@"WARNING: Failed to register connection with name '%@'",
|
||||
if (![connection registerName:name]) {
|
||||
NSLog(@"FATAL ERROR: Failed to register connection with name '%@'",
|
||||
name);
|
||||
[connection release]; connection = nil;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,23 +175,49 @@ typedef struct
|
||||
{
|
||||
//NSLog(@"MMAppController dealloc");
|
||||
|
||||
[connection release]; connection = nil;
|
||||
[pidArguments release]; pidArguments = nil;
|
||||
[vimControllers release]; vimControllers = nil;
|
||||
[openSelectionString release]; openSelectionString = nil;
|
||||
[recentFilesMenuItem release]; recentFilesMenuItem = nil;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
#if MM_HANDLE_XCODE_MOD_EVENT
|
||||
- (void)applicationWillFinishLaunching:(NSNotification *)notification
|
||||
{
|
||||
// Create the "Open Recent" menu. See
|
||||
// http://lapcatsoftware.com/blog/2007/07/10/working-without-a-nib-part-5-open-recent-menu/
|
||||
// and http://www.cocoabuilder.com/archive/message/cocoa/2007/8/15/187793
|
||||
// for more information.
|
||||
//
|
||||
// The menu needs to be created and be added to a toplevel menu in
|
||||
// applicationWillFinishLaunching at the latest, otherwise it doesn't work.
|
||||
|
||||
recentFilesMenuItem = [[NSMenuItem alloc] initWithTitle:@"Open Recent"
|
||||
action:nil keyEquivalent:@""];
|
||||
|
||||
NSMenu *recentFilesMenu = [[NSMenu alloc] initWithTitle:@"Open Recent"];
|
||||
[recentFilesMenu performSelector:@selector(_setMenuName:)
|
||||
withObject:@"NSRecentDocumentsMenu"];
|
||||
|
||||
[recentFilesMenu addItemWithTitle:@"Clear Menu"
|
||||
action:@selector(clearRecentDocuments:)
|
||||
keyEquivalent:@""];
|
||||
[recentFilesMenuItem setSubmenu:recentFilesMenu];
|
||||
[recentFilesMenu release]; // the menu is retained by recentFilesMenuItem
|
||||
[recentFilesMenuItem setTag:-1]; // must not be 0
|
||||
|
||||
[[[[NSApp mainMenu] itemWithTitle:@"File"] submenu] addItem:recentFilesMenuItem];
|
||||
|
||||
#if MM_HANDLE_XCODE_MOD_EVENT
|
||||
[[NSAppleEventManager sharedAppleEventManager]
|
||||
setEventHandler:self
|
||||
andSelector:@selector(handleXcodeModEvent:replyEvent:)
|
||||
forEventClass:'KAHL'
|
||||
andEventID:'MOD '];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||
{
|
||||
@@ -252,6 +294,16 @@ typedef struct
|
||||
[arguments setObject:filenames forKey:@"filenames"];
|
||||
[arguments setObject:[NSNumber numberWithBool:YES] forKey:@"openFiles"];
|
||||
|
||||
// Add file names to "Recent Files" menu.
|
||||
int i, count = [filenames count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
// Don't add files that are being edited remotely (using ODB).
|
||||
if ([arguments objectForKey:@"remoteID"]) continue;
|
||||
|
||||
[[NSDocumentController sharedDocumentController]
|
||||
noteNewRecentFilePath:[filenames objectAtIndex:i]];
|
||||
}
|
||||
|
||||
if ((openInTabs && (vc = [self topmostVimController]))
|
||||
|| (vc = [self findUntitledWindow])) {
|
||||
// Open files in an already open window.
|
||||
@@ -273,6 +325,13 @@ typedef struct
|
||||
|
||||
pid = [self launchVimProcessWithArguments:fileArgs];
|
||||
|
||||
if (-1 == pid) {
|
||||
// TODO: Notify user of failure?
|
||||
[NSApp replyToOpenOrPrint:
|
||||
NSApplicationDelegateReplyFailure];
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure these files aren't opened again when
|
||||
// connectBackend:pid: is called.
|
||||
[arguments setObject:[NSNumber numberWithBool:NO]
|
||||
@@ -405,9 +464,9 @@ typedef struct
|
||||
andEventID:'MOD '];
|
||||
#endif
|
||||
|
||||
// This will invalidate all connections (since they were spawned from the
|
||||
// default connection).
|
||||
[[NSConnection defaultConnection] invalidate];
|
||||
// This will invalidate all connections (since they were spawned from this
|
||||
// connection).
|
||||
[connection invalidate];
|
||||
|
||||
// Send a SIGINT to all running Vim processes, so that they are sure to
|
||||
// receive the connectionDidDie: notification (a process has to be checking
|
||||
@@ -453,15 +512,15 @@ typedef struct
|
||||
- (void)windowControllerWillOpen:(MMWindowController *)windowController
|
||||
{
|
||||
NSPoint topLeft = NSZeroPoint;
|
||||
NSWindow *keyWin = [NSApp keyWindow];
|
||||
NSWindow *topWin = [[[self topmostVimController] windowController] window];
|
||||
NSWindow *win = [windowController window];
|
||||
|
||||
if (!win) return;
|
||||
|
||||
// If there is a key window, cascade from it, otherwise use the autosaved
|
||||
// window position (if any).
|
||||
if (keyWin) {
|
||||
NSRect frame = [keyWin frame];
|
||||
// If there is a window belonging to a Vim process, cascade from it,
|
||||
// otherwise use the autosaved window position (if any).
|
||||
if (topWin) {
|
||||
NSRect frame = [topWin frame];
|
||||
topLeft = NSMakePoint(frame.origin.x, NSMaxY(frame));
|
||||
} else {
|
||||
NSString *topLeftString = [[NSUserDefaults standardUserDefaults]
|
||||
@@ -471,7 +530,7 @@ typedef struct
|
||||
}
|
||||
|
||||
if (!NSEqualPoints(topLeft, NSZeroPoint)) {
|
||||
if (keyWin)
|
||||
if (topWin)
|
||||
topLeft = [win cascadeTopLeftFromPoint:topLeft];
|
||||
|
||||
[win setFrameTopLeftPoint:topLeft];
|
||||
@@ -496,10 +555,17 @@ typedef struct
|
||||
|
||||
- (IBAction)fileOpen:(id)sender
|
||||
{
|
||||
NSString *dir = nil;
|
||||
BOOL trackPwd = [[NSUserDefaults standardUserDefaults]
|
||||
boolForKey:MMDialogsTrackPwdKey];
|
||||
if (trackPwd) {
|
||||
MMVimController *vc = [self keyVimController];
|
||||
if (vc) dir = [[vc vimState] objectForKey:@"pwd"];
|
||||
}
|
||||
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
[panel setAllowsMultipleSelection:YES];
|
||||
|
||||
int result = [panel runModalForTypes:nil];
|
||||
int result = [panel runModalForDirectory:dir file:nil types:nil];
|
||||
if (NSOKButton == result)
|
||||
[self application:NSApp openFiles:[panel filenames]];
|
||||
}
|
||||
@@ -561,7 +627,13 @@ typedef struct
|
||||
|
||||
- (IBAction)orderFrontPreferencePanel:(id)sender
|
||||
{
|
||||
[[MMPreferenceController sharedPreferenceController] showWindow:self];
|
||||
[[MMPreferenceController sharedPrefsWindowController] showWindow:self];
|
||||
}
|
||||
|
||||
- (IBAction)openWebsite:(id)sender
|
||||
{
|
||||
[[NSWorkspace sharedWorkspace] openURL:
|
||||
[NSURL URLWithString:MMWebsiteString]];
|
||||
}
|
||||
|
||||
- (byref id <MMFrontendProtocol>)
|
||||
@@ -577,7 +649,8 @@ typedef struct
|
||||
setProtocolForProxy:@protocol(MMBackendProtocol)];
|
||||
|
||||
vc = [[[MMVimController alloc]
|
||||
initWithBackend:backend pid:pid] autorelease];
|
||||
initWithBackend:backend pid:pid recentFiles:recentFilesMenuItem]
|
||||
autorelease];
|
||||
|
||||
if (![vimControllers count]) {
|
||||
// The first window autosaves its position. (The autosaving
|
||||
@@ -719,9 +792,10 @@ typedef struct
|
||||
|
||||
- (MMVimController *)topmostVimController
|
||||
{
|
||||
NSArray *windows = [NSApp orderedWindows];
|
||||
if ([windows count] > 0) {
|
||||
NSWindow *window = [windows objectAtIndex:0];
|
||||
// Find the topmost visible window which has an associated vim controller.
|
||||
NSEnumerator *e = [[NSApp orderedWindows] objectEnumerator];
|
||||
id window;
|
||||
while ((window = [e nextObject]) && [window isVisible]) {
|
||||
unsigned i, count = [vimControllers count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
MMVimController *vc = [vimControllers objectAtIndex:i];
|
||||
@@ -735,68 +809,43 @@ typedef struct
|
||||
|
||||
- (int)launchVimProcessWithArguments:(NSArray *)args
|
||||
{
|
||||
NSString *taskPath = nil;
|
||||
NSArray *taskArgs = nil;
|
||||
int pid = -1;
|
||||
NSString *path = [[NSBundle mainBundle] pathForAuxiliaryExecutable:@"Vim"];
|
||||
|
||||
if (!path) {
|
||||
NSLog(@"ERROR: Vim executable could not be found inside app bundle!");
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ([[NSUserDefaults standardUserDefaults] boolForKey:MMLoginShellKey]) {
|
||||
// Run process with a login shell
|
||||
// $SHELL -l -c "exec Vim -g -f args"
|
||||
// (-g for GUI, -f for foreground, i.e. don't fork)
|
||||
NSArray *taskArgs = [NSArray arrayWithObjects:@"-g", @"-f", nil];
|
||||
if (args)
|
||||
taskArgs = [taskArgs arrayByAddingObjectsFromArray:args];
|
||||
|
||||
NSMutableString *execArg = [NSMutableString
|
||||
stringWithFormat:@"exec \"%@\" -g -f", path];
|
||||
if (args) {
|
||||
// Append all arguments while making sure that arguments containing
|
||||
// spaces are enclosed in quotes.
|
||||
NSCharacterSet *space = [NSCharacterSet whitespaceCharacterSet];
|
||||
unsigned i, count = [args count];
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSString *arg = [args objectAtIndex:i];
|
||||
if (NSNotFound != [arg rangeOfCharacterFromSet:space].location)
|
||||
[execArg appendFormat:@" \"%@\"", arg];
|
||||
else
|
||||
[execArg appendFormat:@" %@", arg];
|
||||
}
|
||||
}
|
||||
|
||||
// Launch the process with a login shell so that users environment
|
||||
// settings get sourced. This does not always happen when MacVim is
|
||||
// started.
|
||||
taskArgs = [NSArray arrayWithObjects:@"-l", @"-c", execArg, nil];
|
||||
taskPath = [[[NSProcessInfo processInfo] environment]
|
||||
objectForKey:@"SHELL"];
|
||||
if (!taskPath)
|
||||
taskPath = @"/bin/sh";
|
||||
BOOL useLoginShell = [[NSUserDefaults standardUserDefaults]
|
||||
boolForKey:MMLoginShellKey];
|
||||
if (useLoginShell) {
|
||||
// Run process with a login shell, roughly:
|
||||
// echo "exec Vim -g -f args" | ARGV0=-`basename $SHELL` $SHELL [-l]
|
||||
pid = executeInLoginShell(path, taskArgs);
|
||||
} else {
|
||||
// Run process directly:
|
||||
// Vim -g -f args
|
||||
// (-g for GUI, -f for foreground, i.e. don't fork)
|
||||
taskPath = path;
|
||||
taskArgs = [NSArray arrayWithObjects:@"-g", @"-f", nil];
|
||||
if (args)
|
||||
taskArgs = [taskArgs arrayByAddingObjectsFromArray:args];
|
||||
NSTask *task = [NSTask launchedTaskWithLaunchPath:path
|
||||
arguments:taskArgs];
|
||||
pid = task ? [task processIdentifier] : -1;
|
||||
}
|
||||
|
||||
NSTask *task =[NSTask launchedTaskWithLaunchPath:taskPath
|
||||
arguments:taskArgs];
|
||||
//NSLog(@"launch %@ with args=%@ (pid=%d)", taskPath, taskArgs,
|
||||
// [task processIdentifier]);
|
||||
|
||||
int pid = [task processIdentifier];
|
||||
|
||||
// If the process has no arguments, then add a null argument to the
|
||||
// pidArguments dictionary. This is later used to detect that a process
|
||||
// without arguments is being launched.
|
||||
if (!args)
|
||||
[pidArguments setObject:[NSNull null]
|
||||
forKey:[NSNumber numberWithInt:pid]];
|
||||
if (-1 != pid) {
|
||||
// NOTE: If the process has no arguments, then add a null argument to
|
||||
// the pidArguments dictionary. This is later used to detect that a
|
||||
// process without arguments is being launched.
|
||||
if (!args)
|
||||
[pidArguments setObject:[NSNull null]
|
||||
forKey:[NSNumber numberWithInt:pid]];
|
||||
} else {
|
||||
NSLog(@"WARNING: %s%@ failed (useLoginShell=%d)", _cmd, args,
|
||||
useLoginShell);
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
@@ -1098,3 +1147,101 @@ typedef struct
|
||||
return [self intValue];
|
||||
}
|
||||
@end // NSNumber (MMExtras)
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
executeInLoginShell(NSString *path, NSArray *args)
|
||||
{
|
||||
// Start a login shell and execute the command 'path' with arguments 'args'
|
||||
// in the shell. This ensures that user environment variables are set even
|
||||
// when MacVim was started from the Finder.
|
||||
|
||||
int pid = -1;
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
// Determine which shell to use to execute the command. The user
|
||||
// may decide which shell to use by setting a user default or the
|
||||
// $SHELL environment variable.
|
||||
NSString *shell = [ud stringForKey:MMLoginShellCommandKey];
|
||||
if (!shell || [shell length] == 0)
|
||||
shell = [[[NSProcessInfo processInfo] environment]
|
||||
objectForKey:@"SHELL"];
|
||||
if (!shell)
|
||||
shell = @"/bin/bash";
|
||||
|
||||
//NSLog(@"shell = %@", shell);
|
||||
|
||||
// Bash needs the '-l' flag to launch a login shell. The user may add
|
||||
// flags by setting a user default.
|
||||
NSString *shellArgument = [ud stringForKey:MMLoginShellArgumentKey];
|
||||
if (!shellArgument || [shellArgument length] == 0) {
|
||||
if ([[shell lastPathComponent] isEqual:@"bash"])
|
||||
shellArgument = @"-l";
|
||||
else
|
||||
shellArgument = nil;
|
||||
}
|
||||
|
||||
//NSLog(@"shellArgument = %@", shellArgument);
|
||||
|
||||
// Build input string to pipe to the login shell.
|
||||
NSMutableString *input = [NSMutableString stringWithFormat:
|
||||
@"exec \"%@\"", path];
|
||||
if (args) {
|
||||
// Append all arguments, making sure they are properly quoted, even
|
||||
// when they contain single quotes.
|
||||
NSEnumerator *e = [args objectEnumerator];
|
||||
id obj;
|
||||
|
||||
while ((obj = [e nextObject])) {
|
||||
NSMutableString *arg = [NSMutableString stringWithString:obj];
|
||||
[arg replaceOccurrencesOfString:@"'" withString:@"'\"'\"'"
|
||||
options:NSLiteralSearch
|
||||
range:NSMakeRange(0, [arg length])];
|
||||
[input appendFormat:@" '%@'", arg];
|
||||
}
|
||||
}
|
||||
|
||||
// Build the argument vector used to start the login shell.
|
||||
NSString *shellArg0 = [NSString stringWithFormat:@"-%@",
|
||||
[shell lastPathComponent]];
|
||||
char *shellArgv[3] = { (char *)[shellArg0 UTF8String], NULL, NULL };
|
||||
if (shellArgument)
|
||||
shellArgv[1] = (char *)[shellArgument UTF8String];
|
||||
|
||||
// Get the C string representation of the shell path before the fork since
|
||||
// we must not call Foundation functions after a fork.
|
||||
const char *shellPath = [shell fileSystemRepresentation];
|
||||
|
||||
// Fork and execute the process.
|
||||
int ds[2];
|
||||
if (pipe(ds)) return -1;
|
||||
|
||||
pid = fork();
|
||||
if (pid == -1) {
|
||||
return -1;
|
||||
} else if (pid == 0) {
|
||||
// Child process
|
||||
if (close(ds[1]) == -1) exit(255);
|
||||
if (dup2(ds[0], 0) == -1) exit(255);
|
||||
|
||||
execv(shellPath, shellArgv);
|
||||
|
||||
// Never reached unless execv fails
|
||||
exit(255);
|
||||
} else {
|
||||
// Parent process
|
||||
if (close(ds[0]) == -1) return -1;
|
||||
|
||||
// Send input to execute to the child process
|
||||
[input appendString:@"\n"];
|
||||
int bytes = [input lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
if (write(ds[1], [input UTF8String], bytes) != bytes) return -1;
|
||||
if (close(ds[1]) == -1) return -1;
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,14 @@ enum { MMMaxCellsPerChar = 2 };
|
||||
NSFont *font;
|
||||
float linespace;
|
||||
|
||||
// From NSTextView
|
||||
NSSize insetSize;
|
||||
|
||||
// From vim-cocoa
|
||||
NSImage *contentImage;
|
||||
NSSize imageSize;
|
||||
ATSUStyle atsuStyles[MMMaxCellsPerChar];
|
||||
BOOL antialias;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame;
|
||||
@@ -54,6 +58,8 @@ enum { MMMaxCellsPerChar = 2 };
|
||||
- (void)setShouldDrawInsertionPoint:(BOOL)on;
|
||||
- (void)setPreEditRow:(int)row column:(int)col;
|
||||
- (void)hideMarkedTextField;
|
||||
- (void)setMouseShape:(int)shape;
|
||||
- (void)setAntialias:(BOOL)state;
|
||||
|
||||
//
|
||||
// NSTextView methods
|
||||
@@ -63,6 +69,11 @@ enum { MMMaxCellsPerChar = 2 };
|
||||
- (void)doCommandBySelector:(SEL)selector;
|
||||
- (BOOL)performKeyEquivalent:(NSEvent *)event;
|
||||
|
||||
//
|
||||
// NSTextContainer methods
|
||||
//
|
||||
- (void)setTextContainerInset:(NSSize)inset;
|
||||
|
||||
//
|
||||
// MMAtsuiTextView methods
|
||||
//
|
||||
|
||||
+148
-27
@@ -27,6 +27,7 @@
|
||||
|
||||
#import "MMAtsuiTextView.h"
|
||||
#import "MMVimController.h"
|
||||
#import "MMWindowController.h"
|
||||
#import "MacVim.h"
|
||||
|
||||
|
||||
@@ -65,11 +66,13 @@ enum {
|
||||
- (void)updateAtsuStyles;
|
||||
- (void)dispatchKeyEvent:(NSEvent *)event;
|
||||
- (void)sendKeyDown:(const char *)chars length:(int)len modifiers:(int)flags;
|
||||
- (MMWindowController *)windowController;
|
||||
- (MMVimController *)vimController;
|
||||
@end
|
||||
|
||||
|
||||
@interface MMAtsuiTextView (Drawing)
|
||||
- (NSPoint)originForRow:(int)row column:(int)column;
|
||||
- (NSRect)rectFromRow:(int)row1 column:(int)col1
|
||||
toRow:(int)row2 column:(int)col2;
|
||||
- (NSSize)textAreaSize;
|
||||
@@ -105,6 +108,11 @@ enum {
|
||||
cellSize.width = cellSize.height = 1;
|
||||
contentImage = nil;
|
||||
imageSize = NSZeroSize;
|
||||
insetSize = NSZeroSize;
|
||||
|
||||
// NOTE: If the default changes to 'NO' then the intialization of
|
||||
// p_antialias in option.c must change as well.
|
||||
antialias = YES;
|
||||
|
||||
[self initAtsuStyles];
|
||||
}
|
||||
@@ -152,17 +160,21 @@ enum {
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setTextContainerInset:(NSSize)size
|
||||
{
|
||||
insetSize = size;
|
||||
}
|
||||
|
||||
- (NSRect)rectForRowsInRange:(NSRange)range
|
||||
{
|
||||
// TODO: Add text inset to origin
|
||||
NSRect rect = { 0, 0, 0, 0 };
|
||||
unsigned start = range.location > maxRows ? maxRows : range.location;
|
||||
unsigned length = range.length;
|
||||
|
||||
if (start+length > maxRows)
|
||||
if (start + length > maxRows)
|
||||
length = maxRows - start;
|
||||
|
||||
rect.origin.y = cellSize.height * start;
|
||||
rect.origin.y = cellSize.height * start + insetSize.height;
|
||||
rect.size.height = cellSize.height * length;
|
||||
|
||||
return rect;
|
||||
@@ -170,7 +182,6 @@ enum {
|
||||
|
||||
- (NSRect)rectForColumnsInRange:(NSRange)range
|
||||
{
|
||||
// TODO: Add text inset to origin
|
||||
NSRect rect = { 0, 0, 0, 0 };
|
||||
unsigned start = range.location > maxColumns ? maxColumns : range.location;
|
||||
unsigned length = range.length;
|
||||
@@ -178,7 +189,7 @@ enum {
|
||||
if (start+length > maxColumns)
|
||||
length = maxColumns - start;
|
||||
|
||||
rect.origin.x = cellSize.width * start;
|
||||
rect.origin.x = cellSize.width * start + insetSize.width;
|
||||
rect.size.width = cellSize.width * length;
|
||||
|
||||
return rect;
|
||||
@@ -253,6 +264,15 @@ enum {
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setMouseShape:(int)shape
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setAntialias:(BOOL)state
|
||||
{
|
||||
antialias = state;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -458,8 +478,14 @@ enum {
|
||||
|
||||
- (void)drawRect:(NSRect)rect
|
||||
{
|
||||
[contentImage drawInRect: rect
|
||||
fromRect: rect
|
||||
NSRect srcRect = NSMakeRect(0, 0, imageSize.width, imageSize.height);
|
||||
NSRect dstRect = srcRect;
|
||||
|
||||
dstRect.origin.x += insetSize.width;
|
||||
dstRect.origin.y += insetSize.height;
|
||||
|
||||
[contentImage drawInRect: dstRect
|
||||
fromRect: srcRect
|
||||
operation: NSCompositeCopy
|
||||
fraction: 1.0];
|
||||
}
|
||||
@@ -579,6 +605,11 @@ enum {
|
||||
[self drawInsertionPointAtRow:row column:col shape:shape
|
||||
fraction:percent
|
||||
color:[NSColor colorWithRgbInt:color]];
|
||||
} else if (SetCursorPosDrawType == type) {
|
||||
// TODO: This is used for Voice Over support in MMTextView,
|
||||
// MMAtsuiTextView currently does not support Voice Over.
|
||||
/*cursorRow = *((int*)bytes);*/ bytes += sizeof(int);
|
||||
/*cursorCol = *((int*)bytes);*/ bytes += sizeof(int);
|
||||
} else {
|
||||
NSLog(@"WARNING: Unknown draw type (type=%d)", type);
|
||||
}
|
||||
@@ -599,7 +630,6 @@ enum {
|
||||
- (NSSize)constrainRows:(int *)rows columns:(int *)cols toSize:(NSSize)size
|
||||
{
|
||||
// TODO:
|
||||
// - Take text area inset into consideration
|
||||
// - Rounding errors may cause size change when there should be none
|
||||
// - Desired rows/columns shold not be 'too small'
|
||||
|
||||
@@ -611,18 +641,20 @@ enum {
|
||||
|
||||
if (size.height != desiredSize.height) {
|
||||
float fh = cellSize.height;
|
||||
float ih = 2 * insetSize.height;
|
||||
if (fh < 1.0f) fh = 1.0f;
|
||||
|
||||
desiredRows = floor(size.height/fh);
|
||||
desiredSize.height = fh*desiredRows;
|
||||
desiredRows = floor((size.height - ih)/fh);
|
||||
desiredSize.height = fh*desiredRows + ih;
|
||||
}
|
||||
|
||||
if (size.width != desiredSize.width) {
|
||||
float fw = cellSize.width;
|
||||
float iw = 2 * insetSize.width;
|
||||
if (fw < 1.0f) fw = 1.0f;
|
||||
|
||||
desiredCols = floor(size.width/fw);
|
||||
desiredSize.width = fw*desiredCols;
|
||||
desiredCols = floor((size.width - iw)/fw);
|
||||
desiredSize.width = fw*desiredCols + iw;
|
||||
}
|
||||
|
||||
if (rows) *rows = desiredRows;
|
||||
@@ -635,17 +667,15 @@ enum {
|
||||
{
|
||||
// Compute the size the text view should be for the entire text area and
|
||||
// inset area to be visible with the present number of rows and columns.
|
||||
//
|
||||
// TODO: Add inset area to size.
|
||||
return NSMakeSize(maxColumns*cellSize.width, maxRows*cellSize.height);
|
||||
return NSMakeSize(maxColumns * cellSize.width + 2 * insetSize.width,
|
||||
maxRows * cellSize.height + 2 * insetSize.height);
|
||||
}
|
||||
|
||||
- (NSSize)minSize
|
||||
{
|
||||
// Compute the smallest size the text view is allowed to be.
|
||||
//
|
||||
// TODO: Add inset area to size.
|
||||
return NSMakeSize(MMMinColumns*cellSize.width, MMMinRows*cellSize.height);
|
||||
return NSMakeSize(MMMinColumns * cellSize.width + 2 * insetSize.width,
|
||||
MMMinRows * cellSize.height + 2 * insetSize.height);
|
||||
}
|
||||
|
||||
- (void)changeFont:(id)sender
|
||||
@@ -698,6 +728,42 @@ enum {
|
||||
[[self vimController] sendMessage:ScrollWheelMsgID data:data];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// NOTE: The menu items cut/copy/paste/undo/redo/select all/... must be bound
|
||||
// to the same actions as in IB otherwise they will not work with dialogs. All
|
||||
// we do here is forward these actions to the Vim process.
|
||||
//
|
||||
- (IBAction)cut:(id)sender
|
||||
{
|
||||
[[self windowController] vimMenuItemAction:sender];
|
||||
}
|
||||
|
||||
- (IBAction)copy:(id)sender
|
||||
{
|
||||
[[self windowController] vimMenuItemAction:sender];
|
||||
}
|
||||
|
||||
- (IBAction)paste:(id)sender
|
||||
{
|
||||
[[self windowController] vimMenuItemAction:sender];
|
||||
}
|
||||
|
||||
- (IBAction)undo:(id)sender
|
||||
{
|
||||
[[self windowController] vimMenuItemAction:sender];
|
||||
}
|
||||
|
||||
- (IBAction)redo:(id)sender
|
||||
{
|
||||
[[self windowController] vimMenuItemAction:sender];
|
||||
}
|
||||
|
||||
- (IBAction)selectAll:(id)sender
|
||||
{
|
||||
[[self windowController] vimMenuItemAction:sender];
|
||||
}
|
||||
|
||||
@end // MMAtsuiTextView
|
||||
|
||||
|
||||
@@ -707,8 +773,7 @@ enum {
|
||||
|
||||
- (BOOL)convertPoint:(NSPoint)point toRow:(int *)row column:(int *)column
|
||||
{
|
||||
// TODO: text inset
|
||||
NSPoint origin = { 0,0 };
|
||||
NSPoint origin = { insetSize.width, insetSize.height };
|
||||
|
||||
if (!(cellSize.width > 0 && cellSize.height > 0))
|
||||
return NO;
|
||||
@@ -848,13 +913,17 @@ enum {
|
||||
}
|
||||
}
|
||||
|
||||
- (MMVimController *)vimController
|
||||
- (MMWindowController *)windowController
|
||||
{
|
||||
id windowController = [[self window] windowController];
|
||||
if ([windowController isKindOfClass:[MMWindowController class]])
|
||||
return (MMWindowController*)windowController;
|
||||
return nil;
|
||||
}
|
||||
|
||||
// TODO: Make sure 'windowController' is a MMWindowController before type
|
||||
// casting.
|
||||
return [(MMWindowController*)windowController vimController];
|
||||
- (MMVimController *)vimController
|
||||
{
|
||||
return [[self windowController] vimController];
|
||||
}
|
||||
|
||||
@end // MMAtsuiTextView (Private)
|
||||
@@ -864,10 +933,16 @@ enum {
|
||||
|
||||
@implementation MMAtsuiTextView (Drawing)
|
||||
|
||||
- (NSPoint)originForRow:(int)row column:(int)col
|
||||
{
|
||||
return NSMakePoint(col * cellSize.width, row * cellSize.height);
|
||||
}
|
||||
|
||||
- (NSRect)rectFromRow:(int)row1 column:(int)col1
|
||||
toRow:(int)row2 column:(int)col2
|
||||
{
|
||||
return NSMakeRect(col1 * cellSize.width, row1 * cellSize.height,
|
||||
NSPoint origin = [self originForRow: row1 column: col1];
|
||||
return NSMakeRect(origin.x, origin.y,
|
||||
(col2 + 1 - col1) * cellSize.width,
|
||||
(row2 + 1 - row1) * cellSize.height);
|
||||
}
|
||||
@@ -876,7 +951,7 @@ enum {
|
||||
{
|
||||
// Calculate the (desired) size of the text area, i.e. the text view area
|
||||
// minus the inset area.
|
||||
return NSMakeSize(maxColumns*cellSize.width, maxRows*cellSize.height);
|
||||
return NSMakeSize(maxColumns * cellSize.width, maxRows * cellSize.height);
|
||||
}
|
||||
|
||||
- (void)resizeContentImage
|
||||
@@ -898,6 +973,9 @@ enum {
|
||||
[contentImage unlockFocus];
|
||||
}
|
||||
|
||||
#define atsu_style_set_bool(s, t, b) \
|
||||
ATSUSetAttributes(s, 1, &t, &(sizeof(Boolean)), &&b);
|
||||
|
||||
- (void)drawString:(UniChar *)string length:(UniCharCount)length
|
||||
atRow:(int)row column:(int)col cells:(int)cells
|
||||
withFlags:(int)flags foregroundColor:(NSColor *)fg
|
||||
@@ -906,9 +984,29 @@ enum {
|
||||
// 'string' consists of 'length' utf-16 code pairs and should cover 'cells'
|
||||
// display cells (a normal character takes up one display cell, a wide
|
||||
// character takes up two)
|
||||
ATSUStyle style = atsuStyles[0];
|
||||
ATSUStyle style = (flags & DRAW_WIDE) ? atsuStyles[1] : atsuStyles[0];
|
||||
ATSUTextLayout layout;
|
||||
|
||||
// Font selection and rendering options for ATSUI
|
||||
ATSUAttributeTag attribTags[3] = { kATSUQDBoldfaceTag,
|
||||
kATSUQDItalicTag,
|
||||
kATSUStyleRenderingOptionsTag };
|
||||
ByteCount attribSizes[] = { sizeof(Boolean),
|
||||
sizeof(Boolean),
|
||||
sizeof(UInt32) };
|
||||
Boolean useBold, useItalic;
|
||||
UInt32 useAntialias;
|
||||
ATSUAttributeValuePtr attribValues[3] = { &useBold, &useItalic,
|
||||
&useAntialias };
|
||||
|
||||
useBold = (flags & DRAW_BOLD) ? true : false;
|
||||
useItalic = (flags & DRAW_ITALIC) ? true : false;
|
||||
useAntialias = antialias ? kATSStyleApplyAntiAliasing
|
||||
: kATSStyleNoAntiAliasing;
|
||||
|
||||
ATSUSetAttributes(style, sizeof(attribValues) / sizeof(attribValues[0]),
|
||||
attribTags, attribSizes, attribValues);
|
||||
|
||||
// NSLog(@"drawString: %d", length);
|
||||
|
||||
ATSUCreateTextLayout(&layout);
|
||||
@@ -919,6 +1017,8 @@ enum {
|
||||
|
||||
NSRect rect = NSMakeRect(col * cellSize.width, row * cellSize.height,
|
||||
length * cellSize.width, cellSize.height);
|
||||
if (flags & DRAW_WIDE)
|
||||
rect.size.width = rect.size.width * 2;
|
||||
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
|
||||
|
||||
ATSUAttributeTag tags[] = { kATSUCGContextTag };
|
||||
@@ -1003,6 +1103,27 @@ enum {
|
||||
- (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
|
||||
fraction:(int)percent color:(NSColor *)color
|
||||
{
|
||||
NSPoint origin = [self originForRow:row column:col];
|
||||
NSRect rect = NSMakeRect(origin.x, origin.y,
|
||||
cellSize.width, cellSize.height);
|
||||
|
||||
// NSLog(@"shape = %d, fraction: %d", shape, percent);
|
||||
|
||||
if (MMInsertionPointHorizontal == shape) {
|
||||
int frac = (cellSize.height * percent + 99)/100;
|
||||
rect.origin.y += rect.size.height - frac;
|
||||
rect.size.height = frac;
|
||||
} else if (MMInsertionPointVertical == shape) {
|
||||
int frac = (cellSize.width * percent + 99)/100;
|
||||
rect.size.width = frac;
|
||||
}
|
||||
|
||||
[color set];
|
||||
if (MMInsertionPointHollow == shape) {
|
||||
NSFrameRect(rect);
|
||||
} else {
|
||||
NSRectFill(rect);
|
||||
}
|
||||
}
|
||||
|
||||
@end // MMAtsuiTextView (Drawing)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
id frontendProxy;
|
||||
NSDictionary *colorDict;
|
||||
NSDictionary *sysColorDict;
|
||||
NSDictionary *actionDict;
|
||||
BOOL inputReceived;
|
||||
BOOL tabBarVisible;
|
||||
unsigned backgroundColor;
|
||||
@@ -54,6 +55,7 @@
|
||||
- (void)setSpecialColor:(int)color;
|
||||
- (void)setDefaultColorsBackground:(int)bg foreground:(int)fg;
|
||||
- (NSConnection *)connection;
|
||||
- (NSDictionary *)actionDict;
|
||||
|
||||
- (BOOL)checkin;
|
||||
- (BOOL)openVimWindow;
|
||||
@@ -87,7 +89,8 @@
|
||||
- (void)addMenuItemWithTag:(int)tag parent:(int)parentTag name:(char *)name
|
||||
tip:(char *)tip icon:(char *)icon
|
||||
keyEquivalent:(int)key modifiers:(int)mods
|
||||
action:(NSString *)action atIndex:(int)index;
|
||||
action:(char *)action isAlternate:(int)isAlt
|
||||
atIndex:(int)index;
|
||||
- (void)removeMenuItemWithTag:(int)tag;
|
||||
- (void)enableMenuItemWithTag:(int)tag state:(int)enabled;
|
||||
- (void)showPopupMenuWithName:(char *)name atMouseLocation:(BOOL)mouse;
|
||||
@@ -112,9 +115,11 @@
|
||||
- (int)lookupColorWithKey:(NSString *)key;
|
||||
- (BOOL)hasSpecialKeyWithValue:(NSString *)value;
|
||||
|
||||
- (void)enterFullscreen;
|
||||
- (void)enterFullscreen:(int)fuoptions background:(int)bg;
|
||||
- (void)leaveFullscreen;
|
||||
|
||||
- (void)setAntialias:(BOOL)antialias;
|
||||
|
||||
- (void)updateModifiedFlag;
|
||||
|
||||
- (void)registerServerWithName:(NSString *)name;
|
||||
|
||||
+74
-26
@@ -77,6 +77,7 @@ static NSString *MMSymlinkWarningString =
|
||||
|
||||
|
||||
@interface MMBackend (Private)
|
||||
- (void)queueVimStateMessage;
|
||||
- (void)processInputQueue;
|
||||
- (void)handleInputEvent:(int)msgid data:(NSData *)data;
|
||||
+ (NSDictionary *)specialKeys;
|
||||
@@ -142,8 +143,12 @@ static NSString *MMSymlinkWarningString =
|
||||
sysColorDict = [[NSDictionary dictionaryWithContentsOfFile:path]
|
||||
retain];
|
||||
|
||||
if (!(colorDict && sysColorDict))
|
||||
NSLog(@"ERROR: Failed to load color dictionaries.%@",
|
||||
path = [mainBundle pathForResource:@"Actions" ofType:@"plist"];
|
||||
if (path)
|
||||
actionDict = [[NSDictionary dictionaryWithContentsOfFile:path] retain];
|
||||
|
||||
if (!(colorDict && sysColorDict && actionDict))
|
||||
NSLog(@"ERROR: Failed to load dictionaries.%@",
|
||||
MMSymlinkWarningString);
|
||||
|
||||
return self;
|
||||
@@ -165,6 +170,7 @@ static NSString *MMSymlinkWarningString =
|
||||
[drawData release]; drawData = nil;
|
||||
[frontendProxy release]; frontendProxy = nil;
|
||||
[connection release]; connection = nil;
|
||||
[actionDict release]; actionDict = nil;
|
||||
[sysColorDict release]; sysColorDict = nil;
|
||||
[colorDict release]; colorDict = nil;
|
||||
|
||||
@@ -215,6 +221,11 @@ static NSString *MMSymlinkWarningString =
|
||||
return connection;
|
||||
}
|
||||
|
||||
- (NSDictionary *)actionDict
|
||||
{
|
||||
return actionDict;
|
||||
}
|
||||
|
||||
- (BOOL)checkin
|
||||
{
|
||||
if (![self connection]) {
|
||||
@@ -287,28 +298,29 @@ static NSString *MMSymlinkWarningString =
|
||||
}
|
||||
}
|
||||
|
||||
id proxy = [connection rootProxy];
|
||||
[proxy setProtocolForProxy:@protocol(MMAppProtocol)];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(connectionDidDie:)
|
||||
name:NSConnectionDidDieNotification object:connection];
|
||||
|
||||
int pid = [[NSProcessInfo processInfo] processIdentifier];
|
||||
|
||||
BOOL ok = NO;
|
||||
@try {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(connectionDidDie:)
|
||||
name:NSConnectionDidDieNotification object:connection];
|
||||
|
||||
id proxy = [connection rootProxy];
|
||||
[proxy setProtocolForProxy:@protocol(MMAppProtocol)];
|
||||
|
||||
int pid = [[NSProcessInfo processInfo] processIdentifier];
|
||||
|
||||
frontendProxy = [proxy connectBackend:self pid:pid];
|
||||
if (frontendProxy) {
|
||||
[frontendProxy retain];
|
||||
[frontendProxy setProtocolForProxy:@protocol(MMAppProtocol)];
|
||||
ok = YES;
|
||||
}
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught when trying to connect backend: \"%@\"", e);
|
||||
}
|
||||
|
||||
if (frontendProxy) {
|
||||
[frontendProxy retain];
|
||||
[frontendProxy setProtocolForProxy:@protocol(MMAppProtocol)];
|
||||
}
|
||||
|
||||
return connection && frontendProxy;
|
||||
return ok;
|
||||
}
|
||||
|
||||
- (BOOL)openVimWindow
|
||||
@@ -428,9 +440,10 @@ static NSString *MMSymlinkWarningString =
|
||||
// NOTE! This method gets called a lot; if we were to flush every time it
|
||||
// got called MacVim would feel unresponsive. So there is a time out which
|
||||
// ensures that the queue isn't flushed too often.
|
||||
if (!force && lastFlushDate && -[lastFlushDate timeIntervalSinceNow]
|
||||
< MMFlushTimeoutInterval
|
||||
&& [drawData length] < MMFlushQueueLenHint)
|
||||
if (exiting ||
|
||||
(!force && lastFlushDate &&
|
||||
-[lastFlushDate timeIntervalSinceNow] < MMFlushTimeoutInterval &&
|
||||
[drawData length] < MMFlushQueueLenHint))
|
||||
return;
|
||||
|
||||
if ([drawData length] > 0) {
|
||||
@@ -450,7 +463,12 @@ static NSString *MMSymlinkWarningString =
|
||||
[drawData setLength:0];
|
||||
}
|
||||
|
||||
if ([outputQueue count] > 0) {
|
||||
if ([outputQueue count] > 0 || force) {
|
||||
// When 'force' is set we always update the Vim state to ensure that
|
||||
// MacVim has a copy of the latest state (since 'force' is typically
|
||||
// set just before Vim takes a nap whilst waiting for input).
|
||||
[self queueVimStateMessage];
|
||||
|
||||
@try {
|
||||
[frontendProxy processCommandQueue:outputQueue];
|
||||
}
|
||||
@@ -743,7 +761,8 @@ static NSString *MMSymlinkWarningString =
|
||||
- (void)addMenuItemWithTag:(int)tag parent:(int)parentTag name:(char *)name
|
||||
tip:(char *)tip icon:(char *)icon
|
||||
keyEquivalent:(int)key modifiers:(int)mods
|
||||
action:(NSString *)action atIndex:(int)index
|
||||
action:(char *)action isAlternate:(int)isAlt
|
||||
atIndex:(int)index
|
||||
{
|
||||
//NSLog(@"addMenuItemWithTag:%d parent:%d name:%s tip:%s atIndex:%d", tag,
|
||||
// parentTag, name, tip, index);
|
||||
@@ -752,7 +771,7 @@ static NSString *MMSymlinkWarningString =
|
||||
int tiplen = tip ? strlen(tip) : 0;
|
||||
int iconlen = icon ? strlen(icon) : 0;
|
||||
int eventFlags = vimModMaskToEventModifierFlags(mods);
|
||||
int actionlen = [action lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
int actionlen = action ? strlen(action) : 0;
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
|
||||
key = specialKeyToNSKey(key);
|
||||
@@ -766,10 +785,11 @@ static NSString *MMSymlinkWarningString =
|
||||
[data appendBytes:&iconlen length:sizeof(int)];
|
||||
if (iconlen > 0) [data appendBytes:icon length:iconlen];
|
||||
[data appendBytes:&actionlen length:sizeof(int)];
|
||||
if (actionlen > 0) [data appendBytes:[action UTF8String] length:actionlen];
|
||||
if (actionlen > 0) [data appendBytes:action length:actionlen];
|
||||
[data appendBytes:&index length:sizeof(int)];
|
||||
[data appendBytes:&key length:sizeof(int)];
|
||||
[data appendBytes:&eventFlags length:sizeof(int)];
|
||||
[data appendBytes:&isAlt length:sizeof(int)];
|
||||
|
||||
[self queueMessage:AddMenuItemMsgID data:data];
|
||||
}
|
||||
@@ -1054,9 +1074,13 @@ static NSString *MMSymlinkWarningString =
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)enterFullscreen
|
||||
- (void)enterFullscreen:(int)fuoptions background:(int)bg
|
||||
{
|
||||
[self queueMessage:EnterFullscreenMsgID data:nil];
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
[data appendBytes:&fuoptions length:sizeof(int)];
|
||||
bg = MM_COLOR(bg);
|
||||
[data appendBytes:&bg length:sizeof(int)];
|
||||
[self queueMessage:EnterFullscreenMsgID data:data];
|
||||
}
|
||||
|
||||
- (void)leaveFullscreen
|
||||
@@ -1064,6 +1088,13 @@ static NSString *MMSymlinkWarningString =
|
||||
[self queueMessage:LeaveFullscreenMsgID data:nil];
|
||||
}
|
||||
|
||||
- (void)setAntialias:(BOOL)antialias
|
||||
{
|
||||
int msgid = antialias ? EnableAntialiasMsgID : DisableAntialiasMsgID;
|
||||
|
||||
[self queueMessage:msgid data:nil];
|
||||
}
|
||||
|
||||
- (void)updateModifiedFlag
|
||||
{
|
||||
// Notify MacVim if _any_ buffer has changed from unmodified to modified or
|
||||
@@ -1242,6 +1273,8 @@ static NSString *MMSymlinkWarningString =
|
||||
|
||||
- (BOOL)starRegisterToPasteboard:(byref NSPasteboard *)pboard
|
||||
{
|
||||
// TODO: This method should share code with clip_mch_request_selection().
|
||||
|
||||
if (VIsual_active && (State & NORMAL) && clip_star.available) {
|
||||
// If there is no pasteboard, return YES to indicate that there is text
|
||||
// to copy.
|
||||
@@ -1528,6 +1561,21 @@ static NSString *MMSymlinkWarningString =
|
||||
|
||||
@implementation MMBackend (Private)
|
||||
|
||||
- (void)queueVimStateMessage
|
||||
{
|
||||
// NOTE: This is the place to add Vim state that needs to be accessed from
|
||||
// MacVim. Do not add state that could potentially require lots of memory
|
||||
// since this message gets sent each time the output queue is forcibly
|
||||
// flushed (e.g. storing the currently selected text would be a bad idea).
|
||||
// We take this approach of "pushing" the state to MacVim to avoid having
|
||||
// to make synchronous calls from MacVim to Vim in order to get state.
|
||||
NSDictionary *vimState = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[[NSFileManager defaultManager] currentDirectoryPath], @"pwd",
|
||||
nil];
|
||||
|
||||
[self queueMessage:SetVimStateMsgID data:[vimState dictionaryAsData]];
|
||||
}
|
||||
|
||||
- (void)processInputQueue
|
||||
{
|
||||
// NOTE: One of the input events may cause this method to be called
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* vi:set ts=8 sts=4 sw=4 ft=objc:
|
||||
*
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
*
|
||||
* Do ":help uganda" in Vim to read copying and usage conditions.
|
||||
* Do ":help credits" in Vim to see a list of people who contributed.
|
||||
@@ -19,11 +19,21 @@
|
||||
MMVimView *view;
|
||||
NSPoint oldPosition;
|
||||
NSString *oldTabBarStyle;
|
||||
|
||||
// These are only valid in fullscreen mode and store pre-fu vim size
|
||||
int nonFuRows, nonFuColumns;
|
||||
|
||||
// These store the size vim had right after entering fu mode
|
||||
int startFuRows, startFuColumns;
|
||||
|
||||
// This stores the contents of fuoptions_flags at fu start time
|
||||
int startFuFlags;
|
||||
}
|
||||
|
||||
- (MMFullscreenWindow *)initWithWindow:(NSWindow *)t view:(MMVimView *)v;
|
||||
- (MMFullscreenWindow *)initWithWindow:(NSWindow *)t view:(MMVimView *)v
|
||||
backgroundColor:(NSColor *)back;
|
||||
|
||||
- (void)enterFullscreen;
|
||||
- (void)enterFullscreen:(int)fuoptions;
|
||||
- (void)leaveFullscreen;
|
||||
- (void)centerView;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* vi:set ts=8 sts=4 sw=4 ft=objc:
|
||||
*
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
*
|
||||
* Do ":help uganda" in Vim to read copying and usage conditions.
|
||||
* Do ":help credits" in Vim to see a list of people who contributed.
|
||||
@@ -23,6 +23,7 @@
|
||||
* Author: Nico Weber
|
||||
*/
|
||||
|
||||
#import "MMVimController.h"
|
||||
#import "MMFullscreenWindow.h"
|
||||
#import <PSMTabBarControl.h>
|
||||
#import "MMVimView.h"
|
||||
@@ -30,6 +31,11 @@
|
||||
#import "MMWindowController.h"
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
// These have to be the same as in option.h
|
||||
#define FUOPT_MAXVERT 0x001
|
||||
#define FUOPT_MAXHORZ 0x002
|
||||
#define FUOPT_BGCOLOR_HLGROUP 0x004
|
||||
|
||||
|
||||
static int numFullscreenWindows = 0;
|
||||
|
||||
@@ -41,7 +47,8 @@ static int numFullscreenWindows = 0;
|
||||
|
||||
@implementation MMFullscreenWindow
|
||||
|
||||
- (MMFullscreenWindow *)initWithWindow:(NSWindow *)t view:(MMVimView *)v
|
||||
- (MMFullscreenWindow *)initWithWindow:(NSWindow *)t view:(MMVimView *)v
|
||||
backgroundColor:(NSColor *)back
|
||||
{
|
||||
NSScreen* screen = [t screen];
|
||||
|
||||
@@ -68,7 +75,7 @@ static int numFullscreenWindows = 0;
|
||||
|
||||
[self setHasShadow:NO];
|
||||
[self setShowsResizeIndicator:NO];
|
||||
[self setBackgroundColor:[NSColor blackColor]];
|
||||
[self setBackgroundColor:back];
|
||||
[self setReleasedWhenClosed:NO];
|
||||
|
||||
return self;
|
||||
@@ -82,7 +89,7 @@ static int numFullscreenWindows = 0;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)enterFullscreen
|
||||
- (void)enterFullscreen:(int)fuoptions
|
||||
{
|
||||
[self hideDockIfAppropriate];
|
||||
|
||||
@@ -123,6 +130,42 @@ static int numFullscreenWindows = 0;
|
||||
// focus gained message
|
||||
[self setDelegate:delegate];
|
||||
|
||||
// resize vim view according to fuoptions
|
||||
int currRows, currColumns;
|
||||
[[view textView] getMaxRows:&currRows columns:&currColumns];
|
||||
|
||||
int fuRows = currRows, fuColumns = currColumns;
|
||||
|
||||
int maxRows, maxColumns;
|
||||
NSSize size = [[self screen] frame].size;
|
||||
[view constrainRows:&maxRows columns:&maxColumns toSize:size];
|
||||
|
||||
// Store current pre-fu vim size
|
||||
nonFuRows = currRows;
|
||||
nonFuColumns = currColumns;
|
||||
|
||||
// Compute current fu size
|
||||
if (fuoptions & FUOPT_MAXVERT)
|
||||
fuRows = maxRows;
|
||||
if (fuoptions & FUOPT_MAXHORZ)
|
||||
fuColumns = maxColumns;
|
||||
|
||||
startFuFlags = fuoptions;
|
||||
|
||||
// if necessary, resize vim to target fu size
|
||||
if (currRows != fuRows || currColumns != fuColumns) {
|
||||
int newSize[2] = { fuRows, fuColumns };
|
||||
NSData *data = [NSData dataWithBytes:newSize length:2*sizeof(int)];
|
||||
MMVimController *vimController =
|
||||
[[self windowController] vimController];
|
||||
|
||||
[vimController sendMessage:SetTextDimensionsMsgID data:data];
|
||||
[[view textView] setMaxRows:fuRows columns:fuColumns];
|
||||
}
|
||||
|
||||
startFuRows = fuRows;
|
||||
startFuColumns = fuColumns;
|
||||
|
||||
// move vim view to the window's center
|
||||
[self centerView];
|
||||
|
||||
@@ -149,6 +192,32 @@ static int numFullscreenWindows = 0;
|
||||
didBlend = YES;
|
||||
}
|
||||
|
||||
// restore old vim view size
|
||||
int currRows, currColumns;
|
||||
[[view textView] getMaxRows:&currRows columns:&currColumns];
|
||||
int newRows = currRows, newColumns = currColumns;
|
||||
|
||||
// compute desired non-fu size.
|
||||
// if current fu size is equal to fu size at fu enter time,
|
||||
// restore the old size
|
||||
//
|
||||
if (startFuFlags & FUOPT_MAXVERT && startFuRows == currRows)
|
||||
newRows = nonFuRows;
|
||||
|
||||
if (startFuFlags & FUOPT_MAXHORZ && startFuColumns == currColumns)
|
||||
newColumns = nonFuColumns;
|
||||
|
||||
// resize vim if necessary
|
||||
if (currRows != newRows || currColumns != newColumns) {
|
||||
int newSize[2] = { newRows, newColumns };
|
||||
NSData *data = [NSData dataWithBytes:newSize length:2*sizeof(int)];
|
||||
MMVimController *vimController =
|
||||
[[self windowController] vimController];
|
||||
|
||||
[vimController sendMessage:SetTextDimensionsMsgID data:data];
|
||||
[[view textView] setMaxRows:newRows columns:newColumns];
|
||||
}
|
||||
|
||||
// fix up target controller
|
||||
[self retain]; // NSWindowController releases us once
|
||||
[[self windowController] setWindow:target];
|
||||
@@ -166,6 +235,7 @@ static int numFullscreenWindows = 0;
|
||||
// window.
|
||||
[view removeFromSuperviewWithoutNeedingDisplay];
|
||||
[[target contentView] addSubview:view];
|
||||
|
||||
[view setFrameOrigin:oldPosition];
|
||||
[self close];
|
||||
|
||||
|
||||
@@ -9,10 +9,25 @@
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <DBPrefsWindowController.h>
|
||||
|
||||
@interface MMPreferenceController : DBPrefsWindowController {
|
||||
|
||||
IBOutlet NSView *generalPreferences;
|
||||
IBOutlet NSView *integrationPreferences;
|
||||
|
||||
|
||||
// Integration pane
|
||||
NSDictionary *supportedOdbEditors;
|
||||
IBOutlet NSPopUpButton *editors;
|
||||
IBOutlet NSButton *installOdbButton;
|
||||
IBOutlet NSButton *uninstallOdbButton;
|
||||
IBOutlet NSTextField* obdBundleVersionLabel;
|
||||
|
||||
@interface MMPreferenceController : NSWindowController {
|
||||
}
|
||||
|
||||
+ (MMPreferenceController *)sharedPreferenceController;
|
||||
// Integration pane
|
||||
- (IBAction)installOdb:(id)sender;
|
||||
- (IBAction)uninstallOdb:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* vi:set ts=8 sts=4 sw=4 ft=objc:
|
||||
*
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
*
|
||||
* Do ":help uganda" in Vim to read copying and usage conditions.
|
||||
* Do ":help credits" in Vim to see a list of people who contributed.
|
||||
@@ -11,27 +11,381 @@
|
||||
#import "MMPreferenceController.h"
|
||||
#import "MacVim.h"
|
||||
|
||||
#import "AuthorizedShellCommand.h"
|
||||
|
||||
// On Leopard, we want to use the images provided by the OS for some of the
|
||||
// toolbar images (NSImageNamePreferencesGeneral and friends). We need to jump
|
||||
// through some hoops to do that in a way that MacVim still _compiles_ on Tiger
|
||||
// (life would be easier if we'd require Leopard for building). See
|
||||
// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html
|
||||
// and http://developer.apple.com/technotes/tn2002/tn2064.html
|
||||
// for how you'd do it with a Leopard build system, and see
|
||||
// http://lists.cairographics.org/archives/cairo-bugs/2007-December/001818.html
|
||||
// for why this doesn't work here.
|
||||
// Using the system images gives us resolution independence and consistency
|
||||
// with other apps.
|
||||
|
||||
#import <dlfcn.h>
|
||||
|
||||
NSString* nsImageNamePreferencesGeneral = nil;
|
||||
NSString* nsImageNamePreferencesAdvanced = nil;
|
||||
|
||||
static void loadSymbols()
|
||||
{
|
||||
// use dlfcn() instead of the deprecated NSModule api.
|
||||
void *ptr;
|
||||
if ((ptr = dlsym(RTLD_DEFAULT, "NSImageNamePreferencesGeneral")) != NULL)
|
||||
nsImageNamePreferencesGeneral = *(NSString**)ptr;
|
||||
if ((ptr = dlsym(RTLD_DEFAULT, "NSImageNamePreferencesAdvanced")) != NULL)
|
||||
nsImageNamePreferencesAdvanced = *(NSString**)ptr;
|
||||
}
|
||||
|
||||
|
||||
static CFStringRef ODBEDITOR = CFSTR("org.slashpunt.edit_in_odbeditor");
|
||||
static CFStringRef ODB_BUNDLE_IDENTIFIER = CFSTR("ODBEditorBundleIdentifier");
|
||||
static CFStringRef ODB_EDITOR_NAME = CFSTR("ODBEditorName");
|
||||
static NSString *ODBEDITOR_DIR =
|
||||
@"/Library/InputManagers/Edit in ODBEditor";
|
||||
static NSString *ODBEDITOR_PATH =
|
||||
@"/Library/InputManagers/Edit in ODBEditor/Edit in ODBEditor.bundle";
|
||||
|
||||
|
||||
NSString *kOdbEditorNameNone = @"(None)";
|
||||
NSString *kOdbEditorIdentifierNone = @"";
|
||||
|
||||
NSString *kOdbEditorNameBBEdit = @"BBEdit";
|
||||
NSString *kOdbEditorIdentifierBBEdit = @"com.barebones.bbedit";
|
||||
|
||||
NSString *kOdbEditorNameCSSEdit = @"CSSEdit";
|
||||
NSString *kOdbEditorIdentifierCSSEdit = @"com.macrabbit.cssedit";
|
||||
|
||||
NSString *kOdbEditorNameMacVim = @"MacVim";
|
||||
NSString *kOdbEditorIdentifierMacVim = @"org.vim.MacVim";
|
||||
|
||||
NSString *kOdbEditorNameSmultron = @"Smultron";
|
||||
NSString *kOdbEditorIdentifierSmultron = @"org.smultron.Smultron";
|
||||
|
||||
NSString *kOdbEditorNameSubEthaEdit = @"SubEthaEdit";
|
||||
NSString *kOdbEditorIdentifierSubEthaEdit = @"de.codingmonkeys.SubEthaEdit";
|
||||
|
||||
NSString *kOdbEditorNameTextMate = @"TextMate";
|
||||
NSString *kOdbEditorIdentifierTextMate = @"com.macromates.textmate";
|
||||
|
||||
NSString *kOdbEditorNameTextWrangler = @"TextWrangler";
|
||||
NSString *kOdbEditorIdentifierTextWrangler = @"com.barebones.textwrangler";
|
||||
|
||||
NSString *kOdbEditorNameWriteRoom = @"WriteRoom";
|
||||
NSString *kOdbEditorIdentifierWriteRoom = @"com.hogbaysoftware.WriteRoom";
|
||||
|
||||
|
||||
@interface MMPreferenceController (Private)
|
||||
// Integration pane
|
||||
- (void)updateIntegrationPane;
|
||||
- (void)setOdbEditorByName:(NSString *)name;
|
||||
- (NSString *)odbEditorBundleIdentifier;
|
||||
- (NSString *)odbBundleSourceDir;
|
||||
- (NSString *)versionOfBundle:(NSString *)bundlePath;
|
||||
- (NSString *)odbBundleInstalledVersion;
|
||||
- (NSString *)odbBundleInstallVersion;
|
||||
@end
|
||||
|
||||
@implementation MMPreferenceController
|
||||
|
||||
+ (MMPreferenceController *)sharedPreferenceController
|
||||
- (id)initWithWindow:(NSWindow *)window
|
||||
{
|
||||
static MMPreferenceController *singleton = nil;
|
||||
if (!singleton)
|
||||
singleton = [[MMPreferenceController alloc] init];
|
||||
return singleton;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super initWithWindowNibName:@"Preferences"];
|
||||
if (!self) return nil;
|
||||
|
||||
[self setWindowFrameAutosaveName:@"Preferences"];
|
||||
[[self window] setHidesOnDeactivate:NO];
|
||||
|
||||
self = [super initWithWindow:window];
|
||||
if (self == nil)
|
||||
return nil;
|
||||
// taken from Cyberduck. Thanks :-)
|
||||
supportedOdbEditors = [[NSDictionary alloc] initWithObjectsAndKeys:
|
||||
kOdbEditorIdentifierNone, kOdbEditorNameNone,
|
||||
kOdbEditorIdentifierBBEdit, kOdbEditorNameBBEdit,
|
||||
kOdbEditorIdentifierCSSEdit, kOdbEditorNameCSSEdit,
|
||||
kOdbEditorIdentifierMacVim, kOdbEditorNameMacVim,
|
||||
kOdbEditorIdentifierSmultron, kOdbEditorNameSmultron,
|
||||
kOdbEditorIdentifierSubEthaEdit, kOdbEditorNameSubEthaEdit,
|
||||
kOdbEditorIdentifierTextMate, kOdbEditorNameTextMate,
|
||||
kOdbEditorIdentifierTextWrangler, kOdbEditorNameTextWrangler,
|
||||
kOdbEditorIdentifierWriteRoom, kOdbEditorNameWriteRoom,
|
||||
nil];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[supportedOdbEditors release]; supportedOdbEditors = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
// fill list of editors in integration pane
|
||||
NSArray *keys = [[supportedOdbEditors allKeys]
|
||||
sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
|
||||
NSMenu *editorsMenu = [editors menu];
|
||||
NSEnumerator *enumerator = [keys objectEnumerator];
|
||||
NSString *key;
|
||||
while ((key = [enumerator nextObject]) != nil) {
|
||||
NSString *identifier = [supportedOdbEditors objectForKey:key];
|
||||
|
||||
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:key
|
||||
action:@selector(odbEditorChanged:)
|
||||
keyEquivalent:@""];
|
||||
[item setTarget:self];
|
||||
if (![identifier isEqualToString:kOdbEditorIdentifierNone]) {
|
||||
NSString *appPath = [[NSWorkspace sharedWorkspace]
|
||||
absolutePathForAppBundleWithIdentifier:identifier];
|
||||
[item setEnabled:appPath != nil];
|
||||
if (appPath != nil) {
|
||||
NSImage *icon = [[NSWorkspace sharedWorkspace]
|
||||
iconForFile:appPath];
|
||||
[icon setSize:NSMakeSize(16, 16)]; // XXX: make res independent
|
||||
[item setImage:icon];
|
||||
}
|
||||
}
|
||||
[editorsMenu addItem:item];
|
||||
[item release];
|
||||
}
|
||||
|
||||
[self updateIntegrationPane];
|
||||
}
|
||||
|
||||
- (void)setupToolbar
|
||||
{
|
||||
loadSymbols();
|
||||
|
||||
if (nsImageNamePreferencesGeneral != NULL) {
|
||||
[self addView:generalPreferences
|
||||
label:@"General"
|
||||
image:[NSImage imageNamed:nsImageNamePreferencesGeneral]];
|
||||
} else {
|
||||
[self addView:generalPreferences label:@"General"];
|
||||
}
|
||||
|
||||
[self addView:integrationPreferences label:@"Integration"];
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)currentPaneIdentifier
|
||||
{
|
||||
// We override this to persist the current pane.
|
||||
return [[NSUserDefaults standardUserDefaults]
|
||||
stringForKey:MMCurrentPreferencePaneKey];
|
||||
}
|
||||
|
||||
- (void)setCurrentPaneIdentifier:(NSString *)identifier
|
||||
{
|
||||
// We override this to persist the current pane.
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
setObject:identifier forKey:MMCurrentPreferencePaneKey];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item
|
||||
{
|
||||
if ([item action] == @selector(odbEditorChanged:)) {
|
||||
NSString *identifier = [supportedOdbEditors objectForKey:[item title]];
|
||||
if (identifier == nil)
|
||||
return NO;
|
||||
if ([identifier isEqualToString:kOdbEditorIdentifierNone])
|
||||
return YES;
|
||||
return [[NSWorkspace sharedWorkspace]
|
||||
absolutePathForAppBundleWithIdentifier:identifier] != nil;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Integration pane
|
||||
|
||||
- (void)updateIntegrationPane
|
||||
{
|
||||
// XXX: check validation api.
|
||||
// XXX: call this each time the dialog becomes active (so that if the
|
||||
// user changes settings in terminal, the changes are reflected in the
|
||||
// dialog)
|
||||
|
||||
NSString *versionString;
|
||||
|
||||
// Check if ODB path exists before calling isFilePackageAtPath: otherwise
|
||||
// an error is output to stderr on Tiger.
|
||||
BOOL odbIsInstalled =
|
||||
[[NSFileManager defaultManager] fileExistsAtPath:ODBEDITOR_PATH]
|
||||
&& [[NSWorkspace sharedWorkspace] isFilePackageAtPath:ODBEDITOR_PATH];
|
||||
|
||||
// enable/disable buttons
|
||||
[installOdbButton setTitle:@"Install"];
|
||||
if (odbIsInstalled) {
|
||||
[uninstallOdbButton setEnabled:YES];
|
||||
[editors setEnabled:YES];
|
||||
|
||||
NSString *installVersion = [self odbBundleInstallVersion];
|
||||
NSString *installedVersion = [self odbBundleInstalledVersion];
|
||||
switch ([installedVersion compare:installVersion
|
||||
options:NSNumericSearch]) {
|
||||
case NSOrderedAscending:
|
||||
versionString = [NSString stringWithFormat:
|
||||
@"Latest version is %@, you have %@.",
|
||||
installVersion, installedVersion];
|
||||
[installOdbButton setTitle:@"Update"];
|
||||
[installOdbButton setEnabled:YES];
|
||||
break;
|
||||
case NSOrderedSame:
|
||||
versionString = [NSString stringWithFormat:
|
||||
@"Latest version is %@. You have the latest version.",
|
||||
installVersion];
|
||||
[installOdbButton setEnabled:NO];
|
||||
break;
|
||||
case NSOrderedDescending:
|
||||
versionString = [NSString stringWithFormat:
|
||||
@"Latest version is %@, you have %@.",
|
||||
installVersion, installedVersion];
|
||||
[installOdbButton setEnabled:NO];
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
[installOdbButton setEnabled:YES];
|
||||
[uninstallOdbButton setEnabled:NO];
|
||||
[editors setEnabled:NO];
|
||||
|
||||
versionString = [NSString
|
||||
stringWithFormat:@"Latest version is %@. It is not installed.",
|
||||
[self odbBundleInstallVersion]];
|
||||
}
|
||||
|
||||
[obdBundleVersionLabel setStringValue:versionString];
|
||||
|
||||
// make sure the right editor is selected on the popup button
|
||||
NSString *selectedTitle = kOdbEditorNameNone;
|
||||
NSArray* keys = [supportedOdbEditors
|
||||
allKeysForObject:[self odbEditorBundleIdentifier]];
|
||||
if ([keys count] > 0)
|
||||
selectedTitle = [keys objectAtIndex:0];
|
||||
[editors selectItemWithTitle:selectedTitle];
|
||||
}
|
||||
|
||||
- (void)setOdbEditorByName:(NSString *)name
|
||||
{
|
||||
NSString *identifier = [supportedOdbEditors objectForKey:name];
|
||||
if (identifier != kOdbEditorIdentifierNone) {
|
||||
CFPreferencesSetAppValue(ODB_BUNDLE_IDENTIFIER, identifier, ODBEDITOR);
|
||||
CFPreferencesSetAppValue(ODB_EDITOR_NAME, name, ODBEDITOR);
|
||||
} else {
|
||||
CFPreferencesSetAppValue(ODB_BUNDLE_IDENTIFIER, NULL, ODBEDITOR);
|
||||
CFPreferencesSetAppValue(ODB_EDITOR_NAME, NULL, ODBEDITOR);
|
||||
}
|
||||
CFPreferencesAppSynchronize(ODBEDITOR);
|
||||
}
|
||||
|
||||
// Note that you can't compare the result of this function with ==, you have
|
||||
// to use isStringEqual: (since this returns a new copy of the string).
|
||||
- (NSString *)odbEditorBundleIdentifier
|
||||
{
|
||||
// reading the defaults of a different app is easier with carbon
|
||||
NSString *bundleIdentifier = (NSString*)CFPreferencesCopyAppValue(
|
||||
ODB_BUNDLE_IDENTIFIER, ODBEDITOR);
|
||||
if (bundleIdentifier == nil)
|
||||
return kOdbEditorIdentifierNone;
|
||||
return [bundleIdentifier autorelease];
|
||||
}
|
||||
|
||||
- (void)odbEditorChanged:(id)sender
|
||||
{
|
||||
[self setOdbEditorByName:[sender title]];
|
||||
}
|
||||
|
||||
- (NSString *)odbBundleSourceDir
|
||||
{
|
||||
return [[[NSBundle mainBundle] resourcePath]
|
||||
stringByAppendingString:@"/Edit in ODBEditor"];
|
||||
}
|
||||
|
||||
// Returns the CFBundleVersion of a bundle. This assumes a bundle exists
|
||||
// at bundlePath.
|
||||
- (NSString *)versionOfBundle:(NSString *)bundlePath
|
||||
{
|
||||
// -[NSBundle initWithPath:] caches a bundle, so if the bundle is replaced
|
||||
// with a new bundle on disk, we get the old version. So we can't use it :-(
|
||||
|
||||
NSString *infoPath = [bundlePath
|
||||
stringByAppendingString:@"/Contents/Info.plist"];
|
||||
NSDictionary *info = [NSDictionary dictionaryWithContentsOfFile:infoPath];
|
||||
return [info objectForKey:@"CFBundleVersion"];
|
||||
}
|
||||
|
||||
- (NSString *)odbBundleInstalledVersion
|
||||
{
|
||||
return [self versionOfBundle:ODBEDITOR_PATH];
|
||||
}
|
||||
|
||||
- (NSString *)odbBundleInstallVersion
|
||||
{
|
||||
return [self versionOfBundle:[[self odbBundleSourceDir]
|
||||
stringByAppendingString:@"/Edit in ODBEditor.bundle"]];
|
||||
}
|
||||
|
||||
- (IBAction)installOdb:(id)sender
|
||||
{
|
||||
NSString *source = [self odbBundleSourceDir];
|
||||
|
||||
// It doesn't hurt to rm -rf the InputManager even if it's not there,
|
||||
// the code is simpler that way.
|
||||
NSArray *cmd = [NSArray arrayWithObjects:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"/bin/rm", MMCommand,
|
||||
[NSArray arrayWithObjects:@"-rf", ODBEDITOR_DIR, nil], MMArguments,
|
||||
nil],
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"/bin/mkdir", MMCommand,
|
||||
[NSArray arrayWithObjects:@"-p", ODBEDITOR_DIR, nil], MMArguments,
|
||||
nil],
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"/bin/cp", MMCommand,
|
||||
[NSArray arrayWithObjects: @"-R",
|
||||
source, @"/Library/InputManagers", nil], MMArguments,
|
||||
nil],
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"/usr/sbin/chown", MMCommand,
|
||||
[NSArray arrayWithObjects: @"-R",
|
||||
@"root:admin", @"/Library/InputManagers", nil], MMArguments,
|
||||
nil],
|
||||
nil
|
||||
];
|
||||
|
||||
AuthorizedShellCommand *au = [[AuthorizedShellCommand alloc]
|
||||
initWithCommands:cmd];
|
||||
OSStatus err = [au run];
|
||||
if (err == errAuthorizationSuccess) {
|
||||
// If the user just installed the input manager and no editor was
|
||||
// selected before, chances are he wants to use MacVim as editor
|
||||
if ([[self odbEditorBundleIdentifier]
|
||||
isEqualToString:kOdbEditorIdentifierNone]) {
|
||||
[self setOdbEditorByName:kOdbEditorNameMacVim];
|
||||
}
|
||||
} else {
|
||||
NSLog(@"Failed to install input manager, error is %d", err);
|
||||
}
|
||||
[au release];
|
||||
|
||||
[self updateIntegrationPane];
|
||||
}
|
||||
|
||||
- (IBAction)uninstallOdb:(id)sender
|
||||
{
|
||||
NSArray *cmd = [NSArray arrayWithObject:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"/bin/rm", MMCommand,
|
||||
[NSArray arrayWithObjects: @"-rf", ODBEDITOR_DIR, nil], MMArguments,
|
||||
nil]];
|
||||
|
||||
AuthorizedShellCommand *au = [[AuthorizedShellCommand alloc]
|
||||
initWithCommands:cmd];
|
||||
OSStatus err = [au run];
|
||||
if (err != errAuthorizationSuccess)
|
||||
NSLog(@"Failed to uninstall input manager, error is %d", err);
|
||||
[au release];
|
||||
|
||||
[self updateIntegrationPane];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
NSTextField *markedTextField;
|
||||
int preEditRow;
|
||||
int preEditColumn;
|
||||
int mouseShape;
|
||||
BOOL antialias;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame;
|
||||
@@ -39,6 +41,8 @@
|
||||
fraction:(int)percent color:(NSColor *)color;
|
||||
- (void)hideMarkedTextField;
|
||||
- (void)performBatchDrawWithData:(NSData *)data;
|
||||
- (void)setMouseShape:(int)shape;
|
||||
- (void)setAntialias:(BOOL)antialias;
|
||||
|
||||
//
|
||||
// MMTextStorage methods
|
||||
|
||||
+113
-11
@@ -46,10 +46,12 @@ enum {
|
||||
|
||||
|
||||
@interface MMTextView (Private)
|
||||
- (void)setCursor;
|
||||
- (BOOL)convertPoint:(NSPoint)point toRow:(int *)row column:(int *)column;
|
||||
- (BOOL)convertRow:(int)row column:(int)column toPoint:(NSPoint *)point;
|
||||
- (NSRect)trackingRect;
|
||||
- (void)dispatchKeyEvent:(NSEvent *)event;
|
||||
- (MMWindowController *)windowController;
|
||||
- (MMVimController *)vimController;
|
||||
- (void)startDragTimerWithInterval:(NSTimeInterval)t;
|
||||
- (void)dragTimerFired:(NSTimer *)timer;
|
||||
@@ -110,12 +112,9 @@ enum {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Allow control of text view inset via MMTextInset* user defaults.
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
int left = [ud integerForKey:MMTextInsetLeftKey];
|
||||
int top = [ud integerForKey:MMTextInsetTopKey];
|
||||
[self setTextContainerInset:NSMakeSize(left, top)];
|
||||
|
||||
// NOTE: If the default changes to 'NO' then the intialization of
|
||||
// p_antialias in option.c must change as well.
|
||||
antialias = YES;
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -333,6 +332,17 @@ enum {
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)setMouseShape:(int)shape
|
||||
{
|
||||
mouseShape = shape;
|
||||
[self setCursor];
|
||||
}
|
||||
|
||||
- (void)setAntialias:(BOOL)state
|
||||
{
|
||||
antialias = state;
|
||||
}
|
||||
|
||||
- (NSFont *)font
|
||||
{
|
||||
return [(MMTextStorage*)[self textStorage] font];
|
||||
@@ -441,6 +451,9 @@ enum {
|
||||
|
||||
- (void)drawRect:(NSRect)rect
|
||||
{
|
||||
NSGraphicsContext *context = [NSGraphicsContext currentContext];
|
||||
[context setShouldAntialias:antialias];
|
||||
|
||||
[super drawRect:rect];
|
||||
|
||||
if (shouldDrawInsertionPoint) {
|
||||
@@ -934,6 +947,8 @@ enum {
|
||||
[data appendBytes:&col length:sizeof(int)];
|
||||
|
||||
[[self vimController] sendMessage:MouseMovedMsgID data:data];
|
||||
|
||||
//NSLog(@"Moved %d %d\n", col, row);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -944,8 +959,14 @@ enum {
|
||||
// NOTE: This event is received even when the window is not key; thus we
|
||||
// have to take care not to enable mouse moved events unless our window is
|
||||
// key.
|
||||
if ([[self window] isKeyWindow])
|
||||
if ([[self window] isKeyWindow]) {
|
||||
[[self window] setAcceptsMouseMovedEvents:YES];
|
||||
|
||||
// Ensure Vim gets to choose the mouse cursor when it enters over the
|
||||
// text view, otherwise NSTextView will automatically set its I-Beam
|
||||
// cursor.
|
||||
[self setCursor];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseExited:(NSEvent *)event
|
||||
@@ -1099,6 +1120,42 @@ enum {
|
||||
// The font panel is updated whenever the font is set.
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// NOTE: The menu items cut/copy/paste/undo/redo/select all/... must be bound
|
||||
// to the same actions as in IB otherwise they will not work with dialogs. All
|
||||
// we do here is forward these actions to the Vim process.
|
||||
//
|
||||
- (IBAction)cut:(id)sender
|
||||
{
|
||||
[[self windowController] vimMenuItemAction:sender];
|
||||
}
|
||||
|
||||
- (IBAction)copy:(id)sender
|
||||
{
|
||||
[[self windowController] vimMenuItemAction:sender];
|
||||
}
|
||||
|
||||
- (IBAction)paste:(id)sender
|
||||
{
|
||||
[[self windowController] vimMenuItemAction:sender];
|
||||
}
|
||||
|
||||
- (IBAction)undo:(id)sender
|
||||
{
|
||||
[[self windowController] vimMenuItemAction:sender];
|
||||
}
|
||||
|
||||
- (IBAction)redo:(id)sender
|
||||
{
|
||||
[[self windowController] vimMenuItemAction:sender];
|
||||
}
|
||||
|
||||
- (IBAction)selectAll:(id)sender
|
||||
{
|
||||
[[self windowController] vimMenuItemAction:sender];
|
||||
}
|
||||
|
||||
@end // MMTextView
|
||||
|
||||
|
||||
@@ -1106,6 +1163,47 @@ enum {
|
||||
|
||||
@implementation MMTextView (Private)
|
||||
|
||||
- (void)setCursor
|
||||
{
|
||||
static NSCursor *customIbeamCursor = nil;
|
||||
|
||||
if (!customIbeamCursor) {
|
||||
// Use a custom Ibeam cursor that has better contrast against dark
|
||||
// backgrounds.
|
||||
// TODO: Is the hotspot ok?
|
||||
NSImage *ibeamImage = [NSImage imageNamed:@"ibeam"];
|
||||
if (ibeamImage) {
|
||||
NSSize size = [ibeamImage size];
|
||||
NSPoint hotSpot = { size.width*.5f, size.height*.5f };
|
||||
|
||||
customIbeamCursor = [[NSCursor alloc]
|
||||
initWithImage:ibeamImage hotSpot:hotSpot];
|
||||
}
|
||||
if (!customIbeamCursor) {
|
||||
NSLog(@"WARNING: Failed to load custom Ibeam cursor");
|
||||
customIbeamCursor = [NSCursor IBeamCursor];
|
||||
}
|
||||
}
|
||||
|
||||
// This switch should match mshape_names[] in misc2.c.
|
||||
//
|
||||
// TODO: Add missing cursor shapes.
|
||||
switch (mouseShape) {
|
||||
case 2: [customIbeamCursor set]; break;
|
||||
case 3: case 4: [[NSCursor resizeUpDownCursor] set]; break;
|
||||
case 5: case 6: [[NSCursor resizeLeftRightCursor] set]; break;
|
||||
case 9: [[NSCursor crosshairCursor] set]; break;
|
||||
case 10: [[NSCursor pointingHandCursor] set]; break;
|
||||
case 11: [[NSCursor openHandCursor] set]; break;
|
||||
default:
|
||||
[[NSCursor arrowCursor] set]; break;
|
||||
}
|
||||
|
||||
// Shape 1 indicates that the mouse cursor should be hidden.
|
||||
if (1 == mouseShape)
|
||||
[NSCursor setHiddenUntilMouseMoves:YES];
|
||||
}
|
||||
|
||||
- (BOOL)convertPoint:(NSPoint)point toRow:(int *)row column:(int *)column
|
||||
{
|
||||
MMTextStorage *ts = (MMTextStorage*)[self textStorage];
|
||||
@@ -1198,13 +1296,17 @@ enum {
|
||||
[self sendKeyDown:bytes length:len modifiers:mods];
|
||||
}
|
||||
|
||||
- (MMVimController *)vimController
|
||||
- (MMWindowController *)windowController
|
||||
{
|
||||
id windowController = [[self window] windowController];
|
||||
if ([windowController isKindOfClass:[MMWindowController class]])
|
||||
return (MMWindowController*)windowController;
|
||||
return nil;
|
||||
}
|
||||
|
||||
// TODO: Make sure 'windowController' is a MMWindowController before type
|
||||
// casting.
|
||||
return [(MMWindowController*)windowController vimController];
|
||||
- (MMVimController *)vimController
|
||||
{
|
||||
return [[self windowController] vimController];
|
||||
}
|
||||
|
||||
- (void)startDragTimerWithInterval:(NSTimeInterval)t
|
||||
|
||||
@@ -40,14 +40,19 @@
|
||||
NSData *resendData;
|
||||
#endif
|
||||
NSMenu *lastMenuSearched;
|
||||
NSMenuItem *recentFilesMenuItem;
|
||||
NSMenuItem *recentFilesDummy;
|
||||
NSDictionary *vimState;
|
||||
}
|
||||
|
||||
- (id)initWithBackend:(id)backend pid:(int)processIdentifier;
|
||||
- (id)initWithBackend:(id)backend pid:(int)processIdentifier
|
||||
recentFiles:(NSMenuItem*)menu;
|
||||
- (id)backendProxy;
|
||||
- (int)pid;
|
||||
- (void)setServerName:(NSString *)name;
|
||||
- (NSString *)serverName;
|
||||
- (MMWindowController *)windowController;
|
||||
- (NSDictionary *)vimState;
|
||||
- (void)cleanup;
|
||||
- (void)dropFiles:(NSArray *)filenames forceOpen:(BOOL)force;
|
||||
- (void)dropString:(NSString *)string;
|
||||
|
||||
@@ -70,7 +70,8 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
- (void)addMenuItemWithTag:(int)tag parent:(NSMenu *)parent
|
||||
title:(NSString *)title tip:(NSString *)tip
|
||||
keyEquivalent:(int)key modifiers:(int)mask
|
||||
action:(NSString *)action atIndex:(int)idx;
|
||||
action:(NSString *)action isAlternate:(int)isAlt
|
||||
atIndex:(int)idx;
|
||||
- (NSToolbarItem *)toolbarItemForTag:(int)tag index:(int *)index;
|
||||
- (void)addToolbarItemToDictionaryWithTag:(int)tag label:(NSString *)title
|
||||
toolTip:(NSString *)tip icon:(NSString *)icon;
|
||||
@@ -81,6 +82,7 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
#if MM_RESEND_LAST_FAILURE
|
||||
- (void)resendTimerFired:(NSTimer *)timer;
|
||||
#endif
|
||||
- (void)replaceMenuItem:(NSMenuItem*)old with:(NSMenuItem*)new;
|
||||
@end
|
||||
|
||||
|
||||
@@ -89,8 +91,12 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
@implementation MMVimController
|
||||
|
||||
- (id)initWithBackend:(id)backend pid:(int)processIdentifier
|
||||
recentFiles:(NSMenuItem*)menu;
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
|
||||
recentFilesMenuItem = [menu retain];
|
||||
|
||||
windowController =
|
||||
[[MMWindowController alloc] initWithVimController:self];
|
||||
backendProxy = [backend retain];
|
||||
@@ -135,6 +141,9 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
[mainMenuItems release]; mainMenuItems = nil;
|
||||
[windowController release]; windowController = nil;
|
||||
|
||||
[recentFilesMenuItem release]; recentFilesMenuItem = nil;
|
||||
[recentFilesDummy release]; recentFilesDummy = nil;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -143,6 +152,11 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
return windowController;
|
||||
}
|
||||
|
||||
- (NSDictionary *)vimState
|
||||
{
|
||||
return vimState;
|
||||
}
|
||||
|
||||
- (void)setServerName:(NSString *)name
|
||||
{
|
||||
if (name != serverName) {
|
||||
@@ -382,6 +396,15 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
if (!dir) {
|
||||
// 'dir == nil' means: set dir to the pwd of the Vim process, or let
|
||||
// open dialog decide (depending on the below user default).
|
||||
BOOL trackPwd = [[NSUserDefaults standardUserDefaults]
|
||||
boolForKey:MMDialogsTrackPwdKey];
|
||||
if (trackPwd)
|
||||
dir = [vimState objectForKey:@"pwd"];
|
||||
}
|
||||
|
||||
if (saving) {
|
||||
[[NSSavePanel savePanel] beginSheetForDirectory:dir file:nil
|
||||
modalForWindow:[windowController window]
|
||||
@@ -574,6 +597,14 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
[NSApp setWindowsMenu:windowMenu];
|
||||
}
|
||||
|
||||
// Replace real Recent Files menu in the old menu with the dummy, then
|
||||
// remove dummy from new menu and put Recent Files menu there
|
||||
NSMenuItem *oldItem = (NSMenuItem*)[recentFilesMenuItem representedObject];
|
||||
if (oldItem)
|
||||
[self replaceMenuItem:recentFilesMenuItem with:oldItem];
|
||||
[recentFilesMenuItem setRepresentedObject:recentFilesDummy];
|
||||
[self replaceMenuItem:recentFilesDummy with:recentFilesMenuItem];
|
||||
|
||||
shouldUpdateMainMenu = NO;
|
||||
}
|
||||
|
||||
@@ -689,6 +720,7 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
if (idx < 0) idx = 0;
|
||||
int key = *((int*)bytes); bytes += sizeof(int);
|
||||
int mask = *((int*)bytes); bytes += sizeof(int);
|
||||
int isalt = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
NSString *ident = [NSString stringWithFormat:@"%d.%d",
|
||||
(int)self, parentTag];
|
||||
@@ -699,7 +731,7 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
NSMenu *parent = [self menuForTag:parentTag];
|
||||
[self addMenuItemWithTag:tag parent:parent title:title tip:tip
|
||||
keyEquivalent:key modifiers:mask action:action
|
||||
atIndex:idx];
|
||||
isAlternate:isalt atIndex:idx];
|
||||
}
|
||||
|
||||
[title release];
|
||||
@@ -878,7 +910,12 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
[self setServerName:name];
|
||||
[name release];
|
||||
} else if (EnterFullscreenMsgID == msgid) {
|
||||
[windowController enterFullscreen];
|
||||
const void *bytes = [data bytes];
|
||||
int fuoptions = *((int*)bytes); bytes += sizeof(int);
|
||||
int bg = *((int*)bytes);
|
||||
NSColor *back = [NSColor colorWithArgbInt:bg];
|
||||
|
||||
[windowController enterFullscreen:fuoptions backgroundColor:back];
|
||||
} else if (LeaveFullscreenMsgID == msgid) {
|
||||
[windowController leaveFullscreen];
|
||||
} else if (BuffersNotModifiedMsgID == msgid) {
|
||||
@@ -889,6 +926,16 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
const int *dim = (const int*)[data bytes];
|
||||
[[[windowController vimView] textView] setPreEditRow:dim[0]
|
||||
column:dim[1]];
|
||||
} else if (EnableAntialiasMsgID == msgid) {
|
||||
[[[windowController vimView] textView] setAntialias:YES];
|
||||
} else if (DisableAntialiasMsgID == msgid) {
|
||||
[[[windowController vimView] textView] setAntialias:NO];
|
||||
} else if (SetVimStateMsgID == msgid) {
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithData:data];
|
||||
if (dict) {
|
||||
[vimState release];
|
||||
vimState = [dict retain];
|
||||
}
|
||||
} else {
|
||||
NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid);
|
||||
}
|
||||
@@ -897,9 +944,15 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
- (void)savePanelDidEnd:(NSSavePanel *)panel code:(int)code
|
||||
context:(void *)context
|
||||
{
|
||||
NSString *string = (code == NSOKButton) ? [panel filename] : nil;
|
||||
NSString *path = (code == NSOKButton) ? [panel filename] : nil;
|
||||
@try {
|
||||
[backendProxy setDialogReturn:string];
|
||||
[backendProxy setDialogReturn:path];
|
||||
|
||||
// Add file to the "Recent Files" menu (this ensures that files that
|
||||
// are opened/saved from a :browse command are added to this menu).
|
||||
if (path)
|
||||
[[NSDocumentController sharedDocumentController]
|
||||
noteNewRecentFilePath:path];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught in %s %@", _cmd, e);
|
||||
@@ -1055,7 +1108,8 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
- (void)addMenuItemWithTag:(int)tag parent:(NSMenu *)parent
|
||||
title:(NSString *)title tip:(NSString *)tip
|
||||
keyEquivalent:(int)key modifiers:(int)mask
|
||||
action:(NSString *)action atIndex:(int)idx
|
||||
action:(NSString *)action isAlternate:(int)isAlt
|
||||
atIndex:(int)idx
|
||||
{
|
||||
if (parent) {
|
||||
NSMenuItem *item = nil;
|
||||
@@ -1064,17 +1118,30 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
} else {
|
||||
item = [[[NSMenuItem alloc] init] autorelease];
|
||||
[item setTitle:title];
|
||||
// TODO: Check that 'action' is a valid action (nothing will happen
|
||||
// if it isn't, but it would be nice with a warning).
|
||||
if (action) [item setAction:NSSelectorFromString(action)];
|
||||
else [item setAction:@selector(vimMenuItemAction:)];
|
||||
if (tip) [item setToolTip:tip];
|
||||
|
||||
if (key != 0) {
|
||||
NSString *keyString =
|
||||
[NSString stringWithFormat:@"%C", key];
|
||||
[item setKeyEquivalent:keyString];
|
||||
[item setKeyEquivalentModifierMask:mask];
|
||||
if ([action isEqualToString:@"recentFilesDummy:"]) {
|
||||
// Remove the recent files menu item from its current menu
|
||||
// and put it in the current file menu. See -[MMAppController
|
||||
// applicationWillFinishLaunching for more information.
|
||||
//[[recentFilesMenuItem menu] removeItem:recentFilesMenuItem];
|
||||
//item = recentFilesMenuItem;
|
||||
recentFilesDummy = [item retain];
|
||||
|
||||
} else {
|
||||
// TODO: Check that 'action' is a valid action (nothing will
|
||||
// happen if it isn't, but it would be nice with a warning).
|
||||
if (action) [item setAction:NSSelectorFromString(action)];
|
||||
else [item setAction:@selector(vimMenuItemAction:)];
|
||||
if (tip) [item setToolTip:tip];
|
||||
|
||||
if (key != 0) {
|
||||
NSString *keyString =
|
||||
[NSString stringWithFormat:@"%C", key];
|
||||
[item setKeyEquivalent:keyString];
|
||||
[item setKeyEquivalentModifierMask:mask];
|
||||
}
|
||||
|
||||
if (isAlt) [item setAlternate:YES];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1211,6 +1278,14 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)replaceMenuItem:(NSMenuItem*)old with:(NSMenuItem*)new
|
||||
{
|
||||
NSMenu *menu = [old menu];
|
||||
int index = [menu indexOfItem:old];
|
||||
[menu removeItemAtIndex:index];
|
||||
[menu insertItem:new atIndex:index];
|
||||
}
|
||||
|
||||
@end // MMVimController (Private)
|
||||
|
||||
|
||||
|
||||
@@ -104,6 +104,12 @@ enum {
|
||||
textView = [[MMTextView alloc] initWithFrame:frame];
|
||||
}
|
||||
|
||||
// Allow control of text view inset via MMTextInset* user defaults.
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
int left = [ud integerForKey:MMTextInsetLeftKey];
|
||||
int top = [ud integerForKey:MMTextInsetTopKey];
|
||||
[textView setTextContainerInset:NSMakeSize(left, top)];
|
||||
|
||||
[textView setAutoresizingMask:NSViewNotSizable];
|
||||
[self addSubview:textView];
|
||||
|
||||
@@ -123,7 +129,6 @@ enum {
|
||||
[tabBarControl setDelegate:self];
|
||||
[tabBarControl setHidden:YES];
|
||||
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
[tabBarControl setCellMinWidth:[ud integerForKey:MMTabMinWidthKey]];
|
||||
[tabBarControl setCellMaxWidth:[ud integerForKey:MMTabMaxWidthKey]];
|
||||
[tabBarControl setCellOptimumWidth:
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
- (void)liveResizeWillStart;
|
||||
- (void)liveResizeDidEnd;
|
||||
|
||||
- (void)enterFullscreen;
|
||||
- (void)enterFullscreen:(int)fuoptions backgroundColor:(NSColor *)back;
|
||||
- (void)leaveFullscreen;
|
||||
- (void)setBuffersModified:(BOOL)mod;
|
||||
|
||||
@@ -68,5 +68,6 @@
|
||||
- (IBAction)performClose:(id)sender;
|
||||
- (IBAction)findNext:(id)sender;
|
||||
- (IBAction)findPrevious:(id)sender;
|
||||
- (IBAction)vimMenuItemAction:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
@@ -76,7 +76,6 @@
|
||||
- (NSSize)constrainContentSizeToScreenSize:(NSSize)contentSize;
|
||||
- (void)updateResizeConstraints;
|
||||
- (NSTabViewItem *)addNewTabViewItem;
|
||||
- (IBAction)vimMenuItemAction:(id)sender;
|
||||
- (BOOL)askBackendForStarRegister:(NSPasteboard *)pb;
|
||||
- (void)hideTablineSeparator:(BOOL)hide;
|
||||
- (void)doFindNext:(BOOL)next;
|
||||
@@ -367,7 +366,9 @@
|
||||
// NOTE: This is called when the transparency changes so set the opacity
|
||||
// flag on the window here (should be faster if the window is opaque).
|
||||
BOOL isOpaque = [back alphaComponent] == 1.0f;
|
||||
[[self window] setOpaque:isOpaque];
|
||||
[decoratedWindow setOpaque:isOpaque];
|
||||
if (fullscreenEnabled)
|
||||
[fullscreenWindow setOpaque:isOpaque];
|
||||
|
||||
[vimView setDefaultColorsBackground:back foreground:fore];
|
||||
}
|
||||
@@ -487,23 +488,7 @@
|
||||
|
||||
- (void)setMouseShape:(int)shape
|
||||
{
|
||||
// This switch should match mshape_names[] in misc2.c.
|
||||
//
|
||||
// TODO: Add missing cursor shapes.
|
||||
switch (shape) {
|
||||
case 2: [[NSCursor IBeamCursor] set]; break;
|
||||
case 3: case 4: [[NSCursor resizeUpDownCursor] set]; break;
|
||||
case 5: case 6: [[NSCursor resizeLeftRightCursor] set]; break;
|
||||
case 9: [[NSCursor crosshairCursor] set]; break;
|
||||
case 10: [[NSCursor pointingHandCursor] set]; break;
|
||||
case 11: [[NSCursor openHandCursor] set]; break;
|
||||
default:
|
||||
[[NSCursor arrowCursor] set]; break;
|
||||
}
|
||||
|
||||
// Shape 1 indicates that the mouse cursor should be hidden.
|
||||
if (1 == shape)
|
||||
[NSCursor setHiddenUntilMouseMoves:YES];
|
||||
[[vimView textView] setMouseShape:shape];
|
||||
}
|
||||
|
||||
- (void)adjustLinespace:(int)linespace
|
||||
@@ -560,13 +545,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)enterFullscreen
|
||||
- (void)enterFullscreen:(int)fuoptions backgroundColor:(NSColor *)back
|
||||
{
|
||||
if (fullscreenEnabled) return;
|
||||
|
||||
fullscreenWindow = [[MMFullscreenWindow alloc]
|
||||
initWithWindow:decoratedWindow view:vimView];
|
||||
[fullscreenWindow enterFullscreen];
|
||||
initWithWindow:decoratedWindow view:vimView backgroundColor:back];
|
||||
[fullscreenWindow enterFullscreen:fuoptions];
|
||||
[fullscreenWindow setDelegate:self];
|
||||
fullscreenEnabled = YES;
|
||||
|
||||
@@ -609,11 +594,12 @@
|
||||
|
||||
- (IBAction)performClose:(id)sender
|
||||
{
|
||||
// NOTE: File->Close is bound to this action message instead binding it
|
||||
// directly to the below vim input so that File->Close also works for
|
||||
// auxiliary windows such as the About dialog. (If we were to bind the
|
||||
// below, then <D-w> will not close e.g. the About dialog.)
|
||||
[vimController addVimInput:@"<C-\\><C-N>:conf q<CR>"];
|
||||
// NOTE: With the introduction of :macmenu it is possible to bind
|
||||
// File.Close to ":conf q" but at the same time have it send off the
|
||||
// performClose: action. For this reason we no longer need the CloseMsgID
|
||||
// message. However, we still need File.Close to send performClose:
|
||||
// otherwise Cmd-w will not work on dialogs.
|
||||
[self vimMenuItemAction:sender];
|
||||
}
|
||||
|
||||
- (IBAction)findNext:(id)sender
|
||||
@@ -626,6 +612,16 @@
|
||||
[self doFindNext:NO];
|
||||
}
|
||||
|
||||
- (IBAction)vimMenuItemAction:(id)sender
|
||||
{
|
||||
int tag = [sender tag];
|
||||
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
[data appendBytes:&tag length:sizeof(int)];
|
||||
|
||||
[vimController sendMessage:ExecuteMenuMsgID data:data];
|
||||
}
|
||||
|
||||
|
||||
// -- NSWindow delegate ------------------------------------------------------
|
||||
|
||||
@@ -682,16 +678,35 @@
|
||||
- (NSRect)windowWillUseStandardFrame:(NSWindow *)win
|
||||
defaultFrame:(NSRect)frame
|
||||
{
|
||||
// Keep old width and horizontal position unless user clicked while the
|
||||
// Command key is held down.
|
||||
// By default the window is maximized in the vertical direction only.
|
||||
// Holding down the Cmd key maximizes the window in the horizontal
|
||||
// direction. If the MMZoomBoth user default is set, then the window
|
||||
// maximizes in both directions by default, unless the Cmd key is held in
|
||||
// which case the window only maximizes in the vertical direction.
|
||||
|
||||
NSEvent *event = [NSApp currentEvent];
|
||||
if (!([event type] == NSLeftMouseUp
|
||||
&& [event modifierFlags] & NSCommandKeyMask)) {
|
||||
BOOL cmdLeftClick = [event type] == NSLeftMouseUp
|
||||
&& [event modifierFlags] & NSCommandKeyMask;
|
||||
BOOL zoomBoth = [[NSUserDefaults standardUserDefaults]
|
||||
boolForKey:MMZoomBothKey];
|
||||
|
||||
if (!((zoomBoth && !cmdLeftClick) || (!zoomBoth && cmdLeftClick))) {
|
||||
// Zoom in horizontal direction only.
|
||||
NSRect currentFrame = [win frame];
|
||||
frame.size.width = currentFrame.size.width;
|
||||
frame.origin.x = currentFrame.origin.x;
|
||||
}
|
||||
|
||||
// HACK! The window frame is often higher than the 'defaultFrame' (the fact
|
||||
// that 'defaultFrame' doesn't cover the entire area up to the menu bar
|
||||
// seems like a Cocoa bug). To ensure that the window doesn't move
|
||||
// downwards when the zoom button is clicked we check for this situation
|
||||
// and return a frame whose max Y coordinate is no lower than the current
|
||||
// max Y coordinate.
|
||||
float delta = NSMaxY([win frame]) - NSMaxY(frame);
|
||||
if (delta > 0)
|
||||
frame.origin.y += delta;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
@@ -778,16 +793,6 @@
|
||||
return [vimView addNewTabViewItem];
|
||||
}
|
||||
|
||||
- (IBAction)vimMenuItemAction:(id)sender
|
||||
{
|
||||
int tag = [sender tag];
|
||||
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
[data appendBytes:&tag length:sizeof(int)];
|
||||
|
||||
[vimController sendMessage:ExecuteMenuMsgID data:data];
|
||||
}
|
||||
|
||||
- (BOOL)askBackendForStarRegister:(NSPasteboard *)pb
|
||||
{
|
||||
// TODO: Can this be done with evaluateExpression: instead?
|
||||
|
||||
+29
-1
@@ -160,6 +160,9 @@ enum {
|
||||
ODBEditMsgID,
|
||||
XcodeModMsgID,
|
||||
LiveResizeMsgID,
|
||||
EnableAntialiasMsgID,
|
||||
DisableAntialiasMsgID,
|
||||
SetVimStateMsgID,
|
||||
};
|
||||
|
||||
|
||||
@@ -220,6 +223,11 @@ extern NSString *MMLoginShellKey;
|
||||
extern NSString *MMAtsuiRendererKey;
|
||||
extern NSString *MMUntitledWindowKey;
|
||||
extern NSString *MMTexturedWindowKey;
|
||||
extern NSString *MMZoomBothKey;
|
||||
extern NSString *MMCurrentPreferencePaneKey;
|
||||
extern NSString *MMLoginShellCommandKey;
|
||||
extern NSString *MMLoginShellArgumentKey;
|
||||
extern NSString *MMDialogsTrackPwdKey;
|
||||
|
||||
// Enum for MMUntitledWindowKey
|
||||
enum {
|
||||
@@ -231,6 +239,12 @@ enum {
|
||||
|
||||
|
||||
|
||||
|
||||
// Vim pasteboard type (holds motion type + string)
|
||||
extern NSString *VimPBoardType;
|
||||
|
||||
|
||||
|
||||
// Loads all fonts in the Resouces folder of the app bundle and returns a font
|
||||
// container reference (which should be used to deactivate the loaded fonts).
|
||||
ATSFontContainerRef loadFonts();
|
||||
@@ -264,6 +278,21 @@ NSString *buildSearchTextCommand(NSString *searchText);
|
||||
|
||||
|
||||
|
||||
@interface NSDocumentController (MMExtras)
|
||||
- (void)noteNewRecentFilePath:(NSString *)path;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
|
||||
@interface NSDictionary (MMExtras)
|
||||
+ (id)dictionaryWithData:(NSData *)data;
|
||||
- (NSData *)dictionaryAsData;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
|
||||
// ODB Editor Suite Constants (taken from ODBEditorSuite.h)
|
||||
#define keyFileSender 'FSnd'
|
||||
#define keyFileSenderToken 'FTok'
|
||||
@@ -277,4 +306,3 @@ NSString *buildSearchTextCommand(NSString *searchText);
|
||||
|
||||
// MacVim Apple Event Constants
|
||||
#define keyMMUntitledWindow 'MMuw'
|
||||
|
||||
|
||||
@@ -73,6 +73,9 @@ char *MessageStrings[] =
|
||||
"ODBEditMsgID",
|
||||
"XcodeModMsgID",
|
||||
"LiveResizeMsgID",
|
||||
"EnableAntialiasMsgID",
|
||||
"DisableAntialiasMsgID",
|
||||
"SetVimStateMsgID",
|
||||
};
|
||||
|
||||
|
||||
@@ -100,6 +103,17 @@ NSString *MMLoginShellKey = @"MMLoginShell";
|
||||
NSString *MMAtsuiRendererKey = @"MMAtsuiRenderer";
|
||||
NSString *MMUntitledWindowKey = @"MMUntitledWindow";
|
||||
NSString *MMTexturedWindowKey = @"MMTexturedWindow";
|
||||
NSString *MMZoomBothKey = @"MMZoomBoth";
|
||||
NSString *MMCurrentPreferencePaneKey = @"MMCurrentPreferencePane";
|
||||
NSString *MMLoginShellCommandKey = @"MMLoginShellCommand";
|
||||
NSString *MMLoginShellArgumentKey = @"MMLoginShellArgument";
|
||||
NSString *MMDialogsTrackPwdKey = @"MMDialogsTrackPwd";
|
||||
|
||||
|
||||
|
||||
|
||||
// Vim pasteboard type (holds motion type + string)
|
||||
NSString *VimPBoardType = @"VimPBoardType";
|
||||
|
||||
|
||||
|
||||
@@ -281,3 +295,40 @@ buildSearchTextCommand(NSString *searchText)
|
||||
|
||||
@end // NSColor (MMExtras)
|
||||
|
||||
|
||||
|
||||
|
||||
@implementation NSDocumentController (MMExtras)
|
||||
|
||||
- (void)noteNewRecentFilePath:(NSString *)path
|
||||
{
|
||||
NSURL *url = [NSURL fileURLWithPath:path];
|
||||
if (url)
|
||||
[self noteNewRecentDocumentURL:url];
|
||||
}
|
||||
|
||||
@end // NSDocumentController (MMExtras)
|
||||
|
||||
|
||||
|
||||
|
||||
@implementation NSDictionary (MMExtras)
|
||||
|
||||
+ (id)dictionaryWithData:(NSData *)data
|
||||
{
|
||||
id plist = [NSPropertyListSerialization
|
||||
propertyListFromData:data
|
||||
mutabilityOption:NSPropertyListImmutable
|
||||
format:NULL
|
||||
errorDescription:NULL];
|
||||
|
||||
return [plist isKindOfClass:[NSDictionary class]] ? plist : nil;
|
||||
}
|
||||
|
||||
- (NSData *)dictionaryAsData
|
||||
{
|
||||
return [NSPropertyListSerialization dataFromPropertyList:self
|
||||
format:NSPropertyListBinaryFormat_v1_0 errorDescription:NULL];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,6 +9,13 @@
|
||||
/* Begin PBXBuildFile section */
|
||||
031AD5D40D4DE1F60026C5D7 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 031AD5D30D4DE1F60026C5D7 /* Sparkle.framework */; };
|
||||
031AD5EE0D4DE2490026C5D7 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 031AD5D30D4DE1F60026C5D7 /* Sparkle.framework */; };
|
||||
0395A8330D71ED7800881434 /* DBPrefsWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0395A8320D71ED7800881434 /* DBPrefsWindowController.m */; };
|
||||
0395A8AA0D72D88B00881434 /* General.png in Resources */ = {isa = PBXBuildFile; fileRef = 0395A8A90D72D88B00881434 /* General.png */; };
|
||||
0395A95A0D74D47B00881434 /* Integration.png in Resources */ = {isa = PBXBuildFile; fileRef = 0395A9590D74D47B00881434 /* Integration.png */; };
|
||||
0395A9BF0D75D02400881434 /* AuthorizedShellCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 0395A9BE0D75D02400881434 /* AuthorizedShellCommand.m */; };
|
||||
0395A9C30D75D04D00881434 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0395A9C20D75D04D00881434 /* Security.framework */; };
|
||||
0395AA780D76E77800881434 /* Info in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0395AA770D76E77800881434 /* Info */; };
|
||||
0395AAAD0D76E94000881434 /* Edit in ODBEditor.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0395AA210D76E22700881434 /* Edit in ODBEditor.bundle */; };
|
||||
1D09AB420C6A4D520045497E /* MMTypesetter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D09AB400C6A4D520045497E /* MMTypesetter.m */; };
|
||||
1D0E051C0BA5F83800B6049E /* Colors.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1D0E051B0BA5F83800B6049E /* Colors.plist */; };
|
||||
1D1474980C56703C0038FA2B /* MacVim.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1474960C56703C0038FA2B /* MacVim.m */; };
|
||||
@@ -40,6 +47,7 @@
|
||||
1D9918490D299F9900A96335 /* MMAtsuiTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D9918470D299F9900A96335 /* MMAtsuiTextView.m */; };
|
||||
1DD04DEC0C529C5E006CDC2B /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 1DD04DEB0C529C5E006CDC2B /* Credits.rtf */; };
|
||||
1DD0C20C0C60FFB4008CD84A /* gvimrc in CopyFiles */ = {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 */; };
|
||||
1DD703B90BA9D15D008679E9 /* vim_gloss.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1DD703B80BA9D15D008679E9 /* vim_gloss.icns */; };
|
||||
1DD704310BA9F9C2008679E9 /* SpecialKeys.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DD704300BA9F9C2008679E9 /* SpecialKeys.plist */; };
|
||||
@@ -79,6 +87,20 @@
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
0395AA200D76E22700881434 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0395AA190D76E22700881434 /* Edit in ODBEditor.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 8D5B49B6048680CD000E48DA;
|
||||
remoteInfo = "Edit in ODBEditor";
|
||||
};
|
||||
0395AA230D76E2F300881434 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0395AA190D76E22700881434 /* Edit in ODBEditor.xcodeproj */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 8D5B49AC048680CD000E48DA;
|
||||
remoteInfo = "Edit in ODBEditor";
|
||||
};
|
||||
1D493DB80C52533B00AB718C /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 1D493DB30C52533B00AB718C /* PSMTabBarControl.xcodeproj */;
|
||||
@@ -96,6 +118,17 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
0395AA790D76E77800881434 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "Edit in ODBEditor";
|
||||
dstSubfolderSpec = 7;
|
||||
files = (
|
||||
0395AAAD0D76E94000881434 /* Edit in ODBEditor.bundle in CopyFiles */,
|
||||
0395AA780D76E77800881434 /* Info in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
1D0DCAD80BA3604D00B6CCFA /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -133,6 +166,15 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
031AD5D30D4DE1F60026C5D7 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = "<group>"; };
|
||||
0395A8310D71ED7800881434 /* DBPrefsWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBPrefsWindowController.h; sourceTree = "<group>"; };
|
||||
0395A8320D71ED7800881434 /* DBPrefsWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBPrefsWindowController.m; sourceTree = "<group>"; };
|
||||
0395A8A90D72D88B00881434 /* General.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = General.png; sourceTree = "<group>"; };
|
||||
0395A9590D74D47B00881434 /* Integration.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Integration.png; sourceTree = "<group>"; };
|
||||
0395A9BD0D75D02400881434 /* AuthorizedShellCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AuthorizedShellCommand.h; sourceTree = "<group>"; };
|
||||
0395A9BE0D75D02400881434 /* AuthorizedShellCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AuthorizedShellCommand.m; sourceTree = "<group>"; };
|
||||
0395A9C20D75D04D00881434 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; };
|
||||
0395AA190D76E22700881434 /* Edit in ODBEditor.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "Edit in ODBEditor.xcodeproj"; path = "edit-in-odb/Edit in ODBEditor.xcodeproj"; sourceTree = "<group>"; };
|
||||
0395AA770D76E77800881434 /* Info */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = Info; path = "edit-in-odb/Info"; sourceTree = "<group>"; };
|
||||
089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
|
||||
13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
|
||||
@@ -177,6 +219,7 @@
|
||||
1D9918470D299F9900A96335 /* MMAtsuiTextView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMAtsuiTextView.m; sourceTree = "<group>"; };
|
||||
1DD04DEB0C529C5E006CDC2B /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = "<group>"; };
|
||||
1DD0C20A0C60FF9A008CD84A /* gvimrc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = gvimrc; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
1DD703B80BA9D15D008679E9 /* vim_gloss.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = vim_gloss.icns; sourceTree = "<group>"; };
|
||||
@@ -229,15 +272,37 @@
|
||||
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
|
||||
1D80FBE40CBBD6F200102A1C /* Carbon.framework in Frameworks */,
|
||||
031AD5D40D4DE1F60026C5D7 /* Sparkle.framework in Frameworks */,
|
||||
0395A9C30D75D04D00881434 /* Security.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
0395AA1A0D76E22700881434 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0395AA210D76E22700881434 /* Edit in ODBEditor.bundle */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0395AA980D76E86200881434 /* Edit in ODBEditor */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0395AA190D76E22700881434 /* Edit in ODBEditor.xcodeproj */,
|
||||
0395AA770D76E77800881434 /* Info */,
|
||||
);
|
||||
name = "Edit in ODBEditor";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
080E96DDFE201D6D7F000001 /* MacVim Source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0395A9BD0D75D02400881434 /* AuthorizedShellCommand.h */,
|
||||
0395A9BE0D75D02400881434 /* AuthorizedShellCommand.m */,
|
||||
0395A8310D71ED7800881434 /* DBPrefsWindowController.h */,
|
||||
0395A8320D71ED7800881434 /* DBPrefsWindowController.m */,
|
||||
1DE3F8E80D50F84600052B9E /* MMPreferenceController.h */,
|
||||
1DE3F8E90D50F84600052B9E /* MMPreferenceController.m */,
|
||||
1DE9B94D0D341AB8008FEDD4 /* MMWindow.h */,
|
||||
@@ -339,6 +404,8 @@
|
||||
1D71ACB10BC702AB002F2B60 /* doc-bm-txt.icns */,
|
||||
1D71ACB20BC702AB002F2B60 /* doc-bm-xml.icns */,
|
||||
1D71ACB30BC702AB002F2B60 /* doc-bm.icns */,
|
||||
0395A8A90D72D88B00881434 /* General.png */,
|
||||
0395A9590D74D47B00881434 /* Integration.png */,
|
||||
1DD703B80BA9D15D008679E9 /* vim_gloss.icns */,
|
||||
);
|
||||
name = Icons;
|
||||
@@ -398,6 +465,7 @@
|
||||
29B97317FDCFA39411CA2CEA /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1DD3D51D0D82D4C9006E4320 /* ibeam.png */,
|
||||
1D0F11480D58C77800D5DA09 /* Font */,
|
||||
1DCE78490C460C6C006305A6 /* Icons */,
|
||||
1DE9726C0C48050600F96A9F /* Toolbar */,
|
||||
@@ -417,6 +485,8 @@
|
||||
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0395AA980D76E86200881434 /* Edit in ODBEditor */,
|
||||
0395A9C20D75D04D00881434 /* Security.framework */,
|
||||
1D493DB30C52533B00AB718C /* PSMTabBarControl.xcodeproj */,
|
||||
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
|
||||
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
|
||||
@@ -437,11 +507,13 @@
|
||||
1D0DCAD80BA3604D00B6CCFA /* CopyFiles */,
|
||||
1D9EB2840C366D7B0074B739 /* CopyFiles */,
|
||||
1DE608B80C58807F0055263D /* CopyFiles */,
|
||||
0395AA790D76E77800881434 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
1D493DCD0C5254A400AB718C /* PBXTargetDependency */,
|
||||
0395AA240D76E2F300881434 /* PBXTargetDependency */,
|
||||
);
|
||||
name = MacVim;
|
||||
productInstallPath = "$(HOME)/Applications";
|
||||
@@ -460,6 +532,10 @@
|
||||
mainGroup = 29B97314FDCFA39411CA2CEA /* MacVim */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 0395AA1A0D76E22700881434 /* Products */;
|
||||
ProjectRef = 0395AA190D76E22700881434 /* Edit in ODBEditor.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 1D493DB40C52533B00AB718C /* Products */;
|
||||
ProjectRef = 1D493DB30C52533B00AB718C /* PSMTabBarControl.xcodeproj */;
|
||||
@@ -473,6 +549,13 @@
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
0395AA210D76E22700881434 /* Edit in ODBEditor.bundle */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.cfbundle;
|
||||
path = "Edit in ODBEditor.bundle";
|
||||
remoteRef = 0395AA200D76E22700881434 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
1D493DB90C52533B00AB718C /* PSMTabBarControl.framework */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.framework;
|
||||
@@ -532,6 +615,9 @@
|
||||
1D3D19130CA690FF0004A0A5 /* DejaVuSansMono-Oblique.ttf in Resources */,
|
||||
1D3D19140CA690FF0004A0A5 /* DejaVuSansMono.ttf in Resources */,
|
||||
1DE3F8E70D50F80500052B9E /* Preferences.nib in Resources */,
|
||||
0395A8AA0D72D88B00881434 /* General.png in Resources */,
|
||||
0395A95A0D74D47B00881434 /* Integration.png in Resources */,
|
||||
1DD3D51E0D82D4C9006E4320 /* ibeam.png in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -556,12 +642,19 @@
|
||||
1D9918490D299F9900A96335 /* MMAtsuiTextView.m in Sources */,
|
||||
1DE9B9500D341AB8008FEDD4 /* MMWindow.m in Sources */,
|
||||
1DE3F8EB0D50F84600052B9E /* MMPreferenceController.m in Sources */,
|
||||
0395A8330D71ED7800881434 /* DBPrefsWindowController.m in Sources */,
|
||||
0395A9BF0D75D02400881434 /* AuthorizedShellCommand.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
0395AA240D76E2F300881434 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = "Edit in ODBEditor";
|
||||
targetProxy = 0395AA230D76E2F300881434 /* PBXContainerItemProxy */;
|
||||
};
|
||||
1D493DCD0C5254A400AB718C /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = PSMTabBarControlFramework;
|
||||
@@ -605,7 +698,7 @@
|
||||
i386,
|
||||
);
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 21;
|
||||
CURRENT_PROJECT_VERSION = 28;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
@@ -646,7 +739,7 @@
|
||||
buildSettings = {
|
||||
ARCHS = "$(NATIVE_ARCH)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 21;
|
||||
CURRENT_PROJECT_VERSION = 28;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
@@ -677,7 +770,7 @@
|
||||
buildSettings = {
|
||||
ARCHS = "$(NATIVE_ARCH)";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 21;
|
||||
CURRENT_PROJECT_VERSION = 28;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
|
||||
@@ -416,9 +416,11 @@
|
||||
0259C573FE90428111CA0C5A /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
buildConfigurationList = C056398B08A954F8003078D8 /* Build configuration list for PBXProject "PSMTabBarControl" */;
|
||||
compatibilityVersion = "Xcode 2.4";
|
||||
hasScannedForEncodings = 1;
|
||||
mainGroup = 0259C574FE90428111CA0C5A /* PSMTabBarControl */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
53DF68FC067E5B5A0090B5B0 /* PSMTabBarControlFramework */,
|
||||
53DF6901067E5B8E0090B5B0 /* All */,
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
This archive contains a snapshot of 'MacVim.app' and the shell script
|
||||
'mvim'.
|
||||
|
||||
For usage instructions, please start MacVim and type ":h macvim"
|
||||
(without the quotes).
|
||||
|
||||
MacVim requires a PPC or Intel Mac running Mac OS X 10.4 or 10.5.
|
||||
@@ -0,0 +1,328 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 42;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
17085DDA0939627C000D0081 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17085DD90939627C000D0081 /* Carbon.framework */; };
|
||||
174E80980A57DFA5003FB108 /* url map.plist in Resources */ = {isa = PBXBuildFile; fileRef = 174E80970A57DFA5003FB108 /* url map.plist */; };
|
||||
1796636A093A122C00138851 /* Edit in ODBEditor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 17966367093A122C00138851 /* Edit in ODBEditor.mm */; };
|
||||
1796636B093A122C00138851 /* NSTextView: Edit in ODBEditor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 17966368093A122C00138851 /* NSTextView: Edit in ODBEditor.mm */; };
|
||||
1796636C093A122C00138851 /* WebView: Edit in ODBEditor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 17966369093A122C00138851 /* WebView: Edit in ODBEditor.mm */; };
|
||||
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
|
||||
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
|
||||
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
|
||||
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
|
||||
17085DD90939627C000D0081 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
|
||||
174E80970A57DFA5003FB108 /* url map.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = "url map.plist"; sourceTree = "<group>"; };
|
||||
17966367093A122C00138851 /* Edit in ODBEditor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "Edit in ODBEditor.mm"; path = "src/Edit in ODBEditor.mm"; sourceTree = "<group>"; };
|
||||
17966368093A122C00138851 /* NSTextView: Edit in ODBEditor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "NSTextView: Edit in ODBEditor.mm"; path = "src/NSTextView: Edit in ODBEditor.mm"; sourceTree = "<group>"; };
|
||||
17966369093A122C00138851 /* WebView: Edit in ODBEditor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "WebView: Edit in ODBEditor.mm"; path = "src/WebView: Edit in ODBEditor.mm"; sourceTree = "<group>"; };
|
||||
32DBCF630370AF2F00C91783 /* Edit in ODBEditor_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Edit in ODBEditor_Prefix.pch"; sourceTree = "<group>"; };
|
||||
8D5B49B6048680CD000E48DA /* Edit in ODBEditor.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Edit in ODBEditor.bundle"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
8D5B49B3048680CD000E48DA /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */,
|
||||
17085DDA0939627C000D0081 /* Carbon.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
089C166AFE841209C02AAC07 /* Edit in TextMate */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
08FB77AFFE84173DC02AAC07 /* Classes */,
|
||||
32C88E010371C26100C91783 /* Other Sources */,
|
||||
089C167CFE841241C02AAC07 /* Resources */,
|
||||
089C1671FE841209C02AAC07 /* Frameworks and Libraries */,
|
||||
19C28FB8FE9D52D311CA2CBB /* Products */,
|
||||
);
|
||||
name = "Edit in TextMate";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
17085DD90939627C000D0081 /* Carbon.framework */,
|
||||
1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */,
|
||||
1058C7AEFEA557BF11CA2CBB /* Other Frameworks */,
|
||||
);
|
||||
name = "Frameworks and Libraries";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
089C167CFE841241C02AAC07 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
174E80970A57DFA5003FB108 /* url map.plist */,
|
||||
8D5B49B7048680CD000E48DA /* Info.plist */,
|
||||
089C167DFE841241C02AAC07 /* InfoPlist.strings */,
|
||||
);
|
||||
name = Resources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
08FB77AFFE84173DC02AAC07 /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
17966367093A122C00138851 /* Edit in ODBEditor.mm */,
|
||||
17966368093A122C00138851 /* NSTextView: Edit in ODBEditor.mm */,
|
||||
17966369093A122C00138851 /* WebView: Edit in ODBEditor.mm */,
|
||||
);
|
||||
name = Classes;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */,
|
||||
);
|
||||
name = "Linked Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
089C167FFE841241C02AAC07 /* AppKit.framework */,
|
||||
D2F7E65807B2D6F200F64583 /* CoreData.framework */,
|
||||
089C1672FE841209C02AAC07 /* Foundation.framework */,
|
||||
);
|
||||
name = "Other Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
19C28FB8FE9D52D311CA2CBB /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8D5B49B6048680CD000E48DA /* Edit in ODBEditor.bundle */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
32C88E010371C26100C91783 /* Other Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
32DBCF630370AF2F00C91783 /* Edit in ODBEditor_Prefix.pch */,
|
||||
);
|
||||
name = "Other Sources";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
8D5B49AC048680CD000E48DA /* Edit in ODBEditor */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "Edit in ODBEditor" */;
|
||||
buildPhases = (
|
||||
8D5B49AF048680CD000E48DA /* Resources */,
|
||||
8D5B49B1048680CD000E48DA /* Sources */,
|
||||
8D5B49B3048680CD000E48DA /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "Edit in ODBEditor";
|
||||
productInstallPath = "$(HOME)/Library/Bundles";
|
||||
productName = "Edit in TextMate";
|
||||
productReference = 8D5B49B6048680CD000E48DA /* Edit in ODBEditor.bundle */;
|
||||
productType = "com.apple.product-type.bundle";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
089C1669FE841209C02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "Edit in ODBEditor" */;
|
||||
compatibilityVersion = "Xcode 2.4";
|
||||
hasScannedForEncodings = 1;
|
||||
mainGroup = 089C166AFE841209C02AAC07 /* Edit in TextMate */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
8D5B49AC048680CD000E48DA /* Edit in ODBEditor */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
8D5B49AF048680CD000E48DA /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */,
|
||||
174E80980A57DFA5003FB108 /* url map.plist in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
8D5B49B1048680CD000E48DA /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1796636A093A122C00138851 /* Edit in ODBEditor.mm in Sources */,
|
||||
1796636B093A122C00138851 /* NSTextView: Edit in ODBEditor.mm in Sources */,
|
||||
1796636C093A122C00138851 /* WebView: Edit in ODBEditor.mm in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
089C167DFE841241C02AAC07 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
089C167EFE841241C02AAC07 /* English */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
1DD3D5530D82D8D7006E4320 /* Universal */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
i386,
|
||||
);
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "Edit in ODBEditor_Prefix.pch";
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = "";
|
||||
OTHER_LDFLAGS = (
|
||||
"-undefined",
|
||||
dynamic_lookup,
|
||||
);
|
||||
PRODUCT_NAME = "Edit in ODBEditor";
|
||||
SYMROOT = ../build;
|
||||
WRAPPER_EXTENSION = bundle;
|
||||
};
|
||||
name = Universal;
|
||||
};
|
||||
1DD3D5540D82D8D7006E4320 /* Universal */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_ENABLE_CPP_EXCEPTIONS = NO;
|
||||
GCC_ENABLE_CPP_RTTI = NO;
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
};
|
||||
name = Universal;
|
||||
};
|
||||
1DEB913B08733D840010E9CD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "Edit in ODBEditor_Prefix.pch";
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = "";
|
||||
OTHER_LDFLAGS = (
|
||||
"-undefined",
|
||||
dynamic_lookup,
|
||||
);
|
||||
PRODUCT_NAME = "Edit in ODBEditor";
|
||||
SYMROOT = ../build;
|
||||
WRAPPER_EXTENSION = bundle;
|
||||
ZERO_LINK = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1DEB913C08733D840010E9CD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "Edit in ODBEditor_Prefix.pch";
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = "";
|
||||
OTHER_LDFLAGS = (
|
||||
"-undefined",
|
||||
dynamic_lookup,
|
||||
);
|
||||
PRODUCT_NAME = "Edit in ODBEditor";
|
||||
SYMROOT = ../build;
|
||||
WRAPPER_EXTENSION = bundle;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
1DEB913F08733D840010E9CD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_ENABLE_CPP_EXCEPTIONS = NO;
|
||||
GCC_ENABLE_CPP_RTTI = NO;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1DEB914008733D840010E9CD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_ENABLE_CPP_EXCEPTIONS = NO;
|
||||
GCC_ENABLE_CPP_RTTI = NO;
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "Edit in ODBEditor" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1DEB913B08733D840010E9CD /* Debug */,
|
||||
1DEB913C08733D840010E9CD /* Release */,
|
||||
1DD3D5530D82D8D7006E4320 /* Universal */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "Edit in ODBEditor" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1DEB913F08733D840010E9CD /* Debug */,
|
||||
1DEB914008733D840010E9CD /* Release */,
|
||||
1DD3D5540D82D8D7006E4320 /* Universal */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 089C1669FE841209C02AAC07 /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
//
|
||||
// Prefix header for all source files of the 'Edit in ODBEditor' target in the 'Edit in ODBEditor' project.
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,17 @@
|
||||
<?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>BundleName</key>
|
||||
<string>Edit in ODBEditor.bundle</string>
|
||||
<key>LoadBundleOnLaunch</key>
|
||||
<string>YES</string>
|
||||
<key>LocalizedNames</key>
|
||||
<dict>
|
||||
<key>English</key>
|
||||
<string>Edit in ODBEditor</string>
|
||||
</dict>
|
||||
<key>NoMenuEntry</key>
|
||||
<string>YES</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?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>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.slashpunt.edit_in_odbeditor</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.2</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>EditInODBEditor</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,2 @@
|
||||
all:
|
||||
xcodebuild
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Edit in ODBEditor.h
|
||||
//
|
||||
// Created by Allan Odgaard on 2005-11-26.
|
||||
// See LICENSE for license details
|
||||
//
|
||||
// Generalized by Chris Eidhof and Eelco Lempsink from 'Edit in TextMate.h'
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface EditInODBEditor : NSObject
|
||||
{
|
||||
}
|
||||
+ (void)externalEditString:(NSString*)aString startingAtLine:(int)aLine forView:(NSView*)aView;
|
||||
+ (void)externalEditString:(NSString*)aString startingAtLine:(int)aLine forView:(NSView*)aView withObject:(NSObject*)anObject;
|
||||
@end
|
||||
@@ -0,0 +1,287 @@
|
||||
//
|
||||
// Edit in ODBEditor.mm
|
||||
//
|
||||
// Created by Allan Odgaard on 2005-11-26.
|
||||
// See LICENSE for license details
|
||||
//
|
||||
// Generalized by Chris Eidhof and Eelco Lempsink from 'Edit in TextMate.mm'
|
||||
|
||||
#import <WebKit/WebKit.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
#import <map>
|
||||
#import "Edit in ODBEditor.h"
|
||||
|
||||
// from ODBEditorSuite.h
|
||||
#define keyFileSender 'FSnd'
|
||||
#define kODBEditorSuite 'R*ch'
|
||||
#define kAEModifiedFile 'FMod'
|
||||
#define kAEClosedFile 'FCls'
|
||||
|
||||
static NSMutableDictionary* OpenFiles;
|
||||
static NSMutableSet* FailedFiles;
|
||||
static NSString* ODBEditorBundleIdentifier;
|
||||
static NSString* ODBEditorName;
|
||||
|
||||
#pragma options align=mac68k
|
||||
struct PBX_SelectionRange
|
||||
{
|
||||
short unused1; // 0 (not used)
|
||||
short lineNum; // line to select (<0 to specify range)
|
||||
long startRange; // start of selection range (if line < 0)
|
||||
long endRange; // end of selection range (if line < 0)
|
||||
long unused2; // 0 (not used)
|
||||
long theDate; // modification date/time
|
||||
};
|
||||
#pragma options align=reset
|
||||
|
||||
@implementation EditInODBEditor
|
||||
+ (void)setODBEventHandlers
|
||||
{
|
||||
NSAppleEventManager* eventManager = [NSAppleEventManager sharedAppleEventManager];
|
||||
[eventManager setEventHandler:self andSelector:@selector(handleModifiedFileEvent:withReplyEvent:) forEventClass:kODBEditorSuite andEventID:kAEModifiedFile];
|
||||
[eventManager setEventHandler:self andSelector:@selector(handleClosedFileEvent:withReplyEvent:) forEventClass:kODBEditorSuite andEventID:kAEClosedFile];
|
||||
}
|
||||
|
||||
+ (void)removeODBEventHandlers
|
||||
{
|
||||
NSAppleEventManager* eventManager = [NSAppleEventManager sharedAppleEventManager];
|
||||
[eventManager removeEventHandlerForEventClass:kODBEditorSuite andEventID:kAEModifiedFile];
|
||||
[eventManager removeEventHandlerForEventClass:kODBEditorSuite andEventID:kAEClosedFile];
|
||||
}
|
||||
|
||||
+ (BOOL)launchODBEditor
|
||||
{
|
||||
NSArray* array = [[NSWorkspace sharedWorkspace] launchedApplications];
|
||||
for(unsigned i = [array count]; --i; )
|
||||
{
|
||||
if([[[array objectAtIndex:i] objectForKey:@"NSApplicationBundleIdentifier"] isEqualToString:ODBEditorBundleIdentifier])
|
||||
return YES;
|
||||
}
|
||||
return [[NSWorkspace sharedWorkspace] launchAppWithBundleIdentifier:ODBEditorBundleIdentifier options:0L additionalEventParamDescriptor:nil launchIdentifier:nil];
|
||||
}
|
||||
|
||||
+ (void)asyncEditStringWithOptions:(NSDictionary*)someOptions
|
||||
{
|
||||
NSAutoreleasePool* pool = [NSAutoreleasePool new];
|
||||
|
||||
if(![self launchODBEditor])
|
||||
return;
|
||||
|
||||
/* =========== */
|
||||
|
||||
NSData* targetBundleID = [ODBEditorBundleIdentifier dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSAppleEventDescriptor* targetDescriptor = [NSAppleEventDescriptor descriptorWithDescriptorType:typeApplicationBundleID data:targetBundleID];
|
||||
NSAppleEventDescriptor* appleEvent = [NSAppleEventDescriptor appleEventWithEventClass:kCoreEventClass eventID:kAEOpenDocuments targetDescriptor:targetDescriptor returnID:kAutoGenerateReturnID transactionID:kAnyTransactionID];
|
||||
NSAppleEventDescriptor* replyDescriptor = nil;
|
||||
NSAppleEventDescriptor* errorDescriptor = nil;
|
||||
AEDesc reply = { typeNull, NULL };
|
||||
|
||||
NSString* fileName = [someOptions objectForKey:@"fileName"];
|
||||
[appleEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithDescriptorType:typeFileURL data:[[[NSURL fileURLWithPath:fileName] absoluteString] dataUsingEncoding:NSUTF8StringEncoding]] forKeyword:keyDirectObject];
|
||||
|
||||
UInt32 packageType = 0, packageCreator = 0;
|
||||
CFBundleGetPackageInfo(CFBundleGetMainBundle(), &packageType, &packageCreator);
|
||||
[appleEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithTypeCode:packageCreator] forKeyword:keyFileSender];
|
||||
|
||||
if(int line = [[someOptions objectForKey:@"line"] intValue])
|
||||
{
|
||||
PBX_SelectionRange pos = { };
|
||||
pos.lineNum = line;
|
||||
[appleEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithDescriptorType:typeChar bytes:&pos length:sizeof(pos)] forKeyword:keyAEPosition];
|
||||
}
|
||||
|
||||
OSStatus status = AESend([appleEvent aeDesc], &reply, kAEWaitReply, kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
|
||||
if(status == noErr)
|
||||
{
|
||||
replyDescriptor = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&reply] autorelease];
|
||||
errorDescriptor = [replyDescriptor paramDescriptorForKeyword:keyErrorNumber];
|
||||
if(errorDescriptor != nil)
|
||||
status = [errorDescriptor int32Value];
|
||||
|
||||
if(status != noErr)
|
||||
NSLog(@"%s error %d", _cmd, status), NSBeep();
|
||||
}
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
+ (NSString*)extensionForURL:(NSURL*)anURL
|
||||
{
|
||||
NSString* res = nil;
|
||||
if(NSString* urlString = [anURL absoluteString])
|
||||
{
|
||||
NSString* path = [[NSBundle bundleForClass:[self class]] pathForResource:@"url map" ofType:@"plist"];
|
||||
NSMutableDictionary* map = [NSMutableDictionary dictionaryWithContentsOfFile:path];
|
||||
|
||||
NSString* customBindingsPath = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"Preferences/org.slashpunt.edit_in_odbeditor.plist"];
|
||||
if(NSDictionary* associations = [[NSDictionary dictionaryWithContentsOfFile:customBindingsPath] objectForKey:@"URLAssociations"])
|
||||
[map addEntriesFromDictionary:associations];
|
||||
|
||||
unsigned longestMatch = 0;
|
||||
NSEnumerator* enumerator = [map keyEnumerator];
|
||||
while(NSString* key = [enumerator nextObject])
|
||||
{
|
||||
if([urlString rangeOfString:key].location != NSNotFound && [key length] > longestMatch)
|
||||
{
|
||||
res = [map objectForKey:key];
|
||||
longestMatch = [key length];
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
+ (void)externalEditString:(NSString*)aString startingAtLine:(int)aLine forView:(NSView*)aView
|
||||
{
|
||||
[self externalEditString:aString startingAtLine:aLine forView:aView withObject:nil];
|
||||
}
|
||||
|
||||
+ (void)externalEditString:(NSString*)aString startingAtLine:(int)aLine forView:(NSView*)aView withObject:(NSObject*)anObject
|
||||
{
|
||||
Class cl = NSClassFromString(@"WebFrameView");
|
||||
|
||||
NSURL* url = nil;
|
||||
for(NSView* view = aView; view && !url && cl; view = [view superview])
|
||||
{
|
||||
if([view isKindOfClass:cl])
|
||||
url = [[[[(WebFrameView*)view webFrame] dataSource] mainResource] URL];
|
||||
}
|
||||
|
||||
NSString* basename = [[[[aView window] title] componentsSeparatedByString:@"/"] componentsJoinedByString:@"-"] ?: @"untitled";
|
||||
NSString* extension = [self extensionForURL:url] ?: [[[[NSWorkspace sharedWorkspace] activeApplication] objectForKey:@"NSApplicationName"] lowercaseString];
|
||||
NSString* fileName = [NSString stringWithFormat:@"%@/%@.%@", NSTemporaryDirectory(), basename, extension];
|
||||
for(unsigned i = 2; [[NSFileManager defaultManager] fileExistsAtPath:fileName]; i++)
|
||||
fileName = [NSString stringWithFormat:@"%@/%@ %u.%@", NSTemporaryDirectory(), basename, i, extension];
|
||||
|
||||
[[aString dataUsingEncoding:NSUTF8StringEncoding] writeToFile:fileName atomically:NO];
|
||||
fileName = [fileName stringByStandardizingPath];
|
||||
|
||||
NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
aString, @"string",
|
||||
aView, @"view",
|
||||
fileName, @"fileName",
|
||||
[NSNumber numberWithInt:aLine], @"line",
|
||||
anObject, @"object", /* last since anObject might be nil */
|
||||
nil];
|
||||
|
||||
[OpenFiles setObject:options forKey:[fileName precomposedStringWithCanonicalMapping]];
|
||||
if([OpenFiles count] == 1)
|
||||
[self setODBEventHandlers];
|
||||
[NSThread detachNewThreadSelector:@selector(asyncEditStringWithOptions:) toTarget:self withObject:options];
|
||||
}
|
||||
|
||||
+ (void)handleModifiedFileEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
|
||||
{
|
||||
NSAppleEventDescriptor* fileURL = [[event paramDescriptorForKeyword:keyDirectObject] coerceToDescriptorType:typeFileURL];
|
||||
NSString* urlString = [[[NSString alloc] initWithData:[fileURL data] encoding:NSUTF8StringEncoding] autorelease];
|
||||
NSString* fileName = [[[NSURL URLWithString:urlString] path] stringByStandardizingPath];
|
||||
NSDictionary* options = [OpenFiles objectForKey:[fileName precomposedStringWithCanonicalMapping]];
|
||||
NSView* view = [options objectForKey:@"view"];
|
||||
|
||||
if([view window])
|
||||
{
|
||||
if ([view respondsToSelector:@selector(odbEditorDidModifyString:withObject:)])
|
||||
{
|
||||
NSString* newString = [[[NSString alloc] initWithData:[NSData dataWithContentsOfFile:fileName] encoding:NSUTF8StringEncoding] autorelease];
|
||||
NSObject* anObject = [options objectForKey:@"object"];
|
||||
[view performSelector:@selector(odbEditorDidModifyString:withObject:) withObject:newString withObject:anObject];
|
||||
[FailedFiles removeObject:fileName];
|
||||
fileName = nil;
|
||||
}
|
||||
else if([view respondsToSelector:@selector(odbEditorDidModifyString:)])
|
||||
{
|
||||
NSString* newString = [[[NSString alloc] initWithData:[NSData dataWithContentsOfFile:fileName] encoding:NSUTF8StringEncoding] autorelease];
|
||||
[view performSelector:@selector(odbEditorDidModifyString:) withObject:newString];
|
||||
[FailedFiles removeObject:fileName];
|
||||
fileName = nil;
|
||||
}
|
||||
}
|
||||
if (fileName)
|
||||
{
|
||||
[FailedFiles addObject:fileName];
|
||||
NSLog(@"%s view %p, %@, window %@", _cmd, view, view, [view window]);
|
||||
NSLog(@"%s file name %@, options %@", _cmd, fileName, [options description]);
|
||||
NSLog(@"%s all %@", _cmd, [OpenFiles description]);
|
||||
NSBeep();
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)handleClosedFileEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
|
||||
{
|
||||
NSAppleEventDescriptor* fileURL = [[event paramDescriptorForKeyword:keyDirectObject] coerceToDescriptorType:typeFileURL];
|
||||
NSString* urlString = [[[NSString alloc] initWithData:[fileURL data] encoding:NSUTF8StringEncoding] autorelease];
|
||||
NSString* fileName = [[[NSURL URLWithString:urlString] path] stringByStandardizingPath];
|
||||
|
||||
if([FailedFiles containsObject:fileName])
|
||||
{
|
||||
if([[NSFileManager defaultManager] fileExistsAtPath:fileName])
|
||||
[[NSWorkspace sharedWorkspace] selectFile:fileName inFileViewerRootedAtPath:[fileName stringByDeletingLastPathComponent]];
|
||||
[FailedFiles removeObject:fileName];
|
||||
}
|
||||
else
|
||||
{
|
||||
[[NSFileManager defaultManager] removeFileAtPath:fileName handler:nil];
|
||||
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
|
||||
}
|
||||
|
||||
[OpenFiles removeObjectForKey:[fileName precomposedStringWithCanonicalMapping]];
|
||||
if([OpenFiles count] == 0)
|
||||
[self removeODBEventHandlers];
|
||||
}
|
||||
|
||||
+ (NSMenu*)findEditMenu
|
||||
{
|
||||
NSMenu* mainMenu = [NSApp mainMenu];
|
||||
std::map<size_t, NSMenu*> ranked;
|
||||
for(int i = 0; i != [mainMenu numberOfItems]; i++)
|
||||
{
|
||||
NSMenu* candidate = [[mainMenu itemAtIndex:i] submenu];
|
||||
static SEL const actions[] = { @selector(undo:), @selector(redo:), @selector(cut:), @selector(copy:), @selector(paste:), @selector(delete:), @selector(selectAll:) };
|
||||
size_t score = 0;
|
||||
for(int j = 0; j != sizeof(actions)/sizeof(actions[0]); j++)
|
||||
{
|
||||
if(-1 != [candidate indexOfItemWithTarget:nil andAction:actions[j]])
|
||||
score++;
|
||||
}
|
||||
|
||||
if(score > 0 && ranked.find(score) == ranked.end())
|
||||
ranked[score] = candidate;
|
||||
}
|
||||
return ranked.empty() ? nil : (--ranked.end())->second;
|
||||
}
|
||||
|
||||
+ (void)installMenuItem:(id)sender
|
||||
{
|
||||
if(NSMenu* editMenu = [self findEditMenu])
|
||||
{
|
||||
[editMenu addItem:[NSMenuItem separatorItem]];
|
||||
NSString* ellips = [NSString stringWithUTF8String:"\xe2\x80\xa6"]; // utf-8 for the '...' character (literal utf8 is not allowed in source code)
|
||||
id <NSMenuItem> menuItem = [editMenu addItemWithTitle:[NSString stringWithFormat:@"Edit in %@%@", ODBEditorName, ellips] action:@selector(editInODBEditor:) keyEquivalent:@"E"];
|
||||
[menuItem setKeyEquivalentModifierMask:NSControlKeyMask | NSCommandKeyMask];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)load
|
||||
{
|
||||
OpenFiles = [NSMutableDictionary new];
|
||||
FailedFiles = [NSMutableSet new];
|
||||
NSString* mainBundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; // reads app we're used inside off
|
||||
NSString* bundleIdentifier = @"org.slashpunt.edit_in_odbeditor"; // XXX Should this be hardcoded?
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults addSuiteNamed:bundleIdentifier];
|
||||
NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"NO", @"DisableEditInODBEditorMenuItem",
|
||||
@"", @"ODBEditorBundleIdentifier",
|
||||
@"<Unknown>", @"ODBEditorName",
|
||||
nil];
|
||||
|
||||
[defaults registerDefaults:appDefaults];
|
||||
|
||||
ODBEditorBundleIdentifier = [[defaults stringForKey:@"ODBEditorBundleIdentifier"] retain] ?: @"";
|
||||
ODBEditorName = [[defaults stringForKey:@"ODBEditorName"] retain] ?: @"<Unknown>";
|
||||
if([defaults boolForKey:@"DisableEditInODBEditorMenuItem"] == NO
|
||||
&& ![ODBEditorBundleIdentifier isEqualToString:@""]
|
||||
&& ![ODBEditorBundleIdentifier isEqualToString:mainBundleIdentifier])
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(installMenuItem:) name:NSApplicationDidFinishLaunchingNotification object:[NSApplication sharedApplication]];
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// NSTextView: Edit in ODBEditor.mm
|
||||
//
|
||||
// Created by Allan Odgaard on 2005-11-27.
|
||||
// See LICENSE for license details
|
||||
//
|
||||
// Generalized by Chris Eidhof and Eelco Lempsink from 'NSTextView: Edit in TextMate.mm'
|
||||
|
||||
#import "Edit in ODBEditor.h"
|
||||
|
||||
@interface NSTextView (EditInODBEditor)
|
||||
- (void)editInODBEditor:(id)sender;
|
||||
@end
|
||||
|
||||
@implementation NSTextView (EditInODBEditor)
|
||||
- (void)editInODBEditor:(id)sender
|
||||
{
|
||||
if(![self isEditable])
|
||||
return (void)NSBeep();
|
||||
|
||||
NSString* str = [[self textStorage] string];
|
||||
NSRange selectedRange = [self selectedRange];
|
||||
int lineNumber = 0;
|
||||
if(selectedRange.length == 0)
|
||||
{
|
||||
NSRange range = NSMakeRange(0, 0);
|
||||
do {
|
||||
NSRange oldRange = range;
|
||||
range = [str lineRangeForRange:NSMakeRange(NSMaxRange(range), 0)];
|
||||
if(NSMaxRange(oldRange) == NSMaxRange(range) || selectedRange.location < NSMaxRange(range))
|
||||
break;
|
||||
lineNumber++;
|
||||
} while(true);
|
||||
selectedRange = NSMakeRange(0, [str length]);
|
||||
}
|
||||
|
||||
[EditInODBEditor externalEditString:[str substringWithRange:selectedRange] startingAtLine:lineNumber forView:self];
|
||||
}
|
||||
|
||||
- (void)odbEditorDidModifyString:(NSString*)newString
|
||||
{
|
||||
NSRange selectedRange = [self selectedRange];
|
||||
BOOL hadSelection = selectedRange.length != 0;
|
||||
selectedRange = hadSelection ? selectedRange : NSMakeRange(0, [[self textStorage] length]);
|
||||
if([self shouldChangeTextInRange:selectedRange replacementString:newString])
|
||||
{
|
||||
if(!hadSelection)
|
||||
[self setSelectedRange:NSMakeRange(0, [[self textStorage] length])];
|
||||
[self insertText:newString];
|
||||
if(hadSelection)
|
||||
[self setSelectedRange:NSMakeRange(selectedRange.location, [newString length])];
|
||||
[self didChangeText];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSBeep();
|
||||
NSLog(@"%s couldn't edit text", _cmd);
|
||||
}
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,410 @@
|
||||
//
|
||||
// WebView: Edit in ODBEditor.mm
|
||||
//
|
||||
// Created by Allan Odgaard on 2005-11-27.
|
||||
// See LICENSE for license details
|
||||
//
|
||||
// Generalized by Chris Eidhof and Eelco Lempsink from 'WebView: Edit in TextMate.mm'
|
||||
|
||||
|
||||
#import <WebKit/WebKit.h>
|
||||
#import <vector>
|
||||
#import "Edit in ODBEditor.h"
|
||||
|
||||
#ifndef sizeofA
|
||||
#define sizeofA(x) (sizeof(x)/sizeof(x[0]))
|
||||
#endif
|
||||
|
||||
// only latest WebKit has this stuff, and it is private
|
||||
@interface DOMHTMLTextAreaElement (DOMHTMLTextAreaElementPrivate)
|
||||
- (int)selectionStart;
|
||||
- (void)setSelectionStart:(int)newSelectionStart;
|
||||
- (int)selectionEnd;
|
||||
- (void)setSelectionEnd:(int)newSelectionEnd;
|
||||
- (void)setSelectionRange:(int)start end:(int)end;
|
||||
@end
|
||||
|
||||
@interface WebView (EditInODBEditor)
|
||||
- (void)editInODBEditor:(id)sender;
|
||||
@end
|
||||
|
||||
@interface NSString (EditInODBEditor)
|
||||
- (NSString*)ODB_stringByTrimmingWhitespace;
|
||||
- (NSString*)ODB_stringByReplacingString:(NSString*)aSearchString withString:(NSString*)aReplaceString;
|
||||
- (NSString*)ODB_stringByNbspEscapingSpaces;
|
||||
@end
|
||||
|
||||
@implementation NSString (EditInODBEditor)
|
||||
- (NSString*)ODB_stringByTrimmingWhitespace
|
||||
{
|
||||
NSString* str = self;
|
||||
while([str hasPrefix:@" "])
|
||||
str = [str substringFromIndex:1];
|
||||
|
||||
while([str hasSuffix:@" "])
|
||||
str = [str substringToIndex:[str length]-1];
|
||||
return str;
|
||||
}
|
||||
|
||||
- (NSString*)ODB_stringByReplacingString:(NSString*)aSearchString withString:(NSString*)aReplaceString
|
||||
{
|
||||
return [[self componentsSeparatedByString:aSearchString] componentsJoinedByString:aReplaceString];
|
||||
}
|
||||
|
||||
- (NSString*)ODB_stringByNbspEscapingSpaces
|
||||
{
|
||||
unsigned len = [self length];
|
||||
unichar* buf = new unichar[len];
|
||||
[self getCharacters:buf];
|
||||
for(unsigned i = 0; i != len; i++)
|
||||
{
|
||||
if(buf[i] == ' ' && (i+1 == len || buf[i+1] == ' '))
|
||||
buf[i] = 0xA0;
|
||||
}
|
||||
return [NSString stringWithCharacters:buf length:len];
|
||||
}
|
||||
@end
|
||||
|
||||
struct convert_dom_to_text
|
||||
{
|
||||
convert_dom_to_text (DOMTreeWalker* treeWalker) : string([NSMutableString new]), quoteLevel(0), pendingFlush(NO), pendingWhitespace(NO), didOutputText(NO), atBeginOfLine(YES) { visit_nodes(treeWalker); }
|
||||
~convert_dom_to_text () { [string autorelease]; }
|
||||
operator NSString* () const { return string; }
|
||||
|
||||
private:
|
||||
void enter_block_tag ()
|
||||
{
|
||||
pendingFlush |= didOutputText;
|
||||
didOutputText = NO;
|
||||
pendingWhitespace = NO;
|
||||
}
|
||||
|
||||
void leave_block_tag ()
|
||||
{
|
||||
pendingFlush |= didOutputText;
|
||||
didOutputText = NO;
|
||||
pendingWhitespace = NO;
|
||||
}
|
||||
|
||||
void output_text (NSString* str)
|
||||
{
|
||||
if([str isEqualToString:@""])
|
||||
return;
|
||||
|
||||
str = [str ODB_stringByTrimmingWhitespace];
|
||||
if([str isEqualToString:@""])
|
||||
{
|
||||
pendingWhitespace = YES;
|
||||
return;
|
||||
}
|
||||
|
||||
str = [str ODB_stringByReplacingString:[NSString stringWithUTF8String:" "] withString:@" "];
|
||||
|
||||
if(pendingFlush)
|
||||
{
|
||||
[string appendString:@"\n"];
|
||||
pendingFlush = NO;
|
||||
atBeginOfLine = YES;
|
||||
}
|
||||
|
||||
if(atBeginOfLine && quoteLevel)
|
||||
{
|
||||
for(unsigned i = 0; i < quoteLevel; i++)
|
||||
[string appendString:@"> "];
|
||||
}
|
||||
else if(!atBeginOfLine && pendingWhitespace)
|
||||
{
|
||||
[string appendString:@" "];
|
||||
}
|
||||
|
||||
[string appendString:str];
|
||||
atBeginOfLine = NO;
|
||||
didOutputText = YES;
|
||||
pendingWhitespace = NO;
|
||||
}
|
||||
|
||||
void visit_nodes (DOMTreeWalker* treeWalker);
|
||||
|
||||
NSMutableString* string;
|
||||
unsigned quoteLevel;
|
||||
BOOL pendingFlush;
|
||||
BOOL pendingWhitespace;
|
||||
BOOL didOutputText;
|
||||
BOOL atBeginOfLine;
|
||||
};
|
||||
|
||||
struct helper
|
||||
{
|
||||
helper (DOMHTMLTextAreaElement* textArea) : textArea(textArea)
|
||||
{
|
||||
value = [textArea value];
|
||||
selectionStart = [textArea selectionStart];
|
||||
selectionEnd = [textArea selectionEnd];
|
||||
}
|
||||
|
||||
helper () : textArea(nil), value(nil) { }
|
||||
bool should_change () const { return selectionStart != 0 || selectionEnd != [value length]; }
|
||||
bool did_change () const { return selectionStart != [textArea selectionStart] || selectionEnd != [textArea selectionEnd]; }
|
||||
void reset () const
|
||||
{
|
||||
if([textArea value] != value) [textArea setValue:value];
|
||||
if(did_change()) [textArea setSelectionRange:selectionStart end:selectionEnd];
|
||||
}
|
||||
|
||||
static bool usable (DOMNode* node)
|
||||
{
|
||||
static SEL const selectors[] = { @selector(selectionStart), @selector(selectionEnd), @selector(setSelectionStart:), @selector(setSelectionEnd:), @selector(value), @selector(setValue:), @selector(setSelectionRange:end:) };
|
||||
BOOL res = [node isKindOfClass:[DOMHTMLTextAreaElement class]] && ![(DOMHTMLTextAreaElement*)node disabled] && ![(DOMHTMLTextAreaElement*)node readOnly];
|
||||
for(size_t i = 0; i < sizeofA(selectors); ++i)
|
||||
res = res && [node respondsToSelector:selectors[i]];
|
||||
return res;
|
||||
}
|
||||
|
||||
DOMHTMLTextAreaElement* textArea;
|
||||
NSString* value;
|
||||
unsigned long selectionStart;
|
||||
unsigned long selectionEnd;
|
||||
};
|
||||
|
||||
void convert_dom_to_text::visit_nodes (DOMTreeWalker* treeWalker)
|
||||
{
|
||||
for(DOMNode* node = [treeWalker currentNode]; node; node = [treeWalker nextSibling])
|
||||
{
|
||||
if([node nodeType] == DOM_TEXT_NODE)
|
||||
output_text([node nodeValue]);
|
||||
else if([[[node nodeName] uppercaseString] isEqualToString:@"BR"])
|
||||
output_text(@"\n"), (atBeginOfLine = YES), (didOutputText = NO);
|
||||
else if([[[node nodeName] uppercaseString] isEqualToString:@"DIV"])
|
||||
enter_block_tag();
|
||||
else if([[[node nodeName] uppercaseString] isEqualToString:@"BLOCKQUOTE"])
|
||||
enter_block_tag(), ++quoteLevel;
|
||||
else if([[[node nodeName] uppercaseString] isEqualToString:@"P"])
|
||||
enter_block_tag();
|
||||
|
||||
if([treeWalker firstChild])
|
||||
{
|
||||
visit_nodes(treeWalker);
|
||||
[treeWalker parentNode];
|
||||
}
|
||||
|
||||
if([[[node nodeName] uppercaseString] isEqualToString:@"DIV"])
|
||||
leave_block_tag();
|
||||
else if([[[node nodeName] uppercaseString] isEqualToString:@"BLOCKQUOTE"])
|
||||
leave_block_tag(), --quoteLevel;
|
||||
else if([[[node nodeName] uppercaseString] isEqualToString:@"P"])
|
||||
leave_block_tag();
|
||||
}
|
||||
}
|
||||
|
||||
static DOMHTMLTextAreaElement* find_active_text_area_for_frame (WebFrame* frame)
|
||||
{
|
||||
DOMHTMLTextAreaElement* res = nil;
|
||||
DOMDocument* doc = [frame DOMDocument];
|
||||
if([doc respondsToSelector:@selector(focusNode)])
|
||||
{
|
||||
// OmniWeb 5.6 has a method to get the focused node
|
||||
res = [doc performSelector:@selector(focusNode)];
|
||||
if(!helper::usable(res))
|
||||
res = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The following is a heuristic for finding the active text area:
|
||||
//
|
||||
// 1. If there is just one text area, we use that.
|
||||
//
|
||||
// 2. If there are multiple, we ask the web view to “select all”
|
||||
// which goes to the active text area (hopefully) and then we
|
||||
// check which of the text areas in the DOM actually changed.
|
||||
//
|
||||
// There is a problem if either a text area has no content (in
|
||||
// which case select all makes no changes) or if everything is
|
||||
// already selected. If only one text area is in the state of
|
||||
// “select all would not affect it” and no text areas were
|
||||
// changed, we assume the one with that state is the active.
|
||||
|
||||
std::vector<helper> v;
|
||||
DOMNodeList* textAreas = [doc getElementsByTagName:@"TEXTAREA"];
|
||||
for(unsigned long i = 0; i < [textAreas length]; ++i)
|
||||
{
|
||||
if(helper::usable([textAreas item:i]))
|
||||
v.push_back((DOMHTMLTextAreaElement*)[textAreas item:i]);
|
||||
}
|
||||
|
||||
if(v.size() == 1)
|
||||
{
|
||||
res = v[0].textArea;
|
||||
}
|
||||
else if(v.size() > 1)
|
||||
{
|
||||
for(std::vector<helper>::iterator it = v.begin(); it != v.end(); ++it)
|
||||
if (!it->should_change())
|
||||
[it->textArea setValue:@" "];
|
||||
[[frame webView] selectLine:nil];
|
||||
|
||||
size_t should_change = 0, did_change = 0;
|
||||
for(std::vector<helper>::iterator it = v.begin(); it != v.end(); ++it)
|
||||
{
|
||||
did_change += it->did_change() ? 1 : 0;
|
||||
should_change += it->should_change() ? 1 : 0;
|
||||
}
|
||||
|
||||
if(did_change == 1)
|
||||
{
|
||||
for(std::vector<helper>::iterator it = v.begin(); it != v.end(); ++it)
|
||||
res = it->did_change() ? it->textArea : res;
|
||||
}
|
||||
else if(did_change == 0 && should_change == v.size()-1)
|
||||
{
|
||||
for(std::vector<helper>::iterator it = v.begin(); it != v.end(); ++it)
|
||||
res = !it->should_change() ? it->textArea : res;
|
||||
}
|
||||
|
||||
for(std::vector<helper>::iterator it = v.begin(); it != v.end(); ++it)
|
||||
it->reset();
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static DOMHTMLTextAreaElement* find_active_text_area (WebView* view)
|
||||
{
|
||||
DOMHTMLTextAreaElement* res = nil;
|
||||
if([view respondsToSelector:@selector(selectedFrame)])
|
||||
res = find_active_text_area_for_frame([view performSelector:@selector(selectedFrame)]);
|
||||
else
|
||||
{
|
||||
WebFrame* frame = [view mainFrame];
|
||||
NSArray* frames = [[NSArray arrayWithObject: frame] arrayByAddingObjectsFromArray: [frame childFrames]];
|
||||
for(unsigned i = 0; i != [frames count] && !res; i++)
|
||||
res = find_active_text_area_for_frame([frames objectAtIndex:i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@implementation WebView (EditInODBEditor)
|
||||
- (void)editInODBEditor:(id)sender
|
||||
{
|
||||
if([self isEditable])
|
||||
{
|
||||
// Mail uses an editable WebView, in which case we want to send the entire page to the ODB Editor
|
||||
|
||||
NSString* const CARET = [NSString stringWithFormat:@"%C", 0xFFFD];
|
||||
NSString* str = @"";
|
||||
int lineNumber = 0;
|
||||
|
||||
DOMDocumentFragment* selection = [[self selectedDOMRange] cloneContents];
|
||||
if(!selection)
|
||||
{
|
||||
[self insertText:CARET]; // ugly hack, but we want to preserve the position of the caret
|
||||
[self selectAll:nil];
|
||||
selection = [[self selectedDOMRange] cloneContents];
|
||||
|
||||
// remove the caret marker. TODO we should start an undo group, so the (chunked) undo doesn’t remove more than just the caret
|
||||
if(NSUndoManager* undoManager = [self undoManager])
|
||||
{
|
||||
if([undoManager canUndo])
|
||||
{
|
||||
[undoManager undo];
|
||||
[self selectAll:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(selection)
|
||||
{
|
||||
str = convert_dom_to_text([[[self mainFrame] DOMDocument] createTreeWalker:selection :DOM_SHOW_ALL :nil :YES]);
|
||||
while([str hasSuffix:@"\n\n"])
|
||||
str = [str substringToIndex:[str length]-1];
|
||||
|
||||
NSArray* split = [str componentsSeparatedByString:CARET];
|
||||
if([split count] == 2)
|
||||
{
|
||||
lineNumber = [[[split objectAtIndex:0] componentsSeparatedByString:@"\n"] count] - 1;
|
||||
str = [split componentsJoinedByString:@""];
|
||||
}
|
||||
}
|
||||
[EditInODBEditor externalEditString:str startingAtLine:lineNumber forView:self];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Likely the user wants to edit just a text area, so let’s try to find which
|
||||
if(DOMHTMLTextAreaElement* textArea = find_active_text_area(self))
|
||||
{
|
||||
NSString* str = [textArea value];
|
||||
unsigned long selectionStart = [textArea selectionStart];
|
||||
int lineNumber = 0;
|
||||
NSRange range = NSMakeRange(0, 0);
|
||||
do {
|
||||
NSRange oldRange = range;
|
||||
range = [str lineRangeForRange:NSMakeRange(NSMaxRange(range), 0)];
|
||||
if(NSMaxRange(oldRange) == NSMaxRange(range) || selectionStart < NSMaxRange(range))
|
||||
break;
|
||||
lineNumber++;
|
||||
} while(true);
|
||||
[EditInODBEditor externalEditString:str startingAtLine:lineNumber forView:self withObject:textArea];
|
||||
}
|
||||
else NSBeep();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)odbEditorDidModifyString:(NSString*)newString withObject:(NSObject*)textArea
|
||||
{
|
||||
if([self isEditable])
|
||||
{
|
||||
NSArray* lines = [newString componentsSeparatedByString:@"\n"];
|
||||
NSMutableString* res = [NSMutableString string];
|
||||
unsigned quoteLevel = 0;
|
||||
for(unsigned i = 0; i != [lines count]; i++)
|
||||
{
|
||||
NSString* line = [lines objectAtIndex:i];
|
||||
|
||||
unsigned newQuoteLevel = 0;
|
||||
while([line hasPrefix:@"> "])
|
||||
{
|
||||
line = [line substringFromIndex:2];
|
||||
newQuoteLevel++;
|
||||
}
|
||||
|
||||
if([line isEqualToString:@">"])
|
||||
{
|
||||
line = @"";
|
||||
newQuoteLevel++;
|
||||
}
|
||||
|
||||
if(newQuoteLevel > quoteLevel)
|
||||
{
|
||||
for(unsigned j = 0; j != newQuoteLevel - quoteLevel; j++)
|
||||
[res appendString:@"<BLOCKQUOTE type=\"cite\">"];
|
||||
}
|
||||
else if(newQuoteLevel < quoteLevel)
|
||||
{
|
||||
for(unsigned j = 0; j != quoteLevel - newQuoteLevel; j++)
|
||||
[res appendString:@"</BLOCKQUOTE>"];
|
||||
}
|
||||
quoteLevel = newQuoteLevel;
|
||||
|
||||
if([line isEqualToString:@""])
|
||||
{
|
||||
[res appendString:@"<DIV><BR></DIV>"];
|
||||
}
|
||||
else
|
||||
{
|
||||
line = [line ODB_stringByNbspEscapingSpaces];
|
||||
line = [line ODB_stringByReplacingString:@"&" withString:@"&"];
|
||||
line = [line ODB_stringByReplacingString:@"<" withString:@"<"];
|
||||
line = [line ODB_stringByReplacingString:@">" withString:@">"];
|
||||
[res appendFormat:@"<DIV>%@</DIV>", line];
|
||||
}
|
||||
}
|
||||
|
||||
[self replaceSelectionWithMarkupString:res];
|
||||
if(![[self selectedDOMRange] cloneContents])
|
||||
[self selectAll:nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
[(DOMHTMLTextAreaElement*)textArea setValue:newString];
|
||||
}
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
'macromates.com/blog/' = 'markdown';
|
||||
'blacktree.cocoaforge.com/forums/' = 'bbcode';
|
||||
'mail.google.com/' = 'mail';
|
||||
}
|
||||
+137
-78
@@ -32,7 +32,6 @@ static float MMMaxFontSize = 100.0f;
|
||||
|
||||
|
||||
static NSFont *gui_macvim_font_with_name(char_u *name);
|
||||
static BOOL gui_macvim_is_valid_action(NSString *action);
|
||||
|
||||
|
||||
|
||||
@@ -480,44 +479,75 @@ clip_mch_own_selection(VimClipboard *cbd)
|
||||
clip_mch_request_selection(VimClipboard *cbd)
|
||||
{
|
||||
NSPasteboard *pb = [NSPasteboard generalPasteboard];
|
||||
NSString *pbType = [pb availableTypeFromArray:
|
||||
[NSArray arrayWithObject:NSStringPboardType]];
|
||||
if (pbType) {
|
||||
NSMutableString *string =
|
||||
NSArray *supportedTypes = [NSArray arrayWithObjects:VimPBoardType,
|
||||
NSStringPboardType, nil];
|
||||
NSString *bestType = [pb availableTypeFromArray:supportedTypes];
|
||||
if (!bestType) return;
|
||||
|
||||
int motion_type = MCHAR;
|
||||
NSString *string = nil;
|
||||
|
||||
if ([bestType isEqual:VimPBoardType]) {
|
||||
// This type should consist of an array with two objects:
|
||||
// 1. motion type (NSNumber)
|
||||
// 2. text (NSString)
|
||||
// If this is not the case we fall back on using NSStringPboardType.
|
||||
id plist = [pb propertyListForType:VimPBoardType];
|
||||
if ([plist isKindOfClass:[NSArray class]] && [plist count] == 2) {
|
||||
id obj = [plist objectAtIndex:1];
|
||||
if ([obj isKindOfClass:[NSString class]]) {
|
||||
motion_type = [[plist objectAtIndex:0] intValue];
|
||||
string = obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!string) {
|
||||
// Use NSStringPboardType. The motion type is set to line-wise if the
|
||||
// string contains at least one EOL character, otherwise it is set to
|
||||
// character-wise (block-wise is never used).
|
||||
NSMutableString *mstring =
|
||||
[[pb stringForType:NSStringPboardType] mutableCopy];
|
||||
if (!mstring) return;
|
||||
|
||||
// Replace unrecognized end-of-line sequences with \x0a (line feed).
|
||||
NSRange range = { 0, [string length] };
|
||||
unsigned n = [string replaceOccurrencesOfString:@"\x0d\x0a"
|
||||
NSRange range = { 0, [mstring length] };
|
||||
unsigned n = [mstring replaceOccurrencesOfString:@"\x0d\x0a"
|
||||
withString:@"\x0a" options:0
|
||||
range:range];
|
||||
if (0 == n) {
|
||||
n = [string replaceOccurrencesOfString:@"\x0d" withString:@"\x0a"
|
||||
n = [mstring replaceOccurrencesOfString:@"\x0d" withString:@"\x0a"
|
||||
options:0 range:range];
|
||||
}
|
||||
|
||||
// Scan for newline character to decide whether the string should be
|
||||
// pasted linewise or characterwise.
|
||||
int type = MCHAR;
|
||||
if (0 < n || NSNotFound != [string rangeOfString:@"\n"].location)
|
||||
type = MLINE;
|
||||
// pasted line-wise or character-wise.
|
||||
motion_type = MCHAR;
|
||||
if (0 < n || NSNotFound != [mstring rangeOfString:@"\n"].location)
|
||||
motion_type = MLINE;
|
||||
|
||||
char_u *str = (char_u*)[string UTF8String];
|
||||
int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
if (input_conv.vc_type != CONV_NONE)
|
||||
str = string_convert(&input_conv, str, &len);
|
||||
#endif
|
||||
|
||||
if (str)
|
||||
clip_yank_selection(type, str, len, cbd);
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
if (input_conv.vc_type != CONV_NONE)
|
||||
vim_free(str);
|
||||
#endif
|
||||
string = mstring;
|
||||
}
|
||||
|
||||
if (!(MCHAR == motion_type || MLINE == motion_type || MBLOCK == motion_type
|
||||
|| MAUTO == motion_type))
|
||||
motion_type = MCHAR;
|
||||
|
||||
char_u *str = (char_u*)[string UTF8String];
|
||||
int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
if (input_conv.vc_type != CONV_NONE)
|
||||
str = string_convert(&input_conv, str, &len);
|
||||
#endif
|
||||
|
||||
if (str)
|
||||
clip_yank_selection(motion_type, str, len, cbd);
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
if (input_conv.vc_type != CONV_NONE)
|
||||
vim_free(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -534,8 +564,8 @@ clip_mch_set_selection(VimClipboard *cbd)
|
||||
|
||||
// Get the text to put on the pasteboard.
|
||||
long_u llen = 0; char_u *str = 0;
|
||||
int type = clip_convert_selection(&str, &llen, cbd);
|
||||
if (type < 0)
|
||||
int motion_type = clip_convert_selection(&str, &llen, cbd);
|
||||
if (motion_type < 0)
|
||||
return;
|
||||
|
||||
// TODO: Avoid overflow.
|
||||
@@ -554,9 +584,16 @@ clip_mch_set_selection(VimClipboard *cbd)
|
||||
NSString *string = [[NSString alloc]
|
||||
initWithBytes:str length:len encoding:NSUTF8StringEncoding];
|
||||
|
||||
// See clip_mch_request_selection() for info on pasteboard types.
|
||||
NSPasteboard *pb = [NSPasteboard generalPasteboard];
|
||||
[pb declareTypes:[NSArray arrayWithObject:NSStringPboardType]
|
||||
owner:nil];
|
||||
NSArray *supportedTypes = [NSArray arrayWithObjects:VimPBoardType,
|
||||
NSStringPboardType, nil];
|
||||
[pb declareTypes:supportedTypes owner:nil];
|
||||
|
||||
NSNumber *motion = [NSNumber numberWithInt:motion_type];
|
||||
NSArray *plist = [NSArray arrayWithObjects:motion, string, nil];
|
||||
[pb setPropertyList:plist forType:VimPBoardType];
|
||||
|
||||
[pb setString:string forType:NSStringPboardType];
|
||||
|
||||
[string release];
|
||||
@@ -617,33 +654,16 @@ gui_mch_add_menu_item(vimmenu_T *menu, int idx)
|
||||
char_u *tip = menu->strings[MENU_INDEX_TIP]
|
||||
? menu->strings[MENU_INDEX_TIP] : menu->actext;
|
||||
char_u *map_str = menu->strings[MENU_INDEX_NORMAL];
|
||||
char_u *mac_action = menu->mac_action;
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
icon = CONVERT_TO_UTF8(icon);
|
||||
name = CONVERT_TO_UTF8(name);
|
||||
tip = CONVERT_TO_UTF8(tip);
|
||||
map_str = CONVERT_TO_UTF8(map_str);
|
||||
mac_action = CONVERT_TO_UTF8(mac_action);
|
||||
#endif
|
||||
|
||||
// HACK! Check if menu is mapped to ':macaction actionName:'; if so, pass
|
||||
// the action along so that MacVim can bind the menu item to this action.
|
||||
// This means that if a menu item maps to an action in normal mode, then
|
||||
// all other modes will also use the same action.
|
||||
NSString *action = nil;
|
||||
if (map_str) {
|
||||
NSString *mapping = [NSString stringWithCString:(char*)map_str
|
||||
encoding:NSUTF8StringEncoding];
|
||||
NSArray *parts = [mapping componentsSeparatedByString:@" "];
|
||||
if ([parts count] >=2
|
||||
&& [[parts objectAtIndex:0] hasPrefix:@":maca"]) {
|
||||
action = [parts objectAtIndex:1];
|
||||
action = [action stringByTrimmingCharactersInSet:
|
||||
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
if (!gui_macvim_is_valid_action(action))
|
||||
action = nil;
|
||||
}
|
||||
}
|
||||
|
||||
[[MMBackend sharedInstance]
|
||||
addMenuItemWithTag:(int)menu
|
||||
parent:(int)menu->parent
|
||||
@@ -652,7 +672,8 @@ gui_mch_add_menu_item(vimmenu_T *menu, int idx)
|
||||
icon:(char*)icon
|
||||
keyEquivalent:menu->mac_key
|
||||
modifiers:menu->mac_mods
|
||||
action:action
|
||||
action:(char*)mac_action
|
||||
isAlternate:menu->mac_alternate
|
||||
atIndex:idx];
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
@@ -660,6 +681,7 @@ gui_mch_add_menu_item(vimmenu_T *menu, int idx)
|
||||
CONVERT_TO_UTF8_FREE(name);
|
||||
CONVERT_TO_UTF8_FREE(tip);
|
||||
CONVERT_TO_UTF8_FREE(map_str);
|
||||
CONVERT_TO_UTF8_FREE(mac_action);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1165,12 +1187,12 @@ ex_macaction(eap)
|
||||
arg = CONVERT_TO_UTF8(arg);
|
||||
#endif
|
||||
|
||||
NSString *name = [NSString stringWithCString:(char*)arg
|
||||
encoding:NSUTF8StringEncoding];
|
||||
if (gui_macvim_is_valid_action(name)) {
|
||||
NSDictionary *actionDict = [[MMBackend sharedInstance] actionDict];
|
||||
NSString *name = [NSString stringWithUTF8String:(char*)arg];
|
||||
if (actionDict && [actionDict objectForKey:name] != nil) {
|
||||
[[MMBackend sharedInstance] executeActionWithName:name];
|
||||
} else {
|
||||
EMSG2(_("E???: \"%s\" is not a valid action"), eap->arg);
|
||||
EMSG2(_("E???: Invalid action: %s"), eap->arg);
|
||||
}
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
@@ -1475,32 +1497,11 @@ gui_mch_toggle_tearoffs(int enable)
|
||||
}
|
||||
|
||||
|
||||
static BOOL
|
||||
gui_macvim_is_valid_action(NSString *action)
|
||||
{
|
||||
static NSDictionary *actionDict = nil;
|
||||
|
||||
if (!actionDict) {
|
||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
||||
NSString *path = [mainBundle pathForResource:@"Actions"
|
||||
ofType:@"plist"];
|
||||
if (path) {
|
||||
actionDict = [[NSDictionary alloc] initWithContentsOfFile:path];
|
||||
} else {
|
||||
// Allocate bogus dictionary so that error only pops up once.
|
||||
actionDict = [NSDictionary new];
|
||||
EMSG(_("E???: Failed to load action dictionary"));
|
||||
}
|
||||
}
|
||||
|
||||
return [actionDict objectForKey:action] != nil;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gui_mch_enter_fullscreen()
|
||||
gui_mch_enter_fullscreen(int fuoptions_flags, guicolor_T bg)
|
||||
{
|
||||
[[MMBackend sharedInstance] enterFullscreen];
|
||||
[[MMBackend sharedInstance] enterFullscreen:fuoptions_flags background:bg];
|
||||
}
|
||||
|
||||
|
||||
@@ -1542,6 +1543,13 @@ gui_macvim_add_to_find_pboard(char_u *pat)
|
||||
[pb setString:s forType:NSStringPboardType];
|
||||
}
|
||||
|
||||
void
|
||||
gui_macvim_set_antialias(int antialias)
|
||||
{
|
||||
[[MMBackend sharedInstance] setAntialias:antialias];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1827,3 +1835,54 @@ odb_end(void)
|
||||
}
|
||||
|
||||
#endif // FEAT_ODB_EDITOR
|
||||
|
||||
|
||||
char_u *
|
||||
get_macaction_name(expand_T *xp, int idx)
|
||||
{
|
||||
static char_u *str = NULL;
|
||||
NSDictionary *actionDict = [[MMBackend sharedInstance] actionDict];
|
||||
|
||||
if (nil == actionDict || idx < 0 || idx >= [actionDict count])
|
||||
return NULL;
|
||||
|
||||
NSString *string = [[actionDict allKeys] objectAtIndex:idx];
|
||||
if (!string)
|
||||
return NULL;
|
||||
|
||||
char_u *plainStr = (char_u*)[string UTF8String];
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
if (str) {
|
||||
vim_free(str);
|
||||
str = NULL;
|
||||
}
|
||||
if (input_conv.vc_type != CONV_NONE) {
|
||||
int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
str = string_convert(&input_conv, plainStr, &len);
|
||||
plainStr = str;
|
||||
}
|
||||
#endif
|
||||
|
||||
return plainStr;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
is_valid_macaction(char_u *action)
|
||||
{
|
||||
int isValid = NO;
|
||||
NSDictionary *actionDict = [[MMBackend sharedInstance] actionDict];
|
||||
if (actionDict) {
|
||||
#ifdef FEAT_MBYTE
|
||||
action = CONVERT_TO_UTF8(action);
|
||||
#endif
|
||||
NSString *string = [NSString stringWithUTF8String:(char*)action];
|
||||
isValid = (nil != [actionDict objectForKey:string]);
|
||||
#ifdef FEAT_MBYTE
|
||||
CONVERT_TO_UTF8_FREE(action);
|
||||
#endif
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
+69
-53
@@ -1,7 +1,7 @@
|
||||
" System gvimrc file for MacVim
|
||||
"
|
||||
" Maintainer: Bjorn Winckler <bjorn.winckler@gmail.com>
|
||||
" Last Change: Mon Feb 11 2008
|
||||
" Last Change: Sun May 19 2008
|
||||
"
|
||||
" This is a work in progress. If you feel so inclined, please help me improve
|
||||
" this file.
|
||||
@@ -42,13 +42,15 @@ aunmenu File.-SEP4-
|
||||
aunmenu File.Exit
|
||||
aunmenu File.Save-Exit
|
||||
|
||||
an <silent> 10.290 File.New\ Window :maca newWindow:<CR>
|
||||
an <silent> 10.290 File.New\ Window <Nop>
|
||||
an 10.295 File.New\ Tab :tabnew<CR>
|
||||
an <silent> 10.310 File.&Open\.\.\. :maca fileOpen:<CR>
|
||||
an <silent> 10.310 File.Open\.\.\. <Nop>
|
||||
an <silent> 10.325 File.Open\ Recent <Nop>
|
||||
an 10.328 File.-SEP0- <Nop>
|
||||
an <silent> 10.330 File.Close\ Window<Tab>:qa :confirm qa<CR>
|
||||
an <silent> 10.331 File.Close :maca performClose:<CR>
|
||||
"an 10.331 File.Close\ Tab :tabclose<CR>
|
||||
an <silent> 10.330 File.Close\ Window<Tab>:qa :conf qa<CR>
|
||||
an <silent> 10.332 File.Close :conf q<CR>
|
||||
an <silent> 10.341 File.Save\ All :browse conf wa<CR>
|
||||
an 10.350 File.Save\ As\.\.\.<Tab>:sav :browse confirm saveas<CR>
|
||||
|
||||
|
||||
" Edit menu
|
||||
@@ -57,8 +59,8 @@ aunmenu Edit.Find
|
||||
aunmenu Edit.Find\ and\ Replace
|
||||
|
||||
an 20.410.10 Edit.Find.Find\.\.\.<Tab>/ /
|
||||
an 20.410.20 Edit.Find.Find\ Next :maca findNext:<CR>
|
||||
an 20.410.30 Edit.Find.Find\ Previous :maca findPrevious:<CR>
|
||||
an 20.410.20 Edit.Find.Find\ Next <Nop>
|
||||
an 20.410.30 Edit.Find.Find\ Previous <Nop>
|
||||
vmenu 20.410.35 Edit.Find.Use\ Selection\ for\ Find y:let @/=@"<CR>n
|
||||
an 20.410.40 Edit.Find.-SEP1- <Nop>
|
||||
an 20.410.50 Edit.Find.Find\ and\ Replace\.\.\.<Tab>:%s :%s/
|
||||
@@ -66,27 +68,32 @@ vunmenu Edit.Find.Find\ and\ Replace\.\.\.<Tab>:%s
|
||||
vnoremenu Edit.Find.Find\ and\ Replace\.\.\.<Tab>:s :s/
|
||||
|
||||
an 20.460 Edit.-SEP4- <Nop>
|
||||
an 20.465.10 Edit.Font.Show\ Fonts :maca orderFrontFontPanel:<CR>
|
||||
an 20.465.10 Edit.Font.Show\ Fonts <Nop>
|
||||
an 20.465.20 Edit.Font.-SEP5- <Nop>
|
||||
an 20.465.30 Edit.Font.Bigger :maca fontSizeUp:<CR>
|
||||
an 20.465.40 Edit.Font.Smaller :maca fontSizeDown:<CR>
|
||||
an 20.470 Edit.Special\ Characters\.\.\. :maca orderFrontCharacterPalette:<CR>
|
||||
an 20.465.30 Edit.Font.Bigger <Nop>
|
||||
an 20.465.40 Edit.Font.Smaller <Nop>
|
||||
an 20.470 Edit.Special\ Characters\.\.\. <Nop>
|
||||
|
||||
|
||||
" Window menu (should be next to Help so give it a high priority)
|
||||
aunmenu Window
|
||||
|
||||
an <silent> 9900.300 Window.Minimize :maca performMiniaturize:<CR>
|
||||
an <silent> 9900.310 Window.Zoom :maca performZoom:<CR>
|
||||
an <silent> 9900.300 Window.Minimize <Nop>
|
||||
an <silent> 9900.310 Window.Zoom <Nop>
|
||||
an <silent> 9900.320 Window.Toggle\ Full\ Screen\ Mode :set invfullscreen<CR>
|
||||
an 9900.330 Window.-SEP1- <Nop>
|
||||
" TODO! Grey out if no tabs are visible.
|
||||
an <silent> 9900.340 Window.Previous\ Tab :tabprevious<CR>
|
||||
an <silent> 9900.350 Window.Next\ Tab :tabnext<CR>
|
||||
an 9900.360 Window.-SEP2- <Nop>
|
||||
an <silent> 9900.370 Window.Bring\ All\ To\ Front :maca arrangeInFront:<CR>
|
||||
an <silent> 9900.370 Window.Bring\ All\ To\ Front <Nop>
|
||||
|
||||
|
||||
" Help menu
|
||||
an 9999.1 Help.MacVim\ Help :h gui_mac<CR>
|
||||
an <silent> 9999.2 Help.MacVim\ Website <Nop>
|
||||
an 9999.3 Help.-sep0- <Nop>
|
||||
|
||||
|
||||
"
|
||||
" Toolbar
|
||||
@@ -183,50 +190,59 @@ endif " exists("macvim_hig_shift_movement")
|
||||
|
||||
|
||||
"
|
||||
" Menu key equivalents (these should always have the 'D' modifier set)
|
||||
" Set up menu key equivalents (these should always have the 'D' modifier set),
|
||||
" action bindings, and alternate items.
|
||||
"
|
||||
" Note: menu items which should execute an action are bound to <Nop>; the
|
||||
" action message is specified here via the :macmenu command.
|
||||
"
|
||||
|
||||
macmenukey File.New\ Window <D-n>
|
||||
macmenukey File.New\ Tab <D-t>
|
||||
macm File.New\ Window key=<D-n> action=newWindow:
|
||||
macm File.New\ Tab key=<D-t>
|
||||
macm File.Open\.\.\. key=<D-o> action=fileOpen:
|
||||
macm File.Open\ Tab\.\.\. key=<D-T>
|
||||
macm File.Open\ Recent action=recentFilesDummy:
|
||||
macm File.Close\ Window key=<D-W>
|
||||
macm File.Close key=<D-w> action=performClose:
|
||||
macm File.Save key=<D-s>
|
||||
macm File.Save\ All key=<D-M-s> alt=YES
|
||||
macm File.Save\ As\.\.\. key=<D-S>
|
||||
macm File.Print key=<D-p>
|
||||
|
||||
macmenukey File.Open\.\.\. <D-o>
|
||||
macmenukey File.Open\ Tab\.\.\. <D-T>
|
||||
macmenukey File.Close\ Window <D-W>
|
||||
"macmenukey File.Close\ Tab <D-w>
|
||||
macmenukey File.Close <D-w>
|
||||
macmenukey File.Save <D-s>
|
||||
macmenukey File.Save\ As\.\.\. <D-S>
|
||||
macmenukey File.Print <D-p>
|
||||
macm Edit.Undo key=<D-z> action=undo:
|
||||
macm Edit.Redo key=<D-Z> action=redo:
|
||||
macm Edit.Cut key=<D-x> action=cut:
|
||||
macm Edit.Copy key=<D-c> action=copy:
|
||||
macm Edit.Paste key=<D-v> action=paste:
|
||||
macm Edit.Select\ All key=<D-a> action=selectAll:
|
||||
macm Edit.Find.Find\.\.\. key=<D-f>
|
||||
macm Edit.Find.Find\ Next key=<D-g> action=findNext:
|
||||
macm Edit.Find.Find\ Previous key=<D-G> action=findPrevious:
|
||||
macm Edit.Find.Use\ Selection\ for\ Find key=<D-e>
|
||||
macm Edit.Special\ Characters\.\.\. key=<D-M-t>
|
||||
macm Edit.Font.Show\ Fonts action=orderFrontFontPanel:
|
||||
macm Edit.Font.Bigger key=<D-=> action=fontSizeUp:
|
||||
macm Edit.Font.Smaller key=<D--> action=fontSizeDown:
|
||||
macm Edit.Special\ Characters\.\.\. action=orderFrontCharacterPalette:
|
||||
|
||||
macmenukey Edit.Undo <D-z>
|
||||
macmenukey Edit.Redo <D-Z>
|
||||
macmenukey Edit.Cut <D-x>
|
||||
macmenukey Edit.Copy <D-c>
|
||||
macmenukey Edit.Paste <D-v>
|
||||
macmenukey Edit.Select\ All <D-a>
|
||||
macmenukey Edit.Find.Find\.\.\. <D-f>
|
||||
macmenukey Edit.Find.Find\ Next <D-g>
|
||||
macmenukey Edit.Find.Find\ Previous <D-G>
|
||||
macmenukey Edit.Find.Use\ Selection\ for\ Find <D-e>
|
||||
macmenukey Edit.Special\ Characters\.\.\. <D-M-t>
|
||||
macmenukey Edit.Font.Bigger <D-=>
|
||||
macmenukey Edit.Font.Smaller <D-->
|
||||
macm Tools.Spelling.To\ Next\ error key=<D-;>
|
||||
macm Tools.Spelling.Suggest\ Corrections key=<D-:>
|
||||
macm Tools.Make key=<D-b>
|
||||
macm Tools.List\ Errors key=<D-l>
|
||||
macm Tools.List\ Messages key=<D-L>
|
||||
macm Tools.Next\ Error key=<D-C-Right>
|
||||
macm Tools.Previous\ Error key=<D-C-Left>
|
||||
macm Tools.Older\ List key=<D-C-Up>
|
||||
macm Tools.Newer\ List key=<D-C-Down>
|
||||
|
||||
macmenukey Tools.Spelling.To\ Next\ error <D-;>
|
||||
macmenukey Tools.Spelling.Suggest\ Corrections <D-:>
|
||||
macmenukey Tools.Make <D-b>
|
||||
macmenukey Tools.List\ Errors <D-l>
|
||||
macmenukey Tools.List\ Messages <D-L>
|
||||
macmenukey Tools.Next\ Error <D-C-Right>
|
||||
macmenukey Tools.Previous\ Error <D-C-Left>
|
||||
macmenukey Tools.Older\ List <D-C-Up>
|
||||
macmenukey Tools.Newer\ List <D-C-Down>
|
||||
|
||||
macmenukey Window.Minimize <D-m>
|
||||
macmenukey Window.Toggle\ Full\ Screen\ Mode <D-F>
|
||||
macmenukey Window.Previous\ Tab <D-{>
|
||||
macmenukey Window.Next\ Tab <D-}>
|
||||
macm Window.Minimize key=<D-m> action=performMiniaturize:
|
||||
macm Window.Zoom key=<D-C-z> action=performZoom:
|
||||
macm Window.Toggle\ Full\ Screen\ Mode key=<D-F>
|
||||
macm Window.Previous\ Tab key=<D-{>
|
||||
macm Window.Next\ Tab key=<D-}>
|
||||
macm Window.Bring\ All\ To\ Front action=arrangeInFront:
|
||||
|
||||
macm Help.MacVim\ Website action=openWebsite:
|
||||
|
||||
" Restore the previous value of 'cpoptions'.
|
||||
let &cpo = s:cpo_save
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 193 B |
+228
-11
@@ -41,31 +41,248 @@
|
||||
-->
|
||||
|
||||
<item>
|
||||
<title>Snapshot 21 released</title>
|
||||
<title>Snapshot 28 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 21 released</h1>
|
||||
<h1>MacVim snapshot 28 released</h1>
|
||||
<p><em>The ":macmenukey" command is now deprecated. Please update your .gvimrc
|
||||
file to use the ":macmenu" command instead (if you use ":macmenukey").</em></p>
|
||||
|
||||
<p> Changes since snapshot 27:
|
||||
<ul>
|
||||
<li> Added the ":macmenu" commmand (see ":h macmenu") and deprecated
|
||||
":macmenukey"</li>
|
||||
<li> Cmd-w now works even when mappings to <-\> are present </li>
|
||||
<li> Added "File.Save All" menu item (Cmd-Alt-s) </li>
|
||||
<li> The Logitech Control Center no longer causes any problems </li>
|
||||
<li> "Edit" menu items now work better with open and save dialogs </li>
|
||||
<li> The 'backspace' option now includes "indent,eol,start" by default </li>
|
||||
<li> Open and save dialogs track the present working directory </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Sun, 25 May 2008 19:40 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-28.tbz"
|
||||
length="8124499"
|
||||
sparkle:version="28"
|
||||
sparkle:shortVersionString="7.1"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 27 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 27 released</h1>
|
||||
<p> This is the first snapshot compiled on the new Mac I bought with money
|
||||
donated from MacVim users! There were problems with compiling universal
|
||||
binaries with Ruby and Perl support on PPC/Tiger so I was hoping to be able
|
||||
to include these now that I have Intel/Leopard. The good news is that Ruby
|
||||
support is now included, but Perl still is problematic and I had to drop
|
||||
TCL support. I will try to get these working in a future snapshot.
|
||||
</p>
|
||||
|
||||
<p> Here is the list of changes since snapshot 26:
|
||||
<ul>
|
||||
<li> 'fuoptions' now support setting the background color while in
|
||||
full-screen mode, check ":h 'fuopt'" (patch by Enno Lübbers) </li>
|
||||
<li> <D-w> shows confirmation dialog when buffer is modified </li>
|
||||
<li> setting 'antialias' from gvimrc now works </li>
|
||||
<li> zooming a window no longer causes it to move downwards </li>
|
||||
<li> the File menu now contains a "Recent Files" submenu; note that only
|
||||
files opened from Finder or with the ":browse" command are added to this
|
||||
list, and not files opened with e.g. ":e" (patch by Nico Weber) </li>
|
||||
<li> includes latest Vim patches and runtime files </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Mon, 12 May 2008 22:05 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-27-fixed.tbz"
|
||||
length="8102568"
|
||||
sparkle:version="27"
|
||||
sparkle:shortVersionString="7.1"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 26 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 26 released</h1>
|
||||
<p> This snapshot contains a fix to the bug which caused the first window to
|
||||
open in the wrong position as well as an initial version of the new MacVim
|
||||
icon. </p>
|
||||
|
||||
]]></description>
|
||||
<pubDate>Fri, 11 Apr 2008 20:37 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-26.tbz"
|
||||
length="8147362"
|
||||
sparkle:version="26"
|
||||
sparkle:shortVersionString="7.1"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 25 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 25 released</h1>
|
||||
|
||||
<p> This snapshot adds support for two new options: 'antialias' and
|
||||
'fuoptions'. The former lets you turn text antialiasing on or off (it's
|
||||
on by default), the latter can be used to make the view maximize when
|
||||
full-screen is entered. See the built-in help for more information (:h
|
||||
'anti' and :h 'fuopt'). </p>
|
||||
|
||||
<p> Another minor addition is that <C-c> and <C-v> work with
|
||||
block-wise selections (do note that <C-v> behaves like "P", not "p").
|
||||
Also, <D-w> now works in ex-mode and in a command-line window. </p>
|
||||
|
||||
<p> Here is the list of changes since snapshot 24:
|
||||
<ul>
|
||||
<li> support 'antialias' option (Jjgod Jiang) </li>
|
||||
<li> add option 'fuoptions' to control resizing when full-screen is entered
|
||||
(Nico Weber) </li>
|
||||
<li> fixed bug where transparency setting was lost after leaving full-screen
|
||||
(Nico Weber) </li>
|
||||
<li> help menu contains MacVim help and website link </li>
|
||||
<li> <D-w> now works in ex-mode and in command-line window </li>
|
||||
<li> :macaction command supports command-line completion (Nico Weber) </li>
|
||||
<li> copy/paste respects block selections (requested by George Harker) </li>
|
||||
<li> window no longer cascades from preferences panel </li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
]]></description>
|
||||
<pubDate>Fri, 06 Apr 2008 19:11 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-25.tbz"
|
||||
length="8042440"
|
||||
sparkle:version="25"
|
||||
sparkle:shortVersionString="7.1"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 24 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 24 released</h1>
|
||||
|
||||
<p><em> The input manager bundled with snapshot 23 contained a bug which could
|
||||
lead to other apps crashing on startup. If you have installed the input
|
||||
manager, then you are strongly advised to update now and install the new input
|
||||
manager (via the Integration preference pane). </em></p>
|
||||
|
||||
<p> Changes since snapshot 23:
|
||||
<ul>
|
||||
<li> The mouse cursor has higher contrast in insert mode (when bg=dark). </li>
|
||||
<li> The layout of the Integration preference pane has been updated. </li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
]]></description>
|
||||
<pubDate>Fri, 14 Mar 2008 20:44 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-24.tbz"
|
||||
length="8036815"
|
||||
sparkle:version="24"
|
||||
sparkle:shortVersionString="7.1"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 23 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 23 released</h1>
|
||||
|
||||
Changes since snapshot 22:
|
||||
|
||||
<ul>
|
||||
<li> The preferences panel has been updated with an "Integration pane". This
|
||||
can be used to easily install (and uninstall) the "Edit in ODBEditor"
|
||||
input manager. The input manager enables you to use MacVim to edit text
|
||||
in any Cocoa text field (e.g. you can use MacVim to edit emails in Mail).
|
||||
Please read the warning on the Integration pane before installing the
|
||||
input manager. (Patch by Nico Weber.) </li>
|
||||
<li> The "Login Shell" preference has been updated so it should now work with
|
||||
most shells. This option ensures that environment variables (e.g. $PATH)
|
||||
are set properly. You should enable it if you ever need to issue shell
|
||||
commands from within MacVim. (Patch by Ben Schmidt.) </li>
|
||||
<li> Added MMZoomBoth user default. Enable this if you prefer the window to
|
||||
maximize in both directions when you press the green "maximize button"
|
||||
(hold down Cmd to temporarily restrict resizing to the vertical direction
|
||||
only). (Requested by Brian McKee.) </li>
|
||||
<li> Added Cmd-Ctrl-z as key equivalent for "Window->Zoom" (this is the same
|
||||
key equivalent as in iTunes) </li>
|
||||
<li> The Vim runtime files have been updated to the latest version </li>
|
||||
<li> MacVim recognizes files with .patch and .diff extension </li>
|
||||
<li> The mouse cursor in insert mode has higher contrast (when used with dark
|
||||
backgrounds). (Requested by Enno et al.) </li>
|
||||
<li> Line numbers (:h 'number') are brighter when bakground=dark. (Requested
|
||||
by Ted Pavlic) </li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Like MacVim? Go to <a href="http://code.google.com/p/macvim/">
|
||||
http://code.google.com/p/macvim/</a> to see how you can show your
|
||||
support.
|
||||
</p>
|
||||
|
||||
]]></description>
|
||||
<pubDate>Sun, 9 Mar 2008 16:43 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-23.tbz"
|
||||
length="8037899"
|
||||
sparkle:version="23"
|
||||
sparkle:shortVersionString="7.1"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 22 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 22 released</h1>
|
||||
|
||||
<p><em>This snapshot replaces the broken snapshot 21. If you installed build 21
|
||||
then please update immediately.</em></p>
|
||||
|
||||
<p>Changes since snapshot 20:</p>
|
||||
<ul>
|
||||
<li>Fix forking bug which caused snapshot 21 to lock up OS X</li>
|
||||
<li>The macvim color scheme changed so that line numbers look better when
|
||||
the background is dark (enable line numbers with :set number, set dark
|
||||
the background is dark (enable line numbers with :set number; set dark
|
||||
background with :set bg=dark)</li>
|
||||
<li>Improved support for Voice Over (enable with <D-F5>)</li>
|
||||
<li>Improved support for Voice Over (enable with <D-F5>)</li>
|
||||
<li>System bell support (see :h 'vb' on how to turn it off)</li>
|
||||
<li>MacVim no longer associates to .plist and .dict since these may well be
|
||||
in binary format</li>
|
||||
<li>Added Find Next <D-g>, Find Previous <D-G> and Use Selection for Find
|
||||
<D-e> menu items</li>
|
||||
<li>Added Find Next <D-g>, Find Previous <D-G> and Use Selection
|
||||
for Find <D-e> menu items</li>
|
||||
<li>Track pad scrolling is now force sensitive</li>
|
||||
<li>Added help section on preferences</li>
|
||||
<li>Preferences panel updated (also no longer hides when MacVim loses focus)
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>The most exciting new addition in this snapshot is support for <D-g>.
|
||||
It repeats the last search you made in any other application (that supports the
|
||||
Find Pasteboard).</p>
|
||||
<p>This is very useful if you have several windows open in MacVim...try
|
||||
searching for something in one window (using "/"), then switching to another
|
||||
window and hitting <D-g> for an example (after having pressed <D-g>
|
||||
once you can of course use "n" to repeat the search).</p>
|
||||
]]></description>
|
||||
<pubDate>Mon, 11 Feb 2008 22:17 CET</pubDate>
|
||||
<pubDate>Wed, 13 Feb 2008 19:36 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-21.tbz"
|
||||
length="7814596"
|
||||
sparkle:version="21"
|
||||
sparkle:shortVersionString="snapshot 21"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-22.tbz"
|
||||
length="7812907"
|
||||
sparkle:version="22"
|
||||
sparkle:shortVersionString="7.1"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
Executable
+60
@@ -0,0 +1,60 @@
|
||||
#!/bin/sh
|
||||
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.4
|
||||
|
||||
# Increment build number
|
||||
/Developer/usr/bin/agvtool next-version -all > /dev/null
|
||||
|
||||
# Get current build number
|
||||
BUILDNUM=`/Developer/usr/bin/agvtool what-version -terse`
|
||||
DEST=~/Desktop/MacVim-snapshot-$BUILDNUM
|
||||
|
||||
echo '****************************************************'
|
||||
echo " BUILDING SNAPSHOT $BUILDNUM"
|
||||
echo '****************************************************'
|
||||
echo ''
|
||||
|
||||
# Build Vim binary
|
||||
echo 'BUILDING VIM BINARY'
|
||||
echo ' running configure...'
|
||||
cd .. && ./configure --enable-gui=macvim --with-mac-arch=both \
|
||||
--with-features=huge --enable-pythoninterp \
|
||||
--enable-cscope --enable-rubyinterp \
|
||||
--with-compiledby="Bjorn Winckler <bjorn.winckler@gmail.com>" > /dev/null
|
||||
|
||||
echo ' cleaning...'
|
||||
make clean > /dev/null
|
||||
echo ' calling make...'
|
||||
make > /dev/null
|
||||
echo ' done'
|
||||
|
||||
# Build MacVim.app
|
||||
echo 'BUILDING MacVim.app'
|
||||
cd MacVim
|
||||
echo ' cleaning...'
|
||||
xcodebuild -configuration Universal clean > /dev/null
|
||||
echo ' calling xcodebuild...'
|
||||
xcodebuild -configuration Universal > /dev/null
|
||||
echo ' done'
|
||||
|
||||
# Create archive of build/Universal/MacVim.app
|
||||
echo 'CREATING SNAPSHOT ARCHIVE'
|
||||
echo ' copying MacVim.app and supporting files...'
|
||||
mkdir $DEST
|
||||
cp -pR build/Universal/MacVim.app $DEST/
|
||||
cp -p mvim $DEST/
|
||||
cp -p README-snapshot.txt $DEST/
|
||||
echo ' creating archive....'
|
||||
cd $DEST && cd ..
|
||||
tar cjf MacVim-snapshot-$BUILDNUM.tbz MacVim-snapshot-$BUILDNUM
|
||||
echo ' done'
|
||||
|
||||
echo 'ALL DONE'
|
||||
echo 'Now update the Appcast, commit and tag, then post on vim_mac.'
|
||||
# Update app-cast
|
||||
|
||||
# Commit & tag
|
||||
# git-commit -a -m "$BUILDNUM"
|
||||
# git-tag -a -F tagfile $BUILDNUM
|
||||
|
||||
# Post on vim_mac
|
||||
Binary file not shown.
+5
-1
@@ -1,6 +1,10 @@
|
||||
" System vimrc file for MacVim
|
||||
"
|
||||
" Maintainer: Bjorn Winckler <bjorn.winckler@gmail.com>
|
||||
" Last Change: Sat Aug 11 14:26:41 CEST 2007
|
||||
" Last Change: Sun May 25 2008
|
||||
|
||||
set nocompatible
|
||||
|
||||
" The default for 'backspace' is very confusing to new users, so change it to a
|
||||
" more sensible value. Add "set backspace&" to your ~/.vimrc to reset it.
|
||||
set backspace+=indent,eol,start
|
||||
|
||||
+18
-12
@@ -1,6 +1,7 @@
|
||||
# Makefile for Vim on Win32 (Windows NT/2000/XP/2003 and Windows 95/98/Me)
|
||||
# and Win64, using the Microsoft Visual C++ compilers. Known to work with
|
||||
# VC5, VC6 (VS98), VC7.0 (VS2002), VC7.1 (VS2003), and VC8 (VS2005).
|
||||
# VC5, VC6 (VS98), VC7.0 (VS2002), VC7.1 (VS2003), VC8 (VS2005),
|
||||
# and VC9 (VS2008).
|
||||
#
|
||||
# To build using other Windows compilers, see INSTALLpc.txt
|
||||
#
|
||||
@@ -285,7 +286,8 @@ XPM_INC = -I $(XPM)\include
|
||||
# need shell32.lib for ExtractIcon()
|
||||
# gdi32.lib and comdlg32.lib for printing support
|
||||
# ole32.lib and uuid.lib are needed for FEAT_SHORTCUT
|
||||
CON_LIB = advapi32.lib shell32.lib gdi32.lib comdlg32.lib ole32.lib uuid.lib
|
||||
CON_LIB = oldnames.lib kernel32.lib advapi32.lib shell32.lib gdi32.lib \
|
||||
comdlg32.lib ole32.lib uuid.lib /machine:$(CPU) /nodefaultlib
|
||||
!if "$(DELAYLOAD)" == "yes"
|
||||
CON_LIB = $(CON_LIB) /DELAYLOAD:comdlg32.dll /DELAYLOAD:ole32.dll DelayImp.lib
|
||||
!endif
|
||||
@@ -331,6 +333,7 @@ MSVCVER = 5.0
|
||||
!endif
|
||||
!if "$(_NMAKE_VER)" == "6.00.8168.0"
|
||||
MSVCVER = 6.0
|
||||
CPU = ix86
|
||||
!endif
|
||||
!if "$(_NMAKE_VER)" == "7.00.9466"
|
||||
MSVCVER = 7.0
|
||||
@@ -344,6 +347,9 @@ MSVCVER = 8.0
|
||||
!if "$(_NMAKE_VER)" == "8.00.50727.762"
|
||||
MSVCVER = 8.0
|
||||
!endif
|
||||
!if "$(_NMAKE_VER)" == "9.00.20706.01"
|
||||
MSVCVER = 9.0
|
||||
!endif
|
||||
!endif
|
||||
|
||||
# Abort bulding VIM if version of VC is unrecognised.
|
||||
@@ -352,13 +358,13 @@ MSVCVER = 8.0
|
||||
!message Cannot determine Visual C version being used. If you are using the
|
||||
!message Windows SDK then you must have the environment variable MSVCVER set to
|
||||
!message your version of the VC compiler. If you are not using the Express
|
||||
!message version of Visual C you van either set MSVCVER or update this makefile
|
||||
!message to handle the new value for _NMAKE_VER.
|
||||
!message version of Visual C, you can either set MSVCVER or update this makefile
|
||||
!message to handle the new value for _NMAKE_VER, "$(_NMAKE_VER)".
|
||||
!error Make aborted.
|
||||
!endif
|
||||
|
||||
# Convert processor ID to MVC-compatible number
|
||||
!if "$(MSVCVER)" != "8.0"
|
||||
!if ("$(MSVCVER)" != "8.0") && ("$(MSVCVER)" != "9.0")
|
||||
!if "$(CPUNR)" == "i386"
|
||||
CPUARG = /G3
|
||||
!elseif "$(CPUNR)" == "i486"
|
||||
@@ -373,7 +379,7 @@ CPUARG = /G7 /arch:SSE2
|
||||
CPUARG =
|
||||
!endif
|
||||
!else
|
||||
# VC8 only allows specifying SSE architecture
|
||||
# VC8/9 only allows specifying SSE architecture
|
||||
!if "$(CPUNR)" == "pentium4"
|
||||
CPUARG = /arch:SSE2
|
||||
!endif
|
||||
@@ -391,7 +397,7 @@ OPTFLAG = /O2
|
||||
!else # MAXSPEED
|
||||
OPTFLAG = /Ox
|
||||
!endif
|
||||
!if "$(MSVCVER)" == "8.0"
|
||||
!if ("$(MSVCVER)" == "8.0") || ("$(MSVCVER)" == "9.0")
|
||||
# Use link time code generation if not worried about size
|
||||
!if "$(OPTIMIZE)" != "SPACE"
|
||||
OPTFLAG = $(OPTFLAG) /GL
|
||||
@@ -404,11 +410,11 @@ CFLAGS = $(CFLAGS) /MD
|
||||
LIBC = msvcrt.lib
|
||||
! else
|
||||
LIBC = libcmt.lib
|
||||
CFLAGS = $(CFLAGS) /MT
|
||||
CFLAGS = $(CFLAGS) /Zl /MT
|
||||
! endif
|
||||
!else # DEBUG
|
||||
VIM = vimd
|
||||
! if "$(CPU)" == "i386"
|
||||
! if ("$(CPU)" == "i386") || ("$(CPU)" == "ix86")
|
||||
DEBUGINFO = /ZI
|
||||
! endif
|
||||
CFLAGS = $(CFLAGS) -D_DEBUG -DDEBUG /Od
|
||||
@@ -424,7 +430,7 @@ CFLAGS = $(CFLAGS) /MDd
|
||||
LIBC = $(LIBC) msvcrtd.lib
|
||||
! else
|
||||
LIBC = $(LIBC) libcmtd.lib
|
||||
CFLAGS = $(CFLAGS) /MTd
|
||||
CFLAGS = $(CFLAGS) /Zl /MTd
|
||||
! endif
|
||||
!endif # DEBUG
|
||||
|
||||
@@ -534,7 +540,7 @@ GUI_OBJ = \
|
||||
$(OUTDIR)\gui_w32.obj \
|
||||
$(OUTDIR)\os_w32exe.obj
|
||||
GUI_LIB = \
|
||||
oldnames.lib kernel32.lib gdi32.lib version.lib $(IME_LIB) \
|
||||
gdi32.lib version.lib $(IME_LIB) \
|
||||
winspool.lib comctl32.lib advapi32.lib shell32.lib \
|
||||
/machine:$(CPU) /nodefaultlib
|
||||
!else
|
||||
@@ -757,7 +763,7 @@ LINKARGS2 = $(CON_LIB) $(GUI_LIB) $(LIBC) $(OLE_LIB) user32.lib $(SNIFF_LIB) \
|
||||
|
||||
# Report link time code generation progress if used.
|
||||
!ifdef NODEBUG
|
||||
!if "$(MSVCVER)" == "8.0"
|
||||
!if ("$(MSVCVER)" == "8.0") || ("$(MSVCVER)" == "9.0")
|
||||
!if "$(OPTIMIZE)" != "SPACE"
|
||||
LINKARGS1 = $(LINKARGS1) /LTCG:STATUS
|
||||
!endif
|
||||
|
||||
+5
-2
@@ -545,7 +545,7 @@ LINT_OPTIONS = -beprxzF
|
||||
# For unknown reasons adding "-lc" fixes a linking problem with GCC. That's
|
||||
# probably a bug in the "-pg" implementation.
|
||||
# Need to recompile everything after changing this: "make clean" "make".
|
||||
#PROFILE_CFLAGS = -pg -g
|
||||
#PROFILE_CFLAGS = -pg -g -DWE_ARE_PROFILING
|
||||
#PROFILE_LIBS = -pg
|
||||
#PROFILE_LIBS = -pg -lc
|
||||
|
||||
@@ -1883,6 +1883,8 @@ installmacros: $(DEST_VIM) $(DEST_RT) $(DEST_MACRO)
|
||||
installtutorbin: $(DEST_VIM)
|
||||
$(INSTALL_DATA) vimtutor $(DEST_BIN)/$(VIMNAME)tutor
|
||||
chmod $(SCRIPTMOD) $(DEST_BIN)/$(VIMNAME)tutor
|
||||
$(INSTALL_DATA) gvimtutor $(DEST_BIN)/$(GVIMNAME)tutor
|
||||
chmod $(SCRIPTMOD) $(DEST_BIN)/$(GVIMNAME)tutor
|
||||
|
||||
installtutor: $(DEST_RT) $(DEST_TUTOR)
|
||||
-$(INSTALL_DATA) $(TUTORSOURCE)/README* $(TUTORSOURCE)/tutor* $(DEST_TUTOR)
|
||||
@@ -2091,6 +2093,7 @@ installmanlinks:
|
||||
uninstall: uninstall_runtime
|
||||
-rm -f $(DEST_BIN)/$(VIMTARGET)
|
||||
-rm -f $(DEST_BIN)/vimtutor
|
||||
-rm -f $(DEST_BIN)/gvimtutor
|
||||
-rm -f $(DEST_BIN)/$(EXTARGET) $(DEST_BIN)/$(VIEWTARGET)
|
||||
-rm -f $(DEST_BIN)/$(GVIMTARGET) $(DEST_BIN)/$(GVIEWTARGET)
|
||||
-rm -f $(DEST_BIN)/$(RVIMTARGET) $(DEST_BIN)/$(RVIEWTARGET)
|
||||
@@ -2187,7 +2190,7 @@ SHADOWDIR = shadow
|
||||
|
||||
shadow: runtime pixmaps
|
||||
mkdir $(SHADOWDIR)
|
||||
cd $(SHADOWDIR); ln -s ../*.[ch] ../*.in ../*.sh ../*.xs ../*.xbm ../toolcheck ../proto ../vimtutor ../mkinstalldirs .
|
||||
cd $(SHADOWDIR); ln -s ../*.[ch] ../*.in ../*.sh ../*.xs ../*.xbm ../toolcheck ../proto ../vimtutor ../gvimtutor ../mkinstalldirs .
|
||||
mkdir $(SHADOWDIR)/auto
|
||||
cd $(SHADOWDIR)/auto; ln -s ../../auto/configure .
|
||||
cd $(SHADOWDIR); rm -f auto/link.sed
|
||||
|
||||
Vendored
+92
-2
@@ -845,6 +845,7 @@ Optional Features:
|
||||
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
|
||||
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
||||
--disable-darwin Disable Darwin (Mac OS X) support.
|
||||
--disable-selinux Don't check for SELinux support.
|
||||
--disable-xsmp Disable XSMP session management
|
||||
--disable-xsmp-interact Disable XSMP interaction
|
||||
--enable-mzschemeinterp Include MzScheme interpreter.
|
||||
@@ -3611,6 +3612,94 @@ echo "${ECHO_T}no" >&6
|
||||
esac
|
||||
fi
|
||||
|
||||
echo "$as_me:$LINENO: checking --disable-selinux argument" >&5
|
||||
echo $ECHO_N "checking --disable-selinux argument... $ECHO_C" >&6
|
||||
# Check whether --enable-selinux or --disable-selinux was given.
|
||||
if test "${enable_selinux+set}" = set; then
|
||||
enableval="$enable_selinux"
|
||||
|
||||
else
|
||||
enable_selinux="yes"
|
||||
fi;
|
||||
if test "$enable_selinux" = "yes"; then
|
||||
echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6
|
||||
echo "$as_me:$LINENO: checking for is_selinux_enabled in -lselinux" >&5
|
||||
echo $ECHO_N "checking for is_selinux_enabled in -lselinux... $ECHO_C" >&6
|
||||
if test "${ac_cv_lib_selinux_is_selinux_enabled+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lselinux $LIBS"
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any gcc2 internal prototype to avoid an error. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
/* We use char because int might match the return type of a gcc2
|
||||
builtin and then its argument prototype would still apply. */
|
||||
char is_selinux_enabled ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
is_selinux_enabled ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
(eval $ac_link) 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; } &&
|
||||
{ ac_try='test -s conftest$ac_exeext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_lib_selinux_is_selinux_enabled=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_lib_selinux_is_selinux_enabled=no
|
||||
fi
|
||||
rm -f conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $ac_cv_lib_selinux_is_selinux_enabled" >&5
|
||||
echo "${ECHO_T}$ac_cv_lib_selinux_is_selinux_enabled" >&6
|
||||
if test $ac_cv_lib_selinux_is_selinux_enabled = yes; then
|
||||
LIBS="$LIBS -lselinux"
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_SELINUX 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
else
|
||||
echo "$as_me:$LINENO: result: yes" >&5
|
||||
echo "${ECHO_T}yes" >&6
|
||||
fi
|
||||
|
||||
|
||||
echo "$as_me:$LINENO: checking --with-features argument" >&5
|
||||
@@ -4669,10 +4758,11 @@ echo "${ECHO_T}$tclver - OK" >&6;
|
||||
echo "$as_me:$LINENO: checking for location of Tcl include" >&5
|
||||
echo $ECHO_N "checking for location of Tcl include... $ECHO_C" >&6
|
||||
if test "x$MACOSX" != "xyes"; then
|
||||
tclinc="$tclloc/include $tclloc/include/tcl $tclloc/include/tcl$tclver /usr/local/include /usr/include"
|
||||
tclinc="$tclloc/include $tclloc/include/tcl $tclloc/include/tcl$tclver /usr/local/include /usr/include /usr/include/tcl$tclver"
|
||||
else
|
||||
tclinc="/System/Library/Frameworks/Tcl.framework/Headers"
|
||||
fi
|
||||
TCL_INC=
|
||||
for try in $tclinc; do
|
||||
if test -f "$try/tcl.h"; then
|
||||
echo "$as_me:$LINENO: result: $try/tcl.h" >&5
|
||||
@@ -14259,7 +14349,7 @@ echo "${ECHO_T}$TAGPRG" >&6
|
||||
echo "$as_me:$LINENO: checking how to run man with a section nr" >&5
|
||||
echo $ECHO_N "checking how to run man with a section nr... $ECHO_C" >&6
|
||||
MANDEF="man"
|
||||
(eval man -s 2 read) < /dev/null > /dev/null 2>&5 && MANDEF="man -s"
|
||||
(eval MANPAGER=cat PAGER=cat man -s 2 read) < /dev/null > /dev/null 2>&5 && MANDEF="man -s"
|
||||
echo "$as_me:$LINENO: result: $MANDEF" >&5
|
||||
echo "${ECHO_T}$MANDEF" >&6
|
||||
if test "$MANDEF" = "man -s"; then
|
||||
|
||||
+4
-3
@@ -4922,7 +4922,7 @@ chk_modeline(lnum, flags)
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef FEAT_VIMINFO
|
||||
#if defined(FEAT_VIMINFO) || defined(PROTO)
|
||||
int
|
||||
read_viminfo_bufferlist(virp, writing)
|
||||
vir_T *virp;
|
||||
@@ -5043,13 +5043,14 @@ buf_spname(buf)
|
||||
#if defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)
|
||||
if (bt_quickfix(buf))
|
||||
{
|
||||
win_T *win;
|
||||
win_T *win = NULL;
|
||||
tabpage_T *tp;
|
||||
|
||||
/*
|
||||
* For location list window, w_llist_ref points to the location list.
|
||||
* For quickfix window, w_llist_ref is NULL.
|
||||
*/
|
||||
FOR_ALL_WINDOWS(win)
|
||||
FOR_ALL_TAB_WINDOWS(tp, win)
|
||||
if (win->w_buffer == buf)
|
||||
break;
|
||||
if (win != NULL && win->w_llist_ref != NULL)
|
||||
|
||||
+2
-1
@@ -1290,7 +1290,8 @@ getvcol(wp, pos, start, cursor, end)
|
||||
/* If a double-cell char doesn't fit at the end of a line
|
||||
* it wraps to the next line, it's like this char is three
|
||||
* cells wide. */
|
||||
if (incr == 2 && wp->w_p_wrap && in_win_border(wp, vcol))
|
||||
if (incr == 2 && wp->w_p_wrap && MB_BYTE2LEN(*ptr) > 1
|
||||
&& in_win_border(wp, vcol))
|
||||
{
|
||||
++incr;
|
||||
head = 1;
|
||||
|
||||
@@ -155,6 +155,7 @@
|
||||
#undef HAVE_READLINK
|
||||
#undef HAVE_RENAME
|
||||
#undef HAVE_SELECT
|
||||
#undef HAVE_SELINUX
|
||||
#undef HAVE_SETENV
|
||||
#undef HAVE_SETPGID
|
||||
#undef HAVE_SETSID
|
||||
|
||||
+16
-2
@@ -308,6 +308,19 @@ case `uname` in
|
||||
esac
|
||||
fi
|
||||
|
||||
dnl Link with -lselinux for SELinux stuff; if not found
|
||||
AC_MSG_CHECKING(--disable-selinux argument)
|
||||
AC_ARG_ENABLE(selinux,
|
||||
[ --disable-selinux Don't check for SELinux support.],
|
||||
, enable_selinux="yes")
|
||||
if test "$enable_selinux" = "yes"; then
|
||||
AC_MSG_RESULT(no)
|
||||
AC_CHECK_LIB(selinux, is_selinux_enabled,
|
||||
[LIBS="$LIBS -lselinux"
|
||||
AC_DEFINE(HAVE_SELINUX)])
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
fi
|
||||
|
||||
dnl Check user requested features.
|
||||
|
||||
@@ -803,11 +816,12 @@ if test "$enable_tclinterp" = "yes"; then
|
||||
|
||||
AC_MSG_CHECKING(for location of Tcl include)
|
||||
if test "x$MACOSX" != "xyes"; then
|
||||
tclinc="$tclloc/include $tclloc/include/tcl $tclloc/include/tcl$tclver /usr/local/include /usr/include"
|
||||
tclinc="$tclloc/include $tclloc/include/tcl $tclloc/include/tcl$tclver /usr/local/include /usr/local/include/tcl$tclver /usr/include /usr/include/tcl$tclver"
|
||||
else
|
||||
dnl For Mac OS X 10.3, use the OS-provided framework location
|
||||
tclinc="/System/Library/Frameworks/Tcl.framework/Headers"
|
||||
fi
|
||||
TCL_INC=
|
||||
for try in $tclinc; do
|
||||
if test -f "$try/tcl.h"; then
|
||||
AC_MSG_RESULT($try/tcl.h)
|
||||
@@ -2762,7 +2776,7 @@ AC_MSG_RESULT($TAGPRG) AC_SUBST(TAGPRG)
|
||||
dnl Check how we can run man with a section number
|
||||
AC_MSG_CHECKING(how to run man with a section nr)
|
||||
MANDEF="man"
|
||||
(eval man -s 2 read) < /dev/null > /dev/null 2>&AC_FD_CC && MANDEF="man -s"
|
||||
(eval MANPAGER=cat PAGER=cat man -s 2 read) < /dev/null > /dev/null 2>&AC_FD_CC && MANDEF="man -s"
|
||||
AC_MSG_RESULT($MANDEF)
|
||||
if test "$MANDEF" = "man -s"; then
|
||||
AC_DEFINE(USEMAN_S)
|
||||
|
||||
+1
-1
@@ -1365,7 +1365,7 @@ install_registry(void)
|
||||
|
||||
printf("Creating \"Edit with Vim\" popup menu entry\n");
|
||||
|
||||
fprintf(fd, "HKEY_CLASSES_ROOT\\CLSID\\%s\n", vim_ext_clsid);
|
||||
fprintf(fd, "[HKEY_CLASSES_ROOT\\CLSID\\%s]\n", vim_ext_clsid);
|
||||
fprintf(fd, "@=\"%s\"\n", vim_ext_name);
|
||||
fprintf(fd, "[HKEY_CLASSES_ROOT\\CLSID\\%s\\InProcServer32]\n",
|
||||
vim_ext_clsid);
|
||||
|
||||
+2
-2
@@ -5491,7 +5491,7 @@ insertchar(c, flags, second_indent)
|
||||
#if defined(FEAT_EVAL)
|
||||
int do_internal = TRUE;
|
||||
|
||||
if (*curbuf->b_p_fex != NUL)
|
||||
if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0)
|
||||
{
|
||||
do_internal = (fex_format(curwin->w_cursor.lnum, 1L, c) != 0);
|
||||
/* It may be required to save for undo again, e.g. when setline()
|
||||
@@ -6057,7 +6057,7 @@ auto_format(trailblank, prev_line)
|
||||
* be adjusted for the text formatting.
|
||||
*/
|
||||
saved_cursor = pos;
|
||||
format_lines((linenr_T)-1);
|
||||
format_lines((linenr_T)-1, FALSE);
|
||||
curwin->w_cursor = saved_cursor;
|
||||
saved_cursor.lnum = 0;
|
||||
|
||||
|
||||
+38
-11
@@ -532,6 +532,7 @@ static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_getline __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_getmatches __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_getpid __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
@@ -7132,6 +7133,7 @@ static struct fst
|
||||
{"getline", 1, 2, f_getline},
|
||||
{"getloclist", 1, 1, f_getqflist},
|
||||
{"getmatches", 0, 0, f_getmatches},
|
||||
{"getpid", 0, 0, f_getpid},
|
||||
{"getpos", 1, 1, f_getpos},
|
||||
{"getqflist", 0, 0, f_getqflist},
|
||||
{"getreg", 0, 2, f_getreg},
|
||||
@@ -9203,13 +9205,13 @@ f_filewritable(argvars, rettv)
|
||||
rettv->vval.v_number = filewritable(get_tv_string(&argvars[0]));
|
||||
}
|
||||
|
||||
static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir));
|
||||
static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int find_what));
|
||||
|
||||
static void
|
||||
findfilendir(argvars, rettv, dir)
|
||||
findfilendir(argvars, rettv, find_what)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
int dir;
|
||||
int find_what;
|
||||
{
|
||||
#ifdef FEAT_SEARCHPATH
|
||||
char_u *fname;
|
||||
@@ -9254,8 +9256,11 @@ findfilendir(argvars, rettv, dir)
|
||||
vim_free(fresult);
|
||||
fresult = find_file_in_path_option(first ? fname : NULL,
|
||||
first ? (int)STRLEN(fname) : 0,
|
||||
0, first, path, dir, curbuf->b_ffname,
|
||||
dir ? (char_u *)"" : curbuf->b_p_sua);
|
||||
0, first, path,
|
||||
find_what,
|
||||
curbuf->b_ffname,
|
||||
find_what == FINDFILE_DIR
|
||||
? (char_u *)"" : curbuf->b_p_sua);
|
||||
first = FALSE;
|
||||
|
||||
if (fresult != NULL && rettv->v_type == VAR_LIST)
|
||||
@@ -9445,7 +9450,7 @@ f_finddir(argvars, rettv)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
{
|
||||
findfilendir(argvars, rettv, TRUE);
|
||||
findfilendir(argvars, rettv, FINDFILE_DIR);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -9456,7 +9461,7 @@ f_findfile(argvars, rettv)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
{
|
||||
findfilendir(argvars, rettv, FALSE);
|
||||
findfilendir(argvars, rettv, FINDFILE_FILE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -10370,6 +10375,18 @@ f_getmatches(argvars, rettv)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* "getpid()" function
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
f_getpid(argvars, rettv)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
{
|
||||
rettv->vval.v_number = mch_get_pid();
|
||||
}
|
||||
|
||||
/*
|
||||
* "getpos(string)" function
|
||||
*/
|
||||
@@ -13957,6 +13974,7 @@ f_reverse(argvars, rettv)
|
||||
rettv->vval.v_list = l;
|
||||
rettv->v_type = VAR_LIST;
|
||||
++l->lv_refcount;
|
||||
l->lv_idx = l->lv_len - l->lv_idx - 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14665,6 +14683,8 @@ f_setline(argvars, rettv)
|
||||
appended_lines_mark(lcount, added);
|
||||
}
|
||||
|
||||
static void set_qf_ll_list __ARGS((win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv));
|
||||
|
||||
/*
|
||||
* Used by "setqflist()" and "setloclist()" functions
|
||||
*/
|
||||
@@ -14796,24 +14816,31 @@ f_setpos(argvars, rettv)
|
||||
int fnum;
|
||||
char_u *name;
|
||||
|
||||
rettv->vval.v_number = -1;
|
||||
name = get_tv_string_chk(argvars);
|
||||
if (name != NULL)
|
||||
{
|
||||
if (list2fpos(&argvars[1], &pos, &fnum) == OK)
|
||||
{
|
||||
--pos.col;
|
||||
if (name[0] == '.') /* cursor */
|
||||
if (name[0] == '.' && name[1] == NUL)
|
||||
{
|
||||
/* set cursor */
|
||||
if (fnum == curbuf->b_fnum)
|
||||
{
|
||||
curwin->w_cursor = pos;
|
||||
check_cursor();
|
||||
rettv->vval.v_number = 0;
|
||||
}
|
||||
else
|
||||
EMSG(_(e_invarg));
|
||||
}
|
||||
else if (name[0] == '\'') /* mark */
|
||||
(void)setmark_pos(name[1], &pos, fnum);
|
||||
else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL)
|
||||
{
|
||||
/* set mark */
|
||||
if (setmark_pos(name[1], &pos, fnum) == OK)
|
||||
rettv->vval.v_number = 0;
|
||||
}
|
||||
else
|
||||
EMSG(_(e_invarg));
|
||||
}
|
||||
@@ -15196,7 +15223,7 @@ f_sort(argvars, rettv)
|
||||
if (!item_compare_func_err)
|
||||
{
|
||||
/* Clear the List and append the items in the sorted order. */
|
||||
l->lv_first = l->lv_last = NULL;
|
||||
l->lv_first = l->lv_last = l->lv_idx_item = NULL;
|
||||
l->lv_len = 0;
|
||||
for (i = 0; i < len; ++i)
|
||||
list_append(l, ptrs[i]);
|
||||
|
||||
+9
-1
@@ -365,6 +365,10 @@ ex_sort(eap)
|
||||
int sort_oct; /* sort on octal number */
|
||||
int sort_hex; /* sort on hex number */
|
||||
|
||||
/* Sorting one line is really quick! */
|
||||
if (count <= 1)
|
||||
return;
|
||||
|
||||
if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL)
|
||||
return;
|
||||
sortbuf1 = NULL;
|
||||
@@ -1156,6 +1160,7 @@ do_filter(line1, line2, eap, cmd, do_in, do_out)
|
||||
if (!do_out)
|
||||
msg_putchar('\n');
|
||||
|
||||
/* Create the shell command in allocated memory. */
|
||||
cmd_buf = make_filter_cmd(cmd, itmp, otmp);
|
||||
if (cmd_buf == NULL)
|
||||
goto filterend;
|
||||
@@ -1176,7 +1181,10 @@ do_filter(line1, line2, eap, cmd, do_in, do_out)
|
||||
if (do_out)
|
||||
{
|
||||
if (u_save((linenr_T)(line2), (linenr_T)(line2 + 1)) == FAIL)
|
||||
{
|
||||
vim_free(cmd_buf);
|
||||
goto error;
|
||||
}
|
||||
redraw_curbuf_later(VALID);
|
||||
}
|
||||
read_linecount = curbuf->b_ml.ml_line_count;
|
||||
@@ -4467,7 +4475,7 @@ do_sub(eap)
|
||||
/*
|
||||
* The new text is build up step by step, to avoid too much
|
||||
* copying. There are these pieces:
|
||||
* sub_firstline The old text, unmodifed.
|
||||
* sub_firstline The old text, unmodified.
|
||||
* copycol Column in the old text where we started
|
||||
* looking for a match; from here old text still
|
||||
* needs to be copied to the new text.
|
||||
|
||||
+2
-2
@@ -597,8 +597,8 @@ EX(CMD_match, "match", ex_match,
|
||||
RANGE|NOTADR|EXTRA|CMDWIN),
|
||||
EX(CMD_macaction, "macaction", ex_macaction,
|
||||
EXTRA|NOSPC|NEEDARG),
|
||||
EX(CMD_macmenukey, "macmenukey", ex_macmenukey,
|
||||
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
|
||||
EX(CMD_macmenu, "macmenu", ex_macmenu,
|
||||
EXTRA|TRLBAR|CMDWIN),
|
||||
EX(CMD_menu, "menu", ex_menu,
|
||||
RANGE|NOTADR|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
|
||||
EX(CMD_menutranslate, "menutranslate", ex_menutranslate,
|
||||
|
||||
+14
-7
@@ -466,7 +466,7 @@ static void ex_folddo __ARGS((exarg_T *eap));
|
||||
|
||||
#ifndef FEAT_GUI_MACVIM
|
||||
# define ex_macaction ex_ni
|
||||
# define ex_macmenukey ex_ni
|
||||
# define ex_macmenu ex_ni
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -3015,7 +3015,7 @@ modifier_len(cmd)
|
||||
break;
|
||||
if (!isalpha(p[j]) && j >= cmdmods[i].minlen
|
||||
&& (p == cmd || cmdmods[i].has_count))
|
||||
return j + (p - cmd);
|
||||
return j + (int)(p - cmd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -3352,6 +3352,7 @@ set_one_cmd_context(xp, buff)
|
||||
#endif
|
||||
))
|
||||
{
|
||||
len = 0; /* avoid getting stuck when space is in 'isfname' */
|
||||
while (*p != NUL)
|
||||
{
|
||||
#ifdef FEAT_MBYTE
|
||||
@@ -3763,7 +3764,7 @@ set_one_cmd_context(xp, buff)
|
||||
case CMD_tmenu: case CMD_tunmenu:
|
||||
case CMD_popup: case CMD_tearoff: case CMD_emenu:
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
case CMD_macmenukey:
|
||||
case CMD_macmenu:
|
||||
#endif
|
||||
return set_context_in_menu_cmd(xp, cmd, arg, forceit);
|
||||
#endif
|
||||
@@ -3791,6 +3792,14 @@ set_one_cmd_context(xp, buff)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
case CMD_macaction:
|
||||
xp->xp_context = EXPAND_MACACTION;
|
||||
xp->xp_pattern = arg;
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* FEAT_CMDL_COMPL */
|
||||
|
||||
default:
|
||||
@@ -3940,8 +3949,7 @@ get_address(ptr, skip, to_other_file)
|
||||
curwin->w_cursor.col = 0;
|
||||
searchcmdlen = 0;
|
||||
if (!do_search(NULL, c, cmd, 1L,
|
||||
SEARCH_HIS + SEARCH_MSG + SEARCH_START,
|
||||
NULL))
|
||||
SEARCH_HIS | SEARCH_MSG, NULL))
|
||||
{
|
||||
curwin->w_cursor = pos;
|
||||
cmd = NULL;
|
||||
@@ -3988,8 +3996,7 @@ get_address(ptr, skip, to_other_file)
|
||||
pos.col = 0;
|
||||
if (searchit(curwin, curbuf, &pos,
|
||||
*cmd == '?' ? BACKWARD : FORWARD,
|
||||
(char_u *)"", 1L,
|
||||
SEARCH_MSG + SEARCH_START,
|
||||
(char_u *)"", 1L, SEARCH_MSG,
|
||||
i, (linenr_T)0, NULL) != FAIL)
|
||||
lnum = pos.lnum;
|
||||
else
|
||||
|
||||
@@ -4449,6 +4449,9 @@ ExpandFromContext(xp, pat, num_file, file, options)
|
||||
{EXPAND_LANGUAGE, get_lang_arg, TRUE},
|
||||
#endif
|
||||
{EXPAND_ENV_VARS, get_env_name, TRUE},
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
{EXPAND_MACACTION, get_macaction_name, FALSE},
|
||||
#endif
|
||||
};
|
||||
int i;
|
||||
|
||||
|
||||
@@ -1296,3 +1296,10 @@
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
#define FEAT_GUI_SCROLL_WHEEL_FORCE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Support for enabling/disabling antialiased text.
|
||||
*/
|
||||
#if defined(FEAT_GUI) && defined(MACOS_X)
|
||||
#define FEAT_ANTIALIAS
|
||||
#endif
|
||||
|
||||
+17
-4
@@ -3651,6 +3651,9 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit,
|
||||
)
|
||||
mch_setperm(backup,
|
||||
(perm & 0707) | ((perm & 07) << 3));
|
||||
# ifdef HAVE_SELINUX
|
||||
mch_copy_sec(fname, backup);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -3686,6 +3689,9 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit,
|
||||
#endif
|
||||
#ifdef HAVE_ACL
|
||||
mch_set_acl(backup, acl);
|
||||
#endif
|
||||
#ifdef HAVE_SELINUX
|
||||
mch_copy_sec(fname, backup);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -4309,6 +4315,12 @@ restore_backup:
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
/* Probably need to set the security context. */
|
||||
if (!backup_copy)
|
||||
mch_copy_sec(backup, wfname);
|
||||
#endif
|
||||
|
||||
#ifdef UNIX
|
||||
/* When creating a new file, set its owner/group to that of the original
|
||||
* file. Get the new device and inode number. */
|
||||
@@ -5518,10 +5530,11 @@ check_for_bom(p, size, lenp, flags)
|
||||
else if (p[0] == 0xfe && p[1] == 0xff
|
||||
&& (flags == FIO_ALL || flags == FIO_UCS2 || flags == FIO_UTF16))
|
||||
{
|
||||
if (flags == FIO_UTF16)
|
||||
name = "utf-16"; /* FE FF */
|
||||
else
|
||||
/* Default to utf-16, it works also for ucs-2 text. */
|
||||
if (flags == FIO_UCS2)
|
||||
name = "ucs-2"; /* FE FF */
|
||||
else
|
||||
name = "utf-16"; /* FE FF */
|
||||
}
|
||||
else if (size >= 4 && p[0] == 0 && p[1] == 0 && p[2] == 0xfe
|
||||
&& p[3] == 0xff && (flags == FIO_ALL || flags == FIO_UCS4))
|
||||
@@ -9243,7 +9256,7 @@ aucmd_prepbuf(aco, buf)
|
||||
aco_save_T *aco; /* structure to save values in */
|
||||
buf_T *buf; /* new curbuf */
|
||||
{
|
||||
aco->save_buf = buf;
|
||||
aco->save_buf = curbuf;
|
||||
curbuf = buf;
|
||||
curwin->w_buffer = buf;
|
||||
}
|
||||
|
||||
+1
-1
@@ -2307,7 +2307,7 @@ foldUpdateIEMS(wp, top, bot)
|
||||
|
||||
/* If some fold changed, need to redraw and position cursor. */
|
||||
if (fold_changed && wp->w_p_fen)
|
||||
changed_window_setting();
|
||||
changed_window_setting_win(wp);
|
||||
|
||||
/* If we updated folds past "bot", need to redraw more lines. Don't do
|
||||
* this in other situations, the changed lines will be redrawn anyway and
|
||||
|
||||
+1
-1
@@ -1263,7 +1263,7 @@ EXTERN int echo_wid_arg INIT(= FALSE); /* --echo-wid argument */
|
||||
* The value of the --windowid argument.
|
||||
* For embedding gvim inside another application.
|
||||
*/
|
||||
EXTERN int win_socket_id INIT(= 0);
|
||||
EXTERN long_u win_socket_id INIT(= 0);
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_CLIENTSERVER) || defined(FEAT_EVAL)
|
||||
|
||||
@@ -163,6 +163,10 @@ http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/fork.2.h
|
||||
}
|
||||
newargv[argc+1] = NULL;
|
||||
|
||||
/* shut down all the stuff we just started, just to start
|
||||
* it again from the exec :-\ */
|
||||
prepare_getout();
|
||||
|
||||
pid = fork();
|
||||
switch(pid) {
|
||||
case -1:
|
||||
@@ -173,10 +177,6 @@ http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/fork.2.h
|
||||
case 0:
|
||||
/* Child. */
|
||||
|
||||
/* shut down all the stuff we just started, just to start
|
||||
* it again from the exec :-\ */
|
||||
prepare_getout();
|
||||
|
||||
/* make sure we survive our shell */
|
||||
setsid();
|
||||
|
||||
@@ -1383,11 +1383,7 @@ again:
|
||||
out_flush();
|
||||
|
||||
gui.num_cols = (pixel_width - gui_get_base_width()) / gui.char_width;
|
||||
gui.num_rows = (pixel_height - gui_get_base_height()
|
||||
#if !defined(FEAT_GUI_PHOTON) && !defined(FEAT_GUI_MSWIN)
|
||||
+ (gui.char_height / 2)
|
||||
#endif
|
||||
) / gui.char_height;
|
||||
gui.num_rows = (pixel_height - gui_get_base_height()) / gui.char_height;
|
||||
|
||||
gui_position_components(pixel_width);
|
||||
|
||||
@@ -4959,6 +4955,15 @@ gui_update_screen()
|
||||
{
|
||||
update_topline();
|
||||
validate_cursor();
|
||||
#ifdef FEAT_AUTOCMD
|
||||
/* Trigger CursorMoved if the cursor moved. */
|
||||
if (!finish_op && has_cursormoved()
|
||||
&& !equalpos(last_cursormoved, curwin->w_cursor))
|
||||
{
|
||||
apply_autocmds(EVENT_CURSORMOVED, NULL, NULL, FALSE, curbuf);
|
||||
last_cursormoved = curwin->w_cursor;
|
||||
}
|
||||
#endif
|
||||
update_screen(0); /* may need to update the screen */
|
||||
setcursor();
|
||||
out_flush(); /* make sure output has been written */
|
||||
|
||||
@@ -495,7 +495,7 @@ typedef struct Gui
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_GUI_SCROLL_WHEEL_FORCE
|
||||
int scroll_wheel_force;
|
||||
int scroll_wheel_force;
|
||||
#endif
|
||||
} gui_T;
|
||||
|
||||
|
||||
+667
-231
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Start GUI Vim on a copy of the tutor file.
|
||||
|
||||
# Usage: gvimtutor [xx]
|
||||
# See vimtutor for usage.
|
||||
|
||||
exec `dirname $0`/vimtutor -g "$@"
|
||||
+95
-16
@@ -1400,7 +1400,7 @@ cs_lookup_cmd(eap)
|
||||
return NULL;
|
||||
|
||||
/* Store length of eap->arg before it gets modified by strtok(). */
|
||||
eap_arg_len = STRLEN(eap->arg);
|
||||
eap_arg_len = (int)STRLEN(eap->arg);
|
||||
|
||||
if ((stok = strtok((char *)(eap->arg), (const char *)" ")) == NULL)
|
||||
return NULL;
|
||||
@@ -2096,6 +2096,18 @@ cs_read_prompt(i)
|
||||
return CSCOPE_SUCCESS;
|
||||
}
|
||||
|
||||
#if defined(UNIX) && defined(SIGALRM)
|
||||
/*
|
||||
* Used to catch and ignore SIGALRM below.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static RETSIGTYPE
|
||||
sig_handler SIGDEFARG(sigarg)
|
||||
{
|
||||
/* do nothing */
|
||||
SIGRETURN;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PRIVATE: cs_release_csp
|
||||
@@ -2108,9 +2120,6 @@ cs_release_csp(i, freefnpp)
|
||||
int i;
|
||||
int freefnpp;
|
||||
{
|
||||
#if defined(UNIX)
|
||||
int pstat;
|
||||
#else
|
||||
/*
|
||||
* Trying to exit normally (not sure whether it is fit to UNIX cscope
|
||||
*/
|
||||
@@ -2119,6 +2128,88 @@ cs_release_csp(i, freefnpp)
|
||||
(void)fputs("q\n", csinfo[i].to_fp);
|
||||
(void)fflush(csinfo[i].to_fp);
|
||||
}
|
||||
#if defined(UNIX)
|
||||
{
|
||||
int waitpid_errno;
|
||||
int pstat;
|
||||
pid_t pid;
|
||||
|
||||
# if defined(HAVE_SIGACTION)
|
||||
struct sigaction sa, old;
|
||||
|
||||
/* Use sigaction() to limit the waiting time to two seconds. */
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_handler = sig_handler;
|
||||
sa.sa_flags = SA_NODEFER;
|
||||
sigaction(SIGALRM, &sa, &old);
|
||||
alarm(2); /* 2 sec timeout */
|
||||
|
||||
/* Block until cscope exits or until timer expires */
|
||||
pid = waitpid(csinfo[i].pid, &pstat, 0);
|
||||
waitpid_errno = errno;
|
||||
|
||||
/* cancel pending alarm if still there and restore signal */
|
||||
alarm(0);
|
||||
sigaction(SIGALRM, &old, NULL);
|
||||
# else
|
||||
int waited;
|
||||
|
||||
/* Can't use sigaction(), loop for two seconds. First yield the CPU
|
||||
* to give cscope a chance to exit quickly. */
|
||||
sleep(0);
|
||||
for (waited = 0; waited < 40; ++waited)
|
||||
{
|
||||
pid = waitpid(csinfo[i].pid, &pstat, WNOHANG);
|
||||
waitpid_errno = errno;
|
||||
if (pid != 0)
|
||||
break; /* break unless the process is still running */
|
||||
mch_delay(50L, FALSE); /* sleep 50 ms */
|
||||
}
|
||||
# endif
|
||||
/*
|
||||
* If the cscope process is still running: kill it.
|
||||
* Safety check: If the PID would be zero here, the entire X session
|
||||
* would be killed. -1 and 1 are dangerous as well.
|
||||
*/
|
||||
if (pid < 0 && csinfo[i].pid > 1)
|
||||
{
|
||||
# ifdef ECHILD
|
||||
int alive = TRUE;
|
||||
|
||||
if (waitpid_errno == ECHILD)
|
||||
{
|
||||
/*
|
||||
* When using 'vim -g', vim is forked and cscope process is
|
||||
* no longer a child process but a sibling. So waitpid()
|
||||
* fails with errno being ECHILD (No child processes).
|
||||
* Don't send SIGKILL to cscope immediately but wait
|
||||
* (polling) for it to exit normally as result of sending
|
||||
* the "q" command, hence giving it a chance to clean up
|
||||
* its temporary files.
|
||||
*/
|
||||
int waited;
|
||||
|
||||
sleep(0);
|
||||
for (waited = 0; waited < 40; ++waited)
|
||||
{
|
||||
/* Check whether cscope process is still alive */
|
||||
if (kill(csinfo[i].pid, 0) != 0)
|
||||
{
|
||||
alive = FALSE; /* cscope process no longer exists */
|
||||
break;
|
||||
}
|
||||
mch_delay(50L, FALSE); /* sleep 50ms */
|
||||
}
|
||||
}
|
||||
if (alive)
|
||||
# endif
|
||||
{
|
||||
kill(csinfo[i].pid, SIGKILL);
|
||||
(void)waitpid(csinfo[i].pid, &pstat, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else /* !UNIX */
|
||||
if (csinfo[i].hProc != NULL)
|
||||
{
|
||||
/* Give cscope a chance to exit normally */
|
||||
@@ -2133,18 +2224,6 @@ cs_release_csp(i, freefnpp)
|
||||
if (csinfo[i].to_fp != NULL)
|
||||
(void)fclose(csinfo[i].to_fp);
|
||||
|
||||
/*
|
||||
* Safety check: If the PID would be zero here, the entire X session would
|
||||
* be killed. -1 and 1 are dangerous as well.
|
||||
*/
|
||||
#if defined(UNIX)
|
||||
if (csinfo[i].pid > 1)
|
||||
{
|
||||
kill(csinfo[i].pid, SIGTERM);
|
||||
(void)waitpid(csinfo[i].pid, &pstat, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (freefnpp)
|
||||
{
|
||||
vim_free(csinfo[i].fname);
|
||||
|
||||
+9
-3
@@ -34,6 +34,12 @@ extern HWND s_hwnd;
|
||||
extern HWND vim_parent_hwnd;
|
||||
}
|
||||
|
||||
#if _MSC_VER < 1300
|
||||
/* Work around old versions of basetsd.h which wrongly declares
|
||||
* UINT_PTR as unsigned long */
|
||||
# define UINT_PTR UINT
|
||||
#endif
|
||||
|
||||
#include "if_ole.h" // Interface definitions
|
||||
#include "iid_ole.c" // UUID definitions (compile here)
|
||||
|
||||
@@ -107,7 +113,7 @@ public:
|
||||
STDMETHOD(SendKeys)(BSTR keys);
|
||||
STDMETHOD(Eval)(BSTR expr, BSTR *result);
|
||||
STDMETHOD(SetForeground)(void);
|
||||
STDMETHOD(GetHwnd)(UINT *result);
|
||||
STDMETHOD(GetHwnd)(UINT_PTR *result);
|
||||
|
||||
private:
|
||||
// Constructor is private - create using CVim::Create()
|
||||
@@ -288,9 +294,9 @@ CVim::Invoke(
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CVim::GetHwnd(UINT *result)
|
||||
CVim::GetHwnd(UINT_PTR *result)
|
||||
{
|
||||
*result = (UINT) s_hwnd;
|
||||
*result = (UINT_PTR)s_hwnd;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -79,7 +79,7 @@ EXTERN_C const IID IID_IVim;
|
||||
virtual HRESULT STDMETHODCALLTYPE SetForeground( void) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetHwnd(
|
||||
/* [retval][out] */ UINT __RPC_FAR *result) = 0;
|
||||
/* [retval][out] */ UINT_PTR __RPC_FAR *result) = 0;
|
||||
|
||||
};
|
||||
|
||||
@@ -143,7 +143,7 @@ EXTERN_C const IID IID_IVim;
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetHwnd )(
|
||||
IVim __RPC_FAR * This,
|
||||
/* [retval][out] */ UINT __RPC_FAR *result);
|
||||
/* [retval][out] */ UINT_PTR __RPC_FAR *result);
|
||||
|
||||
END_INTERFACE
|
||||
} IVimVtbl;
|
||||
@@ -236,7 +236,7 @@ void __RPC_STUB IVim_SetForeground_Stub(
|
||||
|
||||
HRESULT STDMETHODCALLTYPE IVim_GetHwnd_Proxy(
|
||||
IVim __RPC_FAR * This,
|
||||
/* [retval][out] */ UINT __RPC_FAR *result);
|
||||
/* [retval][out] */ UINT_PTR __RPC_FAR *result);
|
||||
|
||||
|
||||
void __RPC_STUB IVim_GetHwnd_Stub(
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ interface IVim : IDispatch
|
||||
HRESULT SendKeys([in]BSTR keys);
|
||||
HRESULT Eval([in]BSTR expr, [out, retval]BSTR* result);
|
||||
HRESULT SetForeground(void);
|
||||
HRESULT GetHwnd([out, retval]UINT* result);
|
||||
HRESULT GetHwnd([out, retval]UINT_PTR* result);
|
||||
};
|
||||
|
||||
// Component and type library definitions
|
||||
|
||||
+4
-4
@@ -1605,15 +1605,15 @@ early_arg_scan(parmp)
|
||||
else if (STRICMP(argv[i], "--socketid") == 0)
|
||||
# endif
|
||||
{
|
||||
unsigned int id;
|
||||
int count;
|
||||
long_u id;
|
||||
int count;
|
||||
|
||||
if (i == argc - 1)
|
||||
mainerr_arg_missing((char_u *)argv[i]);
|
||||
if (STRNICMP(argv[i+1], "0x", 2) == 0)
|
||||
count = sscanf(&(argv[i + 1][2]), "%x", &id);
|
||||
count = sscanf(&(argv[i + 1][2]), SCANF_HEX_LONG_U, &id);
|
||||
else
|
||||
count = sscanf(argv[i+1], "%u", &id);
|
||||
count = sscanf(argv[i + 1], SCANF_DECIMAL_LONG_U, &id);
|
||||
if (count != 1)
|
||||
mainerr(ME_INVALID_ARG, (char_u *)argv[i]);
|
||||
else
|
||||
|
||||
+7
-1
@@ -79,6 +79,12 @@ setmark_pos(c, pos, fnum)
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (c == '"')
|
||||
{
|
||||
curbuf->b_last_cursor = *pos;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Allow setting '[ and '] for an autocommand that simulates reading a
|
||||
* file. */
|
||||
if (c == '[')
|
||||
@@ -516,7 +522,7 @@ fname2fnum(fm)
|
||||
int len;
|
||||
|
||||
expand_env((char_u *)"~/", NameBuff, MAXPATHL);
|
||||
len = STRLEN(NameBuff);
|
||||
len = (int)STRLEN(NameBuff);
|
||||
vim_strncpy(NameBuff + len, fm->fname + 2, MAXPATHL - len - 1);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -360,6 +360,12 @@ enc_alias_table[] =
|
||||
{"ucs4be", IDX_UCS4},
|
||||
{"ucs-4be", IDX_UCS4},
|
||||
{"ucs4le", IDX_UCS4LE},
|
||||
{"utf32", IDX_UCS4},
|
||||
{"utf-32", IDX_UCS4},
|
||||
{"utf32be", IDX_UCS4},
|
||||
{"utf-32be", IDX_UCS4},
|
||||
{"utf32le", IDX_UCS4LE},
|
||||
{"utf-32le", IDX_UCS4LE},
|
||||
{"932", IDX_CP932},
|
||||
{"949", IDX_CP949},
|
||||
{"936", IDX_CP936},
|
||||
|
||||
@@ -1346,5 +1346,10 @@ mf_do_open(mfp, fname, flags)
|
||||
mfp->mf_ffname = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_SELINUX
|
||||
mch_copy_sec(fname, mfp->mf_fname);
|
||||
#endif
|
||||
mch_hide(mfp->mf_fname); /* try setting the 'hidden' flag */
|
||||
}
|
||||
}
|
||||
|
||||
+354
-101
@@ -1038,6 +1038,9 @@ free_menu(menup)
|
||||
# ifdef FEAT_GUI_MOTIF
|
||||
vim_free(menu->xpm_fname);
|
||||
# endif
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
vim_free(menu->mac_action);
|
||||
#endif
|
||||
#endif
|
||||
for (i = 0; i < MENU_MODES; i++)
|
||||
free_menu_string(menu, i);
|
||||
@@ -2137,6 +2140,9 @@ ex_emenu(eap)
|
||||
char_u *p;
|
||||
int idx;
|
||||
char_u *mode;
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
char_u *old_arg;
|
||||
#endif
|
||||
|
||||
saved_name = vim_strsave(eap->arg);
|
||||
if (saved_name == NULL)
|
||||
@@ -2243,8 +2249,10 @@ ex_emenu(eap)
|
||||
idx = MENU_INDEX_NORMAL;
|
||||
}
|
||||
|
||||
if (idx != MENU_INDEX_INVALID && menu->strings[idx] != NULL)
|
||||
if (idx != MENU_INDEX_INVALID && menu->strings[idx] != NULL &&
|
||||
menu->strings[idx][0] != NUL)
|
||||
{
|
||||
|
||||
/* When executing a script or function execute the commands right now.
|
||||
* Otherwise put them in the typeahead buffer. */
|
||||
#ifdef FEAT_EVAL
|
||||
@@ -2256,6 +2264,19 @@ ex_emenu(eap)
|
||||
ins_typebuf(menu->strings[idx], menu->noremap[idx], 0,
|
||||
TRUE, menu->silent[idx]);
|
||||
}
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
else if (menu->mac_action != NULL && menu->strings[idx][0] == NUL)
|
||||
{
|
||||
/* This allows us to bind a menu to an action without mapping to
|
||||
* anything so that pressing the menu's key equivalent and typing
|
||||
* ":emenu ..." does the same thing. (HACK: We count on the fact that
|
||||
* ex_macaction() only looks at eap->arg.) */
|
||||
old_arg = eap->arg;
|
||||
eap->arg = menu->mac_action;
|
||||
ex_macaction(eap);
|
||||
eap->arg = old_arg;
|
||||
}
|
||||
#endif /* FEAT_GUI_MACVIM */
|
||||
else
|
||||
EMSG2(_("E335: Menu not defined for %s mode"), mode);
|
||||
}
|
||||
@@ -2473,32 +2494,145 @@ menutrans_lookup(name, len)
|
||||
|
||||
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
vimmenu_T *
|
||||
menu_for_path(char_u *menu_path)
|
||||
{
|
||||
vimmenu_T *menu;
|
||||
char_u *name;
|
||||
char_u *saved_name;
|
||||
char_u *p;
|
||||
|
||||
saved_name = vim_strsave(menu_path);
|
||||
if (saved_name == NULL)
|
||||
return NULL;
|
||||
|
||||
menu = root_menu;
|
||||
name = saved_name;
|
||||
while (*name)
|
||||
{
|
||||
/* Find in the menu hierarchy */
|
||||
p = menu_name_skip(name);
|
||||
|
||||
while (menu != NULL)
|
||||
{
|
||||
if (menu_name_equal(name, menu))
|
||||
{
|
||||
if (*p == NUL && menu->children != NULL)
|
||||
{
|
||||
EMSG(_("E333: Menu path must lead to a menu item"));
|
||||
menu = NULL;
|
||||
}
|
||||
else if (*p != NUL && menu->children == NULL)
|
||||
{
|
||||
EMSG(_(e_notsubmenu));
|
||||
menu = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
menu = menu->next;
|
||||
}
|
||||
if (menu == NULL || *p == NUL)
|
||||
break;
|
||||
menu = menu->children;
|
||||
name = p;
|
||||
}
|
||||
|
||||
vim_free(saved_name);
|
||||
|
||||
if (menu == NULL)
|
||||
{
|
||||
EMSG2(_("E334: Menu not found: %s"), menu_path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle the ":macmenu" command.
|
||||
*/
|
||||
void
|
||||
ex_macmenukey(eap)
|
||||
ex_macmenu(eap)
|
||||
exarg_T *eap;
|
||||
{
|
||||
char_u *arg = eap->arg;
|
||||
char_u *keys, *name, *p;
|
||||
vimmenu_T *menu;
|
||||
vimmenu_T *menu = NULL;
|
||||
char_u *arg;
|
||||
char_u *menu_path;
|
||||
char_u *p;
|
||||
char_u *keys;
|
||||
int len;
|
||||
#ifdef FEAT_MULTI_LANG
|
||||
char_u *tofree = NULL;
|
||||
char_u *new_cmd;
|
||||
#endif
|
||||
char_u *linep;
|
||||
char_u *key_start;
|
||||
char_u *key = NULL;
|
||||
char_u *arg_start = NULL;
|
||||
int error = FALSE;
|
||||
char_u *action = NULL;
|
||||
int mac_key = 0;
|
||||
int mac_mods = 0;
|
||||
int mac_alternate = 0;
|
||||
char_u *last_dash;
|
||||
int modifiers;
|
||||
int bit;
|
||||
int key;
|
||||
int set_action = FALSE;
|
||||
int set_key = FALSE;
|
||||
int set_alt = FALSE;
|
||||
|
||||
arg = eap->arg;
|
||||
|
||||
#ifdef FEAT_MULTI_LANG
|
||||
/*
|
||||
* Translate menu names as specified with ":menutrans" commands.
|
||||
*/
|
||||
menu_path = arg;
|
||||
while (*menu_path)
|
||||
{
|
||||
/* find the end of one part and check if it should be translated */
|
||||
p = menu_skip_part(menu_path);
|
||||
keys = menutrans_lookup(menu_path, (int)(p - menu_path));
|
||||
if (keys != NULL)
|
||||
{
|
||||
/* found a match: replace with the translated part */
|
||||
len = (int)STRLEN(keys);
|
||||
new_cmd = alloc((unsigned)STRLEN(arg) + len + 1);
|
||||
if (new_cmd == NULL)
|
||||
break;
|
||||
mch_memmove(new_cmd, arg, menu_path - arg);
|
||||
mch_memmove(new_cmd + (menu_path - arg), keys, (size_t)len);
|
||||
STRCPY(new_cmd + (menu_path - arg) + len, p);
|
||||
p = new_cmd + (menu_path - arg) + len;
|
||||
vim_free(tofree);
|
||||
tofree = new_cmd;
|
||||
arg = new_cmd;
|
||||
}
|
||||
if (*p != '.')
|
||||
break;
|
||||
menu_path = p + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Isolate the menu name.
|
||||
* Skip the menu name, and translate <Tab> into a real TAB.
|
||||
*/
|
||||
name = arg;
|
||||
if (*name == '.')
|
||||
menu_path = arg;
|
||||
if (*menu_path == '.')
|
||||
{
|
||||
EMSG2(_(e_invarg2), name);
|
||||
return;
|
||||
EMSG2(_(e_invarg2), menu_path);
|
||||
goto theend;
|
||||
}
|
||||
|
||||
while (*arg && !vim_iswhite(*arg))
|
||||
{
|
||||
if ((*arg == '\\' || *arg == Ctrl_V) && arg[1] != NUL)
|
||||
arg++;
|
||||
else if (STRNICMP(arg, "<TAB>", 5) == 0)
|
||||
{
|
||||
*arg = TAB;
|
||||
mch_memmove(arg + 1, arg + 5, STRLEN(arg + 4));
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
if (*arg != NUL)
|
||||
@@ -2506,108 +2640,227 @@ ex_macmenukey(eap)
|
||||
arg = skipwhite(arg);
|
||||
keys = arg;
|
||||
|
||||
// TODO: move to gui_find_menu_item(path_name)
|
||||
menu = root_menu;
|
||||
while (*name)
|
||||
{
|
||||
/* find the end of one dot-separated name and put a NUL at the dot */
|
||||
p = menu_name_skip(name);
|
||||
menu = menu_for_path(menu_path);
|
||||
if (!menu) goto theend;
|
||||
|
||||
while (menu != NULL)
|
||||
/*
|
||||
* Parse all key=value arguments.
|
||||
*/
|
||||
arg = NULL;
|
||||
linep = keys;
|
||||
while (!ends_excmd(*linep))
|
||||
{
|
||||
key_start = linep;
|
||||
if (*linep == '=')
|
||||
{
|
||||
if (STRCMP(name, menu->name) == 0 || STRCMP(name, menu->dname) == 0)
|
||||
{
|
||||
if (*p == NUL)
|
||||
{
|
||||
if (menu->children != NULL)
|
||||
menu = NULL;
|
||||
goto search_end;
|
||||
}
|
||||
break;
|
||||
}
|
||||
menu = menu->next;
|
||||
}
|
||||
if (menu == NULL) /* didn't find it */
|
||||
EMSG2(_("E415: unexpected equal sign: %s"), key_start);
|
||||
error = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Found a match, search the sub-menu. */
|
||||
menu = menu->children;
|
||||
name = p;
|
||||
/*
|
||||
* Isolate the key ("action", "alt", or "key").
|
||||
*/
|
||||
while (*linep && !vim_iswhite(*linep) && *linep != '=')
|
||||
++linep;
|
||||
vim_free(key);
|
||||
key = vim_strnsave_up(key_start, (int)(linep - key_start));
|
||||
if (key == NULL)
|
||||
{
|
||||
error = TRUE;
|
||||
break;
|
||||
}
|
||||
linep = skipwhite(linep);
|
||||
|
||||
/*
|
||||
* Check for the equal sign.
|
||||
*/
|
||||
if (*linep != '=')
|
||||
{
|
||||
EMSG2(_("E416: missing equal sign: %s"), key_start);
|
||||
error = TRUE;
|
||||
break;
|
||||
}
|
||||
++linep;
|
||||
|
||||
/*
|
||||
* Isolate the argument.
|
||||
*/
|
||||
linep = skipwhite(linep);
|
||||
arg_start = linep;
|
||||
linep = skiptowhite(linep);
|
||||
|
||||
if (linep == arg_start)
|
||||
{
|
||||
EMSG2(_("E417: missing argument: %s"), key_start);
|
||||
error = TRUE;
|
||||
break;
|
||||
}
|
||||
vim_free(arg);
|
||||
arg = vim_strnsave(arg_start, (int)(linep - arg_start));
|
||||
if (arg == NULL)
|
||||
{
|
||||
error = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the argument.
|
||||
*/
|
||||
if (STRCMP(key, "ACTION") == 0)
|
||||
{
|
||||
action = vim_strsave(arg);
|
||||
if (action == NULL)
|
||||
{
|
||||
error = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_valid_macaction(action))
|
||||
{
|
||||
EMSG2(_("E???: Invalid action: %s"), arg);
|
||||
error = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
set_action = TRUE;
|
||||
}
|
||||
else if (STRCMP(key, "ALT") == 0)
|
||||
{
|
||||
len = (int)STRLEN(arg);
|
||||
if ( (len == 1 && (*arg == '0' || *arg == '1')) ||
|
||||
(STRICMP("no", arg) == 0 || STRICMP("yes", arg) == 0) )
|
||||
{
|
||||
mac_alternate = (*arg == '1' || STRICMP("yes", arg) == 0);
|
||||
set_alt = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
EMSG2(_(e_invarg2), arg);
|
||||
error = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (STRCMP(key, "KEY") == 0)
|
||||
{
|
||||
if (arg[0] != '<')
|
||||
{
|
||||
EMSG2(_(e_invarg2), arg);
|
||||
error = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (STRICMP("<nop>", arg) == 0)
|
||||
{
|
||||
/* This is to let the user unset a key equivalent, thereby
|
||||
* freeing up that key combination to be used for a :map
|
||||
* command (which would otherwise not be possible since key
|
||||
* equivalents take precedence over :map). */
|
||||
mac_key = 0;
|
||||
mac_mods = 0;
|
||||
set_key = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Find end of modifier list */
|
||||
last_dash = arg;
|
||||
for (p = arg + 1; *p == '-' || vim_isIDc(*p); p++)
|
||||
{
|
||||
if (*p == '-')
|
||||
{
|
||||
last_dash = p;
|
||||
if (p[1] != NUL && p[2] == '>')
|
||||
++p; /* anything accepted, like <C-?> */
|
||||
}
|
||||
if (p[0] == 't' && p[1] == '_' && p[2] && p[3])
|
||||
p += 3; /* skip t_xx, xx may be '-' or '>' */
|
||||
}
|
||||
|
||||
if (*p == '>') /* found matching '>' */
|
||||
{
|
||||
/* Which modifiers are given? */
|
||||
mac_mods = 0x0;
|
||||
for (p = arg + 1; p < last_dash; p++)
|
||||
{
|
||||
if (*p != '-')
|
||||
{
|
||||
bit = name_to_mod_mask(*p);
|
||||
if (bit == 0x0)
|
||||
break; /* Illegal modifier name */
|
||||
mac_mods |= bit;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Legal modifier name.
|
||||
*/
|
||||
if (p >= last_dash)
|
||||
{
|
||||
/*
|
||||
* Modifier with single letter, or special key name.
|
||||
*/
|
||||
if (mac_mods != 0 && last_dash[2] == '>')
|
||||
mac_key = last_dash[1];
|
||||
else
|
||||
{
|
||||
mac_key = get_special_key_code(last_dash + 1);
|
||||
mac_key = handle_x_keys(mac_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_key = (mac_key != 0);
|
||||
|
||||
if (mac_key == 0)
|
||||
{
|
||||
EMSG2(_(e_invarg2), arg);
|
||||
error = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EMSG2(_(e_invarg2), key_start);
|
||||
error = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Continue with next argument.
|
||||
*/
|
||||
linep = skipwhite(linep);
|
||||
}
|
||||
|
||||
search_end:
|
||||
if (!menu) {
|
||||
EMSG(_("E337: Menu not found - check menu names"));
|
||||
return;
|
||||
}
|
||||
vim_free(key);
|
||||
vim_free(arg);
|
||||
|
||||
if (keys[0] == '<')
|
||||
/*
|
||||
* Store all the keys that were set in the menu item.
|
||||
*/
|
||||
if (!error)
|
||||
{
|
||||
key = 0;
|
||||
|
||||
/* Find end of modifier list */
|
||||
last_dash = keys;
|
||||
for (p = keys + 1; *p == '-' || vim_isIDc(*p); p++)
|
||||
{
|
||||
if (*p == '-')
|
||||
{
|
||||
last_dash = p;
|
||||
if (p[1] != NUL && p[2] == '>')
|
||||
++p; /* anything accepted, like <C-?> */
|
||||
}
|
||||
if (p[0] == 't' && p[1] == '_' && p[2] && p[3])
|
||||
p += 3; /* skip t_xx, xx may be '-' or '>' */
|
||||
}
|
||||
|
||||
if (*p == '>') /* found matching '>' */
|
||||
{
|
||||
/* Which modifiers are given? */
|
||||
modifiers = 0x0;
|
||||
for (p = keys + 1; p < last_dash; p++)
|
||||
{
|
||||
if (*p != '-')
|
||||
{
|
||||
bit = name_to_mod_mask(*p);
|
||||
if (bit == 0x0)
|
||||
break; /* Illegal modifier name */
|
||||
modifiers |= bit;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Legal modifier name.
|
||||
*/
|
||||
if (p >= last_dash)
|
||||
{
|
||||
/*
|
||||
* Modifier with single letter, or special key name.
|
||||
*/
|
||||
if (modifiers != 0 && last_dash[2] == '>')
|
||||
key = last_dash[1];
|
||||
else
|
||||
{
|
||||
key = get_special_key_code(last_dash + 1);
|
||||
key = handle_x_keys(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (key != 0)
|
||||
{
|
||||
menu->mac_key = key;
|
||||
menu->mac_mods = modifiers;
|
||||
}
|
||||
}
|
||||
else if (keys[0] == NUL)
|
||||
{
|
||||
/* Clear the key equivalent */
|
||||
menu->mac_key = 0;
|
||||
menu->mac_mods = 0;
|
||||
if (set_action)
|
||||
menu->mac_action = action;
|
||||
if (set_key)
|
||||
{
|
||||
menu->mac_key = mac_key;
|
||||
menu->mac_mods = mac_mods;
|
||||
}
|
||||
if (set_alt)
|
||||
menu->mac_alternate = mac_alternate;
|
||||
}
|
||||
else
|
||||
{
|
||||
EMSG(_(e_invarg));
|
||||
vim_free(action);
|
||||
}
|
||||
|
||||
theend:
|
||||
#ifdef FEAT_MULTI_LANG
|
||||
vim_free(tofree);
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif /* FEAT_GUI_MACVIM */
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user