mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-02 11:19:22 +02:00
Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3b966f9e01 | |||
| 8009a9912d | |||
| cdf043f0f9 | |||
| 757e8b4359 | |||
| 7b68b0b56d | |||
| 21b029712f | |||
| 80b4c97a2c | |||
| 404077032e | |||
| 04cd1420c1 | |||
| 46ae2ec9cb | |||
| 85cc2265e8 | |||
| 4c3907a8ff | |||
| f4fef46de2 | |||
| 28c76af675 | |||
| 9716d0b66f | |||
| 428d1b4412 | |||
| bf70f82498 | |||
| 89d9e60b8a | |||
| 0ea7546c7c | |||
| 321fdf61aa | |||
| 2fa74c01aa | |||
| c4222c6ebb | |||
| 1f538dc364 | |||
| 9471224d0b | |||
| 1d83527039 | |||
| 7752431b82 | |||
| 2ac28f887e | |||
| 9c517cb4e9 | |||
| 3915c6afc6 | |||
| a4569d06ac | |||
| cb120a21cf | |||
| 7070fd3f76 | |||
| 9f1b770ee6 | |||
| ebf10927c7 | |||
| e18186c461 | |||
| af279d2477 | |||
| 8c442b7b28 | |||
| 4c6ed9759c | |||
| d98e291038 | |||
| 092e0cc894 | |||
| b904b019b8 | |||
| c0159b8fdf | |||
| 11ec93a03a | |||
| c2f8b396de | |||
| fa15736b2b | |||
| d1a9e08f94 | |||
| 9d2727c56f | |||
| ce9c112020 | |||
| 0e2ddfca38 | |||
| 1f7de911ba | |||
| f6ab5cbc03 | |||
| 44d7e60b06 | |||
| 0e37f590ab | |||
| a0f684e003 | |||
| f54c3100e9 | |||
| a588fc3e33 | |||
| 039f611554 | |||
| 3a4682c9dd | |||
| fdc64858c5 | |||
| 45a9151fc6 | |||
| b9241163d8 | |||
| defa7bd098 | |||
| 6bfab82aca | |||
| 64959e3177 | |||
| 2eee45eb39 | |||
| 8d051eef4e | |||
| 7f449520a5 | |||
| 07831f45b2 | |||
| 9a69ad0d62 | |||
| be6ecb5d92 | |||
| 138be9d567 | |||
| 0430474168 | |||
| 0f1ee64746 | |||
| d08cc220fd | |||
| 04d9ab21b0 | |||
| 9c7523e944 | |||
| 030d0d07ec | |||
| 0578f14843 | |||
| 11274e43c4 | |||
| e899e2dfc7 |
@@ -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 \
|
||||
|
||||
+22
-10
@@ -1,6 +1,6 @@
|
||||
" Vim autoload file for editing compressed files.
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2007 May 10
|
||||
" Last Change: 2008 May 29
|
||||
|
||||
" These functions are used by the gzip plugin.
|
||||
|
||||
@@ -73,8 +73,15 @@ fun gzip#read(cmd)
|
||||
let empty = line("'[") == 1 && line("']") == line("$")
|
||||
let tmp = tempname()
|
||||
let tmpe = tmp . "." . expand("<afile>:e")
|
||||
if exists('*fnameescape')
|
||||
let tmp_esc = fnameescape(tmp)
|
||||
let tmpe_esc = fnameescape(tmpe)
|
||||
else
|
||||
let tmp_esc = escape(tmp, ' ')
|
||||
let tmpe_esc = escape(tmpe, ' ')
|
||||
endif
|
||||
" write the just read lines to a temp file "'[,']w tmp.gz"
|
||||
execute "silent '[,']w " . escape(tmpe, ' ')
|
||||
execute "silent '[,']w " . tmpe_esc
|
||||
" uncompress the temp file: call system("gzip -dn tmp.gz")
|
||||
call system(a:cmd . " " . s:escape(tmpe))
|
||||
if !filereadable(tmp)
|
||||
@@ -95,12 +102,12 @@ fun gzip#read(cmd)
|
||||
setlocal nobin
|
||||
if exists(":lockmarks")
|
||||
if empty
|
||||
execute "silent lockmarks " . l . "r ++edit " . tmp
|
||||
execute "silent lockmarks " . l . "r ++edit " . tmp_esc
|
||||
else
|
||||
execute "silent lockmarks " . l . "r " . tmp
|
||||
execute "silent lockmarks " . l . "r " . tmp_esc
|
||||
endif
|
||||
else
|
||||
execute "silent " . l . "r " . tmp
|
||||
execute "silent " . l . "r " . tmp_esc
|
||||
endif
|
||||
|
||||
" if buffer became empty, delete trailing blank line
|
||||
@@ -110,8 +117,8 @@ fun gzip#read(cmd)
|
||||
endif
|
||||
" delete the temp file and the used buffers
|
||||
call delete(tmp)
|
||||
silent! exe "bwipe " . tmp
|
||||
silent! exe "bwipe " . tmpe
|
||||
silent! exe "bwipe " . tmp_esc
|
||||
silent! exe "bwipe " . tmpe_esc
|
||||
endif
|
||||
|
||||
" Restore saved option values.
|
||||
@@ -124,10 +131,15 @@ fun gzip#read(cmd)
|
||||
|
||||
" When uncompressed the whole buffer, do autocommands
|
||||
if ok && empty
|
||||
if &verbose >= 8
|
||||
execute "doau BufReadPost " . expand("%:r")
|
||||
if exists('*fnameescape')
|
||||
let fname = fnameescape(expand("%:r"))
|
||||
else
|
||||
execute "silent! doau BufReadPost " . expand("%:r")
|
||||
let fname = escape(expand("%:r"), " \t\n*?[{`$\\%#'\"|!<")
|
||||
endif
|
||||
if &verbose >= 8
|
||||
execute "doau BufReadPost " . fname
|
||||
else
|
||||
execute "silent! doau BufReadPost " . fname
|
||||
endif
|
||||
endif
|
||||
endfun
|
||||
|
||||
+15
-1
@@ -1,4 +1,4 @@
|
||||
*eval.txt* For Vim version 7.1. Last change: 2008 Feb 20
|
||||
*eval.txt* For Vim version 7.1. Last change: 2008 May 28
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -1609,6 +1609,7 @@ finddir( {name}[, {path}[, {count}]])
|
||||
String find directory {name} in {path}
|
||||
findfile( {name}[, {path}[, {count}]])
|
||||
String find file {name} in {path}
|
||||
fnameescape( {fname}) String escape special characters in {fname}
|
||||
fnamemodify( {fname}, {mods}) String modify file name
|
||||
foldclosed( {lnum}) Number first line of fold at {lnum} if closed
|
||||
foldclosedend( {lnum}) Number last line of fold at {lnum} if closed
|
||||
@@ -2620,6 +2621,19 @@ findfile({name}[, {path}[, {count}]]) *findfile()*
|
||||
< Searches from the directory of the current file upwards until
|
||||
it finds the file "tags.vim".
|
||||
|
||||
fnameescape({string}) *fnameescape()*
|
||||
Escape {string} for use as file name command argument. All
|
||||
characters that have a special meaning, such as '%' and '|'
|
||||
are escaped with a backslash.
|
||||
For most systems the characters escaped are "". For systems
|
||||
where a backslash appears in a filename, it depends on the
|
||||
value of 'isfname'.
|
||||
Example: >
|
||||
:let fname = 'some str%nge|name'
|
||||
:exe "edit " . fnameescape(fname)
|
||||
< results in executing: >
|
||||
edit some\ str\%nge\|name
|
||||
|
||||
fnamemodify({fname}, {mods}) *fnamemodify()*
|
||||
Modify file name {fname} according to {mods}. {mods} is a
|
||||
string of characters like it is used for file names on the
|
||||
|
||||
+88
-50
@@ -1,4 +1,4 @@
|
||||
*gui_mac.txt* For Vim version 7.1. Last change: 2008 Mar 16
|
||||
*gui_mac.txt* For Vim version 7.1. Last change: 2008 May 25
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bjorn Winckler
|
||||
@@ -142,6 +142,11 @@ 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*
|
||||
|
||||
@@ -222,6 +227,7 @@ 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]
|
||||
@@ -310,49 +316,84 @@ 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>
|
||||
>
|
||||
|
||||
The standard Vim menus are modified in "$VIM/gvimrc". Take a look at that
|
||||
file for more examples on how to set up menus. Note: When no window is open a
|
||||
minimal default menu is used. The default menu is set up in MainMenu.nib
|
||||
which resides in "Resources/English.lproj/" folder inside the app bundle.
|
||||
|
||||
*Actions.plist*
|
||||
Some action messages would not be suitable to call from within Vim, so there
|
||||
@@ -368,26 +409,23 @@ Here is a random assortment of actions from Actions.plist which might be
|
||||
useful.
|
||||
|
||||
Action Description ~
|
||||
fileOpen: Show "File Open" dialog
|
||||
findNext: Search forward using the "Find Pasteboard"
|
||||
findPrevious: Search backward using the "Find Pasteboard"
|
||||
fontSizeDown: Decrease font size
|
||||
fontSizeUp: Increase font size
|
||||
hide: Hide MacVim
|
||||
miniaturizeAll: Minimize all windows to the dock
|
||||
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
|
||||
performMiniaturize: Minimize window to the dock
|
||||
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.)
|
||||
terminate: Quit MacVim
|
||||
zoomAll: Zoom all windows
|
||||
_cycleWindows: Select next window (similar to <D-`>)
|
||||
_cycleWindowsBackwards: Select previous window (similar to <D-S-`>)
|
||||
|
||||
==============================================================================
|
||||
6. Toolbar *macvim-toolbar*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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|
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -16,20 +16,23 @@ set cpo&vim
|
||||
augroup filetypedetect
|
||||
|
||||
" Ignored extensions
|
||||
if exists("*fnameescape")
|
||||
au BufNewFile,BufRead ?\+.orig,?\+.bak,?\+.old,?\+.new,?\+.rpmsave,?\+.rpmnew
|
||||
\ exe "doau filetypedetect BufRead " . expand("<afile>:r")
|
||||
\ exe "doau filetypedetect BufRead " . fnameescape(expand("<afile>:r"))
|
||||
au BufNewFile,BufRead *~
|
||||
\ let s:name = expand("<afile>") |
|
||||
\ let s:short = substitute(s:name, '\~$', '', '') |
|
||||
\ if s:name != s:short && s:short != "" |
|
||||
\ exe "doau filetypedetect BufRead " . s:short |
|
||||
\ exe "doau filetypedetect BufRead " . fnameescape(s:short) |
|
||||
\ endif |
|
||||
\ unlet s:name |
|
||||
\ unlet s:short
|
||||
\ unlet s:name s:short
|
||||
au BufNewFile,BufRead ?\+.in
|
||||
\ if expand("<afile>:t") != "configure.in" |
|
||||
\ exe "doau filetypedetect BufRead " . expand("<afile>:r") |
|
||||
\ exe "doau filetypedetect BufRead " . fnameescape(expand("<afile>:r")) |
|
||||
\ endif
|
||||
elseif &verbose > 0
|
||||
echomsg "Warning: some filetypes will not be recognized because this version of Vim does not have fnameescape()"
|
||||
endif
|
||||
|
||||
" Pattern used to match file names which should not be inspected.
|
||||
" Currently finds compressed files.
|
||||
@@ -187,7 +190,7 @@ func! s:FTasmsyntax()
|
||||
let head = " ".getline(1)." ".getline(2)." ".getline(3)." ".getline(4).
|
||||
\" ".getline(5)." "
|
||||
if head =~ '\sasmsyntax=\S\+\s'
|
||||
let b:asmsyntax = substitute(head, '.*\sasmsyntax=\(\S\+\)\s.*','\1', "")
|
||||
let b:asmsyntax = substitute(head, '.*\sasmsyntax=\([a-zA-Z0-9]\+\)\s.*','\1', "")
|
||||
elseif ((head =~? '\.title') || (head =~? '\.ident') || (head =~? '\.macro') || (head =~? '\.subtitle') || (head =~? '\.library'))
|
||||
let b:asmsyntax = "vmasm"
|
||||
endif
|
||||
|
||||
+3
-2
@@ -783,8 +783,9 @@ func! s:BMMunge(fname, bnum)
|
||||
return name
|
||||
endfunc
|
||||
|
||||
" When just starting Vim, load the buffer menu later
|
||||
if has("vim_starting")
|
||||
" When just starting Vim, load the buffer menu later. Don't do this for MacVim
|
||||
" because it makes the menu flicker each time a new editor window is opened.
|
||||
if has("vim_starting") && !has("gui_macvim")
|
||||
augroup LoadBufferMenu
|
||||
au! VimEnter * if !exists("no_buffers_menu") | call <SID>BMShow() | endif
|
||||
au VimEnter * au! LoadBufferMenu
|
||||
|
||||
+6
-2
@@ -1,7 +1,7 @@
|
||||
" These commands create the option window.
|
||||
"
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2006 Oct 10
|
||||
" Last Change: 2008 May 12
|
||||
|
||||
" If there already is an option window, jump to that one.
|
||||
if bufwinnr("option-window") > 0
|
||||
@@ -147,7 +147,7 @@ endwhile
|
||||
|
||||
" Open the window
|
||||
new option-window
|
||||
setlocal ts=15 tw=0
|
||||
setlocal ts=15 tw=0 noro
|
||||
|
||||
" Insert help and a "set" command for each option.
|
||||
call append(0, '" Each "set" line shows the current value of an option (on the left).')
|
||||
@@ -350,6 +350,10 @@ call append("$", "lines\tnumber of lines in the display")
|
||||
call append("$", " \tset lines=" . &lines)
|
||||
call append("$", "lazyredraw\tdon't redraw while executing macros")
|
||||
call <SID>BinOptionG("lz", &lz)
|
||||
if has("reltime")
|
||||
call append("$", "redrawtime\ttimeout for 'hlsearch' and :match highlighting in msec")
|
||||
call append("$", " \tset rdt=" . &rdt)
|
||||
endif
|
||||
call append("$", "writedelay\tdelay in msec for each char written to the display")
|
||||
call append("$", "\t(for debugging)")
|
||||
call append("$", " \tset wd=" . &wd)
|
||||
|
||||
@@ -1,13 +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>_cycleWindows:</key>
|
||||
<string></string>
|
||||
<key>_cycleWindowsBackwards:</key>
|
||||
<string></string>
|
||||
<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>
|
||||
@@ -34,6 +42,8 @@
|
||||
<string></string>
|
||||
<key>orderFrontPreferencePanel:</key>
|
||||
<string></string>
|
||||
<key>paste:</key>
|
||||
<string></string>
|
||||
<key>performClose:</key>
|
||||
<string></string>
|
||||
<key>performMiniaturize:</key>
|
||||
@@ -42,15 +52,25 @@
|
||||
<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>showVimHelp:</key>
|
||||
<string></string>
|
||||
<key>terminate:</key>
|
||||
<string></string>
|
||||
<key>undo:</key>
|
||||
<string></string>
|
||||
<key>unhide:</key>
|
||||
<string></string>
|
||||
<key>unhideAllApplications:</key>
|
||||
<string></string>
|
||||
<key>zoomAll:</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
+20
@@ -15,12 +15,20 @@
|
||||
<string>id</string>
|
||||
<key>newWindow</key>
|
||||
<string>id</string>
|
||||
<key>openWebsite</key>
|
||||
<string>id</string>
|
||||
<key>orderFrontPreferencePanel</key>
|
||||
<string>id</string>
|
||||
<key>selectNextWindow</key>
|
||||
<string>id</string>
|
||||
<key>selectPreviousWindow</key>
|
||||
<string>id</string>
|
||||
<key>showHelp</key>
|
||||
<string>id</string>
|
||||
<key>showVimHelp</key>
|
||||
<string>id</string>
|
||||
<key>zoomAll</key>
|
||||
<string>id</string>
|
||||
</dict>
|
||||
<key>CLASS</key>
|
||||
<string>MMAppController</string>
|
||||
@@ -29,9 +37,21 @@
|
||||
<key>SUPERCLASS</key>
|
||||
<string>NSObject</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CLASS</key>
|
||||
<string>NSMenu</string>
|
||||
<key>LANGUAGE</key>
|
||||
<string>ObjC</string>
|
||||
<key>SUPERCLASS</key>
|
||||
<string>NSObject</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>ACTIONS</key>
|
||||
<dict>
|
||||
<key>_cycleWindows</key>
|
||||
<string>id</string>
|
||||
<key>_cycleWindowsBackwards</key>
|
||||
<string>id</string>
|
||||
<key>addNewTab</key>
|
||||
<string>id</string>
|
||||
</dict>
|
||||
|
||||
+2
-4
@@ -9,11 +9,9 @@
|
||||
<key>IBOldestOS</key>
|
||||
<integer>5</integer>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>57</integer>
|
||||
</array>
|
||||
<array/>
|
||||
<key>IBSystem Version</key>
|
||||
<string>9B18</string>
|
||||
<string>9D34</string>
|
||||
<key>targetFramework</key>
|
||||
<string>IBCocoaFramework</string>
|
||||
</dict>
|
||||
|
||||
Binary file not shown.
+30
-1
@@ -4,6 +4,35 @@
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<!--
|
||||
Both UTExportedTypeDeclarations (for Spotlight and QuickLook) and
|
||||
CFBundleDocumentTypes seem to be required, even though they contain
|
||||
more or less the same information:
|
||||
http://lists.apple.com/archives/Spotlight-dev/2007/Jul/msg00019.html
|
||||
-->
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.text</string>
|
||||
<string>public.plain-text</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>vim script file</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.vim.vim</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>com.apple.ostype</key>
|
||||
<string>TEXT</string>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>vim</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
@@ -545,7 +574,7 @@
|
||||
<key>CFBundleSignature</key>
|
||||
<string>VIMM</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>27</string>
|
||||
<string>31</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
||||
@@ -16,23 +16,29 @@
|
||||
|
||||
|
||||
@interface MMAppController : NSObject <MMAppProtocol> {
|
||||
NSConnection *connection;
|
||||
NSMutableArray *vimControllers;
|
||||
NSString *openSelectionString;
|
||||
ATSFontContainerRef fontContainerRef;
|
||||
NSMutableDictionary *pidArguments;
|
||||
|
||||
NSMenu *defaultMainMenu;
|
||||
NSMenuItem *appMenuItemTemplate;
|
||||
NSMenuItem *recentFilesMenuItem;
|
||||
}
|
||||
|
||||
+ (MMAppController *)sharedInstance;
|
||||
- (NSMenu *)defaultMainMenu;
|
||||
- (NSMenuItem *)appMenuItemTemplate;
|
||||
- (void)removeVimController:(id)controller;
|
||||
- (void)windowControllerWillOpen:(MMWindowController *)windowController;
|
||||
- (void)setMainMenu:(NSMenu *)mainMenu;
|
||||
- (IBAction)newWindow:(id)sender;
|
||||
- (IBAction)fileOpen:(id)sender;
|
||||
- (IBAction)selectNextWindow:(id)sender;
|
||||
- (IBAction)selectPreviousWindow:(id)sender;
|
||||
- (IBAction)fontSizeUp:(id)sender;
|
||||
- (IBAction)fontSizeDown:(id)sender;
|
||||
- (IBAction)orderFrontPreferencePanel:(id)sender;
|
||||
- (IBAction)openWebsite:(id)sender;
|
||||
- (IBAction)showVimHelp:(id)sender;
|
||||
- (IBAction)zoomAll:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
+315
-110
@@ -13,7 +13,7 @@
|
||||
* MMAppController is the delegate of NSApp and as such handles file open
|
||||
* requests, application termination, etc. It sets up a named NSConnection on
|
||||
* which it listens to incoming connections from Vim processes. It also
|
||||
* coordinates all MMVimControllers.
|
||||
* coordinates all MMVimControllers and takes care of the main menu.
|
||||
*
|
||||
* A new Vim process is started by calling launchVimProcessWithArguments:.
|
||||
* When the Vim process is initialized it notifies the app controller by
|
||||
@@ -24,6 +24,17 @@
|
||||
* A Vim process started from the command line connects directly by sending the
|
||||
* connectBackend:pid: message (launchVimProcessWithArguments: is never called
|
||||
* in this case).
|
||||
*
|
||||
* The main menu is handled as follows. Each Vim controller keeps its own main
|
||||
* menu. All menus except the "MacVim" menu are controlled by the Vim process.
|
||||
* The app controller also keeps a reference to the "default main menu" which
|
||||
* is set up in MainMenu.nib. When no editor window is open the default main
|
||||
* menu is used. When a new editor window becomes main its main menu becomes
|
||||
* the new main menu, this is done in -[MMAppController setMainMenu:].
|
||||
* NOTE: Certain heuristics are used to find the "MacVim", "Windows", "File",
|
||||
* and "Services" menu. If MainMenu.nib changes these heuristics may have to
|
||||
* change as well. For specifics see the find... methods defined in the NSMenu
|
||||
* category "MMExtras".
|
||||
*/
|
||||
|
||||
#import "MMAppController.h"
|
||||
@@ -43,6 +54,10 @@ static NSTimeInterval MMReplyTimeout = 5;
|
||||
|
||||
static NSString *MMWebsiteString = @"http://code.google.com/p/macvim/";
|
||||
|
||||
// When terminating, notify Vim processes then sleep for these many
|
||||
// microseconds.
|
||||
static useconds_t MMTerminationSleepPeriod = 10000;
|
||||
|
||||
|
||||
#pragma options align=mac68k
|
||||
typedef struct
|
||||
@@ -86,15 +101,24 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
- (void)passArguments:(NSDictionary *)args toVimController:(MMVimController*)vc;
|
||||
@end
|
||||
|
||||
@interface NSMenu (MMExtras)
|
||||
- (void)recurseSetAutoenablesItems:(BOOL)on;
|
||||
@end
|
||||
|
||||
@interface NSNumber (MMExtras)
|
||||
- (int)tag;
|
||||
@end
|
||||
|
||||
|
||||
@interface NSMenu (MMExtras)
|
||||
- (int)indexOfItemWithAction:(SEL)action;
|
||||
- (NSMenuItem *)itemWithAction:(SEL)action;
|
||||
- (NSMenu *)findMenuContainingItemWithAction:(SEL)action;
|
||||
- (NSMenu *)findWindowsMenu;
|
||||
- (NSMenu *)findApplicationMenu;
|
||||
- (NSMenu *)findServicesMenu;
|
||||
- (NSMenu *)findFileMenu;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
|
||||
@implementation MMAppController
|
||||
|
||||
@@ -124,6 +148,7 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
[NSNumber numberWithBool:NO], MMZoomBothKey,
|
||||
@"", MMLoginShellCommandKey,
|
||||
@"", MMLoginShellArgumentKey,
|
||||
[NSNumber numberWithBool:YES], MMDialogsTrackPwdKey,
|
||||
nil];
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
|
||||
@@ -140,24 +165,30 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,39 +199,56 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
{
|
||||
//NSLog(@"MMAppController dealloc");
|
||||
|
||||
[connection release]; connection = nil;
|
||||
[pidArguments release]; pidArguments = nil;
|
||||
[vimControllers release]; vimControllers = nil;
|
||||
[openSelectionString release]; openSelectionString = nil;
|
||||
[recentFilesMenuItem release]; recentFilesMenuItem = nil;
|
||||
[defaultMainMenu release]; defaultMainMenu = nil;
|
||||
[appMenuItemTemplate release]; appMenuItemTemplate = nil;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (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
|
||||
// Remember the default menu so that it can be restored if the user closes
|
||||
// all editor windows.
|
||||
defaultMainMenu = [[NSApp mainMenu] retain];
|
||||
|
||||
// Store a copy of the default app menu so we can use this as a template
|
||||
// for all other menus. We make a copy here because the "Services" menu
|
||||
// will not yet have been populated at this time. If we don't we get
|
||||
// problems trying to set key equivalents later on because they might clash
|
||||
// with items on the "Services" menu.
|
||||
appMenuItemTemplate = [defaultMainMenu itemAtIndex:0];
|
||||
appMenuItemTemplate = [appMenuItemTemplate copy];
|
||||
|
||||
// Set up 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.
|
||||
//
|
||||
// The menu itself is created in MainMenu.nib but we still seem to have to
|
||||
// hack around a bit to get it to work. (This has to be done in
|
||||
// applicationWillFinishLaunching at the latest, otherwise it doesn't
|
||||
// work.)
|
||||
NSMenu *fileMenu = [defaultMainMenu findFileMenu];
|
||||
if (fileMenu) {
|
||||
int idx = [fileMenu indexOfItemWithAction:@selector(fileOpen:)];
|
||||
if (idx >= 0 && idx+1 < [fileMenu numberOfItems])
|
||||
|
||||
recentFilesMenuItem = [[NSMenuItem alloc] initWithTitle:@"Open Recent"
|
||||
action:nil keyEquivalent:@""];
|
||||
recentFilesMenuItem = [fileMenu itemWithTitle:@"Open Recent"];
|
||||
[[recentFilesMenuItem submenu] performSelector:@selector(_setMenuName:)
|
||||
withObject:@"NSRecentDocumentsMenu"];
|
||||
|
||||
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];
|
||||
// Note: The "Recent Files" menu must be moved around since there is no
|
||||
// -[NSApp setRecentFilesMenu:] method. We keep a reference to it to
|
||||
// facilitate this move (see setMainMenu: below).
|
||||
[recentFilesMenuItem retain];
|
||||
}
|
||||
|
||||
#if MM_HANDLE_XCODE_MOD_EVENT
|
||||
[[NSAppleEventManager sharedAppleEventManager]
|
||||
@@ -375,11 +423,16 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
if (modifiedBuffers) {
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setAlertStyle:NSWarningAlertStyle];
|
||||
[alert addButtonWithTitle:@"Quit"];
|
||||
[alert addButtonWithTitle:@"Cancel"];
|
||||
[alert setMessageText:@"Quit without saving?"];
|
||||
[alert setInformativeText:@"There are modified buffers, "
|
||||
"if you quit now all changes will be lost. Quit anyway?"];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"Quit",
|
||||
@"Dialog button")];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"Cancel",
|
||||
@"Dialog button")];
|
||||
[alert setMessageText:NSLocalizedString(@"Quit without saving?",
|
||||
@"Quit dialog with changed buffers, title")];
|
||||
[alert setInformativeText:NSLocalizedString(
|
||||
@"There are modified buffers, "
|
||||
"if you quit now all changes will be lost. Quit anyway?",
|
||||
@"Quit dialog with changed buffers, text")];
|
||||
|
||||
if ([alert runModal] != NSAlertFirstButtonReturn)
|
||||
reply = NSTerminateCancel;
|
||||
@@ -406,24 +459,35 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
if (numWindows > 1 || numTabs > 1) {
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setAlertStyle:NSWarningAlertStyle];
|
||||
[alert addButtonWithTitle:@"Quit"];
|
||||
[alert addButtonWithTitle:@"Cancel"];
|
||||
[alert setMessageText:@"Are you sure you want to quit MacVim?"];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"Quit",
|
||||
@"Dialog button")];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"Cancel",
|
||||
@"Dialog button")];
|
||||
[alert setMessageText:NSLocalizedString(
|
||||
@"Are you sure you want to quit MacVim?",
|
||||
@"Quit dialog with no changed buffers, title")];
|
||||
|
||||
NSString *info = nil;
|
||||
if (numWindows > 1) {
|
||||
if (numTabs > numWindows)
|
||||
info = [NSString stringWithFormat:@"There are %d windows "
|
||||
"open in MacVim, with a total of %d tabs. Do you want "
|
||||
"to quit anyway?", numWindows, numTabs];
|
||||
info = [NSString stringWithFormat:NSLocalizedString(
|
||||
@"There are %d windows open in MacVim, with a "
|
||||
"total of %d tabs. Do you want to quit anyway?",
|
||||
@"Quit dialog with no changed buffers, text"),
|
||||
numWindows, numTabs];
|
||||
else
|
||||
info = [NSString stringWithFormat:@"There are %d windows "
|
||||
"open in MacVim. Do you want to quit anyway?",
|
||||
info = [NSString stringWithFormat:NSLocalizedString(
|
||||
@"There are %d windows open in MacVim. "
|
||||
"Do you want to quit anyway?",
|
||||
@"Quit dialog with no changed buffers, text"),
|
||||
numWindows];
|
||||
|
||||
} else {
|
||||
info = [NSString stringWithFormat:@"There are %d tabs open "
|
||||
"in MacVim. Do you want to quit anyway?", numTabs];
|
||||
info = [NSString stringWithFormat:NSLocalizedString(
|
||||
@"There are %d tabs open in MacVim. "
|
||||
"Do you want to quit anyway?",
|
||||
@"Quit dialog with no changed buffers, text"),
|
||||
numTabs];
|
||||
}
|
||||
|
||||
[alert setInformativeText:info];
|
||||
@@ -443,6 +507,11 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
id vc;
|
||||
while ((vc = [e nextObject]))
|
||||
[vc sendMessage:TerminateNowMsgID data:nil];
|
||||
|
||||
// Give Vim processes a chance to terminate before MacVim. If they
|
||||
// haven't terminated by the time applicationWillTerminate: is sent,
|
||||
// they may be forced to quit (see below).
|
||||
usleep(MMTerminationSleepPeriod);
|
||||
}
|
||||
|
||||
return reply;
|
||||
@@ -456,9 +525,9 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
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
|
||||
@@ -479,6 +548,24 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
[NSApp setDelegate:nil];
|
||||
}
|
||||
|
||||
+ (MMAppController *)sharedInstance
|
||||
{
|
||||
// Note: The app controller is a singleton which is instantiated in
|
||||
// MainMenu.nib where it is also connected as the delegate of NSApp.
|
||||
id delegate = [NSApp delegate];
|
||||
return [delegate isKindOfClass:self] ? (MMAppController*)delegate : nil;
|
||||
}
|
||||
|
||||
- (NSMenu *)defaultMainMenu
|
||||
{
|
||||
return defaultMainMenu;
|
||||
}
|
||||
|
||||
- (NSMenuItem *)appMenuItemTemplate
|
||||
{
|
||||
return appMenuItemTemplate;
|
||||
}
|
||||
|
||||
- (void)removeVimController:(id)controller
|
||||
{
|
||||
//NSLog(@"%s%@", _cmd, controller);
|
||||
@@ -488,16 +575,9 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
[vimControllers removeObject:controller];
|
||||
|
||||
if (![vimControllers count]) {
|
||||
// Turn on autoenabling of menus (because no Vim is open to handle it),
|
||||
// but do not touch the MacVim menu. Note that the menus must be
|
||||
// enabled first otherwise autoenabling does not work.
|
||||
NSMenu *mainMenu = [NSApp mainMenu];
|
||||
int i, count = [mainMenu numberOfItems];
|
||||
for (i = 1; i < count; ++i) {
|
||||
NSMenuItem *item = [mainMenu itemAtIndex:i];
|
||||
[item setEnabled:YES];
|
||||
[[item submenu] recurseSetAutoenablesItems:YES];
|
||||
}
|
||||
// The last editor window just closed so restore the main menu back to
|
||||
// its default state (which is defined in MainMenu.nib).
|
||||
[self setMainMenu:defaultMainMenu];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,6 +620,69 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setMainMenu:(NSMenu *)mainMenu
|
||||
{
|
||||
if ([NSApp mainMenu] == mainMenu) return;
|
||||
|
||||
// If the new menu has a "Recent Files" dummy item, then swap the real item
|
||||
// for the dummy. We are forced to do this since Cocoa initializes the
|
||||
// "Recent Files" menu and there is no way to simply point Cocoa to a new
|
||||
// item each time the menus are swapped.
|
||||
NSMenu *fileMenu = [mainMenu findFileMenu];
|
||||
if (recentFilesMenuItem && fileMenu) {
|
||||
int dummyIdx =
|
||||
[fileMenu indexOfItemWithAction:@selector(recentFilesDummy:)];
|
||||
if (dummyIdx >= 0) {
|
||||
NSMenuItem *dummyItem = [[fileMenu itemAtIndex:dummyIdx] retain];
|
||||
[fileMenu removeItemAtIndex:dummyIdx];
|
||||
|
||||
NSMenu *recentFilesParentMenu = [recentFilesMenuItem menu];
|
||||
int idx = [recentFilesParentMenu indexOfItem:recentFilesMenuItem];
|
||||
if (idx >= 0) {
|
||||
[[recentFilesMenuItem retain] autorelease];
|
||||
[recentFilesParentMenu removeItemAtIndex:idx];
|
||||
[recentFilesParentMenu insertItem:dummyItem atIndex:idx];
|
||||
}
|
||||
|
||||
[fileMenu insertItem:recentFilesMenuItem atIndex:dummyIdx];
|
||||
[dummyItem release];
|
||||
}
|
||||
}
|
||||
|
||||
// Now set the new menu. Notice that we keep one menu for each editor
|
||||
// window since each editor can have its own set of menus. When swapping
|
||||
// menus we have to tell Cocoa where the new "MacVim", "Windows", and
|
||||
// "Services" menu are.
|
||||
[NSApp setMainMenu:mainMenu];
|
||||
|
||||
// Setting the "MacVim" (or "Application") menu ensures that it is typeset
|
||||
// in boldface. (The setAppleMenu: method used to be public but is now
|
||||
// private so this will have to be considered a bit of a hack!)
|
||||
NSMenu *appMenu = [mainMenu findApplicationMenu];
|
||||
[NSApp performSelector:@selector(setAppleMenu:) withObject:appMenu];
|
||||
|
||||
NSMenu *servicesMenu = [mainMenu findServicesMenu];
|
||||
[NSApp setServicesMenu:servicesMenu];
|
||||
|
||||
NSMenu *windowsMenu = [mainMenu findWindowsMenu];
|
||||
if (windowsMenu) {
|
||||
// Cocoa isn't clever enough to get rid of items it has added to the
|
||||
// "Windows" menu so we have to do it ourselves otherwise there will be
|
||||
// multiple menu items for each window in the "Windows" menu.
|
||||
// This code assumes that the only items Cocoa add are ones which
|
||||
// send off the action makeKeyAndOrderFront:. (Cocoa will not add
|
||||
// another separator item if the last item on the "Windows" menu
|
||||
// already is a separator, so we needen't worry about separators.)
|
||||
int i, count = [windowsMenu numberOfItems];
|
||||
for (i = count-1; i >= 0; --i) {
|
||||
NSMenuItem *item = [windowsMenu itemAtIndex:i];
|
||||
if ([item action] == @selector(makeKeyAndOrderFront:))
|
||||
[windowsMenu removeItem:item];
|
||||
}
|
||||
}
|
||||
[NSApp setWindowsMenu:windowsMenu];
|
||||
}
|
||||
|
||||
- (IBAction)newWindow:(id)sender
|
||||
{
|
||||
[self launchVimProcessWithArguments:nil];
|
||||
@@ -547,10 +690,17 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
|
||||
- (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]];
|
||||
}
|
||||
@@ -598,18 +748,6 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)fontSizeUp:(id)sender
|
||||
{
|
||||
[[NSFontManager sharedFontManager] modifyFont:
|
||||
[NSNumber numberWithInt:NSSizeUpFontAction]];
|
||||
}
|
||||
|
||||
- (IBAction)fontSizeDown:(id)sender
|
||||
{
|
||||
[[NSFontManager sharedFontManager] modifyFont:
|
||||
[NSNumber numberWithInt:NSSizeDownFontAction]];
|
||||
}
|
||||
|
||||
- (IBAction)orderFrontPreferencePanel:(id)sender
|
||||
{
|
||||
[[MMPreferenceController sharedPrefsWindowController] showWindow:self];
|
||||
@@ -621,6 +759,18 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
[NSURL URLWithString:MMWebsiteString]];
|
||||
}
|
||||
|
||||
- (IBAction)showVimHelp:(id)sender
|
||||
{
|
||||
// Open a new window with the help window maximized.
|
||||
[self launchVimProcessWithArguments:[NSArray arrayWithObjects:
|
||||
@"-c", @":h gui_mac", @"-c", @":res", nil]];
|
||||
}
|
||||
|
||||
- (IBAction)zoomAll:(id)sender
|
||||
{
|
||||
[NSApp makeWindowsPerform:@selector(performZoom:) inOrder:YES];
|
||||
}
|
||||
|
||||
- (byref id <MMFrontendProtocol>)
|
||||
connectBackend:(byref in id <MMBackendProtocol>)backend
|
||||
pid:(int)pid
|
||||
@@ -634,7 +784,7 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
setProtocolForProxy:@protocol(MMBackendProtocol)];
|
||||
|
||||
vc = [[[MMVimController alloc]
|
||||
initWithBackend:backend pid:pid recentFiles:recentFilesMenuItem]
|
||||
initWithBackend:backend pid:pid]
|
||||
autorelease];
|
||||
|
||||
if (![vimControllers count]) {
|
||||
@@ -855,18 +1005,23 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
|
||||
if (firstMissingFile) {
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert addButtonWithTitle:@"OK"];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"OK",
|
||||
@"Dialog button")];
|
||||
|
||||
NSString *text;
|
||||
if ([files count] >= count-1) {
|
||||
[alert setMessageText:@"File not found"];
|
||||
text = [NSString stringWithFormat:@"Could not open file with "
|
||||
"name %@.", firstMissingFile];
|
||||
[alert setMessageText:NSLocalizedString(@"File not found",
|
||||
@"File not found dialog, title")];
|
||||
text = [NSString stringWithFormat:NSLocalizedString(
|
||||
@"Could not open file with name %@.",
|
||||
@"File not found dialog, text"), firstMissingFile];
|
||||
} else {
|
||||
[alert setMessageText:@"Multiple files not found"];
|
||||
text = [NSString stringWithFormat:@"Could not open file with "
|
||||
"name %@, and %d other files.", firstMissingFile,
|
||||
count-[files count]-1];
|
||||
[alert setMessageText:NSLocalizedString(@"Multiple files not found",
|
||||
@"File not found dialog, title")];
|
||||
text = [NSString stringWithFormat:NSLocalizedString(
|
||||
@"Could not open file with name %@, and %d other files.",
|
||||
@"File not found dialog, text"),
|
||||
firstMissingFile, count-[files count]-1];
|
||||
}
|
||||
|
||||
[alert setInformativeText:text];
|
||||
@@ -998,6 +1153,8 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
// TODO: This is a moronic test...should query the Vim process if there
|
||||
// are any open buffers or something like that instead.
|
||||
NSString *title = [[[vc windowController] window] title];
|
||||
|
||||
// TODO: this will not work in a localized MacVim
|
||||
if ([title hasPrefix:@"[No Name] - VIM"]) {
|
||||
//NSLog(@"found untitled window");
|
||||
return vc;
|
||||
@@ -1104,28 +1261,6 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
|
||||
|
||||
|
||||
@implementation NSMenu (MMExtras)
|
||||
|
||||
- (void)recurseSetAutoenablesItems:(BOOL)on
|
||||
{
|
||||
[self setAutoenablesItems:on];
|
||||
|
||||
int i, count = [self numberOfItems];
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSMenuItem *item = [self itemAtIndex:i];
|
||||
[item setEnabled:YES];
|
||||
NSMenu *submenu = [item submenu];
|
||||
if (submenu) {
|
||||
[submenu recurseSetAutoenablesItems:on];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end // NSMenu (MMExtras)
|
||||
|
||||
|
||||
|
||||
|
||||
@implementation NSNumber (MMExtras)
|
||||
- (int)tag
|
||||
{
|
||||
@@ -1136,6 +1271,77 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
|
||||
|
||||
|
||||
@implementation NSMenu (MMExtras)
|
||||
|
||||
- (int)indexOfItemWithAction:(SEL)action
|
||||
{
|
||||
int i, count = [self numberOfItems];
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSMenuItem *item = [self itemAtIndex:i];
|
||||
if ([item action] == action)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
- (NSMenuItem *)itemWithAction:(SEL)action
|
||||
{
|
||||
int idx = [self indexOfItemWithAction:action];
|
||||
return idx >= 0 ? [self itemAtIndex:idx] : nil;
|
||||
}
|
||||
|
||||
- (NSMenu *)findMenuContainingItemWithAction:(SEL)action
|
||||
{
|
||||
// NOTE: We only look for the action in the submenus of 'self'
|
||||
int i, count = [self numberOfItems];
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSMenu *menu = [[self itemAtIndex:i] submenu];
|
||||
NSMenuItem *item = [menu itemWithAction:action];
|
||||
if (item) return menu;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSMenu *)findWindowsMenu
|
||||
{
|
||||
return [self findMenuContainingItemWithAction:
|
||||
@selector(performMiniaturize:)];
|
||||
}
|
||||
|
||||
- (NSMenu *)findApplicationMenu
|
||||
{
|
||||
// TODO: Just return [self itemAtIndex:0]?
|
||||
return [self findMenuContainingItemWithAction:@selector(terminate:)];
|
||||
}
|
||||
|
||||
- (NSMenu *)findServicesMenu
|
||||
{
|
||||
// NOTE! Our heuristic for finding the "Services" menu is to look for the
|
||||
// second item before the "Hide MacVim" menu item on the "MacVim" menu.
|
||||
// (The item before "Hide MacVim" should be a separator, but this is not
|
||||
// important as long as the item before that is the "Services" menu.)
|
||||
|
||||
NSMenu *appMenu = [self findApplicationMenu];
|
||||
if (!appMenu) return nil;
|
||||
|
||||
int idx = [appMenu indexOfItemWithAction: @selector(hide:)];
|
||||
if (idx-2 < 0) return nil; // idx == -1, if selector not found
|
||||
|
||||
return [[appMenu itemAtIndex:idx-2] submenu];
|
||||
}
|
||||
|
||||
- (NSMenu *)findFileMenu
|
||||
{
|
||||
return [self findMenuContainingItemWithAction:@selector(performClose:)];
|
||||
}
|
||||
|
||||
@end // NSMenu (MMExtras)
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
executeInLoginShell(NSString *path, NSArray *args)
|
||||
{
|
||||
@@ -1229,4 +1435,3 @@ executeInLoginShell(NSString *path, NSArray *args)
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ enum { MMMaxCellsPerChar = 2 };
|
||||
//
|
||||
// MMTextView methods
|
||||
//
|
||||
- (NSEvent *)lastMouseDownEvent;
|
||||
- (void)setShouldDrawInsertionPoint:(BOOL)on;
|
||||
- (void)setPreEditRow:(int)row column:(int)col;
|
||||
- (void)hideMarkedTextField;
|
||||
|
||||
+101
-21
@@ -27,6 +27,8 @@
|
||||
|
||||
#import "MMAtsuiTextView.h"
|
||||
#import "MMVimController.h"
|
||||
#import "MMWindowController.h"
|
||||
#import "MMAppController.h"
|
||||
#import "MacVim.h"
|
||||
|
||||
|
||||
@@ -65,6 +67,8 @@ enum {
|
||||
- (void)updateAtsuStyles;
|
||||
- (void)dispatchKeyEvent:(NSEvent *)event;
|
||||
- (void)sendKeyDown:(const char *)chars length:(int)len modifiers:(int)flags;
|
||||
- (void)hideMouseCursor;
|
||||
- (MMWindowController *)windowController;
|
||||
- (MMVimController *)vimController;
|
||||
@end
|
||||
|
||||
@@ -92,6 +96,8 @@ enum {
|
||||
- (void)clearAll;
|
||||
- (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
|
||||
fraction:(int)percent color:(NSColor *)color;
|
||||
- (void)drawInvertedRectAtRow:(int)row column:(int)col numRows:(int)nrows
|
||||
numColumns:(int)ncols;
|
||||
@end
|
||||
|
||||
|
||||
@@ -245,11 +251,6 @@ enum {
|
||||
|
||||
|
||||
|
||||
- (NSEvent *)lastMouseDownEvent
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)setShouldDrawInsertionPoint:(BOOL)on
|
||||
{
|
||||
}
|
||||
@@ -335,8 +336,7 @@ enum {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Support 'mousehide' (check p_mh)
|
||||
[NSCursor setHiddenUntilMouseMoves:YES];
|
||||
[self hideMouseCursor];
|
||||
|
||||
// NOTE: 'string' is either an NSString or an NSAttributedString. Since we
|
||||
// do not support attributes, simply pass the corresponding NSString in the
|
||||
@@ -408,20 +408,18 @@ enum {
|
||||
&& !(116 == [event keyCode] || 121 == [event keyCode]))
|
||||
return NO;
|
||||
|
||||
// HACK! KeyCode 50 represent the key which switches between windows
|
||||
// within an application (like Cmd+Tab is used to switch between
|
||||
// applications). Return NO here, else the window switching does not work.
|
||||
if ([event keyCode] == 50)
|
||||
return NO;
|
||||
|
||||
// HACK! Let the main menu try to handle any key down event, before
|
||||
// passing it on to vim, otherwise key equivalents for menus will
|
||||
// effectively be disabled.
|
||||
if ([[NSApp mainMenu] performKeyEquivalent:event])
|
||||
return YES;
|
||||
|
||||
// HACK! KeyCode 50 represent the key which switches between windows
|
||||
// within an application (like Cmd+Tab is used to switch between
|
||||
// applications). Return NO here, else the window switching does not work.
|
||||
//
|
||||
// Will this hack work for all languages / keyboard layouts?
|
||||
if ([event keyCode] == 50)
|
||||
return NO;
|
||||
|
||||
// HACK! On Leopard Ctrl-key events end up here instead of keyDown:.
|
||||
if (flags & NSControlKeyMask) {
|
||||
[self keyDown:event];
|
||||
@@ -603,6 +601,19 @@ enum {
|
||||
[self drawInsertionPointAtRow:row column:col shape:shape
|
||||
fraction:percent
|
||||
color:[NSColor colorWithRgbInt:color]];
|
||||
} else if (DrawInvertedRectDrawType == type) {
|
||||
int row = *((int*)bytes); bytes += sizeof(int);
|
||||
int col = *((int*)bytes); bytes += sizeof(int);
|
||||
int nr = *((int*)bytes); bytes += sizeof(int);
|
||||
int nc = *((int*)bytes); bytes += sizeof(int);
|
||||
/*int invert = *((int*)bytes);*/ bytes += sizeof(int);
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Draw inverted rect: row=%d col=%d nrows=%d ncols=%d",
|
||||
row, col, nr, nc);
|
||||
#endif
|
||||
[self drawInvertedRectAtRow:row column:col numRows:nr
|
||||
numColumns:nc];
|
||||
} else if (SetCursorPosDrawType == type) {
|
||||
// TODO: This is used for Voice Over support in MMTextView,
|
||||
// MMAtsuiTextView currently does not support Voice Over.
|
||||
@@ -726,6 +737,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
|
||||
|
||||
|
||||
@@ -867,21 +914,34 @@ enum {
|
||||
[data appendBytes:&len length:sizeof(int)];
|
||||
[data appendBytes:chars length:len];
|
||||
|
||||
// TODO: Support 'mousehide' (check p_mh)
|
||||
[NSCursor setHiddenUntilMouseMoves:YES];
|
||||
[self hideMouseCursor];
|
||||
|
||||
//NSLog(@"%s len=%d chars=0x%x", _cmd, len, chars[0]);
|
||||
[[self vimController] sendMessage:KeyDownMsgID data:data];
|
||||
}
|
||||
}
|
||||
|
||||
- (MMVimController *)vimController
|
||||
- (void)hideMouseCursor
|
||||
{
|
||||
// Check 'mousehide' option
|
||||
id mh = [[[self vimController] vimState] objectForKey:@"p_mh"];
|
||||
if (mh && ![mh boolValue])
|
||||
[NSCursor setHiddenUntilMouseMoves:NO];
|
||||
else
|
||||
[NSCursor setHiddenUntilMouseMoves:YES];
|
||||
}
|
||||
|
||||
- (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)
|
||||
@@ -1074,6 +1134,10 @@ enum {
|
||||
} else if (MMInsertionPointVertical == shape) {
|
||||
int frac = (cellSize.width * percent + 99)/100;
|
||||
rect.size.width = frac;
|
||||
} else if (MMInsertionPointVerticalRight == shape) {
|
||||
int frac = (cellSize.width * percent + 99)/100;
|
||||
rect.origin.x += rect.size.width - frac;
|
||||
rect.size.width = frac;
|
||||
}
|
||||
|
||||
[color set];
|
||||
@@ -1084,4 +1148,20 @@ enum {
|
||||
}
|
||||
}
|
||||
|
||||
- (void)drawInvertedRectAtRow:(int)row column:(int)col numRows:(int)nrows
|
||||
numColumns:(int)ncols
|
||||
{
|
||||
// TODO: THIS CODE HAS NOT BEEN TESTED!
|
||||
CGContextRef cgctx = [[NSGraphicsContext currentContext] graphicsPort];
|
||||
CGContextSaveGState(cgctx);
|
||||
CGContextSetBlendMode(cgctx, kCGBlendModeDifference);
|
||||
CGContextSetRGBFillColor(cgctx, 1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
CGRect rect = { col * cellSize.width, row * cellSize.height,
|
||||
ncols * cellSize.width, nrows * cellSize.height };
|
||||
CGContextFillRect(cgctx, rect);
|
||||
|
||||
CGContextRestoreGState(cgctx);
|
||||
}
|
||||
|
||||
@end // MMAtsuiTextView (Drawing)
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
- (NSConnection *)connection;
|
||||
- (NSDictionary *)actionDict;
|
||||
|
||||
- (void)queueMessage:(int)msgid properties:(NSDictionary *)props;
|
||||
- (BOOL)checkin;
|
||||
- (BOOL)openVimWindow;
|
||||
- (void)clearAll;
|
||||
@@ -70,6 +71,8 @@
|
||||
scrollBottom:(int)bottom left:(int)left right:(int)right;
|
||||
- (void)drawCursorAtRow:(int)row column:(int)col shape:(int)shape
|
||||
fraction:(int)percent color:(int)color;
|
||||
- (void)drawInvertedRectAtRow:(int)row column:(int)col numRows:(int)nr
|
||||
numColumns:(int)nc invert:(int)invert;
|
||||
- (void)update;
|
||||
- (void)flushQueue:(BOOL)force;
|
||||
- (BOOL)waitForInput:(int)milliseconds;
|
||||
@@ -84,15 +87,6 @@
|
||||
saving:(int)saving;
|
||||
- (int)presentDialogWithType:(int)type title:(char *)title message:(char *)msg
|
||||
buttons:(char *)btns textField:(char *)txtfield;
|
||||
- (void)addMenuWithTag:(int)tag parent:(int)parentTag name:(char *)name
|
||||
atIndex:(int)index;
|
||||
- (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;
|
||||
- (void)removeMenuItemWithTag:(int)tag;
|
||||
- (void)enableMenuItemWithTag:(int)tag state:(int)enabled;
|
||||
- (void)showPopupMenuWithName:(char *)name atMouseLocation:(BOOL)mouse;
|
||||
- (void)showToolbar:(int)enable flags:(int)flags;
|
||||
- (void)createScrollbarWithIdentifier:(long)ident type:(int)type;
|
||||
- (void)destroyScrollbarWithIdentifier:(long)ident;
|
||||
|
||||
+107
-209
@@ -51,10 +51,12 @@ static unsigned MMServerMax = 1000;
|
||||
|
||||
// TODO: Move to separate file.
|
||||
static int eventModifierFlagsToVimModMask(int modifierFlags);
|
||||
static int vimModMaskToEventModifierFlags(int mods);
|
||||
static int eventModifierFlagsToVimMouseModMask(int modifierFlags);
|
||||
static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
static int specialKeyToNSKey(int key);
|
||||
|
||||
// In gui_macvim.m
|
||||
vimmenu_T *menu_for_descriptor(NSArray *desc);
|
||||
|
||||
|
||||
enum {
|
||||
MMBlinkStateNone = 0,
|
||||
@@ -76,7 +78,10 @@ static NSString *MMSymlinkWarningString =
|
||||
|
||||
|
||||
|
||||
|
||||
@interface MMBackend (Private)
|
||||
- (void)waitForDialogReturn;
|
||||
- (void)queueVimStateMessage;
|
||||
- (void)processInputQueue;
|
||||
- (void)handleInputEvent:(int)msgid data:(NSData *)data;
|
||||
+ (NSDictionary *)specialKeys;
|
||||
@@ -225,6 +230,11 @@ static NSString *MMSymlinkWarningString =
|
||||
return actionDict;
|
||||
}
|
||||
|
||||
- (void)queueMessage:(int)msgid properties:(NSDictionary *)props
|
||||
{
|
||||
[self queueMessage:msgid data:[props dictionaryAsData]];
|
||||
}
|
||||
|
||||
- (BOOL)checkin
|
||||
{
|
||||
if (![self connection]) {
|
||||
@@ -419,6 +429,19 @@ static NSString *MMSymlinkWarningString =
|
||||
[drawData appendBytes:&percent length:sizeof(int)];
|
||||
}
|
||||
|
||||
- (void)drawInvertedRectAtRow:(int)row column:(int)col numRows:(int)nr
|
||||
numColumns:(int)nc invert:(int)invert
|
||||
{
|
||||
int type = DrawInvertedRectDrawType;
|
||||
[drawData appendBytes:&type length:sizeof(int)];
|
||||
|
||||
[drawData appendBytes:&row length:sizeof(int)];
|
||||
[drawData appendBytes:&col length:sizeof(int)];
|
||||
[drawData appendBytes:&nr length:sizeof(int)];
|
||||
[drawData appendBytes:&nc length:sizeof(int)];
|
||||
[drawData appendBytes:&invert length:sizeof(int)];
|
||||
}
|
||||
|
||||
- (void)update
|
||||
{
|
||||
// Tend to the run loop, returning immediately if there are no events
|
||||
@@ -462,7 +485,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];
|
||||
}
|
||||
@@ -626,9 +654,7 @@ static NSString *MMSymlinkWarningString =
|
||||
@try {
|
||||
[frontendProxy showSavePanelForDirectory:ds title:ts saving:saving];
|
||||
|
||||
// Wait until a reply is sent from MMVimController.
|
||||
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
|
||||
beforeDate:[NSDate distantFuture]];
|
||||
[self waitForDialogReturn];
|
||||
|
||||
if (dialogReturn && [dialogReturn isKindOfClass:[NSString class]]) {
|
||||
char_u *ret = (char_u*)[dialogReturn UTF8String];
|
||||
@@ -650,13 +676,18 @@ static NSString *MMSymlinkWarningString =
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
- (oneway void)setDialogReturn:(in bycopy id)obj
|
||||
- (void)setDialogReturn:(in bycopy id)obj
|
||||
{
|
||||
// NOTE: This is called by
|
||||
// - [MMVimController panelDidEnd:::], and
|
||||
// - [MMVimController alertDidEnd:::],
|
||||
// to indicate that a save/open panel or alert has finished.
|
||||
|
||||
// We want to distinguish between "no dialog return yet" and "dialog
|
||||
// returned nothing". The former can be tested with dialogReturn == nil,
|
||||
// the latter with dialogReturn == [NSNull null].
|
||||
if (!obj) obj = [NSNull null];
|
||||
|
||||
if (obj != dialogReturn) {
|
||||
[dialogReturn release];
|
||||
dialogReturn = [obj retain];
|
||||
@@ -705,9 +736,7 @@ static NSString *MMSymlinkWarningString =
|
||||
informativeText:text buttonTitles:buttons
|
||||
textFieldString:textFieldString];
|
||||
|
||||
// Wait until a reply is sent from MMVimController.
|
||||
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
|
||||
beforeDate:[NSDate distantFuture]];
|
||||
[self waitForDialogReturn];
|
||||
|
||||
if (dialogReturn && [dialogReturn isKindOfClass:[NSArray class]]
|
||||
&& [dialogReturn count]) {
|
||||
@@ -734,98 +763,6 @@ static NSString *MMSymlinkWarningString =
|
||||
return retval;
|
||||
}
|
||||
|
||||
- (void)addMenuWithTag:(int)tag parent:(int)parentTag name:(char *)name
|
||||
atIndex:(int)index
|
||||
{
|
||||
//NSLog(@"addMenuWithTag:%d parent:%d name:%s atIndex:%d", tag, parentTag,
|
||||
// name, index);
|
||||
|
||||
int namelen = name ? strlen(name) : 0;
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
|
||||
[data appendBytes:&tag length:sizeof(int)];
|
||||
[data appendBytes:&parentTag length:sizeof(int)];
|
||||
[data appendBytes:&namelen length:sizeof(int)];
|
||||
if (namelen > 0) [data appendBytes:name length:namelen];
|
||||
[data appendBytes:&index length:sizeof(int)];
|
||||
|
||||
[self queueMessage:AddMenuMsgID data:data];
|
||||
}
|
||||
|
||||
- (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
|
||||
{
|
||||
//NSLog(@"addMenuItemWithTag:%d parent:%d name:%s tip:%s atIndex:%d", tag,
|
||||
// parentTag, name, tip, index);
|
||||
|
||||
int namelen = name ? strlen(name) : 0;
|
||||
int tiplen = tip ? strlen(tip) : 0;
|
||||
int iconlen = icon ? strlen(icon) : 0;
|
||||
int eventFlags = vimModMaskToEventModifierFlags(mods);
|
||||
int actionlen = [action lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
|
||||
key = specialKeyToNSKey(key);
|
||||
|
||||
[data appendBytes:&tag length:sizeof(int)];
|
||||
[data appendBytes:&parentTag length:sizeof(int)];
|
||||
[data appendBytes:&namelen length:sizeof(int)];
|
||||
if (namelen > 0) [data appendBytes:name length:namelen];
|
||||
[data appendBytes:&tiplen length:sizeof(int)];
|
||||
if (tiplen > 0) [data appendBytes:tip length:tiplen];
|
||||
[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];
|
||||
[data appendBytes:&index length:sizeof(int)];
|
||||
[data appendBytes:&key length:sizeof(int)];
|
||||
[data appendBytes:&eventFlags length:sizeof(int)];
|
||||
|
||||
[self queueMessage:AddMenuItemMsgID data:data];
|
||||
}
|
||||
|
||||
- (void)removeMenuItemWithTag:(int)tag
|
||||
{
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
[data appendBytes:&tag length:sizeof(int)];
|
||||
|
||||
[self queueMessage:RemoveMenuItemMsgID data:data];
|
||||
}
|
||||
|
||||
- (void)enableMenuItemWithTag:(int)tag state:(int)enabled
|
||||
{
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
|
||||
[data appendBytes:&tag length:sizeof(int)];
|
||||
[data appendBytes:&enabled length:sizeof(int)];
|
||||
|
||||
[self queueMessage:EnableMenuItemMsgID data:data];
|
||||
}
|
||||
|
||||
- (void)showPopupMenuWithName:(char *)name atMouseLocation:(BOOL)mouse
|
||||
{
|
||||
int len = strlen(name);
|
||||
int row = -1, col = -1;
|
||||
|
||||
if (len <= 0) return;
|
||||
|
||||
if (!mouse && curwin) {
|
||||
row = curwin->w_wrow;
|
||||
col = curwin->w_wcol;
|
||||
}
|
||||
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
|
||||
[data appendBytes:&row length:sizeof(int)];
|
||||
[data appendBytes:&col length:sizeof(int)];
|
||||
[data appendBytes:&len length:sizeof(int)];
|
||||
[data appendBytes:name length:len];
|
||||
|
||||
[self queueMessage:ShowPopupMenuMsgID data:data];
|
||||
}
|
||||
|
||||
- (void)showToolbar:(int)enable flags:(int)flags
|
||||
{
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
@@ -1553,8 +1490,70 @@ static NSString *MMSymlinkWarningString =
|
||||
|
||||
@implementation MMBackend (Private)
|
||||
|
||||
- (void)waitForDialogReturn
|
||||
{
|
||||
// Keep processing the run loop until a dialog returns. To avoid getting
|
||||
// stuck in an endless loop (could happen if the setDialogReturn: message
|
||||
// was lost) we also do some paranoia checks.
|
||||
//
|
||||
// Note that in Cocoa the user can still resize windows and select menu
|
||||
// items while a sheet is being displayed, so we can't just wait for the
|
||||
// first message to arrive and assume that is the setDialogReturn: call.
|
||||
|
||||
while (nil == dialogReturn && !got_int && [connection isValid]
|
||||
&& !isTerminating)
|
||||
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
|
||||
beforeDate:[NSDate distantFuture]];
|
||||
|
||||
// Search for any resize messages on the input queue. All other messages
|
||||
// on the input queue are dropped. The reason why we single out resize
|
||||
// messages is because the user may have resized the window while a sheet
|
||||
// was open.
|
||||
int i, count = [inputQueue count];
|
||||
if (count > 0) {
|
||||
id textDimData = nil;
|
||||
if (count%2 == 0) {
|
||||
for (i = count-2; i >= 0; i -= 2) {
|
||||
int msgid = [[inputQueue objectAtIndex:i] intValue];
|
||||
if (SetTextDimensionsMsgID == msgid) {
|
||||
textDimData = [[inputQueue objectAtIndex:i+1] retain];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[inputQueue removeAllObjects];
|
||||
|
||||
if (textDimData) {
|
||||
[inputQueue addObject:
|
||||
[NSNumber numberWithInt:SetTextDimensionsMsgID]];
|
||||
[inputQueue addObject:textDimData];
|
||||
[textDimData release];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (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",
|
||||
[NSNumber numberWithInt:p_mh], @"p_mh",
|
||||
nil];
|
||||
|
||||
[self queueMessage:SetVimStateMsgID data:[vimState dictionaryAsData]];
|
||||
}
|
||||
|
||||
- (void)processInputQueue
|
||||
{
|
||||
if ([inputQueue count] == 0) return;
|
||||
|
||||
// NOTE: One of the input events may cause this method to be called
|
||||
// recursively, so copy the input queue to a local variable and clear it
|
||||
// before starting to process input events (otherwise we could get stuck in
|
||||
@@ -1628,14 +1627,12 @@ static NSString *MMSymlinkWarningString =
|
||||
//NSLog(@"[VimTask] Resizing shell to %dx%d.", cols, rows);
|
||||
gui_resize_shell(cols, rows);
|
||||
} else if (ExecuteMenuMsgID == msgid) {
|
||||
if (!data) return;
|
||||
const void *bytes = [data bytes];
|
||||
int tag = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
vimmenu_T *menu = (vimmenu_T*)tag;
|
||||
// TODO! Make sure 'menu' is a valid menu pointer!
|
||||
if (menu) {
|
||||
gui_menu_cb(menu);
|
||||
NSDictionary *attrs = [NSDictionary dictionaryWithData:data];
|
||||
if (attrs) {
|
||||
NSArray *desc = [attrs objectForKey:@"descriptor"];
|
||||
vimmenu_T *menu = menu_for_descriptor(desc);
|
||||
if (menu)
|
||||
gui_menu_cb(menu);
|
||||
}
|
||||
} else if (ToggleToolbarMsgID == msgid) {
|
||||
[self handleToggleToolbar];
|
||||
@@ -1663,24 +1660,6 @@ static NSString *MMSymlinkWarningString =
|
||||
[self handleOdbEdit:data];
|
||||
} else if (XcodeModMsgID == msgid) {
|
||||
[self handleXcodeMod:data];
|
||||
} else if (CloseMsgID == msgid) {
|
||||
// If in Ex mode, then simply exit Ex mode (^U:vi<CR>). Otherwise
|
||||
// try to close one (Vim-)window by going to Normal mode first
|
||||
// (CTRL-\_CTRL-N) and then sending ":q<CR>", but only if the
|
||||
// command-line window is not open. If the command-line window is open
|
||||
// then we just go back to normal mode (since CTRL-\_CTRL-N closes the
|
||||
// command-line window).
|
||||
if (exmode_active) {
|
||||
// Exit Ex mode
|
||||
add_to_input_buf((char_u*)"\x15:vi\n", 5);
|
||||
} else {
|
||||
// Go to normal mode
|
||||
add_to_input_buf((char_u*)"\x1c\xe", 2);
|
||||
if (0 == cmdwin_type) {
|
||||
// Command-line window was not open, so :q
|
||||
add_to_input_buf((char_u*)":conf q\n", 8);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid);
|
||||
}
|
||||
@@ -2462,22 +2441,6 @@ static int eventModifierFlagsToVimModMask(int modifierFlags)
|
||||
return modMask;
|
||||
}
|
||||
|
||||
static int vimModMaskToEventModifierFlags(int mods)
|
||||
{
|
||||
int flags = 0;
|
||||
|
||||
if (mods & MOD_MASK_SHIFT)
|
||||
flags |= NSShiftKeyMask;
|
||||
if (mods & MOD_MASK_CTRL)
|
||||
flags |= NSControlKeyMask;
|
||||
if (mods & MOD_MASK_ALT)
|
||||
flags |= NSAlternateKeyMask;
|
||||
if (mods & MOD_MASK_CMD)
|
||||
flags |= NSCommandKeyMask;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static int eventModifierFlagsToVimMouseModMask(int modifierFlags)
|
||||
{
|
||||
int modMask = 0;
|
||||
@@ -2499,68 +2462,3 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber)
|
||||
return (buttonNumber >= 0 && buttonNumber < 3)
|
||||
? mouseButton[buttonNumber] : -1;
|
||||
}
|
||||
|
||||
static int specialKeyToNSKey(int key)
|
||||
{
|
||||
if (!IS_SPECIAL(key))
|
||||
return key;
|
||||
|
||||
static struct {
|
||||
int special;
|
||||
int nskey;
|
||||
} sp2ns[] = {
|
||||
{ K_UP, NSUpArrowFunctionKey },
|
||||
{ K_DOWN, NSDownArrowFunctionKey },
|
||||
{ K_LEFT, NSLeftArrowFunctionKey },
|
||||
{ K_RIGHT, NSRightArrowFunctionKey },
|
||||
{ K_F1, NSF1FunctionKey },
|
||||
{ K_F2, NSF2FunctionKey },
|
||||
{ K_F3, NSF3FunctionKey },
|
||||
{ K_F4, NSF4FunctionKey },
|
||||
{ K_F5, NSF5FunctionKey },
|
||||
{ K_F6, NSF6FunctionKey },
|
||||
{ K_F7, NSF7FunctionKey },
|
||||
{ K_F8, NSF8FunctionKey },
|
||||
{ K_F9, NSF9FunctionKey },
|
||||
{ K_F10, NSF10FunctionKey },
|
||||
{ K_F11, NSF11FunctionKey },
|
||||
{ K_F12, NSF12FunctionKey },
|
||||
{ K_F13, NSF13FunctionKey },
|
||||
{ K_F14, NSF14FunctionKey },
|
||||
{ K_F15, NSF15FunctionKey },
|
||||
{ K_F16, NSF16FunctionKey },
|
||||
{ K_F17, NSF17FunctionKey },
|
||||
{ K_F18, NSF18FunctionKey },
|
||||
{ K_F19, NSF19FunctionKey },
|
||||
{ K_F20, NSF20FunctionKey },
|
||||
{ K_F21, NSF21FunctionKey },
|
||||
{ K_F22, NSF22FunctionKey },
|
||||
{ K_F23, NSF23FunctionKey },
|
||||
{ K_F24, NSF24FunctionKey },
|
||||
{ K_F25, NSF25FunctionKey },
|
||||
{ K_F26, NSF26FunctionKey },
|
||||
{ K_F27, NSF27FunctionKey },
|
||||
{ K_F28, NSF28FunctionKey },
|
||||
{ K_F29, NSF29FunctionKey },
|
||||
{ K_F30, NSF30FunctionKey },
|
||||
{ K_F31, NSF31FunctionKey },
|
||||
{ K_F32, NSF32FunctionKey },
|
||||
{ K_F33, NSF33FunctionKey },
|
||||
{ K_F34, NSF34FunctionKey },
|
||||
{ K_F35, NSF35FunctionKey },
|
||||
{ K_DEL, NSBackspaceCharacter },
|
||||
{ K_BS, NSDeleteCharacter },
|
||||
{ K_HOME, NSHomeFunctionKey },
|
||||
{ K_END, NSEndFunctionKey },
|
||||
{ K_PAGEUP, NSPageUpFunctionKey },
|
||||
{ K_PAGEDOWN, NSPageDownFunctionKey }
|
||||
};
|
||||
|
||||
int i;
|
||||
for (i = 0; i < sizeof(sp2ns)/sizeof(sp2ns[0]); ++i) {
|
||||
if (sp2ns[i].special == key)
|
||||
return sp2ns[i].nskey;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ static int numFullscreenWindows = 0;
|
||||
int fuRows = currRows, fuColumns = currColumns;
|
||||
|
||||
int maxRows, maxColumns;
|
||||
NSSize size = [[self screen] frame].size;
|
||||
NSSize size = [[self screen] visibleFrame].size;
|
||||
[view constrainRows:&maxRows columns:&maxColumns toSize:size];
|
||||
|
||||
// Store current pre-fu vim size
|
||||
@@ -298,6 +298,15 @@ static int numFullscreenWindows = 0;
|
||||
[super performClose:sender];
|
||||
}
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item
|
||||
{
|
||||
if ([item action] == @selector(vimMenuItemAction:)
|
||||
|| [item action] == @selector(performClose:))
|
||||
return [item tag];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end // MMFullscreenWindow
|
||||
|
||||
|
||||
|
||||
@@ -258,6 +258,16 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar";
|
||||
|| col+cells > maxColumns || !string || !(fg && bg && sp))
|
||||
return;
|
||||
|
||||
BOOL hasControlChars = [string rangeOfCharacterFromSet:
|
||||
[NSCharacterSet controlCharacterSet]].location != NSNotFound;
|
||||
if (hasControlChars) {
|
||||
// HACK! If a string for some reason contains control characters, then
|
||||
// draw blanks instead (otherwise charRangeForRow::: fails).
|
||||
NSRange subRange = { 0, cells };
|
||||
flags &= ~DRAW_WIDE;
|
||||
string = [[emptyRowString string] substringWithRange:subRange];
|
||||
}
|
||||
|
||||
// Find range of characters in text storage to replace.
|
||||
int acol = col;
|
||||
int acells = cells;
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
@interface MMTextView : NSTextView {
|
||||
BOOL shouldDrawInsertionPoint;
|
||||
NSEvent *lastMouseDownEvent;
|
||||
NSTrackingRectTag trackingRectTag;
|
||||
BOOL isDragging;
|
||||
BOOL isAutoscrolling;
|
||||
@@ -30,15 +29,14 @@
|
||||
int preEditColumn;
|
||||
int mouseShape;
|
||||
BOOL antialias;
|
||||
NSRect *invertRects;
|
||||
int numInvertRects;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame;
|
||||
|
||||
- (NSEvent *)lastMouseDownEvent;
|
||||
- (void)setShouldDrawInsertionPoint:(BOOL)on;
|
||||
- (void)setPreEditRow:(int)row column:(int)col;
|
||||
- (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
|
||||
fraction:(int)percent color:(NSColor *)color;
|
||||
- (void)hideMarkedTextField;
|
||||
- (void)performBatchDrawWithData:(NSData *)data;
|
||||
- (void)setMouseShape:(int)shape;
|
||||
|
||||
+189
-47
@@ -22,6 +22,7 @@
|
||||
#import "MMWindowController.h"
|
||||
#import "MMVimController.h"
|
||||
#import "MMTypesetter.h"
|
||||
#import "MMAppController.h"
|
||||
#import "MacVim.h"
|
||||
|
||||
|
||||
@@ -49,12 +50,20 @@ enum {
|
||||
- (void)setCursor;
|
||||
- (BOOL)convertPoint:(NSPoint)point toRow:(int *)row column:(int *)column;
|
||||
- (BOOL)convertRow:(int)row column:(int)column toPoint:(NSPoint *)point;
|
||||
- (BOOL)convertRow:(int)row column:(int)column numRows:(int)nr
|
||||
numColumns:(int)nc toRect:(NSRect *)rect;
|
||||
- (NSRect)trackingRect;
|
||||
- (void)dispatchKeyEvent:(NSEvent *)event;
|
||||
- (MMWindowController *)windowController;
|
||||
- (MMVimController *)vimController;
|
||||
- (void)startDragTimerWithInterval:(NSTimeInterval)t;
|
||||
- (void)dragTimerFired:(NSTimer *)timer;
|
||||
- (void)sendKeyDown:(const char *)chars length:(int)len modifiers:(int)flags;
|
||||
- (void)hideMouseCursor;
|
||||
- (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
|
||||
fraction:(int)percent color:(NSColor *)color;
|
||||
- (void)drawInvertedRectAtRow:(int)row column:(int)col numRows:(int)nrows
|
||||
numColumns:(int)ncols invert:(int)invert;
|
||||
@end
|
||||
|
||||
|
||||
@@ -127,13 +136,13 @@ enum {
|
||||
markedTextField = nil;
|
||||
}
|
||||
|
||||
[lastMouseDownEvent release]; lastMouseDownEvent = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
if (invertRects) {
|
||||
free(invertRects);
|
||||
invertRects = NULL;
|
||||
numInvertRects = 0;
|
||||
}
|
||||
|
||||
- (NSEvent *)lastMouseDownEvent
|
||||
{
|
||||
return lastMouseDownEvent;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (BOOL)shouldDrawInsertionPoint
|
||||
@@ -156,23 +165,6 @@ enum {
|
||||
preEditColumn = col;
|
||||
}
|
||||
|
||||
- (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
|
||||
fraction:(int)percent color:(NSColor *)color
|
||||
{
|
||||
//NSLog(@"drawInsertionPointAtRow:%d column:%d shape:%d color:%@",
|
||||
// row, col, shape, color);
|
||||
|
||||
// This only stores where to draw the insertion point, the actual drawing
|
||||
// is done in drawRect:.
|
||||
shouldDrawInsertionPoint = YES;
|
||||
insertionPointRow = row;
|
||||
insertionPointColumn = col;
|
||||
insertionPointShape = shape;
|
||||
insertionPointFraction = percent;
|
||||
|
||||
[self setInsertionPointColor:color];
|
||||
}
|
||||
|
||||
- (void)hideMarkedTextField
|
||||
{
|
||||
if (markedTextField) {
|
||||
@@ -303,6 +295,19 @@ enum {
|
||||
[self drawInsertionPointAtRow:row column:col shape:shape
|
||||
fraction:percent
|
||||
color:[NSColor colorWithRgbInt:color]];
|
||||
} else if (DrawInvertedRectDrawType == type) {
|
||||
int row = *((int*)bytes); bytes += sizeof(int);
|
||||
int col = *((int*)bytes); bytes += sizeof(int);
|
||||
int nr = *((int*)bytes); bytes += sizeof(int);
|
||||
int nc = *((int*)bytes); bytes += sizeof(int);
|
||||
int invert = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Draw inverted rect: row=%d col=%d nrows=%d ncols=%d",
|
||||
row, col, nr, nc);
|
||||
#endif
|
||||
[self drawInvertedRectAtRow:row column:col numRows:nr numColumns:nc
|
||||
invert:invert];
|
||||
} else if (SetCursorPosDrawType == type) {
|
||||
cursorRow = *((int*)bytes); bytes += sizeof(int);
|
||||
cursorCol = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -455,6 +460,24 @@ enum {
|
||||
|
||||
[super drawRect:rect];
|
||||
|
||||
if (invertRects) {
|
||||
CGContextRef cgctx = (CGContextRef)[context graphicsPort];
|
||||
CGContextSaveGState(cgctx);
|
||||
CGContextSetBlendMode(cgctx, kCGBlendModeDifference);
|
||||
CGContextSetRGBFillColor(cgctx, 1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
int i;
|
||||
CGRect *rect = (CGRect*)invertRects;
|
||||
for (i = 0; i < numInvertRects; ++i)
|
||||
CGContextFillRect(cgctx, rect[i]);
|
||||
|
||||
CGContextRestoreGState(cgctx);
|
||||
|
||||
free(invertRects);
|
||||
invertRects = NULL;
|
||||
numInvertRects = 0;
|
||||
}
|
||||
|
||||
if (shouldDrawInsertionPoint) {
|
||||
MMTextStorage *ts = (MMTextStorage*)[self textStorage];
|
||||
|
||||
@@ -468,7 +491,11 @@ enum {
|
||||
ipRect.origin.y += ipRect.size.height - frac;
|
||||
ipRect.size.height = frac;
|
||||
} else if (MMInsertionPointVertical == insertionPointShape) {
|
||||
int frac = ([ts cellSize].width* insertionPointFraction + 99)/100;
|
||||
int frac = ([ts cellSize].width * insertionPointFraction + 99)/100;
|
||||
ipRect.size.width = frac;
|
||||
} else if (MMInsertionPointVerticalRight == insertionPointShape) {
|
||||
int frac = ([ts cellSize].width * insertionPointFraction + 99)/100;
|
||||
ipRect.origin.x += ipRect.size.width - frac;
|
||||
ipRect.size.width = frac;
|
||||
}
|
||||
|
||||
@@ -566,8 +593,7 @@ enum {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Support 'mousehide' (check p_mh)
|
||||
[NSCursor setHiddenUntilMouseMoves:YES];
|
||||
[self hideMouseCursor];
|
||||
|
||||
// NOTE: 'string' is either an NSString or an NSAttributedString. Since we
|
||||
// do not support attributes, simply pass the corresponding NSString in the
|
||||
@@ -640,20 +666,18 @@ enum {
|
||||
&& !(116 == [event keyCode] || 121 == [event keyCode]))
|
||||
return NO;
|
||||
|
||||
// HACK! KeyCode 50 represent the key which switches between windows
|
||||
// within an application (like Cmd+Tab is used to switch between
|
||||
// applications). Return NO here, else the window switching does not work.
|
||||
if ([event keyCode] == 50)
|
||||
return NO;
|
||||
|
||||
// HACK! Let the main menu try to handle any key down event, before
|
||||
// passing it on to vim, otherwise key equivalents for menus will
|
||||
// effectively be disabled.
|
||||
if ([[NSApp mainMenu] performKeyEquivalent:event])
|
||||
return YES;
|
||||
|
||||
// HACK! KeyCode 50 represent the key which switches between windows
|
||||
// within an application (like Cmd+Tab is used to switch between
|
||||
// applications). Return NO here, else the window switching does not work.
|
||||
//
|
||||
// Will this hack work for all languages / keyboard layouts?
|
||||
if ([event keyCode] == 50)
|
||||
return NO;
|
||||
|
||||
// HACK! On Leopard Ctrl-key events end up here instead of keyDown:.
|
||||
if (flags & NSControlKeyMask) {
|
||||
[self keyDown:event];
|
||||
@@ -823,8 +847,6 @@ enum {
|
||||
if (![self convertPoint:pt toRow:&row column:&col])
|
||||
return;
|
||||
|
||||
lastMouseDownEvent = [event copy];
|
||||
|
||||
int button = [event buttonNumber];
|
||||
int flags = [event modifierFlags];
|
||||
int count = [event clickCount];
|
||||
@@ -928,6 +950,11 @@ enum {
|
||||
MMTextStorage *ts = (MMTextStorage*)[self textStorage];
|
||||
if (!ts) return;
|
||||
|
||||
// HACK! NSTextView has a nasty habit of resetting the cursor to the
|
||||
// default I-beam cursor at random moments. The only reliable way we know
|
||||
// of to work around this is to set the cursor each time the mouse moves.
|
||||
[self setCursor];
|
||||
|
||||
NSPoint pt = [self convertPoint:[event locationInWindow] fromView:nil];
|
||||
int row, col;
|
||||
if (![self convertPoint:pt toRow:&row column:&col])
|
||||
@@ -960,11 +987,6 @@ enum {
|
||||
// key.
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1119,6 +1141,54 @@ 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];
|
||||
}
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item
|
||||
{
|
||||
if ([item action] == @selector(cut:)
|
||||
|| [item action] == @selector(copy:)
|
||||
|| [item action] == @selector(paste:)
|
||||
|| [item action] == @selector(undo:)
|
||||
|| [item action] == @selector(redo:)
|
||||
|| [item action] == @selector(selectAll:))
|
||||
return [item tag];
|
||||
|
||||
return YES;
|
||||
}
|
||||
@end // MMTextView
|
||||
|
||||
|
||||
@@ -1198,6 +1268,23 @@ enum {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)convertRow:(int)row column:(int)column numRows:(int)nr
|
||||
numColumns:(int)nc toRect:(NSRect *)rect
|
||||
{
|
||||
MMTextStorage *ts = (MMTextStorage*)[self textStorage];
|
||||
NSSize cellSize = [ts cellSize];
|
||||
if (!(rect && cellSize.width > 0 && cellSize.height > 0))
|
||||
return NO;
|
||||
|
||||
rect->origin = [self textContainerOrigin];
|
||||
rect->origin.x += column * cellSize.width;
|
||||
rect->origin.y += row * cellSize.height;
|
||||
rect->size.width = cellSize.width * nc;
|
||||
rect->size.height = cellSize.height * nr;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSRect)trackingRect
|
||||
{
|
||||
NSRect rect = [self frame];
|
||||
@@ -1259,13 +1346,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
|
||||
@@ -1327,12 +1418,63 @@ enum {
|
||||
[data appendBytes:&len length:sizeof(int)];
|
||||
[data appendBytes:chars length:len];
|
||||
|
||||
// TODO: Support 'mousehide' (check p_mh)
|
||||
[NSCursor setHiddenUntilMouseMoves:YES];
|
||||
[self hideMouseCursor];
|
||||
|
||||
//NSLog(@"%s len=%d chars=0x%x", _cmd, len, chars[0]);
|
||||
[[self vimController] sendMessage:KeyDownMsgID data:data];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)hideMouseCursor
|
||||
{
|
||||
// Check 'mousehide' option
|
||||
id mh = [[[self vimController] vimState] objectForKey:@"p_mh"];
|
||||
if (mh && ![mh boolValue])
|
||||
[NSCursor setHiddenUntilMouseMoves:NO];
|
||||
else
|
||||
[NSCursor setHiddenUntilMouseMoves:YES];
|
||||
}
|
||||
|
||||
- (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
|
||||
fraction:(int)percent color:(NSColor *)color
|
||||
{
|
||||
//NSLog(@"drawInsertionPointAtRow:%d column:%d shape:%d color:%@",
|
||||
// row, col, shape, color);
|
||||
|
||||
// This only stores where to draw the insertion point, the actual drawing
|
||||
// is done in drawRect:.
|
||||
shouldDrawInsertionPoint = YES;
|
||||
insertionPointRow = row;
|
||||
insertionPointColumn = col;
|
||||
insertionPointShape = shape;
|
||||
insertionPointFraction = percent;
|
||||
|
||||
[self setInsertionPointColor:color];
|
||||
}
|
||||
|
||||
- (void)drawInvertedRectAtRow:(int)row column:(int)col numRows:(int)nrows
|
||||
numColumns:(int)ncols invert:(int)invert
|
||||
{
|
||||
if (invert) {
|
||||
// The result should be inverted.
|
||||
int n = numInvertRects++;
|
||||
invertRects = reallocf(invertRects,
|
||||
numInvertRects*sizeof(NSRect));
|
||||
if (NULL != invertRects) {
|
||||
[self convertRow:row column:col numRows:nrows numColumns:ncols
|
||||
toRect:&invertRects[n]];
|
||||
[self setNeedsDisplayInRect:invertRects[n]];
|
||||
} else {
|
||||
n = numInvertRects = 0;
|
||||
}
|
||||
} else {
|
||||
// The result should look normal; all we need to do is to mark
|
||||
// the rect for redrawing and Cocoa will redraw the text.
|
||||
NSRect rect;
|
||||
[self convertRow:row column:col numRows:nrows numColumns:ncols
|
||||
toRect:&rect];
|
||||
[self setNeedsDisplayInRect:rect];
|
||||
}
|
||||
}
|
||||
|
||||
@end // MMTextView (Private)
|
||||
|
||||
@@ -27,9 +27,8 @@
|
||||
id backendProxy;
|
||||
BOOL inProcessCommandQueue;
|
||||
NSMutableArray *sendQueue;
|
||||
NSMutableArray *mainMenuItems;
|
||||
NSMenu *mainMenu;
|
||||
NSMutableArray *popupMenuItems;
|
||||
BOOL shouldUpdateMainMenu;
|
||||
NSToolbar *toolbar;
|
||||
NSMutableDictionary *toolbarItemDict;
|
||||
int pid;
|
||||
@@ -39,18 +38,17 @@
|
||||
int resendMsgid;
|
||||
NSData *resendData;
|
||||
#endif
|
||||
NSMenu *lastMenuSearched;
|
||||
NSMenuItem *recentFilesMenuItem;
|
||||
NSMenuItem *recentFilesDummy;
|
||||
NSDictionary *vimState;
|
||||
}
|
||||
|
||||
- (id)initWithBackend:(id)backend pid:(int)processIdentifier
|
||||
recentFiles:(NSMenuItem*)menu;
|
||||
- (id)initWithBackend:(id)backend pid:(int)processIdentifier;
|
||||
- (id)backendProxy;
|
||||
- (int)pid;
|
||||
- (void)setServerName:(NSString *)name;
|
||||
- (NSString *)serverName;
|
||||
- (MMWindowController *)windowController;
|
||||
- (NSDictionary *)vimState;
|
||||
- (NSMenu *)mainMenu;
|
||||
- (void)cleanup;
|
||||
- (void)dropFiles:(NSArray *)filenames forceOpen:(BOOL)force;
|
||||
- (void)dropString:(NSString *)string;
|
||||
@@ -61,5 +59,4 @@
|
||||
timeout:(NSTimeInterval)timeout;
|
||||
- (void)addVimInput:(NSString *)string;
|
||||
- (NSString *)evaluateVimExpression:(NSString *)expr;
|
||||
- (void)updateMainMenu;
|
||||
@end
|
||||
|
||||
+398
-367
@@ -47,6 +47,8 @@ static NSTimeInterval MMBackendProxyRequestTimeout = 0;
|
||||
static NSTimeInterval MMResendInterval = 0.5;
|
||||
#endif
|
||||
|
||||
static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
|
||||
|
||||
|
||||
@interface MMAlert : NSAlert {
|
||||
NSTextField *textField;
|
||||
@@ -61,27 +63,39 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
- (void)savePanelDidEnd:(NSSavePanel *)panel code:(int)code
|
||||
context:(void *)context;
|
||||
- (void)alertDidEnd:(MMAlert *)alert code:(int)code context:(void *)context;
|
||||
- (NSMenuItem *)recurseMenuItemForTag:(int)tag rootMenu:(NSMenu *)root;
|
||||
- (NSMenuItem *)menuItemForTag:(int)tag;
|
||||
- (NSMenu *)menuForTag:(int)tag;
|
||||
- (NSMenuItem *)menuItemForDescriptor:(NSArray *)desc;
|
||||
- (NSMenu *)parentMenuForDescriptor:(NSArray *)desc;
|
||||
- (NSMenu *)topLevelMenuForTitle:(NSString *)title;
|
||||
- (void)addMenuWithTag:(int)tag parent:(int)parentTag title:(NSString *)title
|
||||
atIndex:(int)idx;
|
||||
- (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;
|
||||
- (NSToolbarItem *)toolbarItemForTag:(int)tag index:(int *)index;
|
||||
- (void)addToolbarItemToDictionaryWithTag:(int)tag label:(NSString *)title
|
||||
- (void)addMenuWithDescriptor:(NSArray *)desc atIndex:(int)index;
|
||||
- (void)addMenuItemWithDescriptor:(NSArray *)desc
|
||||
atIndex:(int)index
|
||||
tip:(NSString *)tip
|
||||
icon:(NSString *)icon
|
||||
keyEquivalent:(NSString *)keyEquivalent
|
||||
modifierMask:(int)modifierMask
|
||||
action:(NSString *)action
|
||||
isAlternate:(BOOL)isAlternate;
|
||||
- (void)removeMenuItemWithDescriptor:(NSArray *)desc;
|
||||
- (void)enableMenuItemWithDescriptor:(NSArray *)desc state:(BOOL)on;
|
||||
- (void)addToolbarItemToDictionaryWithLabel:(NSString *)title
|
||||
toolTip:(NSString *)tip icon:(NSString *)icon;
|
||||
- (void)addToolbarItemWithTag:(int)tag label:(NSString *)label
|
||||
- (void)addToolbarItemWithLabel:(NSString *)label
|
||||
tip:(NSString *)tip icon:(NSString *)icon
|
||||
atIndex:(int)idx;
|
||||
- (void)popupMenuWithDescriptor:(NSArray *)desc
|
||||
atRow:(NSNumber *)row
|
||||
column:(NSNumber *)col;
|
||||
- (void)connectionDidDie:(NSNotification *)notification;
|
||||
#if MM_RESEND_LAST_FAILURE
|
||||
- (void)resendTimerFired:(NSTimer *)timer;
|
||||
#endif
|
||||
- (void)replaceMenuItem:(NSMenuItem*)old with:(NSMenuItem*)new;
|
||||
@end
|
||||
|
||||
|
||||
@interface NSToolbar (MMExtras)
|
||||
- (int)indexOfItemWithItemIdentifier:(NSString *)identifier;
|
||||
- (NSToolbarItem *)itemAtIndex:(int)idx;
|
||||
- (NSToolbarItem *)itemWithItemIdentifier:(NSString *)identifier;
|
||||
@end
|
||||
|
||||
|
||||
@@ -90,17 +104,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];
|
||||
sendQueue = [NSMutableArray new];
|
||||
mainMenuItems = [[NSMutableArray alloc] init];
|
||||
popupMenuItems = [[NSMutableArray alloc] init];
|
||||
toolbarItemDict = [[NSMutableDictionary alloc] init];
|
||||
pid = processIdentifier;
|
||||
@@ -115,6 +124,25 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
selector:@selector(connectionDidDie:)
|
||||
name:NSConnectionDidDieNotification object:connection];
|
||||
|
||||
// Set up a main menu with only a "MacVim" menu (copied from a template
|
||||
// which itself is set up in MainMenu.nib). The main menu is populated
|
||||
// by Vim later on.
|
||||
mainMenu = [[NSMenu alloc] initWithTitle:@"MainMenu"];
|
||||
NSMenuItem *appMenuItem = [[MMAppController sharedInstance]
|
||||
appMenuItemTemplate];
|
||||
appMenuItem = [[appMenuItem copy] autorelease];
|
||||
|
||||
// Note: If the title of the application menu is anything but what
|
||||
// CFBundleName says then the application menu will not be typeset in
|
||||
// boldface for some reason. (It should already be set when we copy
|
||||
// from the default main menu, but this is not the case for some
|
||||
// reason.)
|
||||
NSString *appName = [[NSBundle mainBundle]
|
||||
objectForInfoDictionaryKey:@"CFBundleName"];
|
||||
[appMenuItem setTitle:appName];
|
||||
|
||||
[mainMenu addItem:appMenuItem];
|
||||
|
||||
isInitialized = YES;
|
||||
}
|
||||
|
||||
@@ -137,11 +165,10 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
[toolbarItemDict release]; toolbarItemDict = nil;
|
||||
[toolbar release]; toolbar = nil;
|
||||
[popupMenuItems release]; popupMenuItems = nil;
|
||||
[mainMenuItems release]; mainMenuItems = nil;
|
||||
[windowController release]; windowController = nil;
|
||||
|
||||
[recentFilesMenuItem release]; recentFilesMenuItem = nil;
|
||||
[recentFilesDummy release]; recentFilesDummy = nil;
|
||||
[vimState release]; vimState = nil;
|
||||
[mainMenu release]; mainMenu = nil;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
@@ -151,6 +178,16 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
return windowController;
|
||||
}
|
||||
|
||||
- (NSDictionary *)vimState
|
||||
{
|
||||
return vimState;
|
||||
}
|
||||
|
||||
- (NSMenu *)mainMenu
|
||||
{
|
||||
return mainMenu;
|
||||
}
|
||||
|
||||
- (void)setServerName:(NSString *)name
|
||||
{
|
||||
if (name != serverName) {
|
||||
@@ -390,6 +427,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]
|
||||
@@ -482,33 +528,33 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
unsigned i, count = [queue count];
|
||||
if (count % 2) {
|
||||
NSLog(@"WARNING: Uneven number of components (%d) in flush queue "
|
||||
"message; ignoring this message.", count);
|
||||
return;
|
||||
@try {
|
||||
unsigned i, count = [queue count];
|
||||
if (count % 2) {
|
||||
NSLog(@"WARNING: Uneven number of components (%d) in flush queue "
|
||||
"message; ignoring this message.", count);
|
||||
return;
|
||||
}
|
||||
|
||||
inProcessCommandQueue = YES;
|
||||
|
||||
//NSLog(@"======== %s BEGIN ========", _cmd);
|
||||
for (i = 0; i < count; i += 2) {
|
||||
NSData *value = [queue objectAtIndex:i];
|
||||
NSData *data = [queue objectAtIndex:i+1];
|
||||
|
||||
int msgid = *((int*)[value bytes]);
|
||||
//NSLog(@"%s%s", _cmd, MessageStrings[msgid]);
|
||||
|
||||
[self handleMessage:msgid data:data];
|
||||
}
|
||||
//NSLog(@"======== %s END ========", _cmd);
|
||||
}
|
||||
|
||||
inProcessCommandQueue = YES;
|
||||
|
||||
//NSLog(@"======== %s BEGIN ========", _cmd);
|
||||
for (i = 0; i < count; i += 2) {
|
||||
NSData *value = [queue objectAtIndex:i];
|
||||
NSData *data = [queue objectAtIndex:i+1];
|
||||
|
||||
int msgid = *((int*)[value bytes]);
|
||||
//NSLog(@"%s%s", _cmd, MessageStrings[msgid]);
|
||||
|
||||
[self handleMessage:msgid data:data];
|
||||
}
|
||||
//NSLog(@"======== %s END ========", _cmd);
|
||||
|
||||
if (shouldUpdateMainMenu) {
|
||||
[self updateMainMenu];
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught whilst processing command queue: %@", e);
|
||||
}
|
||||
|
||||
[windowController processCommandQueueDidFinish];
|
||||
|
||||
inProcessCommandQueue = NO;
|
||||
|
||||
if ([sendQueue count] > 0) {
|
||||
@@ -546,53 +592,6 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)updateMainMenu
|
||||
{
|
||||
NSMenu *mainMenu = [NSApp mainMenu];
|
||||
|
||||
// Stop NSApp from updating the Window menu.
|
||||
[NSApp setWindowsMenu:nil];
|
||||
|
||||
// Remove all menus from main menu (except the MacVim menu).
|
||||
int i, count = [mainMenu numberOfItems];
|
||||
for (i = count-1; i > 0; --i) {
|
||||
[mainMenu removeItemAtIndex:i];
|
||||
}
|
||||
|
||||
// Add menus from 'mainMenuItems' to main menu.
|
||||
count = [mainMenuItems count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
[mainMenu addItem:[mainMenuItems objectAtIndex:i]];
|
||||
}
|
||||
|
||||
// Set the new Window menu.
|
||||
// TODO! Need to look for 'Window' in all localized languages.
|
||||
NSMenu *windowMenu = [[mainMenu itemWithTitle:@"Window"] submenu];
|
||||
if (windowMenu) {
|
||||
// Remove all AppKit owned menu items (tag == 0); they will be added
|
||||
// again when setWindowsMenu: is called.
|
||||
count = [windowMenu numberOfItems];
|
||||
for (i = count-1; i >= 0; --i) {
|
||||
NSMenuItem *item = [windowMenu itemAtIndex:i];
|
||||
if (![item tag]) {
|
||||
[windowMenu removeItem:item];
|
||||
}
|
||||
}
|
||||
|
||||
[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;
|
||||
}
|
||||
|
||||
@end // MMVimController
|
||||
|
||||
|
||||
@@ -639,126 +638,26 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
|
||||
[string release];
|
||||
} else if (AddMenuMsgID == msgid) {
|
||||
NSString *title = nil;
|
||||
const void *bytes = [data bytes];
|
||||
int tag = *((int*)bytes); bytes += sizeof(int);
|
||||
int parentTag = *((int*)bytes); bytes += sizeof(int);
|
||||
int len = *((int*)bytes); bytes += sizeof(int);
|
||||
if (len > 0) {
|
||||
title = [[NSString alloc] initWithBytes:(void*)bytes length:len
|
||||
encoding:NSUTF8StringEncoding];
|
||||
bytes += len;
|
||||
}
|
||||
int idx = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
if (MenuToolbarType == parentTag) {
|
||||
if (!toolbar) {
|
||||
// NOTE! Each toolbar must have a unique identifier, else each
|
||||
// window will have the same toolbar.
|
||||
NSString *ident = [NSString stringWithFormat:@"%d.%d",
|
||||
(int)self, tag];
|
||||
toolbar = [[NSToolbar alloc] initWithIdentifier:ident];
|
||||
|
||||
[toolbar setShowsBaselineSeparator:NO];
|
||||
[toolbar setDelegate:self];
|
||||
[toolbar setDisplayMode:NSToolbarDisplayModeIconOnly];
|
||||
[toolbar setSizeMode:NSToolbarSizeModeSmall];
|
||||
|
||||
[windowController setToolbar:toolbar];
|
||||
}
|
||||
} else if (title) {
|
||||
[self addMenuWithTag:tag parent:parentTag title:title atIndex:idx];
|
||||
}
|
||||
|
||||
[title release];
|
||||
NSDictionary *attrs = [NSDictionary dictionaryWithData:data];
|
||||
[self addMenuWithDescriptor:[attrs objectForKey:@"descriptor"]
|
||||
atIndex:[[attrs objectForKey:@"index"] intValue]];
|
||||
} else if (AddMenuItemMsgID == msgid) {
|
||||
NSString *title = nil, *tip = nil, *icon = nil, *action = nil;
|
||||
const void *bytes = [data bytes];
|
||||
int tag = *((int*)bytes); bytes += sizeof(int);
|
||||
int parentTag = *((int*)bytes); bytes += sizeof(int);
|
||||
int namelen = *((int*)bytes); bytes += sizeof(int);
|
||||
if (namelen > 0) {
|
||||
title = [[NSString alloc] initWithBytes:(void*)bytes length:namelen
|
||||
encoding:NSUTF8StringEncoding];
|
||||
bytes += namelen;
|
||||
}
|
||||
int tiplen = *((int*)bytes); bytes += sizeof(int);
|
||||
if (tiplen > 0) {
|
||||
tip = [[NSString alloc] initWithBytes:(void*)bytes length:tiplen
|
||||
encoding:NSUTF8StringEncoding];
|
||||
bytes += tiplen;
|
||||
}
|
||||
int iconlen = *((int*)bytes); bytes += sizeof(int);
|
||||
if (iconlen > 0) {
|
||||
icon = [[NSString alloc] initWithBytes:(void*)bytes length:iconlen
|
||||
encoding:NSUTF8StringEncoding];
|
||||
bytes += iconlen;
|
||||
}
|
||||
int actionlen = *((int*)bytes); bytes += sizeof(int);
|
||||
if (actionlen > 0) {
|
||||
action = [[NSString alloc] initWithBytes:(void*)bytes
|
||||
length:actionlen
|
||||
encoding:NSUTF8StringEncoding];
|
||||
bytes += actionlen;
|
||||
}
|
||||
int idx = *((int*)bytes); bytes += sizeof(int);
|
||||
if (idx < 0) idx = 0;
|
||||
int key = *((int*)bytes); bytes += sizeof(int);
|
||||
int mask = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
NSString *ident = [NSString stringWithFormat:@"%d.%d",
|
||||
(int)self, parentTag];
|
||||
if (toolbar && [[toolbar identifier] isEqual:ident]) {
|
||||
[self addToolbarItemWithTag:tag label:title tip:tip icon:icon
|
||||
atIndex:idx];
|
||||
} else {
|
||||
NSMenu *parent = [self menuForTag:parentTag];
|
||||
[self addMenuItemWithTag:tag parent:parent title:title tip:tip
|
||||
keyEquivalent:key modifiers:mask action:action
|
||||
atIndex:idx];
|
||||
}
|
||||
|
||||
[title release];
|
||||
[tip release];
|
||||
[icon release];
|
||||
[action release];
|
||||
NSDictionary *attrs = [NSDictionary dictionaryWithData:data];
|
||||
[self addMenuItemWithDescriptor:[attrs objectForKey:@"descriptor"]
|
||||
atIndex:[[attrs objectForKey:@"index"] intValue]
|
||||
tip:[attrs objectForKey:@"tip"]
|
||||
icon:[attrs objectForKey:@"icon"]
|
||||
keyEquivalent:[attrs objectForKey:@"keyEquivalent"]
|
||||
modifierMask:[[attrs objectForKey:@"modifierMask"] intValue]
|
||||
action:[attrs objectForKey:@"action"]
|
||||
isAlternate:[[attrs objectForKey:@"isAlternate"] boolValue]];
|
||||
} else if (RemoveMenuItemMsgID == msgid) {
|
||||
const void *bytes = [data bytes];
|
||||
int tag = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
id item;
|
||||
int idx;
|
||||
if ((item = [self toolbarItemForTag:tag index:&idx])) {
|
||||
[toolbar removeItemAtIndex:idx];
|
||||
} else if ((item = [self menuItemForTag:tag])) {
|
||||
[item retain];
|
||||
|
||||
if ([item menu] == [NSApp mainMenu] || ![item menu]) {
|
||||
// NOTE: To be on the safe side we try to remove the item from
|
||||
// both arrays (it is ok to call removeObject: even if an array
|
||||
// does not contain the object to remove).
|
||||
[mainMenuItems removeObject:item];
|
||||
[popupMenuItems removeObject:item];
|
||||
}
|
||||
|
||||
if ([item menu])
|
||||
[[item menu] removeItem:item];
|
||||
|
||||
[item release];
|
||||
}
|
||||
|
||||
// Reset cached menu, just to be on the safe side.
|
||||
lastMenuSearched = nil;
|
||||
NSDictionary *attrs = [NSDictionary dictionaryWithData:data];
|
||||
[self removeMenuItemWithDescriptor:[attrs objectForKey:@"descriptor"]];
|
||||
} else if (EnableMenuItemMsgID == msgid) {
|
||||
const void *bytes = [data bytes];
|
||||
int tag = *((int*)bytes); bytes += sizeof(int);
|
||||
int state = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
id item = [self toolbarItemForTag:tag index:NULL];
|
||||
if (!item)
|
||||
item = [self menuItemForTag:tag];
|
||||
|
||||
[item setEnabled:state];
|
||||
NSDictionary *attrs = [NSDictionary dictionaryWithData:data];
|
||||
[self enableMenuItemWithDescriptor:[attrs objectForKey:@"descriptor"]
|
||||
state:[[attrs objectForKey:@"enable"] boolValue]];
|
||||
} else if (ShowToolbarMsgID == msgid) {
|
||||
const void *bytes = [data bytes];
|
||||
int enable = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -857,23 +756,10 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
|
||||
[actionName release];
|
||||
} else if (ShowPopupMenuMsgID == msgid) {
|
||||
const void *bytes = [data bytes];
|
||||
int row = *((int*)bytes); bytes += sizeof(int);
|
||||
int col = *((int*)bytes); bytes += sizeof(int);
|
||||
int len = *((int*)bytes); bytes += sizeof(int);
|
||||
NSString *title = [[NSString alloc]
|
||||
initWithBytes:(void*)bytes length:len
|
||||
encoding:NSUTF8StringEncoding];
|
||||
|
||||
NSMenu *menu = [self topLevelMenuForTitle:title];
|
||||
if (menu) {
|
||||
[windowController popupMenu:menu atRow:row column:col];
|
||||
} else {
|
||||
NSLog(@"WARNING: Cannot popup menu with title %@; no such menu.",
|
||||
title);
|
||||
}
|
||||
|
||||
[title release];
|
||||
NSDictionary *attrs = [NSDictionary dictionaryWithData:data];
|
||||
[self popupMenuWithDescriptor:[attrs objectForKey:@"descriptor"]
|
||||
atRow:[attrs objectForKey:@"row"]
|
||||
column:[attrs objectForKey:@"column"]];
|
||||
} else if (SetMouseShapeMsgID == msgid) {
|
||||
const void *bytes = [data bytes];
|
||||
int shape = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -914,6 +800,12 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
[[[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);
|
||||
}
|
||||
@@ -923,6 +815,15 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
context:(void *)context
|
||||
{
|
||||
NSString *path = (code == NSOKButton) ? [panel filename] : nil;
|
||||
|
||||
// NOTE! setDialogReturn: is a synchronous call so set a proper timeout to
|
||||
// avoid waiting forever for it to finish. We make this a synchronous call
|
||||
// so that we can be fairly certain that Vim doesn't think the dialog box
|
||||
// is still showing when MacVim has in fact already dismissed it.
|
||||
NSConnection *conn = [backendProxy connectionForProxy];
|
||||
NSTimeInterval oldTimeout = [conn requestTimeout];
|
||||
[conn setRequestTimeout:MMSetDialogReturnTimeout];
|
||||
|
||||
@try {
|
||||
[backendProxy setDialogReturn:path];
|
||||
|
||||
@@ -935,6 +836,9 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught in %s %@", _cmd, e);
|
||||
}
|
||||
@finally {
|
||||
[conn setRequestTimeout:oldTimeout];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)alertDidEnd:(MMAlert *)alert code:(int)code context:(void *)context
|
||||
@@ -958,74 +862,61 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSMenuItem *)recurseMenuItemForTag:(int)tag rootMenu:(NSMenu *)root
|
||||
- (NSMenuItem *)menuItemForDescriptor:(NSArray *)desc
|
||||
{
|
||||
if (root) {
|
||||
NSMenuItem *item = [root itemWithTag:tag];
|
||||
if (item) {
|
||||
lastMenuSearched = root;
|
||||
return item;
|
||||
}
|
||||
if (!(desc && [desc count] > 0)) return nil;
|
||||
|
||||
NSArray *items = [root itemArray];
|
||||
unsigned i, count = [items count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
item = [items objectAtIndex:i];
|
||||
if ([item hasSubmenu]) {
|
||||
item = [self recurseMenuItemForTag:tag
|
||||
rootMenu:[item submenu]];
|
||||
if (item) {
|
||||
lastMenuSearched = [item submenu];
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
NSString *rootName = [desc objectAtIndex:0];
|
||||
NSArray *rootItems = [rootName hasPrefix:@"PopUp"] ? popupMenuItems
|
||||
: [mainMenu itemArray];
|
||||
|
||||
NSMenuItem *item = nil;
|
||||
int i, count = [rootItems count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
item = [rootItems objectAtIndex:i];
|
||||
if ([[item title] isEqual:rootName])
|
||||
break;
|
||||
}
|
||||
|
||||
return nil;
|
||||
if (i == count) return nil;
|
||||
|
||||
count = [desc count];
|
||||
for (i = 1; i < count; ++i) {
|
||||
item = [[item submenu] itemWithTitle:[desc objectAtIndex:i]];
|
||||
if (!item) return nil;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
- (NSMenuItem *)menuItemForTag:(int)tag
|
||||
- (NSMenu *)parentMenuForDescriptor:(NSArray *)desc
|
||||
{
|
||||
// First search the same menu that was search last time this method was
|
||||
// called. Since this method is often called for each menu item in a
|
||||
// menu this can significantly improve search times.
|
||||
if (lastMenuSearched) {
|
||||
NSMenuItem *item = [self recurseMenuItemForTag:tag
|
||||
rootMenu:lastMenuSearched];
|
||||
if (item) return item;
|
||||
}
|
||||
if (!(desc && [desc count] > 0)) return nil;
|
||||
|
||||
// Search the main menu.
|
||||
int i, count = [mainMenuItems count];
|
||||
NSString *rootName = [desc objectAtIndex:0];
|
||||
NSArray *rootItems = [rootName hasPrefix:@"PopUp"] ? popupMenuItems
|
||||
: [mainMenu itemArray];
|
||||
|
||||
NSMenu *menu = nil;
|
||||
int i, count = [rootItems count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSMenuItem *item = [mainMenuItems objectAtIndex:i];
|
||||
if ([item tag] == tag) return item;
|
||||
item = [self recurseMenuItemForTag:tag rootMenu:[item submenu]];
|
||||
if (item) {
|
||||
lastMenuSearched = [item submenu];
|
||||
return item;
|
||||
NSMenuItem *item = [rootItems objectAtIndex:i];
|
||||
if ([[item title] isEqual:rootName]) {
|
||||
menu = [item submenu];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Search the popup menus.
|
||||
count = [popupMenuItems count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSMenuItem *item = [popupMenuItems objectAtIndex:i];
|
||||
if ([item tag] == tag) return item;
|
||||
item = [self recurseMenuItemForTag:tag rootMenu:[item submenu]];
|
||||
if (item) {
|
||||
lastMenuSearched = [item submenu];
|
||||
return item;
|
||||
}
|
||||
if (!menu) return nil;
|
||||
|
||||
count = [desc count] - 1;
|
||||
for (i = 1; i < count; ++i) {
|
||||
NSMenuItem *item = [menu itemWithTitle:[desc objectAtIndex:i]];
|
||||
menu = [item submenu];
|
||||
if (!menu) return nil;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSMenu *)menuForTag:(int)tag
|
||||
{
|
||||
return [[self menuItemForTag:tag] submenu];
|
||||
return menu;
|
||||
}
|
||||
|
||||
- (NSMenu *)topLevelMenuForTitle:(NSString *)title
|
||||
@@ -1039,9 +930,9 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
return [item submenu];
|
||||
}
|
||||
|
||||
count = [mainMenuItems count];
|
||||
count = [mainMenu numberOfItems];
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSMenuItem *item = [mainMenuItems objectAtIndex:i];
|
||||
NSMenuItem *item = [mainMenu itemAtIndex:i];
|
||||
if ([title isEqual:[item title]])
|
||||
return [item submenu];
|
||||
}
|
||||
@@ -1049,110 +940,191 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)addMenuWithTag:(int)tag parent:(int)parentTag title:(NSString *)title
|
||||
atIndex:(int)idx
|
||||
- (void)addMenuWithDescriptor:(NSArray *)desc atIndex:(int)idx
|
||||
{
|
||||
NSMenu *parent = [self menuForTag:parentTag];
|
||||
if (!(desc && [desc count] > 0 && idx >= 0)) return;
|
||||
|
||||
NSString *rootName = [desc objectAtIndex:0];
|
||||
if ([rootName isEqual:@"ToolBar"]) {
|
||||
// The toolbar only has one menu, we take this as a hint to create a
|
||||
// toolbar, then we return.
|
||||
if (!toolbar) {
|
||||
// NOTE! Each toolbar must have a unique identifier, else each
|
||||
// window will have the same toolbar.
|
||||
NSString *ident = [NSString stringWithFormat:@"%d", (int)self];
|
||||
toolbar = [[NSToolbar alloc] initWithIdentifier:ident];
|
||||
|
||||
[toolbar setShowsBaselineSeparator:NO];
|
||||
[toolbar setDelegate:self];
|
||||
[toolbar setDisplayMode:NSToolbarDisplayModeIconOnly];
|
||||
[toolbar setSizeMode:NSToolbarSizeModeSmall];
|
||||
|
||||
[windowController setToolbar:toolbar];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// This is either a main menu item or a popup menu item.
|
||||
NSString *title = [desc lastObject];
|
||||
NSMenuItem *item = [[NSMenuItem alloc] init];
|
||||
NSMenu *menu = [[NSMenu alloc] initWithTitle:title];
|
||||
|
||||
[menu setAutoenablesItems:NO];
|
||||
[item setTag:tag];
|
||||
[item setTitle:title];
|
||||
[item setSubmenu:menu];
|
||||
|
||||
if (parent) {
|
||||
NSMenu *parent = [self parentMenuForDescriptor:desc];
|
||||
if (!parent && [rootName hasPrefix:@"PopUp"]) {
|
||||
if ([popupMenuItems count] <= idx) {
|
||||
[popupMenuItems addObject:item];
|
||||
} else {
|
||||
[popupMenuItems insertObject:item atIndex:idx];
|
||||
}
|
||||
} else {
|
||||
// If descriptor has no parent and its not a popup (or toolbar) menu,
|
||||
// then it must belong to main menu.
|
||||
if (!parent) parent = mainMenu;
|
||||
|
||||
if ([parent numberOfItems] <= idx) {
|
||||
[parent addItem:item];
|
||||
} else {
|
||||
[parent insertItem:item atIndex:idx];
|
||||
}
|
||||
} else {
|
||||
NSMutableArray *items = (MenuPopupType == parentTag)
|
||||
? popupMenuItems : mainMenuItems;
|
||||
if ([items count] <= idx) {
|
||||
[items addObject:item];
|
||||
} else {
|
||||
[items insertObject:item atIndex:idx];
|
||||
}
|
||||
|
||||
shouldUpdateMainMenu = (MenuPopupType != parentTag);
|
||||
}
|
||||
|
||||
[item release];
|
||||
[menu release];
|
||||
}
|
||||
|
||||
- (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
|
||||
- (void)addMenuItemWithDescriptor:(NSArray *)desc
|
||||
atIndex:(int)idx
|
||||
tip:(NSString *)tip
|
||||
icon:(NSString *)icon
|
||||
keyEquivalent:(NSString *)keyEquivalent
|
||||
modifierMask:(int)modifierMask
|
||||
action:(NSString *)action
|
||||
isAlternate:(BOOL)isAlternate
|
||||
{
|
||||
if (parent) {
|
||||
NSMenuItem *item = nil;
|
||||
if (!title || ([title hasPrefix:@"-"] && [title hasSuffix:@"-"])) {
|
||||
item = [NSMenuItem separatorItem];
|
||||
} else {
|
||||
item = [[[NSMenuItem alloc] init] autorelease];
|
||||
[item setTitle:title];
|
||||
if (!(desc && [desc count] > 1 && idx >= 0)) return;
|
||||
|
||||
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];
|
||||
NSString *title = [desc lastObject];
|
||||
NSString *rootName = [desc objectAtIndex:0];
|
||||
|
||||
} 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 ([rootName isEqual:@"ToolBar"]) {
|
||||
if (toolbar && [desc count] == 2)
|
||||
[self addToolbarItemWithLabel:title tip:tip icon:icon atIndex:idx];
|
||||
return;
|
||||
}
|
||||
|
||||
if (key != 0) {
|
||||
NSString *keyString =
|
||||
[NSString stringWithFormat:@"%C", key];
|
||||
[item setKeyEquivalent:keyString];
|
||||
[item setKeyEquivalentModifierMask:mask];
|
||||
}
|
||||
NSMenu *parent = [self parentMenuForDescriptor:desc];
|
||||
if (!parent) {
|
||||
NSLog(@"WARNING: Menu item '%@' has no parent",
|
||||
[desc componentsJoinedByString:@"->"]);
|
||||
return;
|
||||
}
|
||||
|
||||
NSMenuItem *item = nil;
|
||||
if (0 == [title length]
|
||||
|| ([title hasPrefix:@"-"] && [title hasSuffix:@"-"])) {
|
||||
item = [NSMenuItem separatorItem];
|
||||
[item setTitle:title];
|
||||
} else {
|
||||
item = [[[NSMenuItem alloc] init] autorelease];
|
||||
[item setTitle:title];
|
||||
|
||||
// Note: It is possible to set the action to a message that "doesn't
|
||||
// exist" without problems. We take advantage of this when adding
|
||||
// "dummy items" e.g. when dealing with the "Recent Files" menu (in
|
||||
// which case a recentFilesDummy: action is set, although it is never
|
||||
// used).
|
||||
if ([action length] > 0)
|
||||
[item setAction:NSSelectorFromString(action)];
|
||||
else
|
||||
[item setAction:@selector(vimMenuItemAction:)];
|
||||
if ([tip length] > 0) [item setToolTip:tip];
|
||||
if ([keyEquivalent length] > 0) {
|
||||
[item setKeyEquivalent:keyEquivalent];
|
||||
[item setKeyEquivalentModifierMask:modifierMask];
|
||||
}
|
||||
[item setAlternate:isAlternate];
|
||||
|
||||
// The tag is used to indicate whether Vim thinks a menu item should be
|
||||
// enabled or disabled. By default Vim thinks menu items are enabled.
|
||||
[item setTag:1];
|
||||
}
|
||||
|
||||
if ([parent numberOfItems] <= idx) {
|
||||
[parent addItem:item];
|
||||
} else {
|
||||
[parent insertItem:item atIndex:idx];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeMenuItemWithDescriptor:(NSArray *)desc
|
||||
{
|
||||
if (!(desc && [desc count] > 0)) return;
|
||||
|
||||
NSString *title = [desc lastObject];
|
||||
NSString *rootName = [desc objectAtIndex:0];
|
||||
if ([rootName isEqual:@"ToolBar"]) {
|
||||
if (toolbar) {
|
||||
if ([desc count] == 1) {
|
||||
[windowController setToolbar:nil];
|
||||
[toolbar release]; toolbar = nil;
|
||||
} else if ([desc count] == 2) {
|
||||
int idx = [toolbar indexOfItemWithItemIdentifier:title];
|
||||
if (idx != NSNotFound)
|
||||
[toolbar removeItemAtIndex:idx];
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE! The tag is used to idenfity which menu items were
|
||||
// added by Vim (tag != 0) and which were added by the AppKit
|
||||
// (tag == 0).
|
||||
[item setTag:tag];
|
||||
NSMenuItem *item = [self menuItemForDescriptor:desc];
|
||||
if (!item) {
|
||||
NSLog(@"Failed to remove menu item, descriptor not found: %@",
|
||||
[desc componentsJoinedByString:@"->"]);
|
||||
return;
|
||||
}
|
||||
|
||||
if ([parent numberOfItems] <= idx) {
|
||||
[parent addItem:item];
|
||||
} else {
|
||||
[parent insertItem:item atIndex:idx];
|
||||
[item retain];
|
||||
|
||||
if ([item menu] == [NSApp mainMenu] || ![item menu]) {
|
||||
// NOTE: To be on the safe side we try to remove the item from
|
||||
// both arrays (it is ok to call removeObject: even if an array
|
||||
// does not contain the object to remove).
|
||||
[popupMenuItems removeObject:item];
|
||||
}
|
||||
|
||||
if ([item menu])
|
||||
[[item menu] removeItem:item];
|
||||
|
||||
[item release];
|
||||
}
|
||||
|
||||
- (void)enableMenuItemWithDescriptor:(NSArray *)desc state:(BOOL)on
|
||||
{
|
||||
if (!(desc && [desc count] > 0)) return;
|
||||
|
||||
/*NSLog(@"%sable item %@", on ? "En" : "Dis",
|
||||
[desc componentsJoinedByString:@"->"]);*/
|
||||
|
||||
NSString *rootName = [desc objectAtIndex:0];
|
||||
if ([rootName isEqual:@"ToolBar"]) {
|
||||
if (toolbar && [desc count] == 2) {
|
||||
NSString *title = [desc lastObject];
|
||||
[[toolbar itemWithItemIdentifier:title] setEnabled:on];
|
||||
}
|
||||
} else {
|
||||
NSLog(@"WARNING: Menu item '%@' (tag=%d) has no parent.", title, tag);
|
||||
// Use tag to set whether item is enabled or disabled instead of
|
||||
// calling setEnabled:. This way the menus can autoenable themselves
|
||||
// but at the same time Vim can set if a menu is enabled whenever it
|
||||
// wants to.
|
||||
[[self menuItemForDescriptor:desc] setTag:on];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSToolbarItem *)toolbarItemForTag:(int)tag index:(int *)index
|
||||
{
|
||||
if (!toolbar) return nil;
|
||||
|
||||
NSArray *items = [toolbar items];
|
||||
int i, count = [items count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSToolbarItem *item = [items objectAtIndex:i];
|
||||
if ([item tag] == tag) {
|
||||
if (index) *index = i;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)addToolbarItemToDictionaryWithTag:(int)tag label:(NSString *)title
|
||||
- (void)addToolbarItemToDictionaryWithLabel:(NSString *)title
|
||||
toolTip:(NSString *)tip icon:(NSString *)icon
|
||||
{
|
||||
// If the item corresponds to a separator then do nothing, since it is
|
||||
@@ -1163,10 +1135,9 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
return;
|
||||
|
||||
NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:title];
|
||||
[item setTag:tag];
|
||||
[item setLabel:title];
|
||||
[item setToolTip:tip];
|
||||
[item setAction:@selector(vimMenuItemAction:)];
|
||||
[item setAction:@selector(vimToolbarItemAction:)];
|
||||
[item setAutovalidates:NO];
|
||||
|
||||
NSImage *img = [NSImage imageNamed:icon];
|
||||
@@ -1186,7 +1157,7 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
[item release];
|
||||
}
|
||||
|
||||
- (void)addToolbarItemWithTag:(int)tag label:(NSString *)label tip:(NSString
|
||||
- (void)addToolbarItemWithLabel:(NSString *)label tip:(NSString
|
||||
*)tip icon:(NSString *)icon atIndex:(int)idx
|
||||
{
|
||||
if (!toolbar) return;
|
||||
@@ -1207,8 +1178,7 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
[self addToolbarItemToDictionaryWithTag:tag label:label toolTip:tip
|
||||
icon:icon];
|
||||
[self addToolbarItemToDictionaryWithLabel:label toolTip:tip icon:icon];
|
||||
|
||||
int maxIdx = [[toolbar items] count];
|
||||
if (maxIdx < idx) idx = maxIdx;
|
||||
@@ -1216,6 +1186,39 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
[toolbar insertItemWithItemIdentifier:label atIndex:idx];
|
||||
}
|
||||
|
||||
- (void)popupMenuWithDescriptor:(NSArray *)desc
|
||||
atRow:(NSNumber *)row
|
||||
column:(NSNumber *)col
|
||||
{
|
||||
NSMenu *menu = [[self menuItemForDescriptor:desc] submenu];
|
||||
if (!menu) return;
|
||||
|
||||
id textView = [[windowController vimView] textView];
|
||||
NSPoint pt;
|
||||
if (row && col) {
|
||||
// TODO: Let textView convert (row,col) to NSPoint.
|
||||
int r = [row intValue];
|
||||
int c = [col intValue];
|
||||
NSSize cellSize = [textView cellSize];
|
||||
pt = NSMakePoint((c+1)*cellSize.width, (r+1)*cellSize.height);
|
||||
pt = [textView convertPoint:pt toView:nil];
|
||||
} else {
|
||||
pt = [[windowController window] mouseLocationOutsideOfEventStream];
|
||||
}
|
||||
|
||||
NSEvent *event = [NSEvent mouseEventWithType:NSRightMouseDown
|
||||
location:pt
|
||||
modifierFlags:0
|
||||
timestamp:0
|
||||
windowNumber:[[windowController window] windowNumber]
|
||||
context:nil
|
||||
eventNumber:0
|
||||
clickCount:0
|
||||
pressure:1.0];
|
||||
|
||||
[NSMenu popUpContextMenu:menu withEvent:event forView:textView];
|
||||
}
|
||||
|
||||
- (void)connectionDidDie:(NSNotification *)notification
|
||||
{
|
||||
//NSLog(@"%@ %s%@", [self className], _cmd, notification);
|
||||
@@ -1223,14 +1226,14 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
[self cleanup];
|
||||
|
||||
// NOTE! This causes the call to removeVimController: to be delayed.
|
||||
[[NSApp delegate]
|
||||
[[MMAppController sharedInstance]
|
||||
performSelectorOnMainThread:@selector(removeVimController:)
|
||||
withObject:self waitUntilDone:NO];
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@ : isInitialized=%d inProcessCommandQueue=%d mainMenuItems=%@ popupMenuItems=%@ toolbar=%@", [self className], isInitialized, inProcessCommandQueue, mainMenuItems, popupMenuItems, toolbar];
|
||||
return [NSString stringWithFormat:@"%@ : isInitialized=%d inProcessCommandQueue=%d mainMenu=%@ popupMenuItems=%@ toolbar=%@", [self className], isInitialized, inProcessCommandQueue, mainMenu, popupMenuItems, toolbar];
|
||||
}
|
||||
|
||||
#if MM_RESEND_LAST_FAILURE
|
||||
@@ -1253,15 +1256,43 @@ static NSTimeInterval MMResendInterval = 0.5;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)replaceMenuItem:(NSMenuItem*)old with:(NSMenuItem*)new
|
||||
@end // MMVimController (Private)
|
||||
|
||||
|
||||
|
||||
|
||||
@implementation NSToolbar (MMExtras)
|
||||
|
||||
- (int)indexOfItemWithItemIdentifier:(NSString *)identifier
|
||||
{
|
||||
NSMenu *menu = [old menu];
|
||||
int index = [menu indexOfItem:old];
|
||||
[menu removeItemAtIndex:index];
|
||||
[menu insertItem:new atIndex:index];
|
||||
NSArray *items = [self items];
|
||||
int i, count = [items count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
id item = [items objectAtIndex:i];
|
||||
if ([[item itemIdentifier] isEqual:identifier])
|
||||
return i;
|
||||
}
|
||||
|
||||
return NSNotFound;
|
||||
}
|
||||
|
||||
@end // MMVimController (Private)
|
||||
- (NSToolbarItem *)itemAtIndex:(int)idx
|
||||
{
|
||||
NSArray *items = [self items];
|
||||
if (idx < 0 || idx >= [items count])
|
||||
return nil;
|
||||
|
||||
return [items objectAtIndex:idx];
|
||||
}
|
||||
|
||||
- (NSToolbarItem *)itemWithItemIdentifier:(NSString *)identifier
|
||||
{
|
||||
int idx = [self indexOfItemWithItemIdentifier:identifier];
|
||||
return idx != NSNotFound ? [self itemAtIndex:idx] : nil;
|
||||
}
|
||||
|
||||
@end // NSToolbar (MMExtras)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -129,4 +129,13 @@
|
||||
[super performClose:sender];
|
||||
}
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item
|
||||
{
|
||||
if ([item action] == @selector(vimMenuItemAction:)
|
||||
|| [item action] == @selector(performClose:))
|
||||
return [item tag];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end // MMWindow
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
- (void)setFont:(NSFont *)font;
|
||||
- (void)setWideFont:(NSFont *)font;
|
||||
- (void)processCommandQueueDidFinish;
|
||||
- (void)popupMenu:(NSMenu *)menu atRow:(int)row column:(int)col;
|
||||
- (void)showTabBar:(BOOL)on;
|
||||
- (void)showToolbar:(BOOL)on size:(int)size mode:(int)mode;
|
||||
- (void)setMouseShape:(int)shape;
|
||||
@@ -68,5 +67,9 @@
|
||||
- (IBAction)performClose:(id)sender;
|
||||
- (IBAction)findNext:(id)sender;
|
||||
- (IBAction)findPrevious:(id)sender;
|
||||
- (IBAction)vimMenuItemAction:(id)sender;
|
||||
- (IBAction)vimToolbarItemAction:(id)sender;
|
||||
- (IBAction)fontSizeUp:(id)sender;
|
||||
- (IBAction)fontSizeDown:(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;
|
||||
@@ -264,7 +263,7 @@
|
||||
|
||||
- (void)openWindow
|
||||
{
|
||||
[[NSApp delegate] windowControllerWillOpen:self];
|
||||
[[MMAppController sharedInstance] windowControllerWillOpen:self];
|
||||
|
||||
[self addNewTabViewItem];
|
||||
|
||||
@@ -412,33 +411,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)popupMenu:(NSMenu *)menu atRow:(int)row column:(int)col
|
||||
{
|
||||
if (!setupDone) return;
|
||||
|
||||
NSEvent *event;
|
||||
if (row >= 0 && col >= 0) {
|
||||
// TODO: Let textView convert (row,col) to NSPoint.
|
||||
NSSize cellSize = [[vimView textView] cellSize];
|
||||
NSPoint pt = { (col+1)*cellSize.width, (row+1)*cellSize.height };
|
||||
pt = [[vimView textView] convertPoint:pt toView:nil];
|
||||
|
||||
event = [NSEvent mouseEventWithType:NSRightMouseDown
|
||||
location:pt
|
||||
modifierFlags:0
|
||||
timestamp:0
|
||||
windowNumber:[[self window] windowNumber]
|
||||
context:nil
|
||||
eventNumber:0
|
||||
clickCount:0
|
||||
pressure:1.0];
|
||||
} else {
|
||||
event = [[vimView textView] lastMouseDownEvent];
|
||||
}
|
||||
|
||||
[NSMenu popUpContextMenu:menu withEvent:event forView:[vimView textView]];
|
||||
}
|
||||
|
||||
- (void)showTabBar:(BOOL)on
|
||||
{
|
||||
[[vimView tabBarControl] setHidden:!on];
|
||||
@@ -595,9 +567,12 @@
|
||||
|
||||
- (IBAction)performClose:(id)sender
|
||||
{
|
||||
// NOTE: File->Close is bound to this action message so that File->Close
|
||||
// also works for auxiliary windows such as the About dialog.
|
||||
[vimController sendMessage:CloseMsgID data:nil];
|
||||
// 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
|
||||
@@ -610,12 +585,64 @@
|
||||
[self doFindNext:NO];
|
||||
}
|
||||
|
||||
- (IBAction)vimMenuItemAction:(id)sender
|
||||
{
|
||||
if (![sender isKindOfClass:[NSMenuItem class]]) return;
|
||||
|
||||
// TODO: Make into category on NSMenuItem which returns descriptor.
|
||||
NSMenuItem *item = (NSMenuItem*)sender;
|
||||
NSMutableArray *desc = [NSMutableArray arrayWithObject:[item title]];
|
||||
|
||||
NSMenu *menu = [item menu];
|
||||
while (menu) {
|
||||
[desc insertObject:[menu title] atIndex:0];
|
||||
menu = [menu supermenu];
|
||||
}
|
||||
|
||||
// The "MainMenu" item is part of the Cocoa menu and should not be part of
|
||||
// the descriptor.
|
||||
if ([[desc objectAtIndex:0] isEqual:@"MainMenu"])
|
||||
[desc removeObjectAtIndex:0];
|
||||
|
||||
NSDictionary *attrs = [NSDictionary dictionaryWithObject:desc
|
||||
forKey:@"descriptor"];
|
||||
[vimController sendMessage:ExecuteMenuMsgID data:[attrs dictionaryAsData]];
|
||||
}
|
||||
|
||||
- (IBAction)vimToolbarItemAction:(id)sender
|
||||
{
|
||||
NSArray *desc = [NSArray arrayWithObjects:@"ToolBar", [sender label], nil];
|
||||
NSDictionary *attrs = [NSDictionary dictionaryWithObject:desc
|
||||
forKey:@"descriptor"];
|
||||
[vimController sendMessage:ExecuteMenuMsgID data:[attrs dictionaryAsData]];
|
||||
}
|
||||
|
||||
- (IBAction)fontSizeUp:(id)sender
|
||||
{
|
||||
[[NSFontManager sharedFontManager] modifyFont:
|
||||
[NSNumber numberWithInt:NSSizeUpFontAction]];
|
||||
}
|
||||
|
||||
- (IBAction)fontSizeDown:(id)sender
|
||||
{
|
||||
[[NSFontManager sharedFontManager] modifyFont:
|
||||
[NSNumber numberWithInt:NSSizeDownFontAction]];
|
||||
}
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item
|
||||
{
|
||||
if ([item action] == @selector(vimMenuItemAction:)
|
||||
|| [item action] == @selector(performClose:))
|
||||
return [item tag];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
// -- NSWindow delegate ------------------------------------------------------
|
||||
|
||||
- (void)windowDidBecomeMain:(NSNotification *)notification
|
||||
{
|
||||
[vimController updateMainMenu];
|
||||
[[MMAppController sharedInstance] setMainMenu:[vimController mainMenu]];
|
||||
[vimController sendMessage:GotFocusMsgID data:nil];
|
||||
|
||||
if ([vimView textView]) {
|
||||
@@ -781,16 +808,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?
|
||||
|
||||
+13
-2
@@ -29,7 +29,7 @@
|
||||
@protocol MMBackendProtocol
|
||||
- (oneway void)processInput:(int)msgid data:(in bycopy NSData *)data;
|
||||
- (oneway void)processInputAndData:(in bycopy NSArray *)messages;
|
||||
- (oneway void)setDialogReturn:(in bycopy id)obj;
|
||||
- (void)setDialogReturn:(in bycopy id)obj;
|
||||
- (NSString *)evaluateExpression:(in bycopy NSString *)expr;
|
||||
- (BOOL)starRegisterToPasteboard:(byref NSPasteboard *)pboard;
|
||||
@end
|
||||
@@ -162,7 +162,7 @@ enum {
|
||||
LiveResizeMsgID,
|
||||
EnableAntialiasMsgID,
|
||||
DisableAntialiasMsgID,
|
||||
CloseMsgID,
|
||||
SetVimStateMsgID,
|
||||
};
|
||||
|
||||
|
||||
@@ -176,6 +176,7 @@ enum {
|
||||
InsertLinesDrawType,
|
||||
DrawCursorDrawType,
|
||||
SetCursorPosDrawType,
|
||||
DrawInvertedRectDrawType,
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -183,6 +184,7 @@ enum {
|
||||
MMInsertionPointHorizontal,
|
||||
MMInsertionPointVertical,
|
||||
MMInsertionPointHollow,
|
||||
MMInsertionPointVerticalRight,
|
||||
};
|
||||
|
||||
|
||||
@@ -227,6 +229,7 @@ extern NSString *MMZoomBothKey;
|
||||
extern NSString *MMCurrentPreferencePaneKey;
|
||||
extern NSString *MMLoginShellCommandKey;
|
||||
extern NSString *MMLoginShellArgumentKey;
|
||||
extern NSString *MMDialogsTrackPwdKey;
|
||||
|
||||
// Enum for MMUntitledWindowKey
|
||||
enum {
|
||||
@@ -284,6 +287,14 @@ NSString *buildSearchTextCommand(NSString *searchText);
|
||||
|
||||
|
||||
|
||||
@interface NSDictionary (MMExtras)
|
||||
+ (id)dictionaryWithData:(NSData *)data;
|
||||
- (NSData *)dictionaryAsData;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
|
||||
// ODB Editor Suite Constants (taken from ODBEditorSuite.h)
|
||||
#define keyFileSender 'FSnd'
|
||||
#define keyFileSenderToken 'FTok'
|
||||
|
||||
+25
-1
@@ -75,7 +75,7 @@ char *MessageStrings[] =
|
||||
"LiveResizeMsgID",
|
||||
"EnableAntialiasMsgID",
|
||||
"DisableAntialiasMsgID",
|
||||
"CloseMsgID",
|
||||
"SetVimStateMsgID",
|
||||
};
|
||||
|
||||
|
||||
@@ -107,6 +107,7 @@ NSString *MMZoomBothKey = @"MMZoomBoth";
|
||||
NSString *MMCurrentPreferencePaneKey = @"MMCurrentPreferencePane";
|
||||
NSString *MMLoginShellCommandKey = @"MMLoginShellCommand";
|
||||
NSString *MMLoginShellArgumentKey = @"MMLoginShellArgument";
|
||||
NSString *MMDialogsTrackPwdKey = @"MMDialogsTrackPwd";
|
||||
|
||||
|
||||
|
||||
@@ -308,3 +309,26 @@ buildSearchTextCommand(NSString *searchText)
|
||||
|
||||
@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
|
||||
|
||||
@@ -193,10 +193,10 @@
|
||||
1D1474B40C56796D0038FA2B /* MMVimController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMVimController.m; sourceTree = "<group>"; };
|
||||
1D1474B90C567A910038FA2B /* MMWindowController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MMWindowController.h; sourceTree = "<group>"; };
|
||||
1D1474BA0C567A910038FA2B /* MMWindowController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMWindowController.m; sourceTree = "<group>"; };
|
||||
1D3D190D0CA690FF0004A0A5 /* DejaVuSansMono-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "DejaVuSansMono-Bold.ttf"; path = "dejavu-ttf-2.20/DejaVuSansMono-Bold.ttf"; sourceTree = "<group>"; };
|
||||
1D3D190E0CA690FF0004A0A5 /* DejaVuSansMono-BoldOblique.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "DejaVuSansMono-BoldOblique.ttf"; path = "dejavu-ttf-2.20/DejaVuSansMono-BoldOblique.ttf"; sourceTree = "<group>"; };
|
||||
1D3D190F0CA690FF0004A0A5 /* DejaVuSansMono-Oblique.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "DejaVuSansMono-Oblique.ttf"; path = "dejavu-ttf-2.20/DejaVuSansMono-Oblique.ttf"; sourceTree = "<group>"; };
|
||||
1D3D19100CA690FF0004A0A5 /* DejaVuSansMono.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = DejaVuSansMono.ttf; path = "dejavu-ttf-2.20/DejaVuSansMono.ttf"; sourceTree = "<group>"; };
|
||||
1D3D190D0CA690FF0004A0A5 /* DejaVuSansMono-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "DejaVuSansMono-Bold.ttf"; path = "dejavu-ttf/DejaVuSansMono-Bold.ttf"; sourceTree = "<group>"; };
|
||||
1D3D190E0CA690FF0004A0A5 /* DejaVuSansMono-BoldOblique.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "DejaVuSansMono-BoldOblique.ttf"; path = "dejavu-ttf/DejaVuSansMono-BoldOblique.ttf"; sourceTree = "<group>"; };
|
||||
1D3D190F0CA690FF0004A0A5 /* DejaVuSansMono-Oblique.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "DejaVuSansMono-Oblique.ttf"; path = "dejavu-ttf/DejaVuSansMono-Oblique.ttf"; sourceTree = "<group>"; };
|
||||
1D3D19100CA690FF0004A0A5 /* DejaVuSansMono.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = DejaVuSansMono.ttf; path = "dejavu-ttf/DejaVuSansMono.ttf"; sourceTree = "<group>"; };
|
||||
1D493D570C5247BF00AB718C /* Vim */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = Vim; path = ../Vim; sourceTree = SOURCE_ROOT; };
|
||||
1D493DB30C52533B00AB718C /* PSMTabBarControl.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = PSMTabBarControl.xcodeproj; path = PSMTabBarControl/PSMTabBarControl.xcodeproj; sourceTree = "<group>"; };
|
||||
1D71ACA90BC702AB002F2B60 /* doc-bm-c.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-c.icns"; sourceTree = "<group>"; };
|
||||
@@ -698,7 +698,7 @@
|
||||
i386,
|
||||
);
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 27;
|
||||
CURRENT_PROJECT_VERSION = 31;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
@@ -739,7 +739,7 @@
|
||||
buildSettings = {
|
||||
ARCHS = "$(NATIVE_ARCH)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 27;
|
||||
CURRENT_PROJECT_VERSION = 31;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
@@ -770,7 +770,7 @@
|
||||
buildSettings = {
|
||||
ARCHS = "$(NATIVE_ARCH)";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 27;
|
||||
CURRENT_PROJECT_VERSION = 31;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
|
||||
@@ -20,21 +20,25 @@ John Karp
|
||||
Keenan Pepper
|
||||
Lars Naesbye Christensen
|
||||
Mashrab Kuvatov
|
||||
Max Berger
|
||||
Mederic Boquien
|
||||
Michael Everson
|
||||
Misu Moldovan
|
||||
Nguyen Thai Ngoc Duy
|
||||
Nicolas Mailhot
|
||||
Ognyan Kulev
|
||||
Ondrej Koala Vacha
|
||||
Peter Cernak
|
||||
Remy Oudompheng
|
||||
Roozbeh Pournader
|
||||
Sahak Petrosyan
|
||||
Sander Vesik
|
||||
Stepan Roh
|
||||
Stephen Hartke
|
||||
Tavmjong Bah
|
||||
Tim May
|
||||
Valentin Stoykov
|
||||
Vasek Stodulka
|
||||
Wesley Transue
|
||||
|
||||
$Id: AUTHORS 1910 2007-06-25 19:10:14Z ben_laenen $
|
||||
$Id: AUTHORS 2162 2007-12-27 12:39:07Z ben_laenen $
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -1,4 +1,5 @@
|
||||
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. Glyphs imported from Arev fonts are (c) Tavmjung Bah (see below)
|
||||
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
|
||||
Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
|
||||
|
||||
Bitstream Vera Fonts Copyright
|
||||
------------------------------
|
||||
@@ -95,4 +96,4 @@ dealings in this Font Software without prior written authorization
|
||||
from Tavmjong Bah. For further information, contact: tavmjong @ free
|
||||
. fr.
|
||||
|
||||
$Id: LICENSE 778 2006-04-20 18:14:24Z moyogo $
|
||||
$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $
|
||||
@@ -1,3 +1,124 @@
|
||||
Changes from 2.24 to 2.25
|
||||
- moved/added U+2E18 (by Gee Fung Sit)
|
||||
- added empty glyph for U+2064 in Sans and Serif (by Gee Fung Sit)
|
||||
- added U+22CE-U+22CF to Sans (by Gee Fung Sit)
|
||||
- Sans Oblique and Bold Oblique, Serif: reverted digits hinting instructions back to before revision 1590, which fixed mistaken debian bug #471024. This fixes Debian bug #411308. The original bug was in freetype not in the fonts (by Denis Jacquerye)
|
||||
- added U+A726-U+A729, U+A730-U+A733, U+A738-U+A73F, U+A746-U+A74B, U+A74E-U+A74F, U+A780-U+A781, U+A7FB-U+A7FF to Sans (by Gee Fung Sit)
|
||||
- added Macedonian italic glyph shape for U+0453 in Serif (by Ben Laenen)
|
||||
- changed descenders in U+0446, U+0449, U+0497, U+04A3, U+04AD (by Andrey V. Panov)
|
||||
- updated main SFD files to SplineFontDB 3.0 (Denis Jacquerye and Gee Fung Sit)
|
||||
- moved U+0561 2 up since it wasn't aligned with the baseline well (by Ben Laenen)
|
||||
- added U+2E2E to Sans (by Gee Fung Sit)
|
||||
- replaced U+2699 with simpler version in Sans (by Gee Fung Sit)
|
||||
- added a lot of hinting instructions to Latin Extended B, Greek and Coptic glyphs Sans Book (by Wesley Transue)
|
||||
- differentiated U+2219 from U+22C5 and adjusted affected references in Sans and Mono (by Gee Fung Sit)
|
||||
- made Hebrew narrower in Sans Bold and Sans Bold Oblique (by Denis Jacquerye)
|
||||
- added Kurdish and Chuvash letters from Unicode 5.1 Cyrillic Extended block (by Wesley Transue)
|
||||
- added U+1E9F, U+A644-U+A647, U+A64C-U+A64D, U+A650-U+A651, U+A654-U+A655, U+A712U+A716 to Sans (by Gee Fung Sit)
|
||||
- added several glyphs to Sans ExtraLight (by Gee Fung Sit)
|
||||
- added hinting instructions to U+046A-U+046B, U+0508-U+0509, U+050B, U+0512-U+0513 in Sans Book (by Wesley Transue)
|
||||
- corrected width of U+027E in Sans Book (by Gee Fung Sit)
|
||||
- added U+2C79, U+2C7B-U+2C7D to Sans (by Gee Fung Sit)
|
||||
- added a bunch of glyphs+small corrections to Sans Light (by Gee Fung Sit)
|
||||
- added U+0496, U+0497, U+04B0, U+04B1 (by Andrey V. Panov)
|
||||
- updated U+0493, U+049B, U+04B3, U+04B7, U+04F7 (by Andrey V. Panov)
|
||||
- further improvements in extended Cyrillic (by Andrey V. Panov)
|
||||
|
||||
Changes from 2.23 to 2.24
|
||||
- instructions for U+05C0 ׀, U+05C3 ׃, U+05F3 ׳, and U+05F4 ״ in DejaVu
|
||||
Sans. (by Wesley Transue)
|
||||
- instructions for U+2116 in Sans (by Andrey V. Panov)
|
||||
- Unicode 5.1 update: moved U+F208 to U+2C6D, U+F25F to U+2C71, added
|
||||
U+2C6E-U+2C6F, U+2C72-U+2C73, updated outline of U+2C71 in Sans. (by
|
||||
Denis Jacquerye)
|
||||
- updated and instructed U+0401 in Sans (by Andrey V. Panov)
|
||||
- fixed the bug in Sans faces where U+02EC ˬ faced the wrong direction.
|
||||
Also, added a few more glyph instructions. (by Wesley Transue)
|
||||
- removed OS2Sub and OS2Strike that weren't intentional in Sans
|
||||
ExtraLight. (by Denis Jacquerye)
|
||||
- updated instructions for U+401, U+44F in Serif Book. (by Andrey V.
|
||||
Panov)
|
||||
- instructions for U+02C4 ˄, U+02C5 ˅, U+03D8 Ϙ, U+03D9 ϙ, U+0494 Ҕ, and
|
||||
U+0495 ҕ in Sans Book. (by Wesley Transue)
|
||||
- instructions for U+01A6 Ʀ, U+0238 ȸ, U+0239 ȹ, U+02EC ˬ, and U+05C6 ׆
|
||||
in Sans Book. (by Wesley Transue)
|
||||
- DejaVuSans.sfd DejaVuSerif.sfd: updated instructions for U+447 and
|
||||
U+451 using code generated with xgridfit (by Andrey V. Panov)
|
||||
- instructions for a few glyphs in the Latin Extended-B Block, Greek
|
||||
Block, Cyrillic Block, and N'Ko block. (by Wesley Transue)
|
||||
- updated sfdnormalize.pl, and SFD files to new SFD format with empty
|
||||
lines. (by Denis Jacquerye)
|
||||
|
||||
Changes from 2.22 to 2.23
|
||||
|
||||
- fixed bug which made Condensed fonts appear instead of normal width ones
|
||||
- added U+20DB, U+20DC, and U+20E1 to Sans (by Roozbeh Pournader)
|
||||
- added hinting instructions to U+01A7, U+01AA-U+01AC, U+01AE-U+01AF,
|
||||
U+01BC-U+01BD, U+01BF, U+01F7, U+0277, U+027F, U+0285-U+0286, U+0297, U+02AF,
|
||||
U+02B4-U+02B5, U+02BD, U+030D, U+0311, U+0329, U+04A0-U+04A1 in Sans Book (by
|
||||
Wesley Transue)
|
||||
- modified hinting instructions of U+04A2 in Sans Book (by Wesley Transue)
|
||||
- added hinting instructions to U+237D, U+2423 in Mono Book and Mono Bold (by
|
||||
Wesley Transue)
|
||||
- added mathematical alphanumeric symbols to all styles (by Max Berger)
|
||||
- added Unicode 5.1 U+2E18 as U+2E18.u51 (not yet usable) to Sans (by Roozbeh
|
||||
Pournader)
|
||||
- dereferenced all glyphs with mixed references and outlines (by Denis
|
||||
Jacquerye)
|
||||
- removed non-zero width from U+0344 in Sans (by Denis Jacquerye)
|
||||
|
||||
Changes from 2.21 to 2.22
|
||||
|
||||
- directory structure has changed, we now use the Makefile
|
||||
- modified Armenian U+0565 in Sans (by Սահակ Պետրոսյան)
|
||||
- added double struck letters and numbers U+2102, U+210D, U+2115,
|
||||
U+2119-U+211A, U+211D, U+2124, U+213C-U+2140, U+2145-U+2149, U+1D538-U+1D539,
|
||||
U+1D53B-U+1D53E, U+1D540-U+1D544, U+1D546, U+1D54A-U+1D550, U+1D552-U+1D56B,
|
||||
U+1D7D8-U+1D7E1 to Serif (by Stephen Hartke)
|
||||
- added letterlike symbols U+2103, U+2109, U+2127, U+214B, U+2141-U+2144 to
|
||||
Serif (by Ben Laenen)
|
||||
- fixed outline direction of U+2143 in Sans Bold/Bold Oblique (by Ben Laenen)
|
||||
- added arrow set in Serif: arrows: U+2194-U+21FF; dingbats: U+27A1;
|
||||
supplemental arrows A: U+27F0-U+27FF; supplemental arrows B: U+2900-U+2975,
|
||||
U+297A; miscellaneous symbols and arrows: U+2B00-U+2B11 (by Ben Laenen)
|
||||
- added U+0180, U+01DE, U+01E0-01E1, U+022A, U+022C, U+0230, U+1E08-U+1E09,
|
||||
U+1E10-U+1E11, U+1EB0-U+1EB1 to Mono (by Denis Jacquerye)
|
||||
- adjusted U+01D5, U+01D7, U+01D9, U+1DB in Mono (by Denis Jacquerye)
|
||||
- added Ogham in Sans (by Wesley Transue)
|
||||
- added Yijing Hexagram Symbols in Sans (by Wesley Transue)
|
||||
- hinting instructions added to Cyrillic U+0460, U+04A6-U+04A7, U+04AC-U+04AD,
|
||||
U+04C7-U+04C8, U+04F6-U+04F7, U+04FA-U+04FB, U+050C-U+050D in Sans Book (by
|
||||
Wesley Transue)
|
||||
- adjusted Cyrillic letters U+042A, U+044A, U+044C, U+0459-U+045B, U+0462,
|
||||
U+048C-U+048D in Serif (by Andrey V. Panov)
|
||||
- hinting instructions added to Lao U+0EB7 in Sans (by Wesley Transue)
|
||||
- added Roman numerals and Claudian letter U+2160-U+2184 in Serif (by Ben
|
||||
Laenen)
|
||||
- added U+FFF9-U+FFFD to Sans, Serif and Mono (by Lars Næsbye Christensen)
|
||||
- added mathematical symbols to Serif: U+2200, U+2203-U+2204, U+2213-U+2214,
|
||||
U+2217-U+2218, U+2223-U+2226, U+2250-U+2255, U+2295-U+22AF, U+22C5 (by Ben
|
||||
Laenen)
|
||||
- modified bullet symbol U+2219 in Serif (by Ben Laenen)
|
||||
|
||||
Changes from 2.20 to 2.21
|
||||
|
||||
- added U+FE20-U+FE23 (half diacritics) to Sans (by Denis Jacquerye)
|
||||
- added anchor "half" to position right half of double marks, U+FE21 or U+FE23
|
||||
to Sans (by Denis Jacquerye)
|
||||
- shifted U+0360 up to avoid collision with some outlines in Sans (by Denis
|
||||
Jacquerye)
|
||||
- added anchor above-mark anchor to U+035D, U+035E, U+0360, U+0361 in Sans (by
|
||||
Denis Jacquerye)
|
||||
- added instructions for ff, ffi, ffl ligatures in Serif Bold (by Eugeniy
|
||||
Meshcheryakov)
|
||||
- added instructions to some N'Ko glyphs (by Wesley Transue)
|
||||
- added instructions to some Lao glyphs (by Wesley Transue)
|
||||
- cleaning up 'liga' Standard Ligature in Latin, in Sans and Sans Mono (by
|
||||
Denis Jacquerye)
|
||||
- added U+046A, U+046B (big yus) in Serif (by Andrey V. Panov)
|
||||
- added box drawing symbols to Sans and Serif (by Lars Næsbye Christensen)
|
||||
- added Makefile to improve font and packages generating (by Nicolas Mailhot)
|
||||
|
||||
Changes from 2.19 to 2.20
|
||||
|
||||
- removed TeX and TeXData tags from all sfd files (by Eugeniy Meshcheryakov)
|
||||
@@ -931,4 +1052,4 @@ Changes from 0.9 to 0.9.1:
|
||||
- proper caron shape for dcaron and tcaron
|
||||
- minor visual changes
|
||||
|
||||
$Id: NEWS 1998 2007-09-16 14:23:46Z ben_laenen $
|
||||
$Id: NEWS 2227 2008-05-19 06:41:46Z moyogo $
|
||||
@@ -1,4 +1,4 @@
|
||||
DejaVu fonts 2.20 (c)2004-2007 DejaVu fonts team
|
||||
DejaVu fonts 2.24 (c)2004-2008 DejaVu fonts team
|
||||
------------------------------------------------
|
||||
|
||||
The DejaVu fonts are a font family based on the Bitstream Vera Fonts
|
||||
@@ -46,14 +46,14 @@ For more information go to http://dejavu.sourceforge.net/.
|
||||
|
||||
Characters from Arev fonts, Copyright (c) 2006 by Tavmjong Bah:
|
||||
---------------------------
|
||||
U+01ba, U+01bf, U+01f7, U+021c, U+021d, U+0220, U+0222, U+0223,
|
||||
U+02b9, U+02ba, U+02bd, U+02c2, U+02c3, U+02c4, U+02c5, U+02d4,
|
||||
U+02d5, U+02d7, U+02ec, U+02ed, U+02ee, U+0346-034e, U+0360, U+0362,
|
||||
U+03e2-03ef, U+0460-0463, U+0466-0486, U+0488-0489, U+04a8-04a9,
|
||||
U+0500-050f, U+2055-205e, U+20B0, U+20B2-20B3, U+2102, U+210D, U+210f,
|
||||
U+2111, U+2113, U+2115, U+2118-U+211A, U+211c-211d, U+2124,U+2135,
|
||||
U+213C-U+2140, U+2295-2298, U+2308-230b, U+26A2-U+26B1, U+2701-2704,
|
||||
U+2706-2709, U+270c-274b, U+2758-275a, U+2761-2775, U+2780-2794,
|
||||
U+2798-27af, U+27b1-27be, U+fb05-fb06
|
||||
U+01BA, U+01BF, U+01F7, U+021C-U+021D, U+0220, U+0222-U+0223,
|
||||
U+02B9, U+02BA, U+02BD, U+02C2-U+02C5, U+02d4-U+02D5,
|
||||
U+02D7, U+02EC-U+02EE, U+0346-U+034E, U+0360, U+0362,
|
||||
U+03E2-03EF, U+0460-0463, U+0466-U+0486, U+0488-U+0489, U+04A8-U+04A9,
|
||||
U+0500-U+050F, U+2055-205E, U+20B0, U+20B2-U+20B3, U+2102, U+210D, U+210F,
|
||||
U+2111, U+2113, U+2115, U+2118-U+211A, U+211C-U+211D, U+2124, U+2135,
|
||||
U+213C-U+2140, U+2295-U+2298, U+2308-U+230B, U+26A2-U+26B1, U+2701-U+2704,
|
||||
U+2706-U+2709, U+270C-U+274B, U+2758-U+275A, U+2761-U+2775, U+2780-U+2794,
|
||||
U+2798-U+27AF, U+27B1-U+27BE, U+FB05-U+FB06
|
||||
|
||||
$Id: README 1998 2007-09-16 14:23:46Z ben_laenen $
|
||||
$Id: README 2192 2008-03-09 21:25:29Z moyogo $
|
||||
@@ -7,6 +7,7 @@ ab Abkhazia 100% (90/90) 93% (84/90)
|
||||
af Afrikaans 100% (69/69) 100% (69/69) 100% (69/69)
|
||||
am Amharic (0/264) (0/264) (0/264)
|
||||
ar Arabic 100% (125/125) (0/125) 100% (125/125)
|
||||
as (0/89) (0/89) (0/89)
|
||||
ast Asturian 100% (72/72) 100% (72/72) 100% (72/72)
|
||||
ava Avaric 100% (67/67) 100% (67/67) 100% (67/67)
|
||||
ay Aymara 100% (60/60) 100% (60/60) 100% (60/60)
|
||||
@@ -30,25 +31,25 @@ ce Chechen 100% (67/67) 100% (67/67)
|
||||
ch Chamorro 100% (58/58) 100% (58/58) 100% (58/58)
|
||||
chm Mari (Lower Cheremis / Upper Cheremis) 100% (76/76) 100% (76/76) 97% (74/76)
|
||||
chr Cherokee (0/85) (0/85) (0/85)
|
||||
co Corsican 100% (84/84) 100% (84/84) 100% (84/84)
|
||||
co Corsican 100% (85/85) 100% (85/85) 100% (85/85)
|
||||
cs Czech 100% (82/82) 100% (82/82) 100% (82/82)
|
||||
cu Old Church Slavonic 100% (103/103) 82% (85/103) 74% (77/103)
|
||||
cu Old Church Slavonic 100% (103/103) 84% (87/103) 74% (77/103)
|
||||
cv Chuvash 100% (74/74) 100% (74/74) 100% (74/74)
|
||||
cy Welsh 100% (78/78) 100% (78/78) 100% (78/78)
|
||||
da Danish 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
de German 100% (59/59) 100% (59/59) 100% (59/59)
|
||||
de German 100% (60/60) 100% (60/60) 100% (60/60)
|
||||
dz Dzongkha (0/95) (0/95) (0/95)
|
||||
el Greek 100% (69/69) 100% (69/69) 100% (69/69)
|
||||
en English 100% (72/72) 100% (72/72) 100% (72/72)
|
||||
el Greek 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
en English 100% (73/73) 100% (73/73) 100% (73/73)
|
||||
eo Esperanto 100% (64/64) 100% (64/64) 100% (64/64)
|
||||
es Spanish 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
es Spanish 100% (67/67) 100% (67/67) 100% (67/67)
|
||||
et Estonian 100% (64/64) 100% (64/64) 100% (64/64)
|
||||
eu Basque 100% (56/56) 100% (56/56) 100% (56/56)
|
||||
fa Persian 100% (129/129) (0/129) 100% (129/129)
|
||||
fi Finnish 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
fi Finnish 100% (63/63) 100% (63/63) 100% (63/63)
|
||||
fj Fijian 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
fo Faroese 100% (68/68) 100% (68/68) 100% (68/68)
|
||||
fr French 100% (84/84) 100% (84/84) 100% (84/84)
|
||||
fr French 100% (85/85) 100% (85/85) 100% (85/85)
|
||||
ful Fulah (Fula) 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
fur Friulian 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
fy Frisian 100% (75/75) 100% (75/75) 100% (75/75)
|
||||
@@ -74,10 +75,10 @@ ie Interlingue 100% (52/52) 100% (52/52)
|
||||
ik Inupiaq (Inupiak, Eskimo) 100% (68/68) 100% (68/68) 100% (68/68)
|
||||
io Ido 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
is Icelandic 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
it Italian 100% (72/72) 100% (72/72) 100% (72/72)
|
||||
it Italian 100% (73/73) 100% (73/73) 100% (73/73)
|
||||
iu Inuktitut 100% (161/161) (0/161) (0/161)
|
||||
ja Japanese (0/6538) (0/6538) (0/6538)
|
||||
ka Georgian 100% (34/34) 100% (34/34) 100% (34/34)
|
||||
ka Georgian 100% (33/33) 100% (33/33) 100% (33/33)
|
||||
kaa Kara-Kalpak (Karakalpak) 100% (78/78) 100% (78/78) 100% (78/78)
|
||||
ki Kikuyu 100% (56/56) 100% (56/56) 100% (56/56)
|
||||
kk Kazakh 100% (77/77) 100% (77/77) 100% (77/77)
|
||||
@@ -96,6 +97,7 @@ ky Kirgiz 100% (70/70) 100% (70/70)
|
||||
la Latin 100% (68/68) 100% (68/68) 100% (68/68)
|
||||
lb Luxembourgish (Letzeburgesch) 100% (75/75) 100% (75/75) 100% (75/75)
|
||||
lez Lezghian (Lezgian) 100% (67/67) 100% (67/67) 100% (67/67)
|
||||
ln Lingala 100% (81/81) 100% (81/81) 100% (81/81)
|
||||
lo Lao 100% (65/65) (0/65) 70% (46/65)
|
||||
lt Lithuanian 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
lv Latvian 100% (78/78) 100% (78/78) 100% (78/78)
|
||||
@@ -112,9 +114,11 @@ my Burmese (Myanmar) (0/48) (0/48)
|
||||
nb Norwegian Bokmal 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
nds Low Saxon 100% (59/59) 100% (59/59) 100% (59/59)
|
||||
ne Nepali (Devanagari script) (0/68) (0/68) (0/68)
|
||||
nl Dutch 100% (82/82) 100% (82/82) 100% (82/82)
|
||||
nl Dutch 100% (83/83) 100% (83/83) 100% (83/83)
|
||||
nn Norwegian Nynorsk 100% (76/76) 100% (76/76) 100% (76/76)
|
||||
no Norwegian (Bokmal) 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
nr Ndebele, South 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
nso Northern Sotho 100% (58/58) 100% (58/58) 100% (58/58)
|
||||
ny Chichewa 100% (54/54) 100% (54/54) 100% (54/54)
|
||||
oc Occitan 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
om Oromo or Galla 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
@@ -124,7 +128,7 @@ pa Punjabi (Gurumukhi script) (0/63) (0/63)
|
||||
pl Polish 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
ps-af Pashto in Afghanistan 83% (41/49) (0/49) 83% (41/49)
|
||||
ps-pk Pashto in Pakistan 81% (40/49) (0/49) 81% (40/49)
|
||||
pt Portuguese 100% (82/82) 100% (82/82) 100% (82/82)
|
||||
pt Portuguese 100% (83/83) 100% (83/83) 100% (83/83)
|
||||
rm Rhaeto-Romance (Romansch) 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
ro Romanian 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
ru Russian 100% (66/66) 100% (66/66) 100% (66/66)
|
||||
@@ -145,6 +149,8 @@ sms Skolt Sami 100% (80/80) 100% (80/80)
|
||||
so Somali 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
sq Albanian 100% (56/56) 100% (56/56) 100% (56/56)
|
||||
sr Serbian 100% (76/76) 100% (76/76) 100% (76/76)
|
||||
ss Swati 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
st Sotho, Southern 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
sv Swedish 100% (68/68) 100% (68/68) 100% (68/68)
|
||||
sw Swahili 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
syr Syriac (0/45) (0/45) (0/45)
|
||||
@@ -152,16 +158,16 @@ ta Tamil (0/48) (0/48)
|
||||
te Telugu (0/80) (0/80) (0/80)
|
||||
tg Tajik 100% (78/78) 100% (78/78) 97% (76/78)
|
||||
th Thai 1% (1/87) (0/87) (0/87)
|
||||
ti-er Eritrean Tigrinya (0/256) (0/256) (0/256)
|
||||
ti-et Ethiopian Tigrinya (0/282) (0/282) (0/282)
|
||||
ti-er Eritrean Tigrinya (0/255) (0/255) (0/255)
|
||||
ti-et Ethiopian Tigrinya (0/281) (0/281) (0/281)
|
||||
tig Tigre (0/221) (0/221) (0/221)
|
||||
tk Turkmen 100% (74/74) 100% (74/74) 97% (72/74)
|
||||
tk Turkmen 100% (74/74) 100% (74/74) 100% (74/74)
|
||||
tl Tagalog (0/19) (0/19) (0/19)
|
||||
tn Tswana 100% (56/56) 100% (56/56) 100% (56/56)
|
||||
tn Tswana 100% (58/58) 100% (58/58) 100% (58/58)
|
||||
to Tonga 100% (53/53) 100% (53/53) 100% (53/53)
|
||||
tr Turkish 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
ts Tsonga 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
tt Tatar 100% (76/76) 100% (76/76) 97% (74/76)
|
||||
tt Tatar 100% (76/76) 100% (76/76) 100% (76/76)
|
||||
tw Twi 100% (73/73) 100% (73/73) 100% (73/73)
|
||||
tyv Tuvinian 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
ug Uighur 100% (125/125) (0/125) 100% (125/125)
|
||||
@@ -169,7 +175,7 @@ uk Ukrainian 100% (72/72) 100% (72/72)
|
||||
ur Urdu 94% (137/145) (0/145) 97% (141/145)
|
||||
uz Uzbek 100% (68/68) 100% (68/68) 100% (68/68)
|
||||
ven Venda 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
vi Vietnamese 100% (194/194) 77% (150/194) 62% (122/194)
|
||||
vi Vietnamese 100% (194/194) 77% (150/194) 63% (124/194)
|
||||
vo Volapuk 100% (54/54) 100% (54/54) 100% (54/54)
|
||||
vot Votic 100% (62/62) 100% (62/62) 100% (62/62)
|
||||
wa Walloon 100% (70/70) 100% (70/70) 100% (70/70)
|
||||
@@ -181,7 +187,7 @@ yi Yiddish 100% (27/27) (0/27)
|
||||
yo Yoruba 100% (119/119) 100% (119/119) 100% (119/119)
|
||||
zh-cn Chinese (simplified) 0% (2/6765) 0% (2/6765) 0% (2/6765)
|
||||
zh-hk Chinese Hong Kong Supplementary Character Set (0/2213) (0/2213) (0/2213)
|
||||
zh-mo Chinese in Macau (0/13063) (0/13063) (0/13063)
|
||||
zh-mo Chinese in Macau (0/2213) (0/2213) (0/2213)
|
||||
zh-sg Chinese in Singapore 0% (2/6765) 0% (2/6765) 0% (2/6765)
|
||||
zh-tw Chinese (traditional) (0/13063) (0/13063) (0/13063)
|
||||
zu Zulu 100% (52/52) 100% (52/52) 100% (52/52)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
This is the Unicode coverage file for DejaVu fonts
|
||||
($Id: unicover.txt 2000 2007-09-16 14:34:23Z ben_laenen $)
|
||||
($Id$)
|
||||
|
||||
Control and similar characters are discounted from totals.
|
||||
|
||||
@@ -7,12 +7,12 @@ Control and similar characters are discounted from totals.
|
||||
U+0000 Basic Latin 100% (95/95) 100% (95/95) 100% (95/95)
|
||||
U+0080 Latin-1 Supplement 100% (96/96) 100% (96/96) 100% (96/96)
|
||||
U+0100 Latin Extended-A 100% (128/128) 100% (128/128) 100% (128/128)
|
||||
U+0180 Latin Extended-B 100% (208/208) 90% (189/208) 78% (164/208)
|
||||
U+0180 Latin Extended-B 100% (208/208) 90% (189/208) 82% (172/208)
|
||||
U+0250 IPA Extensions 100% (96/96) 100% (96/96) 100% (96/96)
|
||||
U+02b0 Spacing Modifier Letters 78% (63/80) 56% (45/80) 57% (46/80)
|
||||
U+0300 Combining Diacritical Marks 82% (92/112) 60% (68/112) 59% (67/112)
|
||||
U+0370 Greek and Coptic 100% (127/127) 86% (110/127) 86% (110/127)
|
||||
U+0400 Cyrillic 100% (255/255) 76% (194/255) 66% (170/255)
|
||||
U+0400 Cyrillic 100% (255/255) 77% (198/255) 68% (174/255)
|
||||
U+0500 Cyrillic Supplement 100% (20/20) (0/20) (0/20)
|
||||
U+0530 Armenian 100% (86/86) (0/86) (0/86)
|
||||
U+0590 Hebrew 62% (54/87) (0/87) (0/87)
|
||||
@@ -41,7 +41,7 @@ U+1200 Ethiopic (0/356) (0/356)
|
||||
U+1380 Ethiopic Supplement (0/26) (0/26) (0/26)
|
||||
U+13a0 Cherokee (0/85) (0/85) (0/85)
|
||||
U+1400 Unified Canadian Aboriginal Syllabics 64% (404/630) (0/630) (0/630)
|
||||
U+1680 Ogham (0/29) (0/29) (0/29)
|
||||
U+1680 Ogham 100% (29/29) (0/29) (0/29)
|
||||
U+16a0 Runic (0/81) (0/81) (0/81)
|
||||
U+1700 Tagalog (0/20) (0/20) (0/20)
|
||||
U+1720 Hanunoo (0/23) (0/23) (0/23)
|
||||
@@ -58,32 +58,32 @@ U+1b00 Balinese (0/121) (0/121)
|
||||
U+1d00 Phonetic Extensions 82% (105/128) 48% (62/128) 48% (62/128)
|
||||
U+1d80 Phonetic Extensions Supplement 59% (38/64) 57% (37/64) 57% (37/64)
|
||||
U+1dc0 Combining Diacritical Marks Supplement 46% (6/13) (0/13) (0/13)
|
||||
U+1e00 Latin Extended Additional 100% (246/246) 78% (192/246) 54% (134/246)
|
||||
U+1e00 Latin Extended Additional 100% (246/246) 78% (192/246) 56% (140/246)
|
||||
U+1f00 Greek Extended 100% (233/233) 100% (233/233) 100% (233/233)
|
||||
U+2000 General Punctuation 98% (104/106) 61% (65/106) 42% (45/106)
|
||||
U+2070 Superscripts and Subscripts 100% (34/34) 100% (34/34) 100% (34/34)
|
||||
U+20a0 Currency Symbols 100% (22/22) 27% (6/22) 22% (5/22)
|
||||
U+20d0 Combining Diacritical Marks for Symbols 12% (4/32) (0/32) (0/32)
|
||||
U+2100 Letterlike Symbols 94% (75/79) 7% (6/79) 8% (7/79)
|
||||
U+2150 Number Forms 100% (50/50) 26% (13/50) 26% (13/50)
|
||||
U+2190 Arrows 100% (112/112) 3% (4/112) 100% (112/112)
|
||||
U+2200 Mathematical Operators 95% (245/256) 11% (30/256) 56% (145/256)
|
||||
U+20d0 Combining Diacritical Marks for Symbols 21% (7/32) (0/32) (0/32)
|
||||
U+2100 Letterlike Symbols 94% (75/79) 39% (31/79) 8% (7/79)
|
||||
U+2150 Number Forms 100% (50/50) 100% (50/50) 26% (13/50)
|
||||
U+2190 Arrows 100% (112/112) 100% (112/112) 100% (112/112)
|
||||
U+2200 Mathematical Operators 96% (247/256) 39% (100/256) 56% (145/256)
|
||||
U+2300 Miscellaneous Technical 27% (64/232) 6% (16/232) 50% (117/232)
|
||||
U+2400 Control Pictures 5% (2/39) 2% (1/39) 2% (1/39)
|
||||
U+2440 Optical Character Recognition (0/11) (0/11) (0/11)
|
||||
U+2460 Enclosed Alphanumerics 6% (10/160) (0/160) (0/160)
|
||||
U+2500 Box Drawing (0/128) (0/128) 100% (128/128)
|
||||
U+2500 Box Drawing 100% (128/128) 100% (128/128) 100% (128/128)
|
||||
U+2580 Block Elements 100% (32/32) 100% (32/32) 100% (32/32)
|
||||
U+25a0 Geometric Shapes 100% (96/96) 100% (96/96) 100% (96/96)
|
||||
U+2600 Miscellaneous Symbols 100% (176/176) 17% (30/176) 84% (149/176)
|
||||
U+2700 Dingbats 100% (174/174) (0/174) 82% (144/174)
|
||||
U+2700 Dingbats 100% (174/174) 0% (1/174) 82% (144/174)
|
||||
U+27c0 Miscellaneous Mathematical Symbols-A 17% (7/39) 7% (3/39) 7% (3/39)
|
||||
U+27f0 Supplemental Arrows-A 100% (16/16) (0/16) (0/16)
|
||||
U+27f0 Supplemental Arrows-A 100% (16/16) 100% (16/16) (0/16)
|
||||
U+2800 Braille Patterns 100% (256/256) 100% (256/256) (0/256)
|
||||
U+2900 Supplemental Arrows-B 4% (6/128) (0/128) (0/128)
|
||||
U+2900 Supplemental Arrows-B 4% (6/128) 100% (128/128) (0/128)
|
||||
U+2980 Miscellaneous Mathematical Symbols-B 10% (13/128) 0% (1/128) 2% (3/128)
|
||||
U+2a00 Supplemental Mathematical Operators 28% (72/256) 1% (4/256) 0% (1/256)
|
||||
U+2b00 Miscellaneous Symbols and Arrows 100% (31/31) 29% (9/31) 29% (9/31)
|
||||
U+2b00 Miscellaneous Symbols and Arrows 100% (31/31) 87% (27/31) 29% (9/31)
|
||||
U+2c00 Glagolitic (0/94) (0/94) (0/94)
|
||||
U+2c60 Latin Extended-C 100% (17/17) 52% (9/17) 17% (3/17)
|
||||
U+2c80 Coptic (0/114) (0/114) (0/114)
|
||||
@@ -106,11 +106,11 @@ U+31f0 Katakana Phonetic Extensions (0/16) (0/16)
|
||||
U+3200 Enclosed CJK Letters and Months (0/242) (0/242) (0/242)
|
||||
U+3300 CJK Compatibility (0/256) (0/256) (0/256)
|
||||
U+3400 CJK Unified Ideographs Extension A (0/0) (0/0) (0/0)
|
||||
U+4dc0 Yijing Hexagram Symbols (0/64) (0/64) (0/64)
|
||||
U+4dc0 Yijing Hexagram Symbols 100% (64/64) (0/64) (0/64)
|
||||
U+4e00 CJK Unified Ideographs (0/0) (0/0) (0/0)
|
||||
U+a000 Yi Syllables (0/1165) (0/1165) (0/1165)
|
||||
U+a490 Yi Radicals (0/55) (0/55) (0/55)
|
||||
U+a700 Modifier Tone Letters (0/27) (0/27) (0/27)
|
||||
U+a700 Modifier Tone Letters 18% (5/27) (0/27) (0/27)
|
||||
U+a720 Latin Extended-D (0/2) (0/2) (0/2)
|
||||
U+a800 Syloti Nagri (0/44) (0/44) (0/44)
|
||||
U+a840 Phags-pa (0/56) (0/56) (0/56)
|
||||
@@ -124,12 +124,12 @@ U+fb00 Alphabetic Presentation Forms 100% (58/58) 12% (7/58)
|
||||
U+fb50 Arabic Presentation Forms-A 11% (70/595) (0/595) 12% (72/595)
|
||||
U+fe00 Variation Selectors 100% (16/16) 100% (16/16) (0/16)
|
||||
U+fe10 Vertical Forms (0/10) (0/10) (0/10)
|
||||
U+fe20 Combining Half Marks (0/4) (0/4) (0/4)
|
||||
U+fe20 Combining Half Marks 100% (4/4) (0/4) (0/4)
|
||||
U+fe30 CJK Compatibility Forms (0/32) (0/32) (0/32)
|
||||
U+fe50 Small Form Variants (0/26) (0/26) (0/26)
|
||||
U+fe70 Arabic Presentation Forms-B 100% (141/141) (0/141) 100% (141/141)
|
||||
U+ff00 Halfwidth and Fullwidth Forms (0/225) (0/225) (0/225)
|
||||
U+fff0 Specials 20% (1/5) 20% (1/5) 20% (1/5)
|
||||
U+fff0 Specials 100% (5/5) 100% (5/5) 100% (5/5)
|
||||
U+10000 Linear B Syllabary (0/88) (0/88) (0/88)
|
||||
U+10080 Linear B Ideograms (0/123) (0/123) (0/123)
|
||||
U+10100 Aegean Numbers (0/57) (0/57) (0/57)
|
||||
@@ -151,7 +151,7 @@ U+1d100 Musical Symbols (0/219) (0/219)
|
||||
U+1d200 Ancient Greek Musical Notation (0/70) (0/70) (0/70)
|
||||
U+1d300 Tai Xuan Jing Symbols 100% (87/87) (0/87) (0/87)
|
||||
U+1d360 Counting Rod Numerals (0/18) (0/18) (0/18)
|
||||
U+1d400 Mathematical Alphanumeric Symbols 4% (45/996) (0/996) (0/996)
|
||||
U+1d400 Mathematical Alphanumeric Symbols 10% (107/996) 5% (55/996) 6% (62/996)
|
||||
U+20000 CJK Unified Ideographs Extension B (0/0) (0/0) (0/0)
|
||||
U+2f800 CJK Compatibility Ideographs Supplement (0/542) (0/542) (0/542)
|
||||
U+e0000 Tags (0/98) (0/98) (0/98)
|
||||
+261
-120
@@ -32,7 +32,15 @@ static float MMMaxFontSize = 100.0f;
|
||||
|
||||
|
||||
static NSFont *gui_macvim_font_with_name(char_u *name);
|
||||
static BOOL gui_macvim_is_valid_action(NSString *action);
|
||||
static int specialKeyToNSKey(int key);
|
||||
static int vimModMaskToEventModifierFlags(int mods);
|
||||
|
||||
NSArray *descriptor_for_menu(vimmenu_T *menu);
|
||||
vimmenu_T *menu_for_descriptor(NSArray *desc);
|
||||
|
||||
@interface NSString (VimStrings)
|
||||
+ (id)stringWithVimString:(char_u *)s;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@@ -418,6 +426,17 @@ gui_mch_new_colors(void)
|
||||
foreground:gui.def_norm_pixel];
|
||||
}
|
||||
|
||||
/*
|
||||
* Invert a rectangle from row r, column c, for nr rows and nc columns.
|
||||
*/
|
||||
void
|
||||
gui_mch_invert_rectangle(int r, int c, int nr, int nc, int invert)
|
||||
{
|
||||
[[MMBackend sharedInstance] drawInvertedRectAtRow:r column:c numRows:nr
|
||||
numColumns:nc invert:invert];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- Tabline ---------------------------------------------------------------
|
||||
|
||||
@@ -608,34 +627,61 @@ clip_mch_set_selection(VimClipboard *cbd)
|
||||
|
||||
|
||||
/*
|
||||
* Add a sub menu to the menu bar.
|
||||
* A menu descriptor represents the "address" of a menu as an array of strings.
|
||||
* E.g. the menu "File->Close" has descriptor { "File", "Close" }.
|
||||
*/
|
||||
NSArray *
|
||||
descriptor_for_menu(vimmenu_T *menu)
|
||||
{
|
||||
if (!menu) return nil;
|
||||
|
||||
NSMutableArray *desc = [NSMutableArray array];
|
||||
while (menu) {
|
||||
NSString *name = [NSString stringWithVimString:menu->dname];
|
||||
[desc insertObject:name atIndex:0];
|
||||
menu = menu->parent;
|
||||
}
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
vimmenu_T *
|
||||
menu_for_descriptor(NSArray *desc)
|
||||
{
|
||||
if (!(desc && [desc count] > 0)) return NULL;
|
||||
|
||||
vimmenu_T *menu = root_menu;
|
||||
int i, count = [desc count];
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSString *component = [desc objectAtIndex:i];
|
||||
while (menu) {
|
||||
NSString *name = [NSString stringWithVimString:menu->dname];
|
||||
if ([component isEqual:name]) {
|
||||
if (i+1 == count)
|
||||
return menu; // Matched all components, so return menu
|
||||
menu = menu->children;
|
||||
break;
|
||||
}
|
||||
menu = menu->next;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a submenu to the menu bar, toolbar, or a popup menu.
|
||||
*/
|
||||
void
|
||||
gui_mch_add_menu(vimmenu_T *menu, int idx)
|
||||
{
|
||||
// HACK! If menu has no parent, then we set the parent tag to the type of
|
||||
// menu it is. This will not mix up tag and type because pointers can not
|
||||
// take values close to zero (and the tag is simply the value of the
|
||||
// pointer).
|
||||
int parent = (int)menu->parent;
|
||||
if (!parent) {
|
||||
parent = menu_is_popup(menu->name) ? MenuPopupType :
|
||||
menu_is_toolbar(menu->name) ? MenuToolbarType :
|
||||
MenuMenubarType;
|
||||
}
|
||||
|
||||
char_u *dname = menu->dname;
|
||||
#ifdef FEAT_MBYTE
|
||||
dname = CONVERT_TO_UTF8(dname);
|
||||
#endif
|
||||
|
||||
[[MMBackend sharedInstance]
|
||||
addMenuWithTag:(int)menu parent:parent name:(char*)dname
|
||||
atIndex:idx];
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
CONVERT_TO_UTF8_FREE(dname);
|
||||
#endif
|
||||
NSArray *desc = descriptor_for_menu(menu);
|
||||
[[MMBackend sharedInstance] queueMessage:AddMenuMsgID properties:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
desc, @"descriptor",
|
||||
[NSNumber numberWithInt:idx], @"index",
|
||||
nil]];
|
||||
}
|
||||
|
||||
|
||||
@@ -650,55 +696,25 @@ gui_mch_add_menu_item(vimmenu_T *menu, int idx)
|
||||
char_u *icon = menu->iconfile ? menu->iconfile :
|
||||
menu->iconidx >= 0 ? menu->dname :
|
||||
NULL;
|
||||
//char *name = menu_is_separator(menu->name) ? NULL : (char*)menu->dname;
|
||||
char_u *name = menu->dname;
|
||||
char_u *tip = menu->strings[MENU_INDEX_TIP]
|
||||
? menu->strings[MENU_INDEX_TIP] : menu->actext;
|
||||
char_u *map_str = menu->strings[MENU_INDEX_NORMAL];
|
||||
NSArray *desc = descriptor_for_menu(menu);
|
||||
NSString *keyEquivalent = menu->mac_key
|
||||
? [NSString stringWithFormat:@"%C", specialKeyToNSKey(menu->mac_key)]
|
||||
: [NSString string];
|
||||
int modifierMask = vimModMaskToEventModifierFlags(menu->mac_mods);
|
||||
|
||||
#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);
|
||||
#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
|
||||
name:(char*)name
|
||||
tip:(char*)tip
|
||||
icon:(char*)icon
|
||||
keyEquivalent:menu->mac_key
|
||||
modifiers:menu->mac_mods
|
||||
action:action
|
||||
atIndex:idx];
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
CONVERT_TO_UTF8_FREE(icon);
|
||||
CONVERT_TO_UTF8_FREE(name);
|
||||
CONVERT_TO_UTF8_FREE(tip);
|
||||
CONVERT_TO_UTF8_FREE(map_str);
|
||||
#endif
|
||||
[[MMBackend sharedInstance] queueMessage:AddMenuItemMsgID properties:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
desc, @"descriptor",
|
||||
[NSNumber numberWithInt:idx], @"index",
|
||||
[NSString stringWithVimString:tip], @"tip",
|
||||
[NSString stringWithVimString:icon], @"icon",
|
||||
keyEquivalent, @"keyEquivalent",
|
||||
[NSNumber numberWithInt:modifierMask], @"modifierMask",
|
||||
[NSString stringWithVimString:menu->mac_action], @"action",
|
||||
[NSNumber numberWithBool:menu->mac_alternate], @"isAlternate",
|
||||
nil]];
|
||||
}
|
||||
|
||||
|
||||
@@ -708,7 +724,9 @@ gui_mch_add_menu_item(vimmenu_T *menu, int idx)
|
||||
void
|
||||
gui_mch_destroy_menu(vimmenu_T *menu)
|
||||
{
|
||||
[[MMBackend sharedInstance] removeMenuItemWithTag:(int)menu];
|
||||
NSArray *desc = descriptor_for_menu(menu);
|
||||
[[MMBackend sharedInstance] queueMessage:RemoveMenuItemMsgID properties:
|
||||
[NSDictionary dictionaryWithObject:desc forKey:@"descriptor"]];
|
||||
}
|
||||
|
||||
|
||||
@@ -721,12 +739,17 @@ gui_mch_menu_grey(vimmenu_T *menu, int grey)
|
||||
/* Only update menu if the 'grey' state has changed to avoid having to pass
|
||||
* lots of unnecessary data to MacVim. (Skipping this test makes MacVim
|
||||
* pause noticably on mode changes. */
|
||||
if (menu->was_grey != grey)
|
||||
{
|
||||
menu->was_grey = grey;
|
||||
[[MMBackend sharedInstance]
|
||||
enableMenuItemWithTag:(int)menu state:!grey];
|
||||
}
|
||||
NSArray *desc = descriptor_for_menu(menu);
|
||||
if (menu->was_grey == grey)
|
||||
return;
|
||||
|
||||
menu->was_grey = grey;
|
||||
|
||||
[[MMBackend sharedInstance] queueMessage:EnableMenuItemMsgID properties:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
desc, @"descriptor",
|
||||
[NSNumber numberWithInt:!grey], @"enable",
|
||||
nil]];
|
||||
}
|
||||
|
||||
|
||||
@@ -748,18 +771,9 @@ gui_mch_menu_hidden(vimmenu_T *menu, int hidden)
|
||||
void
|
||||
gui_mch_show_popupmenu(vimmenu_T *menu)
|
||||
{
|
||||
char_u *name = menu->name;
|
||||
#ifdef FEAT_MBYTE
|
||||
name = CONVERT_TO_UTF8(name);
|
||||
#endif
|
||||
|
||||
[[MMBackend sharedInstance] showPopupMenuWithName:(char*)name
|
||||
atMouseLocation:YES];
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
CONVERT_TO_UTF8_FREE(name);
|
||||
#endif
|
||||
|
||||
NSArray *desc = descriptor_for_menu(menu);
|
||||
[[MMBackend sharedInstance] queueMessage:ShowPopupMenuMsgID properties:
|
||||
[NSDictionary dictionaryWithObject:desc forKey:@"descriptor"]];
|
||||
}
|
||||
|
||||
|
||||
@@ -769,16 +783,19 @@ gui_mch_show_popupmenu(vimmenu_T *menu)
|
||||
void
|
||||
gui_make_popup(char_u *path_name, int mouse_pos)
|
||||
{
|
||||
#ifdef FEAT_MBYTE
|
||||
path_name = CONVERT_TO_UTF8(path_name);
|
||||
#endif
|
||||
vimmenu_T *menu = gui_find_menu(path_name);
|
||||
if (!(menu && menu->children)) return;
|
||||
|
||||
[[MMBackend sharedInstance] showPopupMenuWithName:(char*)path_name
|
||||
atMouseLocation:mouse_pos];
|
||||
NSArray *desc = descriptor_for_menu(menu);
|
||||
NSDictionary *p = (mouse_pos || NULL == curwin)
|
||||
? [NSDictionary dictionaryWithObject:desc forKey:@"descriptor"]
|
||||
: [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
desc, @"descriptor",
|
||||
[NSNumber numberWithInt:curwin->w_wrow], @"row",
|
||||
[NSNumber numberWithInt:curwin->w_wcol], @"column",
|
||||
nil];
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
CONVERT_TO_UTF8_FREE(path_name);
|
||||
#endif
|
||||
[[MMBackend sharedInstance] queueMessage:ShowPopupMenuMsgID properties:p];
|
||||
}
|
||||
|
||||
|
||||
@@ -1067,11 +1084,24 @@ gui_mch_draw_part_cursor(int w, int h, guicolor_T color)
|
||||
// font dimensions. Thus these parameters are useless. Instead we look at
|
||||
// the shape_table to determine the shape and size of the cursor (just like
|
||||
// gui_update_cursor() does).
|
||||
|
||||
#ifdef FEAT_RIGHTLEFT
|
||||
// If 'rl' is set the insert mode cursor must be drawn on the right-hand
|
||||
// side of a text cell.
|
||||
int rl = curwin ? curwin->w_p_rl : FALSE;
|
||||
#else
|
||||
int rl = FALSE;
|
||||
#endif
|
||||
int idx = get_shape_idx(FALSE);
|
||||
int shape = MMInsertionPointBlock;
|
||||
switch (shape_table[idx].shape) {
|
||||
case SHAPE_HOR: shape = MMInsertionPointHorizontal; break;
|
||||
case SHAPE_VER: shape = MMInsertionPointVertical; break;
|
||||
case SHAPE_HOR:
|
||||
shape = MMInsertionPointHorizontal;
|
||||
break;
|
||||
case SHAPE_VER:
|
||||
shape = rl ? MMInsertionPointVerticalRight
|
||||
: MMInsertionPointVertical;
|
||||
break;
|
||||
}
|
||||
|
||||
return [[MMBackend sharedInstance]
|
||||
@@ -1203,12 +1233,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
|
||||
@@ -1267,6 +1297,9 @@ gui_mch_browse(
|
||||
//NSLog(@"gui_mch_browse(saving=%d, title=%s, dflt=%s, ext=%s, initdir=%s,"
|
||||
// " filter=%s", saving, title, dflt, ext, initdir, filter);
|
||||
|
||||
// Ensure no data is on the output queue before presenting the dialog.
|
||||
gui_macvim_force_flush();
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
title = CONVERT_TO_UTF8(title);
|
||||
initdir = CONVERT_TO_UTF8(initdir);
|
||||
@@ -1300,6 +1333,9 @@ gui_mch_dialog(
|
||||
// "dfltbutton=%d textfield=%s)", type, title, message, buttons,
|
||||
// dfltbutton, textfield);
|
||||
|
||||
// Ensure no data is on the output queue before presenting the dialog.
|
||||
gui_macvim_force_flush();
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
title = CONVERT_TO_UTF8(title);
|
||||
message = CONVERT_TO_UTF8(message);
|
||||
@@ -1429,15 +1465,6 @@ gui_mch_iconify(void)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Invert a rectangle from row r, column c, for nr rows and nc columns.
|
||||
*/
|
||||
void
|
||||
gui_mch_invert_rectangle(int r, int c, int nr, int nc)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#if defined(FEAT_EVAL) || defined(PROTO)
|
||||
/*
|
||||
* Bring the Vim window to the foreground.
|
||||
@@ -1513,13 +1540,6 @@ gui_mch_toggle_tearoffs(int enable)
|
||||
}
|
||||
|
||||
|
||||
static BOOL
|
||||
gui_macvim_is_valid_action(NSString *action)
|
||||
{
|
||||
NSDictionary *actionDict = [[MMBackend sharedInstance] actionDict];
|
||||
return actionDict && [actionDict objectForKey:action] != nil;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gui_mch_enter_fullscreen(int fuoptions_flags, guicolor_T bg)
|
||||
@@ -1890,3 +1910,124 @@ get_macaction_name(expand_T *xp, int idx)
|
||||
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;
|
||||
}
|
||||
|
||||
static int specialKeyToNSKey(int key)
|
||||
{
|
||||
if (!IS_SPECIAL(key))
|
||||
return key;
|
||||
|
||||
static struct {
|
||||
int special;
|
||||
int nskey;
|
||||
} sp2ns[] = {
|
||||
{ K_UP, NSUpArrowFunctionKey },
|
||||
{ K_DOWN, NSDownArrowFunctionKey },
|
||||
{ K_LEFT, NSLeftArrowFunctionKey },
|
||||
{ K_RIGHT, NSRightArrowFunctionKey },
|
||||
{ K_F1, NSF1FunctionKey },
|
||||
{ K_F2, NSF2FunctionKey },
|
||||
{ K_F3, NSF3FunctionKey },
|
||||
{ K_F4, NSF4FunctionKey },
|
||||
{ K_F5, NSF5FunctionKey },
|
||||
{ K_F6, NSF6FunctionKey },
|
||||
{ K_F7, NSF7FunctionKey },
|
||||
{ K_F8, NSF8FunctionKey },
|
||||
{ K_F9, NSF9FunctionKey },
|
||||
{ K_F10, NSF10FunctionKey },
|
||||
{ K_F11, NSF11FunctionKey },
|
||||
{ K_F12, NSF12FunctionKey },
|
||||
{ K_F13, NSF13FunctionKey },
|
||||
{ K_F14, NSF14FunctionKey },
|
||||
{ K_F15, NSF15FunctionKey },
|
||||
{ K_F16, NSF16FunctionKey },
|
||||
{ K_F17, NSF17FunctionKey },
|
||||
{ K_F18, NSF18FunctionKey },
|
||||
{ K_F19, NSF19FunctionKey },
|
||||
{ K_F20, NSF20FunctionKey },
|
||||
{ K_F21, NSF21FunctionKey },
|
||||
{ K_F22, NSF22FunctionKey },
|
||||
{ K_F23, NSF23FunctionKey },
|
||||
{ K_F24, NSF24FunctionKey },
|
||||
{ K_F25, NSF25FunctionKey },
|
||||
{ K_F26, NSF26FunctionKey },
|
||||
{ K_F27, NSF27FunctionKey },
|
||||
{ K_F28, NSF28FunctionKey },
|
||||
{ K_F29, NSF29FunctionKey },
|
||||
{ K_F30, NSF30FunctionKey },
|
||||
{ K_F31, NSF31FunctionKey },
|
||||
{ K_F32, NSF32FunctionKey },
|
||||
{ K_F33, NSF33FunctionKey },
|
||||
{ K_F34, NSF34FunctionKey },
|
||||
{ K_F35, NSF35FunctionKey },
|
||||
{ K_DEL, NSBackspaceCharacter },
|
||||
{ K_BS, NSDeleteCharacter },
|
||||
{ K_HOME, NSHomeFunctionKey },
|
||||
{ K_END, NSEndFunctionKey },
|
||||
{ K_PAGEUP, NSPageUpFunctionKey },
|
||||
{ K_PAGEDOWN, NSPageDownFunctionKey }
|
||||
};
|
||||
|
||||
int i;
|
||||
for (i = 0; i < sizeof(sp2ns)/sizeof(sp2ns[0]); ++i) {
|
||||
if (sp2ns[i].special == key)
|
||||
return sp2ns[i].nskey;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vimModMaskToEventModifierFlags(int mods)
|
||||
{
|
||||
int flags = 0;
|
||||
|
||||
if (mods & MOD_MASK_SHIFT)
|
||||
flags |= NSShiftKeyMask;
|
||||
if (mods & MOD_MASK_CTRL)
|
||||
flags |= NSControlKeyMask;
|
||||
if (mods & MOD_MASK_ALT)
|
||||
flags |= NSAlternateKeyMask;
|
||||
if (mods & MOD_MASK_CMD)
|
||||
flags |= NSCommandKeyMask;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@implementation NSString (VimStrings)
|
||||
+ (id)stringWithVimString:(char_u *)s
|
||||
{
|
||||
if (s) {
|
||||
#ifdef FEAT_MBYTE
|
||||
s = CONVERT_TO_UTF8(s);
|
||||
#endif
|
||||
NSString *string = [NSString stringWithUTF8String:(char*)s];
|
||||
#ifdef FEAT_MBYTE
|
||||
CONVERT_TO_UTF8_FREE(s);
|
||||
#endif
|
||||
return string;
|
||||
}
|
||||
|
||||
return [NSString string];
|
||||
}
|
||||
@end
|
||||
|
||||
+69
-60
@@ -1,7 +1,7 @@
|
||||
" System gvimrc file for MacVim
|
||||
"
|
||||
" Maintainer: Bjorn Winckler <bjorn.winckler@gmail.com>
|
||||
" Last Change: Sat May 10 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,14 +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.325 File.Open\ Recent :maca recentFilesDummy:<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
|
||||
@@ -58,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/
|
||||
@@ -67,30 +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.301 Window.Minimize\ All <Nop>
|
||||
an <silent> 9900.310 Window.Zoom <Nop>
|
||||
an <silent> 9900.311 Window.Zoom\ All <Nop>
|
||||
an <silent> 9900.320 Window.Toggle\ Full\ Screen\ Mode :set invfullscreen<CR>
|
||||
an 9900.330 Window.-SEP1- <Nop>
|
||||
" TODO! Grey out if no tabs are visible.
|
||||
an <silent> 9900.340 Window.Previous\ Tab :tabprevious<CR>
|
||||
an <silent> 9900.350 Window.Next\ Tab :tabnext<CR>
|
||||
an 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 :maca openWebsite:<CR>
|
||||
an <silent> 9999.2 Help.MacVim\ Website <Nop>
|
||||
an 9999.3 Help.-sep0- <Nop>
|
||||
|
||||
|
||||
@@ -189,55 +192,61 @@ 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.Zoom <D-C-z>
|
||||
macmenukey Window.Toggle\ Full\ Screen\ Mode <D-F>
|
||||
macmenukey Window.Previous\ Tab <D-{>
|
||||
macmenukey Window.Next\ Tab <D-}>
|
||||
|
||||
" TODO: <D-?> seems to be reserved by the system on Leopard. Disable this key
|
||||
" equivalent until I can figure out what to do about it.
|
||||
"macmenukey Help.MacVim\ Help <D-?>
|
||||
macm Window.Minimize key=<D-m> action=performMiniaturize:
|
||||
macm Window.Minimize\ All key=<D-M-m> action=miniaturizeAll: alt=YES
|
||||
macm Window.Zoom key=<D-C-z> action=performZoom:
|
||||
macm Window.Zoom\ All key=<D-M-C-z> action=zoomAll: alt=YES
|
||||
macm Window.Toggle\ Full\ Screen\ Mode key=<D-F>
|
||||
macm Window.Previous\ Tab key=<D-{>
|
||||
macm Window.Next\ Tab key=<D-}>
|
||||
macm Window.Bring\ All\ To\ Front action=arrangeInFront:
|
||||
|
||||
macm Help.MacVim\ Website action=openWebsite:
|
||||
|
||||
" Restore the previous value of 'cpoptions'.
|
||||
let &cpo = s:cpo_save
|
||||
|
||||
@@ -40,6 +40,110 @@
|
||||
Sparkle supports updates in zip, tar, tbz, tgz, or dmg format.
|
||||
-->
|
||||
|
||||
<item>
|
||||
<title>Snapshot 31 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 31 released</h1>
|
||||
<p> Changes since snapshot 30:
|
||||
<ul>
|
||||
<li> Fixed problems with menus on OS X 10.4 and a related crash. </li>
|
||||
<li> Dialog box handling has been updated. This fixes a problem where the
|
||||
"swap file warning" dialog would pop up before the informational text in
|
||||
the editor window updated. Hopefully this will also cure various other
|
||||
problems with dialogs (e.g. nothing happening when opening files from a
|
||||
dialog box). </li>
|
||||
<li> Added dock menu with "New Window" item. This is useful with "Spaces" on
|
||||
OS X 10.5 since you can use this menu to open a new MacVim window on any
|
||||
"space" when another editor window is already open. (Also, now there is
|
||||
always a way to open a new window, even if the menus are customized,
|
||||
or if "-u NONE" is used.) </li>
|
||||
<li> I have started trying to fix "modeless selection" and it sort of works
|
||||
on my machine, but I've had one report stating that its not quite
|
||||
working so you mileage may vary. Make sure to let me know what works
|
||||
and doesn't so that I can fix this properly. (Try selecting text from
|
||||
the command line.) </li>
|
||||
<li> The default font (DejaVu Sans Mono) has been updated to version 2.25.
|
||||
</li>
|
||||
<li> Latest Vim source code merged </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Fri, 13 Jun 2008 16:00 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-31.tbz"
|
||||
length="8182620"
|
||||
sparkle:version="31"
|
||||
sparkle:shortVersionString="7.1"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 30 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 30 released</h1>
|
||||
<p> Changes since snapshot 28:
|
||||
<ul>
|
||||
<li> copy&paste and other "Edit" menu items now work as expected with dialogs
|
||||
(such as open/save). </li>
|
||||
<li> some menus (such as the "Window" menu) has got some new items </li>
|
||||
<li> general menu improvements when no editor window is open </li>
|
||||
<li> ability to access some OS X default Cmd-keys even if menus are
|
||||
completely altered (e.g. when starting with "-u NONE") </li>
|
||||
<li> QuickLook works with .vim files (patch by Nico Weber) </li>
|
||||
<li> insert mode cursor honors the 'rightleft' option </li>
|
||||
<li> no more "freezes" during :shell </li>
|
||||
<li> no beeping on Cmd-q </li>
|
||||
<li> Cmd-w works in full-screen again </li>
|
||||
<li> window dimensions properly restored when leaving full-screen when
|
||||
"maxvert" is in 'fuoptions' </li>
|
||||
<li> support for 'mousehide' option </li>
|
||||
<li> latest vim patches and runtime files </li>
|
||||
</ul>
|
||||
</p>
|
||||
<p> The only difference between snapshot 29 and 30 is that the former did not
|
||||
handle window cycling very well with international keyboard layouts. </p>
|
||||
]]></description>
|
||||
<pubDate>Sun, 8 Jun 2008 16:43 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-30.tbz"
|
||||
length="8137308"
|
||||
sparkle:version="30"
|
||||
sparkle:shortVersionString="7.1"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 28 released</title>
|
||||
<description><![CDATA[
|
||||
<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[
|
||||
@@ -66,10 +170,10 @@
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Sun, 11 May 2008 16:36 CET</pubDate>
|
||||
<pubDate>Mon, 12 May 2008 22:05 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-27.tbz"
|
||||
length="8104821"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-27-fixed.tbz"
|
||||
length="8102568"
|
||||
sparkle:version="27"
|
||||
sparkle:shortVersionString="7.1"
|
||||
/>
|
||||
|
||||
+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
|
||||
|
||||
+8
-3
@@ -780,6 +780,8 @@ LINT_OPTIONS = -beprxzF
|
||||
# 1) make config
|
||||
# 2) edit auto/config.mk, add -n32 to LDFLAGS
|
||||
# 3) make
|
||||
#
|
||||
#Alternatively: use -o32 instead of -n32.
|
||||
###
|
||||
|
||||
### (C) On SCO Unix v3.2.5 (and probably other versions) the termcap library,
|
||||
@@ -1074,7 +1076,7 @@ PRINTSOURCE = ../runtime/print
|
||||
# default vi editor, it will create a link from vi to Vim when doing
|
||||
# "make install". An existing file will be overwritten!
|
||||
# When not using it, some make programs can't handle an undefined $(LINKIT).
|
||||
#LINKIT = -ln -f -s $(BINDIR)/$(VIMTARGET) /usr/bin/vi
|
||||
#LINKIT = ln -f -s $(DEST_BIN)/$(VIMTARGET) $(DESTDIR)/usr/bin/vi
|
||||
LINKIT = @echo >/dev/null
|
||||
|
||||
###
|
||||
@@ -1306,6 +1308,9 @@ LINT_EXTRA = -DUSE_SNIFF -DHANGUL_INPUT -D"__attribute__(x)="
|
||||
|
||||
DEPEND_CFLAGS = -DPROTO -DDEPEND -DFEAT_GUI $(LINT_CFLAGS)
|
||||
|
||||
# If you have problems with flags that cproto doesn't support, and you are
|
||||
# using GNU make, you can try using the other line to filter out arguments.
|
||||
#PFLAGS = $(PROTO_FLAGS) -DPROTO $(filter -D% -I%, $(LINT_CFLAGS))
|
||||
PFLAGS = $(PROTO_FLAGS) -DPROTO $(LINT_CFLAGS)
|
||||
|
||||
ALL_LIB_DIRS = $(GUI_LIBS_DIR) $(X_LIBS_DIR)
|
||||
@@ -2190,7 +2195,7 @@ SHADOWDIR = shadow
|
||||
|
||||
shadow: runtime pixmaps
|
||||
mkdir $(SHADOWDIR)
|
||||
cd $(SHADOWDIR); ln -s ../*.[ch] ../*.in ../*.sh ../*.xs ../*.xbm ../toolcheck ../proto ../vimtutor ../gvimtutor ../mkinstalldirs .
|
||||
cd $(SHADOWDIR); ln -s ../*.[ch] ../*.in ../*.sh ../*.xs ../*.xbm ../toolcheck ../proto ../po ../vimtutor ../gvimtutor ../mkinstalldirs .
|
||||
mkdir $(SHADOWDIR)/auto
|
||||
cd $(SHADOWDIR)/auto; ln -s ../../auto/configure .
|
||||
cd $(SHADOWDIR); rm -f auto/link.sed
|
||||
@@ -2209,7 +2214,7 @@ shadow: runtime pixmaps
|
||||
cd $(SHADOWDIR)/testdir; ln -s ../../testdir/Makefile \
|
||||
../../testdir/vimrc.unix \
|
||||
../../testdir/*.in \
|
||||
../../testdir/unix.vim \
|
||||
../../testdir/*.vim \
|
||||
../../testdir/*.ok .
|
||||
|
||||
# Link needed for doing "make install" in a shadow directory.
|
||||
|
||||
+127
-79
@@ -507,6 +507,7 @@ static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_filter __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_fnameescape __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
@@ -7107,6 +7108,7 @@ static struct fst
|
||||
{"filter", 2, 2, f_filter},
|
||||
{"finddir", 1, 3, f_finddir},
|
||||
{"findfile", 1, 3, f_findfile},
|
||||
{"fnameescape", 1, 1, f_fnameescape},
|
||||
{"fnamemodify", 2, 2, f_fnamemodify},
|
||||
{"foldclosed", 1, 1, f_foldclosed},
|
||||
{"foldclosedend", 1, 1, f_foldclosedend},
|
||||
@@ -9464,6 +9466,19 @@ f_findfile(argvars, rettv)
|
||||
findfilendir(argvars, rettv, FINDFILE_FILE);
|
||||
}
|
||||
|
||||
/*
|
||||
* "fnameescape({string})" function
|
||||
*/
|
||||
static void
|
||||
f_fnameescape(argvars, rettv)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
{
|
||||
rettv->vval.v_string = vim_strsave_fnameescape(
|
||||
get_tv_string(&argvars[0]), FALSE);
|
||||
rettv->v_type = VAR_STRING;
|
||||
}
|
||||
|
||||
/*
|
||||
* "fnamemodify({fname}, {mods})" function
|
||||
*/
|
||||
@@ -21073,8 +21088,12 @@ static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, in
|
||||
static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen));
|
||||
|
||||
/*
|
||||
* Get the short pathname of a file.
|
||||
* Returns 1 on success. *fnamelen is 0 for nonexistent path.
|
||||
* Get the short path (8.3) for the filename in "fnamep".
|
||||
* Only works for a valid file name.
|
||||
* When the path gets longer "fnamep" is changed and the allocated buffer
|
||||
* is put in "bufp".
|
||||
* *fnamelen is the length of "fnamep" and set to 0 for a nonexistent path.
|
||||
* Returns OK on success, FAIL on failure.
|
||||
*/
|
||||
static int
|
||||
get_short_pathname(fnamep, bufp, fnamelen)
|
||||
@@ -21082,36 +21101,44 @@ get_short_pathname(fnamep, bufp, fnamelen)
|
||||
char_u **bufp;
|
||||
int *fnamelen;
|
||||
{
|
||||
int l,len;
|
||||
int l, len;
|
||||
char_u *newbuf;
|
||||
|
||||
len = *fnamelen;
|
||||
|
||||
l = GetShortPathName(*fnamep, *fnamep, len);
|
||||
if (l > len - 1)
|
||||
{
|
||||
/* If that doesn't work (not enough space), then save the string
|
||||
* and try again with a new buffer big enough
|
||||
*/
|
||||
* and try again with a new buffer big enough. */
|
||||
newbuf = vim_strnsave(*fnamep, l);
|
||||
if (newbuf == NULL)
|
||||
return 0;
|
||||
return FAIL;
|
||||
|
||||
vim_free(*bufp);
|
||||
*fnamep = *bufp = newbuf;
|
||||
|
||||
l = GetShortPathName(*fnamep,*fnamep,l+1);
|
||||
|
||||
/* Really should always succeed, as the buffer is big enough */
|
||||
/* Really should always succeed, as the buffer is big enough. */
|
||||
l = GetShortPathName(*fnamep, *fnamep, l+1);
|
||||
}
|
||||
|
||||
*fnamelen = l;
|
||||
return 1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a short path name. Returns the length of the buffer it needs.
|
||||
* Doesn't copy over the end of the buffer passed in.
|
||||
* Get the short path (8.3) for the filename in "fname". The converted
|
||||
* path is returned in "bufp".
|
||||
*
|
||||
* Some of the directories specified in "fname" may not exist. This function
|
||||
* will shorten the existing directories at the beginning of the path and then
|
||||
* append the remaining non-existing path.
|
||||
*
|
||||
* fname - Pointer to the filename to shorten. On return, contains the
|
||||
* pointer to the shortened pathname
|
||||
* bufp - Pointer to an allocated buffer for the filename.
|
||||
* fnamelen - Length of the filename pointed to by fname
|
||||
*
|
||||
* Returns OK on success (or nothing done) and FAIL on failure (out of memory).
|
||||
*/
|
||||
static int
|
||||
shortpath_for_invalid_fname(fname, bufp, fnamelen)
|
||||
@@ -21119,85 +21146,106 @@ shortpath_for_invalid_fname(fname, bufp, fnamelen)
|
||||
char_u **bufp;
|
||||
int *fnamelen;
|
||||
{
|
||||
char_u *s, *p, *pbuf2, *pbuf3;
|
||||
char_u *short_fname, *save_fname, *pbuf_unused;
|
||||
char_u *endp, *save_endp;
|
||||
char_u ch;
|
||||
int len, len2, plen, slen;
|
||||
int old_len, len;
|
||||
int new_len, sfx_len;
|
||||
int retval = OK;
|
||||
|
||||
/* Make a copy */
|
||||
len2 = *fnamelen;
|
||||
pbuf2 = vim_strnsave(*fname, len2);
|
||||
pbuf3 = NULL;
|
||||
old_len = *fnamelen;
|
||||
save_fname = vim_strnsave(*fname, old_len);
|
||||
pbuf_unused = NULL;
|
||||
short_fname = NULL;
|
||||
|
||||
s = pbuf2 + len2 - 1; /* Find the end */
|
||||
slen = 1;
|
||||
plen = len2;
|
||||
endp = save_fname + old_len - 1; /* Find the end of the copy */
|
||||
save_endp = endp;
|
||||
|
||||
if (after_pathsep(pbuf2, s + 1))
|
||||
/*
|
||||
* Try shortening the supplied path till it succeeds by removing one
|
||||
* directory at a time from the tail of the path.
|
||||
*/
|
||||
len = 0;
|
||||
for (;;)
|
||||
{
|
||||
--s;
|
||||
++slen;
|
||||
--plen;
|
||||
/* go back one path-separator */
|
||||
while (endp > save_fname && !after_pathsep(save_fname, endp + 1))
|
||||
--endp;
|
||||
if (endp <= save_fname)
|
||||
break; /* processed the complete path */
|
||||
|
||||
/*
|
||||
* Replace the path separator with a NUL and try to shorten the
|
||||
* resulting path.
|
||||
*/
|
||||
ch = *endp;
|
||||
*endp = 0;
|
||||
short_fname = save_fname;
|
||||
len = STRLEN(short_fname) + 1;
|
||||
if (get_short_pathname(&short_fname, &pbuf_unused, &len) == FAIL)
|
||||
{
|
||||
retval = FAIL;
|
||||
goto theend;
|
||||
}
|
||||
*endp = ch; /* preserve the string */
|
||||
|
||||
if (len > 0)
|
||||
break; /* successfully shortened the path */
|
||||
|
||||
/* failed to shorten the path. Skip the path separator */
|
||||
--endp;
|
||||
}
|
||||
|
||||
do
|
||||
if (len > 0)
|
||||
{
|
||||
/* Go back one path-separator */
|
||||
while (s > pbuf2 && !after_pathsep(pbuf2, s + 1))
|
||||
{
|
||||
--s;
|
||||
++slen;
|
||||
--plen;
|
||||
}
|
||||
if (s <= pbuf2)
|
||||
break;
|
||||
/*
|
||||
* Succeeded in shortening the path. Now concatenate the shortened
|
||||
* path with the remaining path at the tail.
|
||||
*/
|
||||
|
||||
/* Remember the character that is about to be splatted */
|
||||
ch = *s;
|
||||
*s = 0; /* get_short_pathname requires a null-terminated string */
|
||||
/* Compute the length of the new path. */
|
||||
sfx_len = (int)(save_endp - endp) + 1;
|
||||
new_len = len + sfx_len;
|
||||
|
||||
/* Try it in situ */
|
||||
p = pbuf2;
|
||||
if (!get_short_pathname(&p, &pbuf3, &plen))
|
||||
{
|
||||
vim_free(pbuf2);
|
||||
return -1;
|
||||
}
|
||||
*s = ch; /* Preserve the string */
|
||||
} while (plen == 0);
|
||||
|
||||
if (plen > 0)
|
||||
{
|
||||
/* Remember the length of the new string. */
|
||||
*fnamelen = len = plen + slen;
|
||||
*fnamelen = new_len;
|
||||
vim_free(*bufp);
|
||||
if (len > len2)
|
||||
if (new_len > old_len)
|
||||
{
|
||||
/* If there's not enough space in the currently allocated string,
|
||||
* then copy it to a buffer big enough.
|
||||
*/
|
||||
*fname= *bufp = vim_strnsave(p, len);
|
||||
/* There is not enough space in the currently allocated string,
|
||||
* copy it to a buffer big enough. */
|
||||
*fname = *bufp = vim_strnsave(short_fname, new_len);
|
||||
if (*fname == NULL)
|
||||
return -1;
|
||||
{
|
||||
retval = FAIL;
|
||||
goto theend;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Transfer pbuf2 to being the main buffer (it's big enough) */
|
||||
*fname = *bufp = pbuf2;
|
||||
if (p != pbuf2)
|
||||
strncpy(*fname, p, plen);
|
||||
pbuf2 = NULL;
|
||||
/* Transfer short_fname to the main buffer (it's big enough),
|
||||
* unless get_short_pathname() did its work in-place. */
|
||||
*fname = *bufp = save_fname;
|
||||
if (short_fname != save_fname)
|
||||
vim_strncpy(save_fname, short_fname, len);
|
||||
save_fname = NULL;
|
||||
}
|
||||
/* Concat the next bit */
|
||||
strncpy(*fname + plen, s, slen);
|
||||
(*fname)[len] = '\0';
|
||||
|
||||
/* concat the not-shortened part of the path */
|
||||
vim_strncpy(*fname + len, endp, sfx_len);
|
||||
(*fname)[new_len] = NUL;
|
||||
}
|
||||
vim_free(pbuf3);
|
||||
vim_free(pbuf2);
|
||||
return 0;
|
||||
|
||||
theend:
|
||||
vim_free(pbuf_unused);
|
||||
vim_free(save_fname);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a pathname for a partial path.
|
||||
* Returns OK for success, FAIL for failure.
|
||||
*/
|
||||
static int
|
||||
shortpath_for_partial(fnamep, bufp, fnamelen)
|
||||
@@ -21227,8 +21275,8 @@ shortpath_for_partial(fnamep, bufp, fnamelen)
|
||||
|
||||
len = tflen = (int)STRLEN(tfname);
|
||||
|
||||
if (!get_short_pathname(&tfname, &pbuf, &len))
|
||||
return -1;
|
||||
if (get_short_pathname(&tfname, &pbuf, &len) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
@@ -21237,8 +21285,8 @@ shortpath_for_partial(fnamep, bufp, fnamelen)
|
||||
* there's not a lot of point in guessing what it might be.
|
||||
*/
|
||||
len = tflen;
|
||||
if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1)
|
||||
return -1;
|
||||
if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/* Count the paths backward to find the beginning of the desired string. */
|
||||
@@ -21262,7 +21310,7 @@ shortpath_for_partial(fnamep, bufp, fnamelen)
|
||||
if (p >= tfname)
|
||||
*p = '~';
|
||||
else
|
||||
return -1;
|
||||
return FAIL;
|
||||
}
|
||||
else
|
||||
++p;
|
||||
@@ -21273,7 +21321,7 @@ shortpath_for_partial(fnamep, bufp, fnamelen)
|
||||
*bufp = pbuf;
|
||||
*fnamep = p;
|
||||
|
||||
return 0;
|
||||
return OK;
|
||||
}
|
||||
#endif /* WIN3264 */
|
||||
|
||||
@@ -21281,7 +21329,7 @@ shortpath_for_partial(fnamep, bufp, fnamelen)
|
||||
* Adjust a filename, according to a string of modifiers.
|
||||
* *fnamep must be NUL terminated when called. When returning, the length is
|
||||
* determined by *fnamelen.
|
||||
* Returns valid flags.
|
||||
* Returns VALID_ flags or -1 for failure.
|
||||
* When there is an error, *fnamep is set to NULL.
|
||||
*/
|
||||
int
|
||||
@@ -21493,7 +21541,7 @@ repeat:
|
||||
*/
|
||||
if (!has_fullname && !vim_isAbsName(*fnamep))
|
||||
{
|
||||
if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1)
|
||||
if (shortpath_for_partial(fnamep, bufp, fnamelen) == FAIL)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
@@ -21503,7 +21551,7 @@ repeat:
|
||||
/* Simple case, already have the full-name
|
||||
* Nearly always shorter, so try first time. */
|
||||
l = *fnamelen;
|
||||
if (!get_short_pathname(fnamep, bufp, &l))
|
||||
if (get_short_pathname(fnamep, bufp, &l) == FAIL)
|
||||
return -1;
|
||||
|
||||
if (l == 0)
|
||||
@@ -21511,7 +21559,7 @@ repeat:
|
||||
/* Couldn't find the filename.. search the paths.
|
||||
*/
|
||||
l = *fnamelen;
|
||||
if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1)
|
||||
if (shortpath_for_invalid_fname(fnamep, bufp, &l) == FAIL)
|
||||
return -1;
|
||||
}
|
||||
*fnamelen = l;
|
||||
|
||||
+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,
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
/*
|
||||
@@ -3764,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
|
||||
|
||||
+28
-13
@@ -3657,20 +3657,9 @@ ExpandEscape(xp, str, numfiles, files, options)
|
||||
}
|
||||
}
|
||||
#ifdef BACKSLASH_IN_FILENAME
|
||||
{
|
||||
char_u buf[20];
|
||||
int j = 0;
|
||||
|
||||
/* Don't escape '[' and '{' if they are in 'isfname'. */
|
||||
for (p = PATH_ESC_CHARS; *p != NUL; ++p)
|
||||
if ((*p != '[' && *p != '{') || !vim_isfilec(*p))
|
||||
buf[j++] = *p;
|
||||
buf[j] = NUL;
|
||||
p = vim_strsave_escaped(files[i], buf);
|
||||
}
|
||||
p = vim_strsave_fnameescape(files[i], FALSE);
|
||||
#else
|
||||
p = vim_strsave_escaped(files[i],
|
||||
xp->xp_shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS);
|
||||
p = vim_strsave_fnameescape(files[i], xp->xp_shell);
|
||||
#endif
|
||||
if (p != NULL)
|
||||
{
|
||||
@@ -3709,6 +3698,32 @@ ExpandEscape(xp, str, numfiles, files, options)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Escape special characters in "fname" for when used as a file name argument
|
||||
* after a Vim command, or, when "shell" is non-zero, a shell command.
|
||||
* Returns the result in allocated memory.
|
||||
*/
|
||||
char_u *
|
||||
vim_strsave_fnameescape(fname, shell)
|
||||
char_u *fname;
|
||||
int shell;
|
||||
{
|
||||
#ifdef BACKSLASH_IN_FILENAME
|
||||
char_u buf[20];
|
||||
int j = 0;
|
||||
char_u *p;
|
||||
|
||||
/* Don't escape '[' and '{' if they are in 'isfname'. */
|
||||
for (p = PATH_ESC_CHARS; *p != NUL; ++p)
|
||||
if ((*p != '[' && *p != '{') || !vim_isfilec(*p))
|
||||
buf[j++] = *p;
|
||||
buf[j] = NUL;
|
||||
return vim_strsave_escaped(fname, buf);
|
||||
#else
|
||||
return vim_strsave_escaped(fname, shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Put a backslash before the file name in "pp", which is in allocated memory.
|
||||
*/
|
||||
|
||||
+80
-44
@@ -1288,12 +1288,49 @@ retry:
|
||||
#ifdef FEAT_MBYTE
|
||||
else if (conv_restlen > 0)
|
||||
{
|
||||
/* Reached end-of-file but some trailing bytes could
|
||||
* not be converted. Truncated file? */
|
||||
if (conv_error == 0)
|
||||
conv_error = linecnt;
|
||||
if (bad_char_behavior != BAD_DROP)
|
||||
/*
|
||||
* Reached end-of-file but some trailing bytes could
|
||||
* not be converted. Truncated file?
|
||||
*/
|
||||
|
||||
/* When we did a conversion report an error. */
|
||||
if (fio_flags != 0
|
||||
# ifdef USE_ICONV
|
||||
|| iconv_fd != (iconv_t)-1
|
||||
# endif
|
||||
)
|
||||
{
|
||||
if (conv_error == 0)
|
||||
conv_error = curbuf->b_ml.ml_line_count
|
||||
- linecnt + 1;
|
||||
}
|
||||
/* Remember the first linenr with an illegal byte */
|
||||
else if (illegal_byte == 0)
|
||||
illegal_byte = curbuf->b_ml.ml_line_count
|
||||
- linecnt + 1;
|
||||
if (bad_char_behavior == BAD_DROP)
|
||||
{
|
||||
*(ptr - conv_restlen) = NUL;
|
||||
conv_restlen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Replace the trailing bytes with the replacement
|
||||
* character if we were converting; if we weren't,
|
||||
* leave the UTF8 checking code to do it, as it
|
||||
* works slightly differently. */
|
||||
if (bad_char_behavior != BAD_KEEP && (fio_flags != 0
|
||||
# ifdef USE_ICONV
|
||||
|| iconv_fd != (iconv_t)-1
|
||||
# endif
|
||||
))
|
||||
{
|
||||
while (conv_restlen > 0)
|
||||
{
|
||||
*(--ptr) = bad_char_behavior;
|
||||
--conv_restlen;
|
||||
}
|
||||
}
|
||||
fio_flags = 0; /* don't convert this */
|
||||
# ifdef USE_ICONV
|
||||
if (iconv_fd != (iconv_t)-1)
|
||||
@@ -1302,20 +1339,6 @@ retry:
|
||||
iconv_fd = (iconv_t)-1;
|
||||
}
|
||||
# endif
|
||||
if (bad_char_behavior == BAD_KEEP)
|
||||
{
|
||||
/* Keep the trailing bytes as-is. */
|
||||
size = conv_restlen;
|
||||
ptr -= conv_restlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Replace the trailing bytes with the
|
||||
* replacement character. */
|
||||
size = 1;
|
||||
*--ptr = bad_char_behavior;
|
||||
}
|
||||
conv_restlen = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1397,6 +1420,11 @@ retry:
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
/* Include not converted bytes. */
|
||||
ptr -= conv_restlen;
|
||||
size += conv_restlen;
|
||||
conv_restlen = 0;
|
||||
#endif
|
||||
/*
|
||||
* Break here for a read error or end-of-file.
|
||||
@@ -1406,11 +1434,6 @@ retry:
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
|
||||
/* Include not converted bytes. */
|
||||
ptr -= conv_restlen;
|
||||
size += conv_restlen;
|
||||
conv_restlen = 0;
|
||||
|
||||
# ifdef USE_ICONV
|
||||
if (iconv_fd != (iconv_t)-1)
|
||||
{
|
||||
@@ -1872,12 +1895,12 @@ retry:
|
||||
size = (long)((ptr + real_size) - dest);
|
||||
ptr = dest;
|
||||
}
|
||||
else if (enc_utf8 && conv_error == 0 && !curbuf->b_p_bin)
|
||||
else if (enc_utf8 && !curbuf->b_p_bin)
|
||||
{
|
||||
/* Reading UTF-8: Check if the bytes are valid UTF-8.
|
||||
* Need to start before "ptr" when part of the character was
|
||||
* read in the previous read() call. */
|
||||
for (p = ptr - utf_head_off(buffer, ptr); ; ++p)
|
||||
int incomplete_tail = FALSE;
|
||||
|
||||
/* Reading UTF-8: Check if the bytes are valid UTF-8. */
|
||||
for (p = ptr; ; ++p)
|
||||
{
|
||||
int todo = (int)((ptr + size) - p);
|
||||
int l;
|
||||
@@ -1891,43 +1914,56 @@ retry:
|
||||
* read() will get the next bytes, we'll check it
|
||||
* then. */
|
||||
l = utf_ptr2len_len(p, todo);
|
||||
if (l > todo)
|
||||
if (l > todo && !incomplete_tail)
|
||||
{
|
||||
/* Incomplete byte sequence, the next read()
|
||||
* should get them and check the bytes. */
|
||||
p += todo;
|
||||
break;
|
||||
/* Avoid retrying with a different encoding when
|
||||
* a truncated file is more likely, or attempting
|
||||
* to read the rest of an incomplete sequence when
|
||||
* we have already done so. */
|
||||
if (p > ptr || filesize > 0)
|
||||
incomplete_tail = TRUE;
|
||||
/* Incomplete byte sequence, move it to conv_rest[]
|
||||
* and try to read the rest of it, unless we've
|
||||
* already done so. */
|
||||
if (p > ptr)
|
||||
{
|
||||
conv_restlen = todo;
|
||||
mch_memmove(conv_rest, p, conv_restlen);
|
||||
size -= conv_restlen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (l == 1)
|
||||
if (l == 1 || l > todo)
|
||||
{
|
||||
/* Illegal byte. If we can try another encoding
|
||||
* do that. */
|
||||
if (can_retry)
|
||||
* do that, unless at EOF where a truncated
|
||||
* file is more likely than a conversion error. */
|
||||
if (can_retry && !incomplete_tail)
|
||||
break;
|
||||
|
||||
/* Remember the first linenr with an illegal byte */
|
||||
if (illegal_byte == 0)
|
||||
illegal_byte = readfile_linenr(linecnt, ptr, p);
|
||||
# ifdef USE_ICONV
|
||||
/* When we did a conversion report an error. */
|
||||
if (iconv_fd != (iconv_t)-1 && conv_error == 0)
|
||||
conv_error = readfile_linenr(linecnt, ptr, p);
|
||||
# endif
|
||||
/* Remember the first linenr with an illegal byte */
|
||||
if (conv_error == 0 && illegal_byte == 0)
|
||||
illegal_byte = readfile_linenr(linecnt, ptr, p);
|
||||
|
||||
/* Drop, keep or replace the bad byte. */
|
||||
if (bad_char_behavior == BAD_DROP)
|
||||
{
|
||||
mch_memmove(p, p+1, todo - 1);
|
||||
mch_memmove(p, p + 1, todo - 1);
|
||||
--p;
|
||||
--size;
|
||||
}
|
||||
else if (bad_char_behavior != BAD_KEEP)
|
||||
*p = bad_char_behavior;
|
||||
}
|
||||
p += l - 1;
|
||||
else
|
||||
p += l - 1;
|
||||
}
|
||||
}
|
||||
if (p < ptr + size)
|
||||
if (p < ptr + size && !incomplete_tail)
|
||||
{
|
||||
/* Detected a UTF-8 error. */
|
||||
rewind_retry:
|
||||
|
||||
@@ -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 "$@"
|
||||
+115
-87
@@ -38,6 +38,8 @@
|
||||
# undef HAVE_STDARG_H /* Python's config.h defines it as well. */
|
||||
#endif
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
|
||||
#include <Python.h>
|
||||
#if defined(MACOS) && !defined(MACOS_X_UNIX)
|
||||
# include "macglue.h"
|
||||
@@ -55,6 +57,22 @@ struct PyMethodDef { int a; };
|
||||
# define PySequenceMethods int
|
||||
#endif
|
||||
|
||||
#if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02050000
|
||||
# define PyInt Py_ssize_t
|
||||
# define PyInquiry lenfunc
|
||||
# define PyIntArgFunc ssizeargfunc
|
||||
# define PyIntIntArgFunc ssizessizeargfunc
|
||||
# define PyIntObjArgProc ssizeobjargproc
|
||||
# define PyIntIntObjArgProc ssizessizeobjargproc
|
||||
#else
|
||||
# define PyInt int
|
||||
# define PyInquiry inquiry
|
||||
# define PyIntArgFunc intargfunc
|
||||
# define PyIntIntArgFunc intintargfunc
|
||||
# define PyIntObjArgProc intobjargproc
|
||||
# define PyIntIntObjArgProc intintobjargproc
|
||||
#endif
|
||||
|
||||
/* Parser flags */
|
||||
#define single_input 256
|
||||
#define file_input 257
|
||||
@@ -150,11 +168,11 @@ static void (*dll_PyGILState_Release)(PyGILState_STATE);
|
||||
static long(*dll_PyInt_AsLong)(PyObject *);
|
||||
static PyObject*(*dll_PyInt_FromLong)(long);
|
||||
static PyTypeObject* dll_PyInt_Type;
|
||||
static PyObject*(*dll_PyList_GetItem)(PyObject *, int);
|
||||
static PyObject*(*dll_PyList_GetItem)(PyObject *, PyInt);
|
||||
static PyObject*(*dll_PyList_Append)(PyObject *, PyObject *);
|
||||
static PyObject*(*dll_PyList_New)(int size);
|
||||
static int(*dll_PyList_SetItem)(PyObject *, int, PyObject *);
|
||||
static int(*dll_PyList_Size)(PyObject *);
|
||||
static PyObject*(*dll_PyList_New)(PyInt size);
|
||||
static int(*dll_PyList_SetItem)(PyObject *, PyInt, PyObject *);
|
||||
static PyInt(*dll_PyList_Size)(PyObject *);
|
||||
static PyTypeObject* dll_PyList_Type;
|
||||
static PyObject*(*dll_PyImport_ImportModule)(const char *);
|
||||
static PyObject*(*dll_PyDict_New)(void);
|
||||
@@ -163,8 +181,8 @@ static PyObject*(*dll_PyModule_GetDict)(PyObject *);
|
||||
static int(*dll_PyRun_SimpleString)(char *);
|
||||
static char*(*dll_PyString_AsString)(PyObject *);
|
||||
static PyObject*(*dll_PyString_FromString)(const char *);
|
||||
static PyObject*(*dll_PyString_FromStringAndSize)(const char *, int);
|
||||
static int(*dll_PyString_Size)(PyObject *);
|
||||
static PyObject*(*dll_PyString_FromStringAndSize)(const char *, PyInt);
|
||||
static PyInt(*dll_PyString_Size)(PyObject *);
|
||||
static PyTypeObject* dll_PyString_Type;
|
||||
static int(*dll_PySys_SetObject)(char *, PyObject *);
|
||||
static int(*dll_PySys_SetArgv)(int, char **);
|
||||
@@ -367,10 +385,10 @@ static int PythonMod_Init(void);
|
||||
* ----------------------------------------------
|
||||
*/
|
||||
static PyObject *GetBufferLine(buf_T *, int);
|
||||
static PyObject *GetBufferLineList(buf_T *, int, int);
|
||||
static PyObject *GetBufferLineList(buf_T *, PyInt, PyInt);
|
||||
|
||||
static int SetBufferLine(buf_T *, int, PyObject *, int *);
|
||||
static int SetBufferLineList(buf_T *, int, int, PyObject *, int *);
|
||||
static int SetBufferLineList(buf_T *, PyInt, PyInt, PyObject *, int *);
|
||||
static int InsertBufferLines(buf_T *, int, PyObject *, int *);
|
||||
|
||||
static PyObject *LineToString(const char *);
|
||||
@@ -773,8 +791,8 @@ OutputWrite(PyObject *self, PyObject *args)
|
||||
static PyObject *
|
||||
OutputWritelines(PyObject *self, PyObject *args)
|
||||
{
|
||||
int n;
|
||||
int i;
|
||||
PyInt n;
|
||||
PyInt i;
|
||||
PyObject *list;
|
||||
int error = ((OutputObject *)(self))->error;
|
||||
|
||||
@@ -986,11 +1004,11 @@ static void BufferDestructor(PyObject *);
|
||||
static PyObject *BufferGetattr(PyObject *, char *);
|
||||
static PyObject *BufferRepr(PyObject *);
|
||||
|
||||
static int BufferLength(PyObject *);
|
||||
static PyObject *BufferItem(PyObject *, int);
|
||||
static PyObject *BufferSlice(PyObject *, int, int);
|
||||
static int BufferAssItem(PyObject *, int, PyObject *);
|
||||
static int BufferAssSlice(PyObject *, int, int, PyObject *);
|
||||
static PyInt BufferLength(PyObject *);
|
||||
static PyObject *BufferItem(PyObject *, PyInt);
|
||||
static PyObject *BufferSlice(PyObject *, PyInt, PyInt);
|
||||
static PyInt BufferAssItem(PyObject *, PyInt, PyObject *);
|
||||
static PyInt BufferAssSlice(PyObject *, PyInt, PyInt, PyObject *);
|
||||
|
||||
static PyObject *BufferAppend(PyObject *, PyObject *);
|
||||
static PyObject *BufferMark(PyObject *, PyObject *);
|
||||
@@ -1017,11 +1035,11 @@ static void RangeDestructor(PyObject *);
|
||||
static PyObject *RangeGetattr(PyObject *, char *);
|
||||
static PyObject *RangeRepr(PyObject *);
|
||||
|
||||
static int RangeLength(PyObject *);
|
||||
static PyObject *RangeItem(PyObject *, int);
|
||||
static PyObject *RangeSlice(PyObject *, int, int);
|
||||
static int RangeAssItem(PyObject *, int, PyObject *);
|
||||
static int RangeAssSlice(PyObject *, int, int, PyObject *);
|
||||
static PyInt RangeLength(PyObject *);
|
||||
static PyObject *RangeItem(PyObject *, PyInt);
|
||||
static PyObject *RangeSlice(PyObject *, PyInt, PyInt);
|
||||
static PyInt RangeAssItem(PyObject *, PyInt, PyObject *);
|
||||
static PyInt RangeAssSlice(PyObject *, PyInt, PyInt, PyObject *);
|
||||
|
||||
static PyObject *RangeAppend(PyObject *, PyObject *);
|
||||
|
||||
@@ -1029,15 +1047,15 @@ static PyObject *RangeAppend(PyObject *, PyObject *);
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
static int WinListLength(PyObject *);
|
||||
static PyObject *WinListItem(PyObject *, int);
|
||||
static PyInt WinListLength(PyObject *);
|
||||
static PyObject *WinListItem(PyObject *, PyInt);
|
||||
|
||||
/* Buffer list type - Implementation functions
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
static int BufListLength(PyObject *);
|
||||
static PyObject *BufListItem(PyObject *, int);
|
||||
static PyInt BufListLength(PyObject *);
|
||||
static PyObject *BufListItem(PyObject *, PyInt);
|
||||
|
||||
/* Current objects type - Implementation functions
|
||||
* -----------------------------------------------
|
||||
@@ -1130,6 +1148,16 @@ VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
|
||||
result = Py_BuildValue("s", buf);
|
||||
PyDict_SetItemString(lookupDict, ptrBuf, result);
|
||||
}
|
||||
#ifdef FEAT_FLOAT
|
||||
else if (our_tv->v_type == VAR_FLOAT)
|
||||
{
|
||||
char buf[NUMBUFLEN];
|
||||
|
||||
sprintf(buf, "%f", our_tv->vval.v_float);
|
||||
result = Py_BuildValue("s", buf);
|
||||
PyDict_SetItemString(lookupDict, ptrBuf, result);
|
||||
}
|
||||
#endif
|
||||
else if (our_tv->v_type == VAR_LIST)
|
||||
{
|
||||
list_T *list = our_tv->vval.v_list;
|
||||
@@ -1245,7 +1273,7 @@ CheckBuffer(BufferObject *this)
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
RBItem(BufferObject *self, int n, int start, int end)
|
||||
RBItem(BufferObject *self, PyInt n, int start, int end)
|
||||
{
|
||||
if (CheckBuffer(self))
|
||||
return NULL;
|
||||
@@ -1260,9 +1288,9 @@ RBItem(BufferObject *self, int n, int start, int end)
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
RBSlice(BufferObject *self, int lo, int hi, int start, int end)
|
||||
RBSlice(BufferObject *self, PyInt lo, PyInt hi, int start, int end)
|
||||
{
|
||||
int size;
|
||||
PyInt size;
|
||||
|
||||
if (CheckBuffer(self))
|
||||
return NULL;
|
||||
@@ -1283,8 +1311,8 @@ RBSlice(BufferObject *self, int lo, int hi, int start, int end)
|
||||
return GetBufferLineList(self->buf, lo+start, hi+start);
|
||||
}
|
||||
|
||||
static int
|
||||
RBAssItem(BufferObject *self, int n, PyObject *val, int start, int end, int *new_end)
|
||||
static PyInt
|
||||
RBAssItem(BufferObject *self, PyInt n, PyObject *val, int start, int end, int *new_end)
|
||||
{
|
||||
int len_change;
|
||||
|
||||
@@ -1306,8 +1334,8 @@ RBAssItem(BufferObject *self, int n, PyObject *val, int start, int end, int *new
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
RBAssSlice(BufferObject *self, int lo, int hi, PyObject *val, int start, int end, int *new_end)
|
||||
static PyInt
|
||||
RBAssSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, int start, int end, int *new_end)
|
||||
{
|
||||
int size;
|
||||
int len_change;
|
||||
@@ -1384,13 +1412,13 @@ static struct PyMethodDef BufferMethods[] = {
|
||||
};
|
||||
|
||||
static PySequenceMethods BufferAsSeq = {
|
||||
(inquiry) BufferLength, /* sq_length, len(x) */
|
||||
(PyInquiry) BufferLength, /* sq_length, len(x) */
|
||||
(binaryfunc) 0, /* BufferConcat, */ /* sq_concat, x+y */
|
||||
(intargfunc) 0, /* BufferRepeat, */ /* sq_repeat, x*n */
|
||||
(intargfunc) BufferItem, /* sq_item, x[i] */
|
||||
(intintargfunc) BufferSlice, /* sq_slice, x[i:j] */
|
||||
(intobjargproc) BufferAssItem, /* sq_ass_item, x[i]=v */
|
||||
(intintobjargproc) BufferAssSlice, /* sq_ass_slice, x[i:j]=v */
|
||||
(PyIntArgFunc) 0, /* BufferRepeat, */ /* sq_repeat, x*n */
|
||||
(PyIntArgFunc) BufferItem, /* sq_item, x[i] */
|
||||
(PyIntIntArgFunc) BufferSlice, /* sq_slice, x[i:j] */
|
||||
(PyIntObjArgProc) BufferAssItem, /* sq_ass_item, x[i]=v */
|
||||
(PyIntIntObjArgProc) BufferAssSlice, /* sq_ass_slice, x[i:j]=v */
|
||||
};
|
||||
|
||||
static PyTypeObject BufferType = {
|
||||
@@ -1516,7 +1544,7 @@ BufferRepr(PyObject *self)
|
||||
|
||||
/******************/
|
||||
|
||||
static int
|
||||
static PyInt
|
||||
BufferLength(PyObject *self)
|
||||
{
|
||||
/* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
|
||||
@@ -1527,29 +1555,29 @@ BufferLength(PyObject *self)
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
BufferItem(PyObject *self, int n)
|
||||
BufferItem(PyObject *self, PyInt n)
|
||||
{
|
||||
return RBItem((BufferObject *)(self), n, 1,
|
||||
(int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
BufferSlice(PyObject *self, int lo, int hi)
|
||||
BufferSlice(PyObject *self, PyInt lo, PyInt hi)
|
||||
{
|
||||
return RBSlice((BufferObject *)(self), lo, hi, 1,
|
||||
(int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
|
||||
}
|
||||
|
||||
static int
|
||||
BufferAssItem(PyObject *self, int n, PyObject *val)
|
||||
static PyInt
|
||||
BufferAssItem(PyObject *self, PyInt n, PyObject *val)
|
||||
{
|
||||
return RBAssItem((BufferObject *)(self), n, val, 1,
|
||||
(int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
BufferAssSlice(PyObject *self, int lo, int hi, PyObject *val)
|
||||
static PyInt
|
||||
BufferAssSlice(PyObject *self, PyInt lo, PyInt hi, PyObject *val)
|
||||
{
|
||||
return RBAssSlice((BufferObject *)(self), lo, hi, val, 1,
|
||||
(int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
|
||||
@@ -1627,13 +1655,13 @@ static struct PyMethodDef RangeMethods[] = {
|
||||
};
|
||||
|
||||
static PySequenceMethods RangeAsSeq = {
|
||||
(inquiry) RangeLength, /* sq_length, len(x) */
|
||||
(PyInquiry) RangeLength, /* sq_length, len(x) */
|
||||
(binaryfunc) 0, /* RangeConcat, */ /* sq_concat, x+y */
|
||||
(intargfunc) 0, /* RangeRepeat, */ /* sq_repeat, x*n */
|
||||
(intargfunc) RangeItem, /* sq_item, x[i] */
|
||||
(intintargfunc) RangeSlice, /* sq_slice, x[i:j] */
|
||||
(intobjargproc) RangeAssItem, /* sq_ass_item, x[i]=v */
|
||||
(intintobjargproc) RangeAssSlice, /* sq_ass_slice, x[i:j]=v */
|
||||
(PyIntArgFunc) 0, /* RangeRepeat, */ /* sq_repeat, x*n */
|
||||
(PyIntArgFunc) RangeItem, /* sq_item, x[i] */
|
||||
(PyIntIntArgFunc) RangeSlice, /* sq_slice, x[i:j] */
|
||||
(PyIntObjArgProc) RangeAssItem, /* sq_ass_item, x[i]=v */
|
||||
(PyIntIntObjArgProc) RangeAssSlice, /* sq_ass_slice, x[i:j]=v */
|
||||
};
|
||||
|
||||
static PyTypeObject RangeType = {
|
||||
@@ -1738,7 +1766,7 @@ RangeRepr(PyObject *self)
|
||||
|
||||
/****************/
|
||||
|
||||
static int
|
||||
static PyInt
|
||||
RangeLength(PyObject *self)
|
||||
{
|
||||
/* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
|
||||
@@ -1749,7 +1777,7 @@ RangeLength(PyObject *self)
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
RangeItem(PyObject *self, int n)
|
||||
RangeItem(PyObject *self, PyInt n)
|
||||
{
|
||||
return RBItem(((RangeObject *)(self))->buf, n,
|
||||
((RangeObject *)(self))->start,
|
||||
@@ -1757,15 +1785,15 @@ RangeItem(PyObject *self, int n)
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
RangeSlice(PyObject *self, int lo, int hi)
|
||||
RangeSlice(PyObject *self, PyInt lo, PyInt hi)
|
||||
{
|
||||
return RBSlice(((RangeObject *)(self))->buf, lo, hi,
|
||||
((RangeObject *)(self))->start,
|
||||
((RangeObject *)(self))->end);
|
||||
}
|
||||
|
||||
static int
|
||||
RangeAssItem(PyObject *self, int n, PyObject *val)
|
||||
static PyInt
|
||||
RangeAssItem(PyObject *self, PyInt n, PyObject *val)
|
||||
{
|
||||
return RBAssItem(((RangeObject *)(self))->buf, n, val,
|
||||
((RangeObject *)(self))->start,
|
||||
@@ -1773,8 +1801,8 @@ RangeAssItem(PyObject *self, int n, PyObject *val)
|
||||
&((RangeObject *)(self))->end);
|
||||
}
|
||||
|
||||
static int
|
||||
RangeAssSlice(PyObject *self, int lo, int hi, PyObject *val)
|
||||
static PyInt
|
||||
RangeAssSlice(PyObject *self, PyInt lo, PyInt hi, PyObject *val)
|
||||
{
|
||||
return RBAssSlice(((RangeObject *)(self))->buf, lo, hi, val,
|
||||
((RangeObject *)(self))->start,
|
||||
@@ -1801,13 +1829,13 @@ typedef struct
|
||||
BufListObject;
|
||||
|
||||
static PySequenceMethods BufListAsSeq = {
|
||||
(inquiry) BufListLength, /* sq_length, len(x) */
|
||||
(PyInquiry) BufListLength, /* sq_length, len(x) */
|
||||
(binaryfunc) 0, /* sq_concat, x+y */
|
||||
(intargfunc) 0, /* sq_repeat, x*n */
|
||||
(intargfunc) BufListItem, /* sq_item, x[i] */
|
||||
(intintargfunc) 0, /* sq_slice, x[i:j] */
|
||||
(intobjargproc) 0, /* sq_ass_item, x[i]=v */
|
||||
(intintobjargproc) 0, /* sq_ass_slice, x[i:j]=v */
|
||||
(PyIntArgFunc) 0, /* sq_repeat, x*n */
|
||||
(PyIntArgFunc) BufListItem, /* sq_item, x[i] */
|
||||
(PyIntIntArgFunc) 0, /* sq_slice, x[i:j] */
|
||||
(PyIntObjArgProc) 0, /* sq_ass_item, x[i]=v */
|
||||
(PyIntIntObjArgProc) 0, /* sq_ass_slice, x[i:j]=v */
|
||||
};
|
||||
|
||||
static PyTypeObject BufListType = {
|
||||
@@ -1837,7 +1865,7 @@ static PyTypeObject BufListType = {
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
static PyInt
|
||||
BufListLength(PyObject *self)
|
||||
{
|
||||
buf_T *b = firstbuf;
|
||||
@@ -1854,7 +1882,7 @@ BufListLength(PyObject *self)
|
||||
|
||||
/*ARGSUSED*/
|
||||
static PyObject *
|
||||
BufListItem(PyObject *self, int n)
|
||||
BufListItem(PyObject *self, PyInt n)
|
||||
{
|
||||
buf_T *b;
|
||||
|
||||
@@ -2119,13 +2147,13 @@ typedef struct
|
||||
WinListObject;
|
||||
|
||||
static PySequenceMethods WinListAsSeq = {
|
||||
(inquiry) WinListLength, /* sq_length, len(x) */
|
||||
(PyInquiry) WinListLength, /* sq_length, len(x) */
|
||||
(binaryfunc) 0, /* sq_concat, x+y */
|
||||
(intargfunc) 0, /* sq_repeat, x*n */
|
||||
(intargfunc) WinListItem, /* sq_item, x[i] */
|
||||
(intintargfunc) 0, /* sq_slice, x[i:j] */
|
||||
(intobjargproc) 0, /* sq_ass_item, x[i]=v */
|
||||
(intintobjargproc) 0, /* sq_ass_slice, x[i:j]=v */
|
||||
(PyIntArgFunc) 0, /* sq_repeat, x*n */
|
||||
(PyIntArgFunc) WinListItem, /* sq_item, x[i] */
|
||||
(PyIntIntArgFunc) 0, /* sq_slice, x[i:j] */
|
||||
(PyIntObjArgProc) 0, /* sq_ass_item, x[i]=v */
|
||||
(PyIntIntObjArgProc) 0, /* sq_ass_slice, x[i:j]=v */
|
||||
};
|
||||
|
||||
static PyTypeObject WinListType = {
|
||||
@@ -2154,7 +2182,7 @@ static PyTypeObject WinListType = {
|
||||
/* Window list object - Implementation
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
static PyInt
|
||||
WinListLength(PyObject *self)
|
||||
{
|
||||
win_T *w = firstwin;
|
||||
@@ -2171,7 +2199,7 @@ WinListLength(PyObject *self)
|
||||
|
||||
/*ARGSUSED*/
|
||||
static PyObject *
|
||||
WinListItem(PyObject *self, int n)
|
||||
WinListItem(PyObject *self, PyInt n)
|
||||
{
|
||||
win_T *w;
|
||||
|
||||
@@ -2351,10 +2379,10 @@ GetBufferLine(buf_T *buf, int n)
|
||||
* including, hi. The list is returned as a Python list of string objects.
|
||||
*/
|
||||
static PyObject *
|
||||
GetBufferLineList(buf_T *buf, int lo, int hi)
|
||||
GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
|
||||
{
|
||||
int i;
|
||||
int n = hi - lo;
|
||||
PyInt i;
|
||||
PyInt n = hi - lo;
|
||||
PyObject *list = PyList_New(n);
|
||||
|
||||
if (list == NULL)
|
||||
@@ -2517,7 +2545,7 @@ SetBufferLine(buf_T *buf, int n, PyObject *line, int *len_change)
|
||||
* is set to the change in the buffer length.
|
||||
*/
|
||||
static int
|
||||
SetBufferLineList(buf_T *buf, int lo, int hi, PyObject *list, int *len_change)
|
||||
SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, int *len_change)
|
||||
{
|
||||
/* First of all, we check the thpe of the supplied Python object.
|
||||
* There are three cases:
|
||||
@@ -2527,8 +2555,8 @@ SetBufferLineList(buf_T *buf, int lo, int hi, PyObject *list, int *len_change)
|
||||
*/
|
||||
if (list == Py_None || list == NULL)
|
||||
{
|
||||
int i;
|
||||
int n = hi - lo;
|
||||
PyInt i;
|
||||
PyInt n = hi - lo;
|
||||
buf_T *savebuf = curbuf;
|
||||
|
||||
PyErr_Clear();
|
||||
@@ -2564,9 +2592,9 @@ SetBufferLineList(buf_T *buf, int lo, int hi, PyObject *list, int *len_change)
|
||||
}
|
||||
else if (PyList_Check(list))
|
||||
{
|
||||
int i;
|
||||
int new_len = PyList_Size(list);
|
||||
int old_len = hi - lo;
|
||||
PyInt i;
|
||||
PyInt new_len = PyList_Size(list);
|
||||
PyInt old_len = hi - lo;
|
||||
int extra = 0; /* lines added to text, can be negative */
|
||||
char **array;
|
||||
buf_T *savebuf;
|
||||
@@ -2745,8 +2773,8 @@ InsertBufferLines(buf_T *buf, int n, PyObject *lines, int *len_change)
|
||||
}
|
||||
else if (PyList_Check(lines))
|
||||
{
|
||||
int i;
|
||||
int size = PyList_Size(lines);
|
||||
PyInt i;
|
||||
PyInt size = PyList_Size(lines);
|
||||
char **array;
|
||||
buf_T *savebuf;
|
||||
|
||||
@@ -2831,7 +2859,7 @@ InsertBufferLines(buf_T *buf, int n, PyObject *lines, int *len_change)
|
||||
LineToString(const char *str)
|
||||
{
|
||||
PyObject *result;
|
||||
int len = strlen(str);
|
||||
PyInt len = strlen(str);
|
||||
char *p;
|
||||
|
||||
/* Allocate an Python string object, with uninitialised contents. We
|
||||
@@ -2871,8 +2899,8 @@ StringToLine(PyObject *obj)
|
||||
{
|
||||
const char *str;
|
||||
char *save;
|
||||
int len;
|
||||
int i;
|
||||
PyInt len;
|
||||
PyInt i;
|
||||
char *p;
|
||||
|
||||
if (obj == NULL || !PyString_Check(obj))
|
||||
|
||||
+9
-6
@@ -1973,8 +1973,10 @@ utf_class(c)
|
||||
{0x205f, 0x205f, 0},
|
||||
{0x2060, 0x27ff, 1}, /* punctuation and symbols */
|
||||
{0x2070, 0x207f, 0x2070}, /* superscript */
|
||||
{0x2080, 0x208f, 0x2080}, /* subscript */
|
||||
{0x2983, 0x2998, 1},
|
||||
{0x2080, 0x2094, 0x2080}, /* subscript */
|
||||
{0x20a0, 0x27ff, 1}, /* all kinds of symbols */
|
||||
{0x2800, 0x28ff, 0x2800}, /* braille */
|
||||
{0x2900, 0x2998, 1}, /* arrows, brackets, etc. */
|
||||
{0x29d8, 0x29db, 1},
|
||||
{0x29fc, 0x29fd, 1},
|
||||
{0x3000, 0x3000, 0}, /* ideographic space */
|
||||
@@ -5518,13 +5520,13 @@ preedit_callback_setup(GdkIC *ic)
|
||||
preedit_caret_cb.callback = (XIMProc)preedit_caret_cbproc;
|
||||
preedit_done_cb.callback = (XIMProc)preedit_done_cbproc;
|
||||
preedit_attr
|
||||
= XVaCreateNestedList (0,
|
||||
= XVaCreateNestedList(0,
|
||||
XNPreeditStartCallback, &preedit_start_cb,
|
||||
XNPreeditDrawCallback, &preedit_draw_cb,
|
||||
XNPreeditCaretCallback, &preedit_caret_cb,
|
||||
XNPreeditDoneCallback, &preedit_done_cb,
|
||||
0);
|
||||
XSetICValues (xxic, XNPreeditAttributes, preedit_attr, 0);
|
||||
NULL);
|
||||
XSetICValues(xxic, XNPreeditAttributes, preedit_attr, NULL);
|
||||
XFree(preedit_attr);
|
||||
}
|
||||
|
||||
@@ -5534,7 +5536,8 @@ reset_state_setup(GdkIC *ic)
|
||||
{
|
||||
#ifdef USE_X11R6_XIM
|
||||
/* don't change the input context when we call reset */
|
||||
XSetICValues(((GdkICPrivate*)ic)->xic, XNResetState, XIMPreserveState, 0);
|
||||
XSetICValues(((GdkICPrivate *)ic)->xic, XNResetState, XIMPreserveState,
|
||||
NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+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 */
|
||||
|
||||
|
||||
+20
-2
@@ -16,6 +16,10 @@
|
||||
* See ":help netbeans-protocol" for explanation.
|
||||
*/
|
||||
|
||||
#if defined(MSDOS) || defined(MSWIN)
|
||||
# include "vimio.h" /* for mch_open(), must be before vim.h */
|
||||
#endif
|
||||
|
||||
#include "vim.h"
|
||||
|
||||
#if defined(FEAT_NETBEANS_INTG) || defined(PROTO)
|
||||
@@ -1974,13 +1978,16 @@ nb_do_cmd(
|
||||
}
|
||||
else if (streq((char *)cmd, "setModified"))
|
||||
{
|
||||
int prev_b_changed;
|
||||
|
||||
if (buf == NULL || buf->bufp == NULL)
|
||||
{
|
||||
/* EMSG("E646: null bufp in setModified"); */
|
||||
return FAIL;
|
||||
}
|
||||
prev_b_changed = buf->bufp->b_changed;
|
||||
if (streq((char *)args, "T"))
|
||||
buf->bufp->b_changed = 1;
|
||||
buf->bufp->b_changed = TRUE;
|
||||
else
|
||||
{
|
||||
struct stat st;
|
||||
@@ -1990,9 +1997,20 @@ nb_do_cmd(
|
||||
if (buf->bufp->b_ffname != NULL
|
||||
&& mch_stat((char *)buf->bufp->b_ffname, &st) >= 0)
|
||||
buf_store_time(buf->bufp, &st, buf->bufp->b_ffname);
|
||||
buf->bufp->b_changed = 0;
|
||||
buf->bufp->b_changed = FALSE;
|
||||
}
|
||||
buf->modified = buf->bufp->b_changed;
|
||||
if (prev_b_changed != buf->bufp->b_changed)
|
||||
{
|
||||
#ifdef FEAT_WINDOWS
|
||||
check_status(buf->bufp);
|
||||
redraw_tabline = TRUE;
|
||||
#endif
|
||||
#ifdef FEAT_TITLE
|
||||
maketitle();
|
||||
#endif
|
||||
update_screen(0);
|
||||
}
|
||||
/* =====================================================================*/
|
||||
}
|
||||
else if (streq((char *)cmd, "setModtime"))
|
||||
|
||||
+3
-2
@@ -243,7 +243,8 @@
|
||||
/* WV_ and BV_ values get typecasted to this for the "indir" field */
|
||||
typedef enum
|
||||
{
|
||||
PV_NONE = 0
|
||||
PV_NONE = 0,
|
||||
PV_MAXVAL = 0xffff /* to avoid warnings for value out of range */
|
||||
} idopt_T;
|
||||
|
||||
/*
|
||||
@@ -8828,7 +8829,7 @@ put_setstring(fd, cmd, name, valuep, expand)
|
||||
{
|
||||
s = *valuep;
|
||||
while (*s != NUL)
|
||||
if (fputs((char *)str2special(&s, FALSE), fd) < 0)
|
||||
if (put_escstr(fd, str2special(&s, FALSE), 2) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
else if (expand)
|
||||
|
||||
+17
-2
@@ -1,7 +1,8 @@
|
||||
" Vim script for checking .po files.
|
||||
"
|
||||
" Go through the file and verify that all %...s items in "msgid" are identical
|
||||
" to the ones in "msgstr".
|
||||
" Go through the file and verify that:
|
||||
" - All %...s items in "msgid" are identical to the ones in "msgstr".
|
||||
" - An error or warning code in "msgid" matches the one in "msgstr".
|
||||
|
||||
if 1 " Only execute this if the eval feature is available.
|
||||
|
||||
@@ -56,6 +57,20 @@ while 1
|
||||
endif
|
||||
endwhile
|
||||
|
||||
" Check that error code in msgid matches the one in msgstr.
|
||||
"
|
||||
" Examples of mismatches found with msgid "E123: ..."
|
||||
" - msgstr "E321: ..." error code mismatch
|
||||
" - msgstr "W123: ..." warning instead of error
|
||||
" - msgstr "E123 ..." missing colon
|
||||
" - msgstr "..." missing error code
|
||||
"
|
||||
1
|
||||
if search('msgid "\("\n"\)\?\([EW][0-9]\+:\).*\nmsgstr "\("\n"\)\?[^"]\@=\2\@!') > 0
|
||||
echo 'Mismatching error/warning code in line ' . line('.')
|
||||
let error = 1
|
||||
endif
|
||||
|
||||
if error == 0
|
||||
echo "OK"
|
||||
endif
|
||||
|
||||
@@ -24,6 +24,7 @@ char_u *ExpandOne __ARGS((expand_T *xp, char_u *str, char_u *orig, int options,
|
||||
void ExpandInit __ARGS((expand_T *xp));
|
||||
void ExpandCleanup __ARGS((expand_T *xp));
|
||||
void ExpandEscape __ARGS((expand_T *xp, char_u *str, int numfiles, char_u **files, int options));
|
||||
char_u *vim_strsave_fnameescape __ARGS((char_u *fname, int shell));
|
||||
void tilde_replace __ARGS((char_u *orig_pat, int num_files, char_u **files));
|
||||
char_u *sm_gettail __ARGS((char_u *s));
|
||||
char_u *addstar __ARGS((char_u *fname, int len, int context));
|
||||
|
||||
@@ -124,7 +124,7 @@ gui_mch_haskey(char_u *name);
|
||||
void
|
||||
gui_mch_iconify(void);
|
||||
void
|
||||
gui_mch_invert_rectangle(int r, int c, int nr, int nc);
|
||||
gui_mch_invert_rectangle(int r, int c, int nr, int nc, int invert);
|
||||
void
|
||||
gui_mch_new_colors(void);
|
||||
void
|
||||
@@ -202,3 +202,4 @@ OSErr odb_post_buffer_write(buf_T *buf);
|
||||
void odb_end(void);
|
||||
|
||||
char_u *get_macaction_name(expand_T *xp, int idx);
|
||||
int is_valid_macaction(char_u *action);
|
||||
|
||||
@@ -20,6 +20,7 @@ void ex_emenu __ARGS((exarg_T *eap));
|
||||
vimmenu_T *gui_find_menu __ARGS((char_u *path_name));
|
||||
void ex_menutranslate __ARGS((exarg_T *eap));
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
void ex_macmenu __ARGS((exarg_T *eap));
|
||||
void ex_macmenukey __ARGS((exarg_T *eap));
|
||||
#endif
|
||||
/* vim: set ft=c : */
|
||||
|
||||
@@ -9357,6 +9357,11 @@ showruler(always)
|
||||
)
|
||||
maketitle();
|
||||
#endif
|
||||
#ifdef FEAT_WINDOWS
|
||||
/* Redraw the tab pages line if needed. */
|
||||
if (redraw_tabline)
|
||||
draw_tabline();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FEAT_CMDL_INFO
|
||||
|
||||
+5
-3
@@ -2254,9 +2254,11 @@ struct VimMenu
|
||||
PtWidget_t *submenu_id;
|
||||
#endif
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
int mac_key; /* Key equivalent */
|
||||
int mac_mods; /* Modifier flags for the above */
|
||||
int was_grey; /* Remember last 'grey' state */
|
||||
char_u *mac_action; /* Action this menu sends */
|
||||
int mac_key; /* Key equivalent */
|
||||
int mac_mods; /* Modifier flags for the above */
|
||||
int mac_alternate; /* Item is alternate of previous item */
|
||||
int was_grey; /* Remember last 'grey' state */
|
||||
#endif
|
||||
};
|
||||
#else
|
||||
|
||||
@@ -1126,7 +1126,11 @@ clip_invert_rectangle(row, col, height, width, invert)
|
||||
{
|
||||
#ifdef FEAT_GUI
|
||||
if (gui.in_use)
|
||||
# ifdef FEAT_GUI_MACVIM
|
||||
gui_mch_invert_rectangle(row, col, height, width, invert);
|
||||
# else
|
||||
gui_mch_invert_rectangle(row, col, height, width);
|
||||
#endif
|
||||
else
|
||||
#endif
|
||||
screen_draw_rectangle(row, col, height, width, invert);
|
||||
|
||||
@@ -681,6 +681,40 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
314,
|
||||
/**/
|
||||
313,
|
||||
/**/
|
||||
312,
|
||||
/**/
|
||||
311,
|
||||
/**/
|
||||
310,
|
||||
/**/
|
||||
309,
|
||||
/**/
|
||||
308,
|
||||
/**/
|
||||
307,
|
||||
/**/
|
||||
306,
|
||||
/**/
|
||||
305,
|
||||
/**/
|
||||
304,
|
||||
/**/
|
||||
303,
|
||||
/**/
|
||||
302,
|
||||
/**/
|
||||
301,
|
||||
/**/
|
||||
300,
|
||||
/**/
|
||||
299,
|
||||
/**/
|
||||
298,
|
||||
/**/
|
||||
297,
|
||||
/**/
|
||||
|
||||
@@ -337,10 +337,10 @@
|
||||
# endif
|
||||
#endif
|
||||
#ifdef BACKSLASH_IN_FILENAME
|
||||
# define PATH_ESC_CHARS ((char_u *)" \t*?[{`%#")
|
||||
# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`%#'\"|!<")
|
||||
#else
|
||||
# define PATH_ESC_CHARS ((char_u *)" \t*?[{`$\\%#'\"|")
|
||||
# define SHELL_ESC_CHARS ((char_u *)" \t*?[{`$\\%#'\"|<>();&!")
|
||||
# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<")
|
||||
# define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&")
|
||||
#endif
|
||||
|
||||
#define NUMBUFLEN 30 /* length of a buffer to store a number in ASCII */
|
||||
|
||||
Reference in New Issue
Block a user