mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-02 11:19:22 +02:00
Compare commits
257 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 393e47945b | |||
| 5100db4427 | |||
| 19ee857237 | |||
| 781ac5b687 | |||
| 9b52c915d9 | |||
| 7a68824771 | |||
| c2aed127ca | |||
| 12b3ecfdcd | |||
| 4143f69655 | |||
| 7a720947c8 | |||
| 9393a4151c | |||
| 95a678d204 | |||
| 68cec2f91b | |||
| 5ed292ebfb | |||
| 6d70e1a179 | |||
| 355d2ec231 | |||
| c6ceb6c969 | |||
| 60c1c58967 | |||
| ba43ddb524 | |||
| 2a032c05b7 | |||
| 8d8aecf662 | |||
| 380d7b2cbf | |||
| 30a12fc740 | |||
| 43050b40f8 | |||
| d5dfed9cfc | |||
| 0e2e98e570 | |||
| d0a875e3af | |||
| b770256474 | |||
| e14b8cd599 | |||
| 938149499b | |||
| 9245af7148 | |||
| a874eae869 | |||
| cca95bae41 | |||
| 243fcce65c | |||
| b8c8a68a5c | |||
| 8502d5f2b2 | |||
| da857362b0 | |||
| 4c50d72cdf | |||
| 9af39a7cb2 | |||
| d4038f59f4 | |||
| 9150d82be1 | |||
| 87694dc1bf | |||
| 22704e2bb4 | |||
| 95676cfcd4 | |||
| 1e901456a5 | |||
| 899f9a6260 | |||
| 6b989afdb1 | |||
| 4f48c32bc3 | |||
| c2ea4b240d | |||
| f81158c840 | |||
| 3950b3a6b1 | |||
| ae65cb89b3 | |||
| f90e3c31ab | |||
| 014700ca55 | |||
| f86423097b | |||
| a4cdb9b1c4 | |||
| 03a1a0ea74 | |||
| 4e1a1cad93 | |||
| e4abcd6741 | |||
| b0f34cac04 | |||
| dd243c8ab1 | |||
| 02592cfe41 | |||
| e706fca4d6 | |||
| 8d00a30b0a | |||
| 76200b7c03 | |||
| e648d3b011 | |||
| 1db4b7903b | |||
| e5e129b933 | |||
| 354968a9b9 | |||
| 87e4ef758b | |||
| 2b721c9e9c | |||
| c50143db47 | |||
| 2153ab22d7 | |||
| aefc975f1b | |||
| 79851d47b1 | |||
| 2c9f69f2bf | |||
| 9dc3e9172c | |||
| 2e69b16f67 | |||
| 462fb78a85 | |||
| d2dbd62e7b | |||
| e1c4adc8c9 | |||
| 2ffc552c25 | |||
| 7845992803 | |||
| 3142e74a3a | |||
| 1eb73428b0 | |||
| c5b2d1b5b4 | |||
| 2ab7e98bb8 | |||
| ebf311d2df | |||
| 88d6d362c3 | |||
| daf5b3430a | |||
| b13dede64d | |||
| bd1000809d | |||
| 2614f8ee3e | |||
| dd3577db8c | |||
| ff92260a55 | |||
| 90c9bf33a2 | |||
| 8f0b9d6525 | |||
| b9eb197443 | |||
| a61f1bf714 | |||
| c7323339d9 | |||
| 48fc2be299 | |||
| a5be20ba89 | |||
| 48874c704b | |||
| b8d2ad693a | |||
| d11de6c31d | |||
| 4c5d17ec00 | |||
| 34207703d8 | |||
| 8ff21dbb7c | |||
| 1cd2bd4a21 | |||
| 32561e2742 | |||
| fe0e293cb9 | |||
| dcaf01ff54 | |||
| adac29fc57 | |||
| 341e36b48d | |||
| 7b26c6980f | |||
| 668c778621 | |||
| 279e83bccc | |||
| c1a71eedb5 | |||
| 4dea3b30d0 | |||
| 05b47ac89e | |||
| 3965aefc79 | |||
| be089b8aa0 | |||
| 7aab071854 | |||
| cff1a9e3c9 | |||
| 7d03b73992 | |||
| 213d223679 | |||
| f00a001406 | |||
| 7ae32a1bef | |||
| 62b5aae721 | |||
| 1741da563b | |||
| c3239dd5e5 | |||
| 09eb973f44 | |||
| 1dfdf3ebaa | |||
| d50de2f2f0 | |||
| 233164a7d2 | |||
| ae96eb8469 | |||
| d676af07ec | |||
| 73827e6e15 | |||
| 8420566635 | |||
| e4c49238bd | |||
| 616f845128 | |||
| 09c7a21e4f | |||
| 9e75f31ff2 | |||
| 950ef8ff2f | |||
| 915d2e30ac | |||
| 6319b9c517 | |||
| 0dde2b7232 | |||
| 5d900f6f7e | |||
| 6907698f60 | |||
| ce49edcc1e | |||
| 911a34fed0 | |||
| a57ecd4e2e | |||
| 81a5c6dd4e | |||
| a53e7167fc | |||
| 6cf044c8fc | |||
| d0645670b5 | |||
| 3157d8636c | |||
| 8bb0169bd0 | |||
| 00d911af72 | |||
| 1111099ec1 | |||
| 9b4580c4dc | |||
| e63ff36e87 | |||
| 198610ad25 | |||
| a57332a176 | |||
| 9bd6777571 | |||
| aee4e6d6ca | |||
| 7112e2b5f7 | |||
| f9064e4c16 | |||
| 69c156faf4 | |||
| dd74c0b520 | |||
| f6ecb9aae9 | |||
| bc82e6d58e | |||
| 667279dbca | |||
| 331a21d0bd | |||
| 2cccddd458 | |||
| 49a52f9eff | |||
| f231eff6c2 | |||
| 3a8ce4e72c | |||
| 52f08cc6aa | |||
| 1a91b2a5c9 | |||
| 467b890d13 | |||
| fa6eedf24f | |||
| 0b546f60b1 | |||
| 1957b370bb | |||
| 275fc44523 | |||
| ee1fd606dd | |||
| ac3900639d | |||
| aa3ac2d303 | |||
| e84420f7d1 | |||
| 678ceed917 | |||
| f3c411fafe | |||
| 1506bb79d9 | |||
| d366864ff5 | |||
| 69742a596f | |||
| 3d2d6a810e | |||
| 6fb7a6f38b | |||
| cf7a0a71bd | |||
| 6e1e046cbb | |||
| 2d1fc65b0e | |||
| e378d7332b | |||
| 4879bdfc5e | |||
| 52bb6e960f | |||
| 0b018a5836 | |||
| ae2eb1cf48 | |||
| 597590c414 | |||
| 2a70805ffb | |||
| 86ae8db7d6 | |||
| dc9008674b | |||
| 99b9fe4a6d | |||
| 1d73dbfbe5 | |||
| 7d9d31e97d | |||
| 8bc680dd63 | |||
| 5da159c4eb | |||
| def2d1a9e4 | |||
| bdb7f8efa6 | |||
| db0d1f51a5 | |||
| 6b4059f69d | |||
| 232024f71d | |||
| d732c28bfc | |||
| e5bae4cb22 | |||
| bb36e94f24 | |||
| 2e22c44eab | |||
| f6f6f2c8f8 | |||
| ad6fe811e7 | |||
| deaae7e717 | |||
| e52ae8cbc0 | |||
| 8e7466bccc | |||
| 4100056f46 | |||
| df35270598 | |||
| b2e17cca75 | |||
| e25a17541d | |||
| e76375a3e9 | |||
| ea83ab3650 | |||
| c53513d4ac | |||
| 06c64fe88c | |||
| b39b209d02 | |||
| 3e5bc79f11 | |||
| 96e61949b3 | |||
| ce613d4671 | |||
| b2e259fb62 | |||
| 28132658b2 | |||
| 92ed496e29 | |||
| 91ed612ac0 | |||
| cec4f8b9ee | |||
| 22799739f5 | |||
| 053d76dc13 | |||
| 38a0fd10d1 | |||
| 325a3db78d | |||
| 27c683092d | |||
| 0b896e4f59 | |||
| 6fcd21f338 | |||
| 316034e1db | |||
| dd46cfc500 | |||
| 28c43bdc64 | |||
| 97b5e3c119 | |||
| 17f08c9776 | |||
| 9e2f853d00 |
+10
@@ -3,6 +3,16 @@
|
||||
src/MacVim/MacVim.xcodeproj/*.mode1
|
||||
src/MacVim/MacVim.xcodeproj/*.mode1v3
|
||||
src/MacVim/MacVim.xcodeproj/*.pbxuser
|
||||
src/MacVim/icons/*.pyc
|
||||
src/MacVim/icons/*.ttf
|
||||
src/MacVim/icons/*.reg
|
||||
src/MacVim/icons/*.zip
|
||||
src/MacVim/icons/*.txt
|
||||
src/MacVim/icons/*.so
|
||||
src/MacVim/icons/*.egg-info
|
||||
src/MacVim/icons/build
|
||||
src/MacVim/icons/makeicns/*.o
|
||||
src/MacVim/icons/makeicns/makeicns
|
||||
src/MacVim/PSMTabBarControl/PSMTabBarControl.xcodeproj/*.mode1
|
||||
src/MacVim/PSMTabBarControl/PSMTabBarControl.xcodeproj/*.pbxuser
|
||||
src/MacVim/PSMTabBarControl/build
|
||||
|
||||
@@ -285,6 +285,7 @@ SRC_DOS = \
|
||||
src/proto/os_win32.pro \
|
||||
src/proto/os_mswin.pro \
|
||||
src/testdir/Make_dos.mak \
|
||||
src/testdir/Make_ming.mak \
|
||||
src/testdir/dos.vim \
|
||||
src/uninstal.c \
|
||||
src/vim.def \
|
||||
|
||||
@@ -806,13 +806,13 @@ This replaces each 'E' character with a euro sign. Read more in |<Char->|.
|
||||
:promptf[ind] [string]
|
||||
Put up a Search dialog. When [string] is given, it is
|
||||
used as the initial search string.
|
||||
{only for Win32, Motif and GTK GUI}
|
||||
{only for Win32, Motif, GTK and MacVim GUI}
|
||||
|
||||
*:promptr* *:promptrepl*
|
||||
:promptr[epl] [string]
|
||||
Put up a Search/Replace dialog. When [string] is
|
||||
given, it is used as the initial search string.
|
||||
{only for Win32, Motif and GTK GUI}
|
||||
{only for Win32, Motif, GTK and MacVim GUI}
|
||||
|
||||
|
||||
4.4 Changing tabs *change-tabs*
|
||||
|
||||
+24
-9
@@ -1,4 +1,4 @@
|
||||
*cmdline.txt* For Vim version 7.2. Last change: 2008 Jul 29
|
||||
*cmdline.txt* For Vim version 7.2. Last change: 2008 Sep 18
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -157,6 +157,11 @@ CTRL-R {0-9a-z"%#:-=.} *c_CTRL-R* *c_<C-R>*
|
||||
(doesn't work at the expression prompt; some
|
||||
things such as changing the buffer or current
|
||||
window are not allowed to avoid side effects)
|
||||
When the result is a |List| the items are used
|
||||
as lines. They can have line breaks inside
|
||||
too.
|
||||
When the result is a Float it's automatically
|
||||
converted to a String.
|
||||
See |registers| about registers. {not in Vi}
|
||||
Implementation detail: When using the |expression| register
|
||||
and invoking setcmdpos(), this sets the position before
|
||||
@@ -730,19 +735,29 @@ to use |fnameescape()|.
|
||||
In Ex commands, at places where a file name can be used, the following
|
||||
characters have a special meaning. These can also be used in the expression
|
||||
function expand() |expand()|.
|
||||
% is replaced with the current file name *:_%*
|
||||
# is replaced with the alternate file name *:_#*
|
||||
% Is replaced with the current file name. *:_%* *c_%*
|
||||
# Is replaced with the alternate file name. *:_#* *c_#*
|
||||
#n (where n is a number) is replaced with the file name of
|
||||
buffer n. "#0" is the same as "#"
|
||||
## is replaced with all names in the argument list *:_##*
|
||||
buffer n. "#0" is the same as "#".
|
||||
## Is replaced with all names in the argument list *:_##* *c_##*
|
||||
concatenated, separated by spaces. Each space in a name
|
||||
is preceded with a backslash.
|
||||
Note that these give the file name as it was typed. If an absolute path is
|
||||
needed (when using the file name from a different directory), you need to add
|
||||
":p". See |filename-modifiers|.
|
||||
#<n (where n is a number > 0) is replaced with old *:_#<* *c_#<*
|
||||
file name n. See |:oldfiles| or |v:oldfiles| to get the
|
||||
number. *E809*
|
||||
{only when compiled with the +eval and +viminfo features}
|
||||
|
||||
Note that these, except "#<n", give the file name as it was typed. If an
|
||||
absolute path is needed (when using the file name from a different directory),
|
||||
you need to add ":p". See |filename-modifiers|.
|
||||
|
||||
The "#<n" item returns an absolute path, but it will start with "~/" for files
|
||||
below your home directory.
|
||||
|
||||
Note that backslashes are inserted before spaces, so that the command will
|
||||
correctly interpret the file name. But this doesn't happen for shell
|
||||
commands. For those you probably have to use quotes: >
|
||||
commands. For those you probably have to use quotes (this fails for files
|
||||
that contain a quote and wildcards): >
|
||||
:!ls "%"
|
||||
:r !spell "%"
|
||||
|
||||
|
||||
+33
-14
@@ -1,4 +1,4 @@
|
||||
*eval.txt* For Vim version 7.2. Last change: 2008 Aug 09
|
||||
*eval.txt* For Vim version 7.2. Last change: 2008 Nov 27
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -1484,6 +1484,17 @@ v:mouse_col Column number for a mouse click obtained with |getchar()|.
|
||||
This is the screen column number, like with |virtcol()|. The
|
||||
value is zero when there was no mouse button click.
|
||||
|
||||
*v:oldfiles* *oldfiles-variable*
|
||||
v:oldfiles List of file names that is loaded from the |viminfo| file on
|
||||
startup. These are the files that Vim remembers marks for.
|
||||
The length of the List is limited by the ' argument of the
|
||||
'viminfo' option (default is 100).
|
||||
Also see |:oldfiles| and |c_#<|.
|
||||
The List can be modified, but this has no effect on what is
|
||||
stored in the |viminfo| file later. If you use values other
|
||||
than String this will cause trouble.
|
||||
{only when compiled with the +viminfo feature}
|
||||
|
||||
*v:operator* *operator-variable*
|
||||
v:operator The last operator given in Normal mode. This is a single
|
||||
character except for commands starting with <g> or <z>,
|
||||
@@ -1695,7 +1706,7 @@ executable( {expr}) Number 1 if executable {expr} exists
|
||||
exists( {expr}) Number TRUE if {expr} exists
|
||||
extend({expr1}, {expr2} [, {expr3}])
|
||||
List/Dict insert items of {expr2} into {expr1}
|
||||
expand( {expr}) String expand special keywords in {expr}
|
||||
expand( {expr} [, {flag}]) String expand special keywords in {expr}
|
||||
feedkeys( {string} [, {mode}]) Number add key sequence to typeahead buffer
|
||||
filereadable( {file}) Number TRUE if {file} is a readable file
|
||||
filewritable( {file}) Number TRUE if {file} is a writable file
|
||||
@@ -1747,8 +1758,9 @@ gettabwinvar( {tabnr}, {winnr}, {name})
|
||||
getwinposx() Number X coord in pixels of GUI Vim window
|
||||
getwinposy() Number Y coord in pixels of GUI Vim window
|
||||
getwinvar( {nr}, {varname}) any variable {varname} in window {nr}
|
||||
glob( {expr}) String expand file wildcards in {expr}
|
||||
globpath( {path}, {expr}) String do glob({expr}) for all dirs in {path}
|
||||
glob( {expr} [, {flag}]) String expand file wildcards in {expr}
|
||||
globpath( {path}, {expr} [, {flag}])
|
||||
String do glob({expr}) for all dirs in {path}
|
||||
has( {feature}) Number TRUE if feature {feature} supported
|
||||
has_key( {dict}, {key}) Number TRUE if {dict} has entry {key}
|
||||
haslocaldir() Number TRUE if current window executed |:lcd|
|
||||
@@ -3275,14 +3287,16 @@ getwinvar({winnr}, {varname}) *getwinvar()*
|
||||
:let list_is_on = getwinvar(2, '&list')
|
||||
:echo "myvar = " . getwinvar(1, 'myvar')
|
||||
<
|
||||
*glob()*
|
||||
glob({expr}) Expand the file wildcards in {expr}. See |wildcards| for the
|
||||
glob({expr} [, {flag}]) *glob()*
|
||||
Expand the file wildcards in {expr}. See |wildcards| for the
|
||||
use of special characters.
|
||||
The result is a String.
|
||||
When there are several matches, they are separated by <NL>
|
||||
characters.
|
||||
The 'wildignore' option applies: Names matching one of the
|
||||
patterns in 'wildignore' will be skipped.
|
||||
Unless the optional {flag} argument is given and is non-zero,
|
||||
the 'suffixes' and 'wildignore' options apply: Names matching
|
||||
one of the patterns in 'wildignore' will be skipped and
|
||||
'suffixes' affect the ordering of matches.
|
||||
If the expansion fails, the result is an empty string.
|
||||
A name for a non-existing file is not included.
|
||||
|
||||
@@ -3296,20 +3310,22 @@ glob({expr}) Expand the file wildcards in {expr}. See |wildcards| for the
|
||||
See |expand()| for expanding special Vim variables. See
|
||||
|system()| for getting the raw output of an external command.
|
||||
|
||||
globpath({path}, {expr}) *globpath()*
|
||||
globpath({path}, {expr} [, {flag}]) *globpath()*
|
||||
Perform glob() on all directories in {path} and concatenate
|
||||
the results. Example: >
|
||||
:echo globpath(&rtp, "syntax/c.vim")
|
||||
< {path} is a comma-separated list of directory names. Each
|
||||
directory name is prepended to {expr} and expanded like with
|
||||
glob(). A path separator is inserted when needed.
|
||||
|glob()|. A path separator is inserted when needed.
|
||||
To add a comma inside a directory name escape it with a
|
||||
backslash. Note that on MS-Windows a directory may have a
|
||||
trailing backslash, remove it if you put a comma after it.
|
||||
If the expansion fails for one of the directories, there is no
|
||||
error message.
|
||||
The 'wildignore' option applies: Names matching one of the
|
||||
patterns in 'wildignore' will be skipped.
|
||||
Unless the optional {flag} argument is given and is non-zero,
|
||||
the 'suffixes' and 'wildignore' options apply: Names matching
|
||||
one of the patterns in 'wildignore' will be skipped and
|
||||
'suffixes' affect the ordering of matches.
|
||||
|
||||
The "**" item can be used to search in a directory tree.
|
||||
For example, to find all "README.txt" files in the directories
|
||||
@@ -5332,10 +5348,12 @@ synIDattr({synID}, {what} [, {mode}]) *synIDattr()*
|
||||
"fg" foreground color (GUI: color name used to set
|
||||
the color, cterm: color number as a string,
|
||||
term: empty string)
|
||||
"bg" background color (like "fg")
|
||||
"bg" background color (as with "fg")
|
||||
"sp" special color (as with "fg") |highlight-guisp|
|
||||
"fg#" like "fg", but for the GUI and the GUI is
|
||||
running the name in "#RRGGBB" form
|
||||
"bg#" like "fg#" for "bg"
|
||||
"sp#" like "fg#" for "sp"
|
||||
"bold" "1" if bold
|
||||
"italic" "1" if italic
|
||||
"reverse" "1" if reverse
|
||||
@@ -5825,7 +5843,8 @@ mouse_netterm Compiled with support for netterm mouse.
|
||||
mouse_pterm Compiled with support for qnx pterm mouse.
|
||||
mouse_sysmouse Compiled with support for sysmouse (*BSD console mouse)
|
||||
mouse_xterm Compiled with support for xterm mouse.
|
||||
multi_byte Compiled with support for editing Korean et al.
|
||||
multi_byte Compiled with support for 'encoding'
|
||||
multi_byte_encoding 'encoding' is set to a multi-byte encoding.
|
||||
multi_byte_ime Compiled with support for IME input method.
|
||||
multi_lang Compiled with support for multiple languages.
|
||||
mzscheme Compiled with MzScheme interface |mzscheme|.
|
||||
|
||||
+213
-53
@@ -1,4 +1,4 @@
|
||||
*gui_mac.txt* For Vim version 7.2. Last change: 2008 Jul 12
|
||||
*gui_mac.txt* For Vim version 7.2. Last change: 2009 Jan 08
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bjorn Winckler
|
||||
@@ -15,12 +15,13 @@ The MacVim Graphical User Interface *macvim* *gui-macvim*
|
||||
6. Toolbar |macvim-toolbar|
|
||||
7. Dialogs |macvim-dialogs|
|
||||
8. System services |macvim-services|
|
||||
9. Known bugs/missing features |macvim-todo|
|
||||
10. Hints |macvim-hints|
|
||||
9. mvim:// URL handler |macvim-url-handler|
|
||||
10. Keyboard shortcuts |macvim-shortcuts|
|
||||
11. Known bugs/missing features |macvim-todo|
|
||||
12. Hints |macvim-hints|
|
||||
|
||||
Other relevant documentation:
|
||||
|gui.txt| For generic items of the GUI.
|
||||
|os_mac.txt| For Mac specific items.
|
||||
|
||||
{Vi does not have a GUI}
|
||||
|
||||
@@ -76,16 +77,6 @@ file at all. In this situation, you will need to set both 'encoding' and
|
||||
'fileencodings' to a simple single-byte encoding such as Latin1 so that when
|
||||
the file is read into memory, the original bytes are left untouched.
|
||||
|
||||
*macvim-movement*
|
||||
Some Mac OS X standard key mappings involving Cmd or Option and an arrow key
|
||||
are set up by default in "$VIM/gvimrc". You can quickly disable all of these
|
||||
by adding the following lines to your "~/.vimrc" (not .gvimrc) file: >
|
||||
if has("gui_macvim")
|
||||
let macvim_skip_cmd_opt_movement = 1
|
||||
endif
|
||||
Note: These are the only key mappings that MacVim makes (not counting menu key
|
||||
equivalents which are not set up with :map).
|
||||
|
||||
*macvim-shift-movement*
|
||||
Text editors on Mac OS X lets the user hold down shift+movement key to extend
|
||||
the selection. Also, pressing a printable key whilst selecting replaces the
|
||||
@@ -108,6 +99,10 @@ If a file is dropped on the Dock icon, it is always opened in a new tab
|
||||
regardless of the mode Vim is currently in. The same holds if you
|
||||
double-click on a file in the Finder.
|
||||
|
||||
The "Open files from applications" preference in the General preference pane
|
||||
gives more options on how dropped files should open, in case tabs are not
|
||||
desired.
|
||||
|
||||
*macvim-default-menu*
|
||||
The default menu in MacVim has been changed to conform better with the Apple
|
||||
Human Interface Guidelines (HIG). At the moment this breaks the localized
|
||||
@@ -124,7 +119,12 @@ strings like "((3) of 2)" to appear in the window title.
|
||||
|
||||
*macvim-options*
|
||||
These are the non-standard options that MacVim supports:
|
||||
'fullscreen' 'fuoptions' 'toolbariconsize' 'transparency' 'antialias'
|
||||
'antialias' 'fullscreen' 'fuoptions'
|
||||
'macmeta' 'toolbariconsize' 'transparency'
|
||||
|
||||
*macvim-commands*
|
||||
These are the non-standard commands that MacVim supports:
|
||||
|:macaction| |:macmenu|
|
||||
|
||||
*macvim-find*
|
||||
Whenever you search for something in Vim (e.g. using "/") the search query is
|
||||
@@ -161,8 +161,10 @@ formats. This enables you to double-click a file to open it with MacVim (if
|
||||
it is not associated with another program), or to right-click a file to bring
|
||||
up the "Open with" menu. You can also drag and drop files onto the Dock icon
|
||||
to open them in tabs in a new window, or you can drop them in an already open
|
||||
window to open the files in tabs in that specific window. Finally, you can
|
||||
use Mac OS X System Services to open files in MacVim, see |macvim-services|.
|
||||
window to open the files in tabs in that specific window (it is possible to
|
||||
have files open in e.g. splits by changing the "Open files from applications"
|
||||
option in the General preference pane). Finally, you can use Mac OS X System
|
||||
Services to open files in MacVim, see |macvim-services|.
|
||||
|
||||
There are essentially two ways to start MacVim from Terminal: either call the
|
||||
Vim binary with the -g switch >
|
||||
@@ -171,18 +173,19 @@ or use the "open" command (this method can not be used to pass parameters to
|
||||
Vim) >
|
||||
open -a MacVim file ...
|
||||
The advantage of using the latter method is that the settings relating to file
|
||||
opening in the preferences panel are respected, and files open significantly
|
||||
faster if preloading of Vim processes is enabled (i.e. if the user default
|
||||
MMPreloadCacheSize is positive, see |macvim-user-defaults|).
|
||||
opening in the preferences panel are respected, and files open instantly if
|
||||
|Quickstart| is enabled.
|
||||
|
||||
*mvim*
|
||||
To save yourself from having to type the entire path to the Vim binary each
|
||||
time you start MacVim, you could create an alias such as >
|
||||
alias gvim='/Applications/MacVim.app/Contents/MacOS/Vim -g'
|
||||
and add that to "~/.profile". A more flexible way to start MacVim is to use
|
||||
the shell script "mvim" which comes bundled with MacVim. Put this script in a
|
||||
folder in your path and then simply type "mvim" to start MacVim. This script
|
||||
will try to find MacVim.app in various typical folders such as >
|
||||
and add that to "~/.profile".
|
||||
|
||||
*mvim*
|
||||
A more flexible way to start MacVim is to use the shell script "mvim" which
|
||||
comes bundled with MacVim. Put this script in a folder in your path and then
|
||||
simply type "mvim" to start MacVim. This script will try to find MacVim.app
|
||||
in various typical folders such as >
|
||||
~/Applications ~/Applications/vim
|
||||
/Applications /Applications/vim
|
||||
/Applications/Utilities /Applications/Utilities/vim
|
||||
@@ -190,6 +193,17 @@ If you would rather put MacVim.app in some other directory then that is also
|
||||
possible, simply set the environment variable VIM_APP_DIR to whatever folder
|
||||
you have placed MacVim.app in.
|
||||
|
||||
The "mvim" script can be symlinked to in order to start up MacVim in different
|
||||
modes as follows (assuming you placed "mvim" in "/usr/local/bin"): >
|
||||
* Diff: ln -s /usr/local/bin/mvim mvimdiff
|
||||
* Read-only: ln -s /usr/local/bin/mvim mview
|
||||
* Ex: ln -s /usr/local/bin/mvim mex
|
||||
* Restricted: ln -s /usr/local/bin/mvim rmvim
|
||||
If the symlink destination starts with "m" (or "g"), Vim will start in GUI
|
||||
mode. Removing the initial "m" from the above destination names makes Vim
|
||||
start without the GUI. (In the last case, the destination name can be
|
||||
"rmvim", "rgvim" or "rvim".)
|
||||
|
||||
Note: Starting MacVim by creating a symlink to >
|
||||
.../MacVim.app/Contents/MacOS/Vim
|
||||
with 'ln -s' does not work.
|
||||
@@ -199,6 +213,20 @@ command:
|
||||
:gui [++opt] [+cmd] [-f|-b] [files...]
|
||||
Note: Forking ("-b") currently does not work.
|
||||
|
||||
*Quickstart*
|
||||
Quickstart ensures that new windows open instantaneously e.g. when <D-n> is
|
||||
pressed. This feature can be enabled from the Advanced preferences pane (it
|
||||
is disabled by default). Note that this setting does not affect the speed
|
||||
with which windows open when using the |mvim| command.
|
||||
|
||||
The main reason why this feature is not enabled by default is because on OS X
|
||||
10.4 changes to runtime files (e.g. those in "~/.vim") are not detected. For
|
||||
example, if you install a new plugin and then press <D-n> to open a new
|
||||
window, then that first window will not notice the plugin (but any consecutive
|
||||
windows after the first one will). On OS X 10.5 and later all modifications
|
||||
to runtime files in "~/.vim" are detected, so unless you keep runtime files in
|
||||
another folder there should be no problems.
|
||||
|
||||
*odbeditor* *external-editor*
|
||||
MacVim can act as an 'external editor' for Mac OS X applications that support
|
||||
the ODB Editor Protocol (or the 'external editor' protocol). Each application
|
||||
@@ -230,13 +258,13 @@ as general information regarding Mac OS X user defaults.
|
||||
Here is a list of relevant dictionary entries:
|
||||
|
||||
KEY VALUE ~
|
||||
MMAtsuiRenderer enable ATSUI renderer [bool]
|
||||
MMCellWidthMultiplier width of a normal glyph in em units [float]
|
||||
MMDialogsTrackPwd open/save dialogs track the Vim pwd [bool]
|
||||
MMLoadDefaultFont load font (disable for faster startup) [bool]
|
||||
MMLoginShellArgument login shell parameter [string]
|
||||
MMLoginShellCommand which shell to use to launch Vim [string]
|
||||
MMNoFontSubstitution disable automatic font substitution [bool]
|
||||
MMPreloadCacheSize number of Vim processes to preload [int]
|
||||
MMShowAddTabButton enable "add tab" button on tabline [bool]
|
||||
MMTabMaxWidth maximum width of a tab [int]
|
||||
MMTabMinWidth minimum width of a tab [int]
|
||||
MMTabOptimumWidth default width of a tab [int]
|
||||
@@ -262,7 +290,7 @@ Terminal and type: >
|
||||
Applications opened from the Finder do not automatically source the user's
|
||||
environment variables (which are typically set in .profile or .bashrc). This
|
||||
presents a problem when using |:!| to execute commands in the shell since e.g.
|
||||
$PATH might not be set properly. To work around this problem MacVim can start
|
||||
$PATH might not be set properly. To work around this problem MacVim starts
|
||||
new Vim processes via a login shell so that all environment variables are set.
|
||||
|
||||
By default MacVim uses the $SHELL environment variable to determine which
|
||||
@@ -351,7 +379,7 @@ can be used to send action messages.
|
||||
property list file called |Actions.plist|.
|
||||
|
||||
*:macm* *:macmenu*
|
||||
:mac[menu] {menu} {key}={arg} ...
|
||||
:macm[enu] {menu} {key}={arg} ...
|
||||
Set Mac specific properties for {menu}. The
|
||||
properties that can be set are:
|
||||
action the action this menu sends
|
||||
@@ -369,9 +397,11 @@ can be used to send action messages.
|
||||
":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.
|
||||
syntax. This is case-sensitive, so <D-a> means Cmd-a
|
||||
whereas <D-A> means Cmd-Shift-a.
|
||||
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
|
||||
@@ -395,7 +425,12 @@ equivalent Cmd-n, which opens a new window when selected: >
|
||||
: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>
|
||||
>
|
||||
4. Free up Cmd-t and remap it to open a file browser in a split view: >
|
||||
macm File.New\ Tab key=<nop>
|
||||
nmap <D-t> :sp .<CR>
|
||||
Note: These two lines must be added to .gvimrc else the first line will fail.
|
||||
The second line is case sensitive, so <D-T> (Cmd-Shift-t) is not the same as
|
||||
<D-t> (Cmd-t)!
|
||||
|
||||
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
|
||||
@@ -463,11 +498,12 @@ icon can be found a warning triangle is displayed instead.
|
||||
|
||||
Dialogs can be controlled with the keyboard in two ways. By default each
|
||||
button in a dialog is bound to a key. The button that is highlighted by blue
|
||||
is bound to Enter, and any button with the title "Cancel" is bound to Escape.
|
||||
Other buttons are usually bound to the first letter in the title of the
|
||||
button. There is no visual feedback to indicate which letter a button is
|
||||
bound to, so sometimes some experimentation might be required in order to
|
||||
figure out which key to press.
|
||||
is bound to Enter, any button with the title "Cancel" is bound to Escape, and
|
||||
any button with the title "Don't Save" is bound to <D-d>. Other buttons are
|
||||
usually bound to the first letter in the title of the button. There is no
|
||||
visual feedback to indicate which letter a button is bound to, so sometimes
|
||||
some experimentation might be required in order to figure out which key to
|
||||
press.
|
||||
|
||||
The second way of controlling dialogs with the keyboard is to enable "Full
|
||||
keyboard access" in the "Keyboard & Mouse" pane of the System Preferences (you
|
||||
@@ -485,20 +521,106 @@ located in the /Applications folder. (You might have to logout and then login
|
||||
again before Mac OS X detects the MacVim services.)
|
||||
|
||||
These are the currently supported services:
|
||||
* New Tab Containing Selection: Opens a new tab in the topmost window and
|
||||
pastes the currently selected text in that tab. A new window will be
|
||||
opened if necessary.
|
||||
* Open Selected File in Tab: If the selected text represents a file
|
||||
name, then the corresponding file is opened in a new tab in the topmost
|
||||
window.
|
||||
* Open Selected File in Window: Same as the above, but always open in a new
|
||||
window.
|
||||
* New Document Containing Selection: Open a new window and paste the
|
||||
currently selected text.
|
||||
* New Document Here: Open a new window and set the current directory
|
||||
to that of the selected text. This is intended to be used from a
|
||||
Finder window to open an empty document in the currently selected
|
||||
folder.
|
||||
* Open Selected File: If the selected text represents a file name,
|
||||
then the corresponding file is opened in a new window.
|
||||
|
||||
If new files are set to open in the current window (in the General preference
|
||||
pane) then the above services will also reuse the topmost window, instead of
|
||||
opening a new window.
|
||||
|
||||
==============================================================================
|
||||
9. Known bugs/missing features *macvim-todo*
|
||||
9. mvim:// URL handler *mvim://* *macvim-url-handler*
|
||||
|
||||
Here are some of the bigger bugs in MacVim. Of course there are others, but
|
||||
these are ones that are know and/or which were judged major.
|
||||
MacVim supports a custom URL handler for "mvim://" URLs. The handler is
|
||||
supposed to be compatible to TextMate's URL scheme as documented at
|
||||
http://blog.macromates.com/2007/the-textmate-url-scheme/.
|
||||
|
||||
Currently, this means that the format is >
|
||||
mvim://open?<arguments>
|
||||
where "arguments" can be:
|
||||
* url — the actual file to open (i.e. a file://... URL), if you leave
|
||||
out this argument, the frontmost document is implied
|
||||
* line — line number to go to (one based)
|
||||
* column — column number to go to (one based)
|
||||
|
||||
For example, the link >
|
||||
mvim://open?url=file:///etc/profile&line=20
|
||||
will open the file /etc/profile on line 20 when clicked in a web browser.
|
||||
|
||||
Note that url has to be a file:// url pointing to an existing local file.
|
||||
|
||||
==============================================================================
|
||||
10. Keyboard shortcuts *macvim-shortcuts*
|
||||
|
||||
Most keyboard shortcuts in MacVim are bound to menu items and can be
|
||||
discovered by looking through the menus (see |macvim-menus| on how to create
|
||||
your own menu shortcuts). The remaining shortcuts are listed here:
|
||||
|
||||
*Cmd-.* *<D-.>*
|
||||
Cmd-. Interrupt Vim. Unlike Ctrl-C which is sent as normal
|
||||
keyboard input (and hence has to be received and then
|
||||
interpreted) this sends a SIGINT signal to the Vim
|
||||
process. Use this shortcut if the Vim process appears
|
||||
to have locked up and is not responding to key presses.
|
||||
|
||||
*Cmd-`* *<D-`>*
|
||||
Cmd-` Cycle to the next window. On an American keyboard the
|
||||
`-key is located under the Esc-key. On European
|
||||
keyboards this key is often adjacent to the left
|
||||
Shift-key and it may be not even be marked with "`".
|
||||
|
||||
*Cmd-Left* *<D-Left>*
|
||||
Cmd-Left Move cursor to the beginning of the line
|
||||
(see |cmd-movement|).
|
||||
|
||||
*Cmd-Right* *<D-Right>*
|
||||
Cmd-Right Move cursor to the end of the line (see |cmd-movement|).
|
||||
|
||||
*Cmd-Up* *<D-Up>*
|
||||
Cmd-Up Move cursor to the first line (see |cmd-movement|).
|
||||
|
||||
*Cmd-Down* *<D-Down>*
|
||||
Cmd-Down Move cursor to the last line (see |cmd-movement|).
|
||||
|
||||
*Alt-Left* *<M-Left>*
|
||||
Alt-Left Move cursor to the beginning of the previous word
|
||||
(see |alt-movement|).
|
||||
|
||||
*Alt-Right* *<M-Right>*
|
||||
Alt-Right Move cursor to the beginning of the next word
|
||||
(see |alt-movement|).
|
||||
|
||||
*Alt-Up* *<M-Up>*
|
||||
Alt-Up Move cursor one paragraph forward (see |alt-movement|).
|
||||
|
||||
*Alt-Down* *<M-Down>*
|
||||
Alt-Down Move cursor to the previous paragraph
|
||||
(see |alt-movement|).
|
||||
|
||||
*cmd-movement* *alt-movement*
|
||||
The above mappings involving Cmd/Alt + arrow key are enabled by default in the
|
||||
system gvimrc file "$VIM/gvimrc". You can quickly disable all of these by
|
||||
adding the following lines to your "~/.vimrc" (not .gvimrc) file: >
|
||||
if has("gui_macvim")
|
||||
let macvim_skip_cmd_opt_movement = 1
|
||||
endif
|
||||
Note: These are the only key mappings that MacVim makes (not counting menu key
|
||||
equivalents which are not set up with :map).
|
||||
|
||||
See |macvim-shift-movement| if you want Shift to select text when used in
|
||||
conjunction with the above Cmd/Alt movement shortcuts.
|
||||
|
||||
==============================================================================
|
||||
11. Known bugs/missing features *macvim-todo*
|
||||
|
||||
This list is by no means exhaustive, it only enumerates some of the more
|
||||
prominent bugs/missing features.
|
||||
|
||||
- Localized menus are not supported. Choosing anything but "English" in the
|
||||
"International" pane of "System Prefences" may break the menus (and
|
||||
@@ -507,8 +629,9 @@ these are ones that are know and/or which were judged major.
|
||||
- Sometimes multibyte characters look "too wide", i.e. they overlap the
|
||||
following character. It might help to change 'ambiwidth', or override the
|
||||
automatic font substitution by setting 'guifontwide' manually.
|
||||
- Printing
|
||||
- No find/replace dialog
|
||||
- Printing. As a temporary solution <D-p> creates a PostScript file which is
|
||||
then opened in Preview where it may be printed.
|
||||
- The toolbar looks ugly and is not very useful.
|
||||
|
||||
If you find new bugs then add a new issue at http://code.google.com/p/macvim/
|
||||
or post your findings to the |vim_mac| mailing list. If you are missing
|
||||
@@ -517,7 +640,7 @@ might be simple to implement, but unless somebody asks for a particular
|
||||
feature then there is little incentive to add it.
|
||||
|
||||
==============================================================================
|
||||
10. Hints *macvim-hints*
|
||||
12. Hints *macvim-hints*
|
||||
|
||||
In this section some general (not necessarily MacVim specific) hints are
|
||||
given.
|
||||
@@ -551,7 +674,7 @@ See |macvim-shift-movement|.
|
||||
Scenario: ~
|
||||
You do not want MacVim to set up any key mappings.
|
||||
Solution: ~
|
||||
See |macvim-movement|.
|
||||
See |cmd-movement|.
|
||||
|
||||
Scenario: ~
|
||||
Enabling localized menus breaks the toolbar and the menus as well.
|
||||
@@ -584,6 +707,43 @@ If that helps, then you can permanently disable "matchparen" by adding the
|
||||
following line to your "~/.vimrc": >
|
||||
let loaded_matchparen=1
|
||||
<
|
||||
Scenario: ~
|
||||
You want to use MacVim as an editor for some external application.
|
||||
Solution: ~
|
||||
If the external application lets you set a program to execute then something
|
||||
like "mvim -f" might be all you need (the "-f" switch ensures that the "mvim"
|
||||
script returns only after you close the editor window, otherwise "mvim"
|
||||
returns immediately). If the external program honors the EDITOR environment
|
||||
variable (e.g Git does this) then you may get away by adding the following
|
||||
line to your "~/.profile": >
|
||||
export EDITOR='mvim -f'
|
||||
If you have not installed the "mvim" script in your path you can provide the
|
||||
path to the Vim binary instead. Thus, if "MacVim.app" resides in the
|
||||
Applications folder then you would use the following line: >
|
||||
export EDITOR='/Applications/MacVim.app/Contents/MacOS/Vim -g -f'
|
||||
|
||||
Scenario: ~
|
||||
You have set MacVim to open from an external program and when you finish
|
||||
editing (by closing the MacVim window) you want the external program to regain
|
||||
focus.
|
||||
Solution: ~
|
||||
Use the VimLeave autocommand to hide MacVim when the window closes: >
|
||||
au VimLeave * maca hide:
|
||||
Assuming your external program has a setting for which command to execute to
|
||||
bring up an editor, you would set that option to something like: >
|
||||
mvim -f -c "au VimLeave * maca hide:"
|
||||
(See the above Scenario for an explanation of the "-f" switch.)
|
||||
|
||||
Scenario: ~
|
||||
You would like to remap Caps Lock to Esc.
|
||||
Solution: ~
|
||||
The free app "PCKeyboardHack" can be used to remap Caps Lock. It is available
|
||||
as a free download from:
|
||||
http://www.pqrs.org/tekezo/macosx/keyremap4macbook/extra.html
|
||||
On some Apple keyboards the Caps Lock key doesn't immediately register and
|
||||
this makes Caps Lock "drop" key presses. To work around this problem go into
|
||||
the "Keyboard & Mouse" System Preference and remap Caps Lock to Ctrl first
|
||||
(click the "Modifier Keys..." button).
|
||||
|
||||
Scenario: ~
|
||||
You can't find the information on MacVim you thought should be in this manual
|
||||
|
||||
@@ -63,7 +63,8 @@ already running vim will never fork in MacVim.
|
||||
"gvim --nofork" does the same as "gvim -f".
|
||||
|
||||
If you want the GUI to run in the foreground always, include the 'f'
|
||||
flag in 'guioptions'. |-f|.
|
||||
flag in 'guioptions'. |-f|. MacVim does not support this flag in
|
||||
'guioptions'.
|
||||
|
||||
==============================================================================
|
||||
2. GUI Resources *gui-resources* *.Xdefaults*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*netbeans.txt* For Vim version 7.2. Last change: 2008 Jun 28
|
||||
*netbeans.txt* For Vim version 7.2. Last change: 2009 Jan 06
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Gordon Prieur et al.
|
||||
@@ -722,8 +722,10 @@ keyAtPos keyName lnum/col
|
||||
of the cursor.
|
||||
New in version 2.1.
|
||||
|
||||
killed A file was closed by the user. Only for files that have been
|
||||
assigned a number by the IDE.
|
||||
killed A file was deleted or wiped out by the user and the buffer
|
||||
annotations have been removed. The bufID number for this
|
||||
buffer has become invalid. Only for files that have been
|
||||
assigned a bufID number by the IDE.
|
||||
|
||||
newDotAndMark off off
|
||||
Reports the position of the cursor being at "off" bytes into
|
||||
|
||||
+32
-7
@@ -1,4 +1,4 @@
|
||||
*options.txt* For Vim version 7.2. Last change: 2008 Aug 06
|
||||
*options.txt* For Vim version 7.2. Last change: 2008 Nov 25
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -3081,6 +3081,15 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
See 'fuoptions' for how Vim resizes and colors the background when
|
||||
entering and leaving fullscreen mode.
|
||||
|
||||
Note: Setting 'fullscreen' usually changes the size of the Vim
|
||||
control. However, for technical reasons, 'lines' and 'columns' will
|
||||
currently only be updated when Vim runs its event loop. As a
|
||||
consequence, if you set 'fullscreen' and 'lines' or 'columns' in a
|
||||
Vim script file, you should always set 'fullscreen' after setting
|
||||
'lines' and 'columns', else 'lines' and 'columns' will be overwritten
|
||||
with the values 'fullscreen' sets after the script has been executed
|
||||
and the event loop is ran again.
|
||||
|
||||
XXX: Add fuenter/fuleave autocommands? You might want to display
|
||||
a NERDTree or a Tlist only in fullscreen for example. Then again, this
|
||||
could probably be in a sizechanged autocommand that triggers if the
|
||||
@@ -3481,6 +3490,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
foreground. |gui-fork|
|
||||
Note: Set this option in the vimrc file. The forking may have
|
||||
happened already when the |gvimrc| file is read.
|
||||
MacVim does not support this flag due to limitations with
|
||||
forking on Mac OS X.
|
||||
*'go-i'*
|
||||
'i' Use a Vim icon. For GTK with KDE it is used in the left-upper
|
||||
corner of the window. It's black&white on non-GTK, because of
|
||||
@@ -3499,7 +3510,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
Exception: Athena will always use grey menu items.
|
||||
*'go-t'*
|
||||
't' Include tearoff menu items. Currently only works for Win32,
|
||||
GTK+, and Motif 1.2 GUI.
|
||||
GTK+, MacVim, and Motif 1.2 GUI.
|
||||
*'go-T'*
|
||||
'T' Include Toolbar. Currently only in Win32, GTK+, Motif, Photon
|
||||
and Athena GUIs.
|
||||
@@ -3858,14 +3869,14 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
characters with dead keys.
|
||||
|
||||
*'imdisable'* *'imd'* *'nodisable'* *'noimd'*
|
||||
'imdisable' 'imd' boolean (default off, on for some systems (SGI))
|
||||
'imdisable' 'imd' boolean (default off, on for SGI and MacVim)
|
||||
global
|
||||
{not in Vi}
|
||||
{only available when compiled with the |+xim|
|
||||
|+multi_byte_ime| or |global-ime| feature}
|
||||
When set the Input Method is never used. This is useful to disable
|
||||
the IM when it doesn't work properly.
|
||||
Currently this option is on by default for SGI/IRIX machines. This
|
||||
Currently this option is on by default for SGI/IRIX and MacVim. This
|
||||
may change in later releases.
|
||||
|
||||
*'iminsert'* *'imi'*
|
||||
@@ -4484,6 +4495,18 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
'termencoding'.
|
||||
Note: MacVim does not use this option.
|
||||
|
||||
*'macmeta'* *'mmta'* *'nomacmeta'* *'nommta'*
|
||||
'macmeta' boolean (default off)
|
||||
local to buffer
|
||||
{only available in MacVim GUI}
|
||||
Use option (alt) as meta key. When on, option-key presses are not
|
||||
interpreted, thus enabling bindings to <M-..>. When off, option-key
|
||||
presses are interpreted by the selected input method and inserted as
|
||||
text.
|
||||
Note: Some keys (e.g. <M-F1>, <M-Tab>, <M-Return>, <M-Left>) can be
|
||||
bound with the Meta flag even when this option is disabled, but this
|
||||
is not the case for the majority of keys (e.g. <M-a>, <M-`>).
|
||||
|
||||
*'magic'* *'nomagic'*
|
||||
'magic' boolean (default on)
|
||||
global
|
||||
@@ -5430,7 +5453,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
<
|
||||
*'runtimepath'* *'rtp'* *vimfiles*
|
||||
'runtimepath' 'rtp' string (default:
|
||||
Unix: "$HOME/.vim,
|
||||
Unix, Mac OS X: "$HOME/.vim,
|
||||
$VIM/vimfiles,
|
||||
$VIMRUNTIME,
|
||||
$VIM/vimfiles/after,
|
||||
@@ -5445,7 +5468,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
$VIMRUNTIME,
|
||||
$VIM/vimfiles/after,
|
||||
$HOME/vimfiles/after"
|
||||
Macintosh: "$VIM:vimfiles,
|
||||
Macintosh (pre-OS X): "$VIM:vimfiles,
|
||||
$VIMRUNTIME,
|
||||
$VIM:vimfiles:after"
|
||||
RISC-OS: "Choices:vimfiles,
|
||||
@@ -7574,7 +7597,9 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
{not available when compiled without the |+wildignore|
|
||||
feature}
|
||||
A list of file patterns. A file that matches with one of these
|
||||
patterns is ignored when completing file or directory names.
|
||||
patterns is ignored when completing file or directory names, and
|
||||
influences the result of |expand()|, |glob()| and |globpath()| unless
|
||||
a flag is passed to disable this.
|
||||
The pattern is used like with |:autocmd|, see |autocmd-patterns|.
|
||||
Also see 'suffixes'.
|
||||
Example: >
|
||||
|
||||
+125
-4
@@ -1,4 +1,4 @@
|
||||
*os_vms.txt* For Vim version 7.2. Last change: 2006 Nov 18
|
||||
*os_vms.txt* For Vim version 7.2. Last change: 2008 Aug 19
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL
|
||||
@@ -312,7 +312,7 @@ features, it is worth to choose non GUI executables.
|
||||
|
||||
8. Useful notes *vms-notes*
|
||||
|
||||
8.1 backspace/delete
|
||||
8.1 Backspace/delete
|
||||
8.2 Filters
|
||||
8.3 VMS file version numbers
|
||||
8.4 Directory conversion
|
||||
@@ -326,8 +326,10 @@ features, it is worth to choose non GUI executables.
|
||||
8.12 diff-mode
|
||||
8.13 Allow '$' in C keywords
|
||||
8.14 VIMTUTOR for beginners
|
||||
8.15 Slow start in console mode issue
|
||||
8.16 Common VIM directory - different architectures
|
||||
|
||||
8.1 backspace/delete
|
||||
8.1 Backspace/delete
|
||||
|
||||
There are backspace/delete key inconsistencies with VMS.
|
||||
:fixdel doesn't do the trick, but the solution is: >
|
||||
@@ -663,12 +665,130 @@ start it with: >
|
||||
|
||||
(Thomas.R.Wyant III, Vim 6.1)
|
||||
|
||||
8.14 Slow start in console mode issue
|
||||
|
||||
As GUI/GTK Vim works equally well in console mode, many administartors
|
||||
deploy those executables system wide.
|
||||
Unfortunately, on a remote slow connections GUI/GTK executables behave rather
|
||||
slow when user wants to run Vim just in the console mode - because of X environment detection timeout.
|
||||
|
||||
Luckily, there is a simple solution for that. Administrators need to deploy
|
||||
both GUI/GTK build and just console build executables, like below: >
|
||||
|
||||
|- vim72
|
||||
|----- doc
|
||||
|----- syntax
|
||||
vimrc (system rc files)
|
||||
gvimrc
|
||||
gvim.exe (the remaned GUI or GTK built vim.exe)
|
||||
vim.exe (the console only executable)
|
||||
|
||||
Define system symbols like below in for ex in LOGIN.COM or SYLOGIN.COM: >
|
||||
|
||||
$ define/nolog VIM RF10:[UTIL.VIM72] ! where you VIM directory is
|
||||
$ vi*m :== mcr VIM:VIM.EXE
|
||||
$ gvi*m :== mcr VIM:GVIM.EXE
|
||||
$ ! or you can try to spawn with
|
||||
$ gv*im :== spawn/nowait/input=NLA0 mcr VIM:GVIM.EXE -g -GEOMETRY 80x40
|
||||
|
||||
|
||||
Like this, users that do not have X environment and want to use Vim just in
|
||||
console mode can avoid performance problems.
|
||||
|
||||
(Zoltan Arpadffy, Vim 7.2)
|
||||
|
||||
8.15 Common VIM directory - different architectures
|
||||
|
||||
In a cluster that contains nodes with different architectures like below:
|
||||
|
||||
$show cluster
|
||||
View of Cluster from system ID 11655 node: TOR 18-AUG-2008 11:58:31
|
||||
+---------------------------------+
|
||||
¦ SYSTEMS ¦ MEMBERS ¦
|
||||
+-----------------------+---------¦
|
||||
¦ NODE ¦ SOFTWARE ¦ STATUS ¦
|
||||
+--------+--------------+---------¦
|
||||
¦ TOR ¦ VMS V7.3-2 ¦ MEMBER ¦
|
||||
¦ TITAN2 ¦ VMS V8.3 ¦ MEMBER ¦
|
||||
¦ ODIN ¦ VMS V7.3-2 ¦ MEMBER ¦
|
||||
+---------------------------------+
|
||||
|
||||
It is convinient to have a common VIM directory but execute different
|
||||
executables.
|
||||
There are more solutions for this problem:
|
||||
|
||||
solution 1. all executables in the same directory with different names
|
||||
This is easily done with the following script that can be added
|
||||
to the login.com or sylogin.com: >
|
||||
|
||||
$ if f$getsyi("NODE_HWTYPE") .eqs. "VAX"
|
||||
$ then
|
||||
$ say "VAX platform"
|
||||
$ vi*m:== mcr vim:VIM.EXE_VAX
|
||||
$ endif
|
||||
$ if f$getsyi("NODE_HWTYPE") .eqs. "ALPH"
|
||||
$ then
|
||||
$ say "ALPHA platform"
|
||||
$ vi*m :== mcr vim:VIM.EXE_AXP
|
||||
$ endif
|
||||
$ if f$getsyi("ARCH_NAME") .eqs. "IA64"
|
||||
$ then
|
||||
$ say "IA64 platform"
|
||||
$ vi*m :== mcr vim:VIM.EXE_IA64
|
||||
$ endif
|
||||
|
||||
solution 2. different directories: >
|
||||
|
||||
$ if f$getsyi("NODE_HWTYPE") .eqs. "VAX"
|
||||
$ then
|
||||
$ say "VAX platform"
|
||||
$ define/nolog VIM RF10:[UTIL.VAX_EXE] ! VAX executables
|
||||
$ endif
|
||||
$ if f$getsyi("NODE_HWTYPE") .eqs. "ALPH"
|
||||
$ then
|
||||
$ say "ALPHA platform"
|
||||
$ define/nolog VIM RF10:[UTIL.AXP_EXE] ! AXP executables
|
||||
$ endif
|
||||
$ if f$getsyi("ARCH_NAME") .eqs. "IA64"
|
||||
$ then
|
||||
$ say "IA64 platform"
|
||||
$ define/nolog VIM RF10:[UTIL.IA64_EXE] ! IA64 executables
|
||||
$ endif
|
||||
$! VIMRUNTIME must be defined in order to find runtime files
|
||||
$ define/nolog VIMRUNTIME RF10:[UTIL.VIM72]
|
||||
|
||||
A good examle for this approach is the [GNU]gnu_tools.com script from GNU_TOOLS.ZIP
|
||||
package downloadable from http://www.polarhome.com/vim/
|
||||
|
||||
(Zoltan Arpadffy, Vim 7.2)
|
||||
|
||||
==============================================================================
|
||||
|
||||
9. VMS related changes *vms-changes*
|
||||
|
||||
Version 7
|
||||
Recent changes
|
||||
- The following plugins are included into VMS runtime:
|
||||
genutils 2.4, multiselect 2.2, multvals 3.1, selectbuf 4.3,
|
||||
bufexplorer 7.1.7, taglist 4.5
|
||||
- minor changes in vimrc (just in VMS runtime)
|
||||
- make_vms.mms - HUGE model is the default
|
||||
- [TESTDIR]make_vms.mms include as many tests possible
|
||||
- modify test30 and test54 for VMS
|
||||
- enable FLOAT feature in VMS port
|
||||
- os_vms.txt updated
|
||||
|
||||
Version 7.2 (2008 Aug 9)
|
||||
- VCF files write corrected
|
||||
- CTAGS 5.7 included
|
||||
- corrected make_vms.mms (on VAX gave syntax error)
|
||||
|
||||
Version 7.1 (2007 Jun 15)
|
||||
- create TAGS file from menu
|
||||
|
||||
Version 7 (2006 May 8)
|
||||
- Improved low level char input (affects just console mode)
|
||||
- Fixed plugin bug
|
||||
- CTAGS 5.6 included
|
||||
|
||||
Version 6.4 (2005 Oct 15)
|
||||
- GTKLIB and Vim build on IA64
|
||||
@@ -806,6 +926,7 @@ Version 4.5 (1996 Dec 16)
|
||||
|
||||
OpenVMS documentation and executables are maintained by:
|
||||
Zoltan Arpadffy <arpadffy@polarhome.com>
|
||||
OpenVMS Vim page: http://www.polarhome.com/vim/
|
||||
|
||||
This document uses parts and remarks from earlier authors and contributors
|
||||
of OS_VMS.TXT:
|
||||
|
||||
@@ -767,6 +767,7 @@ Short explanation of each option: *option-list*
|
||||
'listchars' 'lcs' characters for displaying in list mode
|
||||
'loadplugins' 'lpl' load plugin scripts when starting up
|
||||
'macatsui' Mac GUI: use ATSUI text drawing
|
||||
'macmeta' 'mmta' use option as meta key (MacVim GUI only)
|
||||
'magic' changes special characters in search patterns
|
||||
'makeef' 'mef' name of the errorfile for ":make"
|
||||
'makeprg' 'mp' program to use for the ":make" command
|
||||
|
||||
+43
-13
@@ -1,4 +1,4 @@
|
||||
*spell.txt* For Vim version 7.2. Last change: 2008 Jun 21
|
||||
*spell.txt* For Vim version 7.2. Last change: 2008 Nov 30
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -831,8 +831,11 @@ Comment lines in the .aff file start with a '#':
|
||||
|
||||
# comment line ~
|
||||
|
||||
With some items it's also possible to put a comment after it, but this isn't
|
||||
supported in general.
|
||||
Items with a fixed number of arguments can be followed by a comment. But only
|
||||
if none of the arguments can contain white space. The comment must start with
|
||||
a "#" character. Example:
|
||||
|
||||
KEEPCASE = # fix case for words with this flag ~
|
||||
|
||||
|
||||
ENCODING *spell-SET*
|
||||
@@ -965,6 +968,9 @@ common items and two-character flags for uncommon items.
|
||||
|
||||
Note: When using utf-8 only characters up to 65000 may be used for flags.
|
||||
|
||||
Note: even when using "num" or "long" the number of flags available to
|
||||
compounding and prefixes is limited to about 250.
|
||||
|
||||
|
||||
AFFIXES
|
||||
*spell-PFX* *spell-SFX*
|
||||
@@ -1178,6 +1184,9 @@ word as good.
|
||||
The flag also applies to the word with affixes, thus this can be used to mark
|
||||
a whole bunch of related words as bad.
|
||||
|
||||
*spell-FORBIDDENWORD*
|
||||
FORBIDDENWORD can be used just like BAD. For compatibility with Hunspell.
|
||||
|
||||
*spell-NEEDAFFIX*
|
||||
The NEEDAFFIX flag is used to require that a word is used with an affix. The
|
||||
word itself is not a good word (unless there is an empty affix). Example:
|
||||
@@ -1268,6 +1277,10 @@ compound word. The word itself is not a good word. Example:
|
||||
|
||||
NEEDCOMPOUND & ~
|
||||
|
||||
*spell-ONLYINCOMPOUND*
|
||||
The ONLYINCOMPOUND does exactly the same as NEEDCOMPOUND. Supported for
|
||||
compatiblity with Hunspell.
|
||||
|
||||
*spell-COMPOUNDMIN*
|
||||
The minimal character length of a word used for compounding is specified with
|
||||
COMPOUNDMIN. Example:
|
||||
@@ -1328,6 +1341,20 @@ compound. This means it counts for two words when checking the compounding
|
||||
rules. Can also be used for an affix to count the affix as a compounding
|
||||
word.
|
||||
|
||||
*spell-CHECKCOMPOUNDPATTERN*
|
||||
CHECKCOMPOUNDPATTERN is used to define patterns that, when matching at the
|
||||
position where two words are compounded together forbids the compound.
|
||||
For example:
|
||||
CHECKCOMPOUNDPATTERN o e ~
|
||||
|
||||
This forbids compounding if the first word ends in "o" and the second word
|
||||
starts with "e".
|
||||
|
||||
The arguments must be plain text, no patterns are actually supported, despite
|
||||
the item name. Case is always ignored.
|
||||
|
||||
The Hunspell feature to use three arguments and flags is not supported.
|
||||
|
||||
*spell-SYLLABLE*
|
||||
The SYLLABLE item defines characters or character sequences that are used to
|
||||
count the number of syllables in a word. Example:
|
||||
@@ -1496,6 +1523,10 @@ ignored, not supported or defined in another way.
|
||||
ACCENT (Hunspell) *spell-ACCENT*
|
||||
Use MAP instead. |spell-MAP|
|
||||
|
||||
BREAK (Hunspell) *spell-BREAK*
|
||||
Define break points. Unclear how it works exactly.
|
||||
Not supported.
|
||||
|
||||
CHECKCOMPOUNDCASE (Hunspell) *spell-CHECKCOMPOUNDCASE*
|
||||
Disallow uppercase letters at compound word boundaries.
|
||||
Not supported.
|
||||
@@ -1512,9 +1543,6 @@ CHECKCOMPOUNDTRIPLE (Hunspell) *spell-CHECKCOMPOUNDTRIPLE*
|
||||
Forbid three identical characters when compounding. Not
|
||||
supported.
|
||||
|
||||
CHECKCOMPOUNDPATTERN (Hunspell) *spell-CHECKCOMPOUNDPATTERN*
|
||||
Forbid compounding when patterns match. Not supported.
|
||||
|
||||
COMPLEXPREFIXES (Hunspell) *spell-COMPLEXPREFIXES*
|
||||
Enables using two prefixes. Not supported.
|
||||
|
||||
@@ -1536,13 +1564,18 @@ COMPOUNDEND (Hunspell) *spell-COMPOUNDEND*
|
||||
COMPOUNDMIDDLE (Hunspell) *spell-COMPOUNDMIDDLE*
|
||||
Use COMPOUNDRULE instead. |spell-COMPOUNDRULE|
|
||||
|
||||
COMPOUNDRULES (Hunspell) *spell-COMPOUNDRULES*
|
||||
Number of COMPOUNDRULE lines following. Ignored, but the
|
||||
argument must be a number.
|
||||
|
||||
COMPOUNDSYLLABLE (Hunspell) *spell-COMPOUNDSYLLABLE*
|
||||
Use SYLLABLE and COMPOUNDSYLMAX instead. |spell-SYLLABLE|
|
||||
|spell-COMPOUNDSYLMAX|
|
||||
|
||||
FORBIDDENWORD (Hunspell) *spell-FORBIDDENWORD*
|
||||
Use BAD instead. |spell-BAD|
|
||||
|
||||
KEY (Hunspell) *spell-KEY*
|
||||
Define characters that are close together on the keyboard.
|
||||
Used to give better suggestions. Not supported.
|
||||
|
||||
LANG (Hunspell) *spell-LANG*
|
||||
This specifies language-specific behavior. This actually
|
||||
moves part of the language knowledge into the program,
|
||||
@@ -1553,10 +1586,7 @@ LEMMA_PRESENT (Hunspell) *spell-LEMMA_PRESENT*
|
||||
Only needed for morphological analysis.
|
||||
|
||||
MAXNGRAMSUGS (Hunspell) *spell-MAXNGRAMSUGS*
|
||||
Not supported.
|
||||
|
||||
ONLYINCOMPOUND (Hunspell) *spell-ONLYINCOMPOUND*
|
||||
Use NEEDCOMPOUND instead. |spell-NEEDCOMPOUND|
|
||||
Set number of n-gram suggestions. Not supported.
|
||||
|
||||
PSEUDOROOT (Hunspell) *spell-PSEUDOROOT*
|
||||
Use NEEDAFFIX instead. |spell-NEEDAFFIX|
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*starting.txt* For Vim version 7.2. Last change: 2008 Jun 21
|
||||
*starting.txt* For Vim version 7.2. Last change: 2008 Nov 09
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -1338,8 +1338,9 @@ enter Vim and directly start working in your desired setup. |session-file|
|
||||
*viminfo-read*
|
||||
When Vim is started and the 'viminfo' option is non-empty, the contents of
|
||||
the viminfo file are read and the info can be used in the appropriate places.
|
||||
The marks are not read in at startup (but file marks are). See
|
||||
|initialization| for how to set the 'viminfo' option upon startup.
|
||||
The |v:oldfiles| variable is filled. The marks are not read in at startup
|
||||
(but file marks are). See |initialization| for how to set the 'viminfo'
|
||||
option upon startup.
|
||||
|
||||
*viminfo-write*
|
||||
When Vim exits and 'viminfo' is non-empty, the info is stored in the viminfo
|
||||
@@ -1373,6 +1374,8 @@ cursor position when the file was last exited. No marks are saved for files
|
||||
that start with any string given with the "r" flag in 'viminfo'. This can be
|
||||
used to avoid saving marks for files on removable media (for MS-DOS you would
|
||||
use "ra:,rb:", for Amiga "rdf0:,rdf1:,rdf2:").
|
||||
The |v:oldfiles| variable is filled with the file names that the viminfo file
|
||||
has marks for.
|
||||
|
||||
*viminfo-file-marks*
|
||||
Uppercase marks ('A to 'Z) are stored when writing the viminfo file. The
|
||||
@@ -1464,8 +1467,8 @@ most of the information will be restored).
|
||||
*:rv* *:rviminfo* *E195*
|
||||
:rv[iminfo][!] [file] Read from viminfo file [file] (default: see above).
|
||||
If [!] is given, then any information that is
|
||||
already set (registers, marks, etc.) will be
|
||||
overwritten. {not in Vi}
|
||||
already set (registers, marks, |v:oldfiles|, etc.)
|
||||
will be overwritten {not in Vi}
|
||||
|
||||
*:wv* *:wviminfo* *E137* *E138* *E574*
|
||||
:wv[iminfo][!] [file] Write to viminfo file [file] (default: see above).
|
||||
@@ -1480,4 +1483,20 @@ most of the information will be restored).
|
||||
the .viminfo file.
|
||||
{not in Vi}
|
||||
|
||||
*:ol* *:oldfiles*
|
||||
:ol[dfiles] List the files that have marks stored in the viminfo
|
||||
file. This list is read on startup and only changes
|
||||
afterwards with ":rviminfo!". Also see |v:oldfiles|.
|
||||
The number can be used with |c_#<|.
|
||||
{not in Vi, only when compiled with the +eval feature}
|
||||
|
||||
:bro[wse] ol[dfiles][!]
|
||||
List file names as with |:oldfiles|, and then prompt
|
||||
for a number. When the number is valid that file from
|
||||
the list is edited.
|
||||
If you get the |press-enter| prompt you can press "q"
|
||||
and still get the prompt to enter a file number.
|
||||
Use ! to abondon a modified buffer. |abandon|
|
||||
{not when compiled with tiny or small features}
|
||||
|
||||
vim:tw=78:ts=8:ft=help:norl:
|
||||
|
||||
+44
-2
@@ -1,4 +1,4 @@
|
||||
*usr_21.txt* For Vim version 7.2. Last change: 2007 May 01
|
||||
*usr_21.txt* For Vim version 7.2. Last change: 2008 Nov 09
|
||||
|
||||
VIM USER MANUAL - by Bram Moolenaar
|
||||
|
||||
@@ -153,7 +153,7 @@ information. This may cause information that previously exiting Vims stored
|
||||
to be lost. Each item can be remembered only once.
|
||||
|
||||
|
||||
GETTING BACK TO WHERE YOU WERE
|
||||
GETTING BACK TO WHERE YOU STOPPED VIM
|
||||
|
||||
You are halfway editing a file and it's time to leave for holidays. You exit
|
||||
Vim and go enjoy yourselves, forgetting all about your work. After a couple
|
||||
@@ -168,6 +168,48 @@ Mark '9 is lost.
|
||||
The |:marks| command is useful to find out where '0 to '9 will take you.
|
||||
|
||||
|
||||
GETTING BACK TO SOME FILE
|
||||
|
||||
If you want to go back to a file that you edited recently, but not when
|
||||
exiting Vim, there is a slightly more complicated way. You can see a list of
|
||||
files by typing the command: >
|
||||
|
||||
:oldfiles
|
||||
< 1: ~/.viminfo ~
|
||||
2: ~/text/resume.txt ~
|
||||
3: /tmp/draft ~
|
||||
|
||||
Now you would like to edit the second file, which is in the list preceded by
|
||||
"2:". You type: >
|
||||
|
||||
:e #<2
|
||||
|
||||
Instead of ":e" you can use any command that has a file name argument, the
|
||||
"#<2" item works in the same place as "%" (current file name) and "#"
|
||||
(alternate file name). So you can also split the window to edit the third
|
||||
file: >
|
||||
|
||||
:split #<3
|
||||
|
||||
That #<123 thing is a bit complicated when you just want to edit a file.
|
||||
Fortunately there is a simpler way: >
|
||||
|
||||
:browse oldfiles
|
||||
< 1: ~/.viminfo ~
|
||||
2: ~/text/resume.txt ~
|
||||
3: /tmp/draft ~
|
||||
-- More --
|
||||
|
||||
You get the same list of files as with |:oldfiles|. If you want to edit
|
||||
"resume.txt" first press "q" to stop the listing. You will get a prompt:
|
||||
|
||||
Type number and <Enter> (empty cancels): ~
|
||||
|
||||
Type "2" and press <Enter> to edit the second file.
|
||||
|
||||
More info at |:oldfiles|, |v:oldfiles| and |c_#<|.
|
||||
|
||||
|
||||
MOVE INFO FROM ONE VIM TO ANOTHER
|
||||
|
||||
You can use the ":wviminfo" and ":rviminfo" commands to save and restore the
|
||||
|
||||
@@ -623,6 +623,9 @@ if has("gui")
|
||||
call <SID>BinOptionG("fullscreen", &fullscreen)
|
||||
call append("$", "fuoptions\tcontrol how fullscreen mode should behave")
|
||||
call <SID>OptionG("fuoptions", &fuoptions)
|
||||
call append("$", "macmeta\tuse option as meta key")
|
||||
call append("$", "\t(local to buffer)")
|
||||
call <SID>BinOptionL("mmta")
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
@@ -234,6 +234,10 @@ else
|
||||
elseif s:line1 =~ '\<DTD\s\+XHTML\s'
|
||||
set ft=xhtml
|
||||
|
||||
" HTML (e.g.: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN")
|
||||
elseif s:line1 =~? '\<DOCTYPE\s\+html\>'
|
||||
set ft=html
|
||||
|
||||
" PDF
|
||||
elseif s:line1 =~ '^%PDF-'
|
||||
set ft=pdf
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf430
|
||||
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\vieww9000\viewh8400\viewkind0
|
||||
@@ -29,6 +29,8 @@ Enno L\'fcbbers\
|
||||
Kyle Lippincott\
|
||||
Matt Tolton\
|
||||
Kaoru Yoshida\
|
||||
Ron Olson\
|
||||
Jonathon Mah\
|
||||
|
||||
\i0 \
|
||||
...and many others who have helped by reporting bugs etc.\
|
||||
@@ -38,8 +40,6 @@ Thank you to {\field{\*\fldinst{HYPERLINK "http://www.positivespinmedia.com"}}{\
|
||||
\
|
||||
Toolbar icons by {\field{\*\fldinst{HYPERLINK "http://www.mattballdesign.com/"}}{\fldrslt Matt Ball}} (free Developer Icons), {\field{\*\fldinst{HYPERLINK "http://www.jonasraskdesign.com/"}}{\fldrslt Jonas Rask}} (Danish Royalty Free icon set), and {\field{\*\fldinst{HYPERLINK "http://www.everaldo.com"}}{\fldrslt Everaldo Coelho}} (Crystal Project Icons, released under LGPL license).\
|
||||
\
|
||||
Vim icons made by {\field{\*\fldinst{HYPERLINK "http://www.cs.princeton.edu/~mtwebb/vim_icon/vim_icons.html"}}{\fldrslt Matthew Webb}}.\
|
||||
\
|
||||
The default font in MacVim, DejaVu Sans Mono, is based on the Bitstream Vera\'99 and Arev fonts. Bitstream Vera\'99 is \'a9 2003 by Bitstream, Inc. Arev is \'a9 2006 by Tavmjong Bah. The DejaVu changes to these fonts are in the public domain.\
|
||||
\
|
||||
Thanks to Andy Matuschak for {\field{\*\fldinst{HYPERLINK "http://sparkle.andymatuschak.org/"}}{\fldrslt Sparkle}}.\
|
||||
@@ -50,4 +50,6 @@ Thanks to Allan Odgaard for making the "Edit in TextMate" input manager source c
|
||||
\
|
||||
Thanks to Rainer Brockerhoff for RBSplitView.\
|
||||
\
|
||||
Thanks to Chad Weider for CTGradient.}
|
||||
Thanks to Chad Weider for CTGradient.\
|
||||
\
|
||||
Thanks to Damien Guard for {\field{\*\fldinst{HYPERLINK "http://damieng.com/blog/2008/05/26/envy-code-r-preview-7-coding-font-released"}}{\fldrslt Envy Code R}} (used in MacVim's 16x16 document icons).}
|
||||
Binary file not shown.
+87
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBClasses</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CLASS</key>
|
||||
<string>RBSplitView</string>
|
||||
<key>LANGUAGE</key>
|
||||
<string>ObjC</string>
|
||||
<key>OUTLETS</key>
|
||||
<dict>
|
||||
<key>delegate</key>
|
||||
<string>id</string>
|
||||
</dict>
|
||||
<key>SUPERCLASS</key>
|
||||
<string>RBSplitSubview</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CLASS</key>
|
||||
<string>RBSplitSubview</string>
|
||||
<key>LANGUAGE</key>
|
||||
<string>ObjC</string>
|
||||
<key>SUPERCLASS</key>
|
||||
<string>NSView</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>ACTIONS</key>
|
||||
<dict>
|
||||
<key>findAndReplace</key>
|
||||
<string>id</string>
|
||||
</dict>
|
||||
<key>CLASS</key>
|
||||
<string>FirstResponder</string>
|
||||
<key>LANGUAGE</key>
|
||||
<string>ObjC</string>
|
||||
<key>SUPERCLASS</key>
|
||||
<string>NSObject</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CLASS</key>
|
||||
<string>NSMenu</string>
|
||||
<key>LANGUAGE</key>
|
||||
<string>ObjC</string>
|
||||
<key>SUPERCLASS</key>
|
||||
<string>NSObject</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>ACTIONS</key>
|
||||
<dict>
|
||||
<key>didAdjustSubviews</key>
|
||||
<string>RBSplitView</string>
|
||||
<key>willAdjustSubviews</key>
|
||||
<string>RBSplitView</string>
|
||||
</dict>
|
||||
<key>CLASS</key>
|
||||
<string>NSObject</string>
|
||||
<key>LANGUAGE</key>
|
||||
<string>ObjC</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CLASS</key>
|
||||
<string>MMFindReplaceController</string>
|
||||
<key>LANGUAGE</key>
|
||||
<string>ObjC</string>
|
||||
<key>OUTLETS</key>
|
||||
<dict>
|
||||
<key>backwardButton</key>
|
||||
<string>NSButton</string>
|
||||
<key>findBox</key>
|
||||
<string>NSTextField</string>
|
||||
<key>ignoreCaseButton</key>
|
||||
<string>NSButton</string>
|
||||
<key>matchWordButton</key>
|
||||
<string>NSButton</string>
|
||||
<key>replaceBox</key>
|
||||
<string>NSTextField</string>
|
||||
</dict>
|
||||
<key>SUPERCLASS</key>
|
||||
<string>NSWindowController</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>IBVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
Generated
+20
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>629</string>
|
||||
<key>IBLastKnownRelativeProjectPath</key>
|
||||
<string>../MacVim.xcodeproj</string>
|
||||
<key>IBOldestOS</key>
|
||||
<integer>5</integer>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>7</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>9F33</string>
|
||||
<key>targetFramework</key>
|
||||
<string>IBCocoaFramework</string>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
Binary file not shown.
+662
-52
@@ -5,6 +5,7 @@
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<!-- See http://developer.apple.com/documentation/Carbon/Conceptual/understanding_utis/utilist/chapter_4_section_1.html#//apple_ref/doc/uid/TP40001319-CH205-CHDIJFGJ for a list of UTIs -->
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
@@ -12,7 +13,7 @@
|
||||
<string>vim</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>doc-bm</string>
|
||||
<string>MacVim-vim</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Vim Script File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -25,9 +26,10 @@
|
||||
<array>
|
||||
<string>txt</string>
|
||||
<string>text</string>
|
||||
<string>utf8</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>doc-bm-txt</string>
|
||||
<string>MacVim-txt</string>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>text/plain</string>
|
||||
@@ -43,9 +45,14 @@
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>tex</string>
|
||||
<string>sty</string>
|
||||
<string>cls</string>
|
||||
<string>ltx</string>
|
||||
<string>ins</string>
|
||||
<string>dtx</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>doc-bm-tex</string>
|
||||
<string>MacVim-tex</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>TeX File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -59,7 +66,7 @@
|
||||
<string>h</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>doc-bm-h</string>
|
||||
<string>MacVim-h</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>C Header Source File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -76,6 +83,8 @@
|
||||
<array>
|
||||
<string>pch</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-h</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>C Precompiled Header Source File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -96,6 +105,8 @@
|
||||
<string>hxx</string>
|
||||
<string>h++</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-h</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>C++ Header Source File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -108,6 +119,8 @@
|
||||
<array>
|
||||
<string>pch++</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-h</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>C++ Precompiled Header Source File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -125,7 +138,7 @@
|
||||
<string>c</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>doc-bm-c</string>
|
||||
<string>MacVim-c</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>C Source File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -142,6 +155,8 @@
|
||||
<array>
|
||||
<string>m</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-m</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Objective-C Source File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -158,6 +173,8 @@
|
||||
<array>
|
||||
<string>mm</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-mm</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Objective-C++ Source File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -178,6 +195,8 @@
|
||||
<string>cxx</string>
|
||||
<string>c++</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-cpp</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>C++ Source File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -229,7 +248,7 @@
|
||||
<string>jav</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>doc-bm-java</string>
|
||||
<string>MacVim-java</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Java Source File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -314,9 +333,13 @@
|
||||
<array>
|
||||
<string>f</string>
|
||||
<string>for</string>
|
||||
<string>fpp</string>
|
||||
<string>f77</string>
|
||||
<string>f90</string>
|
||||
<string>f95</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-f</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Fortran Source File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -366,10 +389,19 @@
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>html</string>
|
||||
<string>phtml</string>
|
||||
<string>shtml</string>
|
||||
<string>xhtml</string>
|
||||
<string>htm</string>
|
||||
<string>pht</string>
|
||||
<string>sht</string>
|
||||
<string>xht</string>
|
||||
<string>phtm</string>
|
||||
<string>shtm</string>
|
||||
<string>xhtm</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>doc-bm-html</string>
|
||||
<string>MacVim-html</string>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>text/html</string>
|
||||
@@ -389,9 +421,14 @@
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>xml</string>
|
||||
<string>rss</string>
|
||||
<string>tld</string>
|
||||
<string>pt</string>
|
||||
<string>cpt</string>
|
||||
<string>dtml</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>doc-bm-xml</string>
|
||||
<string>MacVim-xml</string>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>text/xml</string>
|
||||
@@ -411,9 +448,12 @@
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>js</string>
|
||||
<string>htc</string>
|
||||
<string>jscript</string>
|
||||
<string>javascript</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-js</string>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>text/javascript</string>
|
||||
@@ -430,42 +470,123 @@
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Perl source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>sh</string>
|
||||
<string>command</string>
|
||||
<string>csh</string>
|
||||
<string>pl</string>
|
||||
<string>pm</string>
|
||||
<string>py</string>
|
||||
<string>rb</string>
|
||||
<string>rbw</string>
|
||||
<string>php</string>
|
||||
<string>php3</string>
|
||||
<string>php4</string>
|
||||
<string>ph3</string>
|
||||
<string>ph4</string>
|
||||
<string>phtml</string>
|
||||
<string>applescript</string>
|
||||
<string>pod</string>
|
||||
<string>perl</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>doc-bm-sh</string>
|
||||
<string>MacVim-perl</string>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>text/x-perl-script</string>
|
||||
<string>text/x-python-script</string>
|
||||
<string>text/ruby-script</string>
|
||||
<string>text/php</string>
|
||||
</array>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Script File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSIsAppleDefaultForType</key>
|
||||
<true/>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>public.script</string>
|
||||
<string>public.perl-script</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Python source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>py</string>
|
||||
<string>rpy</string>
|
||||
<string>cpy</string>
|
||||
<string>python</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-py</string>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>text/x-python-script</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>public.python-script</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>PHP source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>php</string>
|
||||
<string>php3</string>
|
||||
<string>php4</string>
|
||||
<string>php5</string>
|
||||
<string>ph3</string>
|
||||
<string>ph4</string>
|
||||
<string>phtml</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-php</string>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>text/php</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>public.php-script</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Ruby source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>rb</string>
|
||||
<string>rbw</string>
|
||||
<string>rbx</string>
|
||||
<string>rjs</string>
|
||||
<string>rxml</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-rb</string>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>text/ruby-script</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>public.ruby-script</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Shell script</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>sh</string>
|
||||
<string>csh</string>
|
||||
<string>command</string>
|
||||
<string>ss</string>
|
||||
<string>bashrc</string>
|
||||
<string>bash_profile</string>
|
||||
<string>bash_login</string>
|
||||
<string>profile</string>
|
||||
<string>bash_logout</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-bash</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>public.shell-script</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
@@ -491,7 +612,7 @@
|
||||
<string>diff</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>doc-bm</string>
|
||||
<string>MacVim-patch</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Patch File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -527,11 +648,485 @@
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>AppleScript source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>applescript</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-applescript</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.apple.applescript.text</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>ActionScript source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>as</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-as</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>ASP document</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>asp</string>
|
||||
<string>asa</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-asp</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>ASP.NET document</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>aspx</string>
|
||||
<string>ascx</string>
|
||||
<string>asmx</string>
|
||||
<string>ashx</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-asp</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>BibTeX bibliography</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>bib</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-bib</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>C# source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>cs</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-cs</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Context Free Design Grammar</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>cfdg</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-csfg</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Comma separated values</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>csv</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-csv</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Tab separated values</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>tsv</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-tsv</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>CGI script</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>cgi</string>
|
||||
<string>fcgi</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-cgi</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Configuration file</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>cfg</string>
|
||||
<string>conf</string>
|
||||
<string>config</string>
|
||||
<string>htaccess</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-cfg</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Cascading style sheet</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>css</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-css</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Document Type Definition</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>dtd</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-dtd</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Dylan source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>dylan</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-dylan</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Erlang source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>erl</string>
|
||||
<string>hrl</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-erl</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>F-Script source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>fscript</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-fscript</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Haskell source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>hs</string>
|
||||
<string>lhs</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-hs</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Include file</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>inc</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-inc</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>iCalendar schedule</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>ics</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-ics</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>MS Windows initialization file</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>ini</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-ini</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Io source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>io</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-io</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>BeanShell script</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>bsh</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-bsh</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Java properties file</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>properties</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-properties</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Java Server Page</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>jsp</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-jsp</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>LISP source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>lisp</string>
|
||||
<string>cl</string>
|
||||
<string>l</string>
|
||||
<string>lsp</string>
|
||||
<string>mud</string>
|
||||
<string>el</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-lisp</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Log file</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>log</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-log</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Mediawiki document</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>wiki</string>
|
||||
<string>wikipedia</string>
|
||||
<string>mediawiki</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-wiki</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>PostScript source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>ps</string>
|
||||
<string>eps</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-ps</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<!--<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Property list</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>dict</string>
|
||||
<string>plist</string>
|
||||
<string>scriptSuite</string>
|
||||
<string>scriptTerminology</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-plist</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>-->
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Scheme source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>scm</string>
|
||||
<string>sch</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-sch</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>SQL source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>sql</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-sql</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Tcl source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>tcl</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-tcl</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>XSL stylesheet</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>xsl</string>
|
||||
<string>xslt</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-xsl</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Electronic business card</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>vcf</string>
|
||||
<string>vcard</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-vcf</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Visual Basic source</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>vb</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-vb</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>YAML document</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>yaml</string>
|
||||
<string>yml</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-yaml</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>GTD document</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>gtd</string>
|
||||
<string>gtdlog</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>MacVim-gtd</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>vim_gloss</string>
|
||||
<string>MacVim</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.vim.MacVim</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
@@ -544,8 +1139,21 @@
|
||||
<string>7.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>VIMM</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>org.vim.MacVim</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>mvim</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>34</string>
|
||||
<string>43</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
@@ -556,7 +1164,7 @@
|
||||
<key>NSMenuItem</key>
|
||||
<dict>
|
||||
<key>default</key>
|
||||
<string>MacVim/New Tab Containing Selection</string>
|
||||
<string>MacVim/New Document Containing Selection</string>
|
||||
</dict>
|
||||
<key>NSMessage</key>
|
||||
<string>openSelection</string>
|
||||
@@ -571,24 +1179,7 @@
|
||||
<key>NSMenuItem</key>
|
||||
<dict>
|
||||
<key>default</key>
|
||||
<string>MacVim/Open Selected File in Tab</string>
|
||||
</dict>
|
||||
<key>NSMessage</key>
|
||||
<string>openFile</string>
|
||||
<key>NSPortName</key>
|
||||
<string>MacVim</string>
|
||||
<key>NSSendTypes</key>
|
||||
<array>
|
||||
<string>NSStringPboardType</string>
|
||||
</array>
|
||||
<key>NSUserData</key>
|
||||
<string>Tab</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSMenuItem</key>
|
||||
<dict>
|
||||
<key>default</key>
|
||||
<string>MacVim/Open Selected File in Window</string>
|
||||
<string>MacVim/Open Selected File</string>
|
||||
</dict>
|
||||
<key>NSMessage</key>
|
||||
<string>openFile</string>
|
||||
@@ -601,9 +1192,28 @@
|
||||
<key>NSUserData</key>
|
||||
<string>Window</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSMenuItem</key>
|
||||
<dict>
|
||||
<key>default</key>
|
||||
<string>MacVim/New Document Here</string>
|
||||
</dict>
|
||||
<key>NSMessage</key>
|
||||
<string>newFileHere</string>
|
||||
<key>NSPortName</key>
|
||||
<string>MacVim</string>
|
||||
<key>NSSendTypes</key>
|
||||
<array>
|
||||
<string>NSStringPboardType</string>
|
||||
</array>
|
||||
<key>NSUserData</key>
|
||||
<string>Window</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>SUFeedURL</key>
|
||||
<string>http://bjorn.winckler.googlepages.com/macvim_latest.xml</string>
|
||||
<key>NSAppleScriptEnabled</key>
|
||||
<true/>
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
NSMutableArray *cachedVimControllers;
|
||||
int preloadPid;
|
||||
BOOL shouldActivateWhenNextWindowOpens;
|
||||
int numChildProcesses;
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
FSEventStreamRef fsEventStream;
|
||||
@@ -46,6 +47,8 @@
|
||||
- (void)windowControllerWillOpen:(MMWindowController *)windowController;
|
||||
- (void)setMainMenu:(NSMenu *)mainMenu;
|
||||
- (NSArray *)filterOpenFiles:(NSArray *)filenames;
|
||||
- (BOOL)openFiles:(NSArray *)filenames withArguments:(NSDictionary *)args;
|
||||
|
||||
|
||||
#ifdef MM_ENABLE_PLUGINS
|
||||
- (void)addItemToPlugInMenu:(NSMenuItem *)item;
|
||||
|
||||
+522
-209
@@ -61,10 +61,6 @@ 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;
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
// Latency (in s) between FS event occuring and being reported to MacVim.
|
||||
// Should be small so that MacVim is notified of changes to the ~/.vim
|
||||
@@ -86,14 +82,14 @@ typedef struct
|
||||
#pragma options align=reset
|
||||
|
||||
|
||||
static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
|
||||
|
||||
@interface MMAppController (MMServices)
|
||||
- (void)openSelection:(NSPasteboard *)pboard userData:(NSString *)userData
|
||||
error:(NSString **)error;
|
||||
- (void)openFile:(NSPasteboard *)pboard userData:(NSString *)userData
|
||||
error:(NSString **)error;
|
||||
- (void)newFileHere:(NSPasteboard *)pboard userData:(NSString *)userData
|
||||
error:(NSString **)error;
|
||||
@end
|
||||
|
||||
|
||||
@@ -107,6 +103,8 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
- (void)handleXcodeModEvent:(NSAppleEventDescriptor *)event
|
||||
replyEvent:(NSAppleEventDescriptor *)reply;
|
||||
#endif
|
||||
- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
|
||||
replyEvent:(NSAppleEventDescriptor *)reply;
|
||||
- (int)findLaunchingProcessWithoutArguments;
|
||||
- (MMVimController *)findUnusedEditor;
|
||||
- (NSMutableDictionary *)extractArgumentsFromOdocEvent:
|
||||
@@ -124,6 +122,9 @@ static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
- (void)startWatchingVimDir;
|
||||
- (void)stopWatchingVimDir;
|
||||
- (void)handleFSEvent;
|
||||
- (void)loadDefaultFont;
|
||||
- (int)executeInLoginShell:(NSString *)path arguments:(NSArray *)args;
|
||||
- (void)reapChildProcesses:(id)sender;
|
||||
|
||||
#ifdef MM_ENABLE_PLUGINS
|
||||
- (void)removePlugInMenu;
|
||||
@@ -155,11 +156,11 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
[NSNumber numberWithInt:64], MMTabMinWidthKey,
|
||||
[NSNumber numberWithInt:6*64], MMTabMaxWidthKey,
|
||||
[NSNumber numberWithInt:132], MMTabOptimumWidthKey,
|
||||
[NSNumber numberWithBool:YES], MMShowAddTabButtonKey,
|
||||
[NSNumber numberWithInt:2], MMTextInsetLeftKey,
|
||||
[NSNumber numberWithInt:1], MMTextInsetRightKey,
|
||||
[NSNumber numberWithInt:1], MMTextInsetTopKey,
|
||||
[NSNumber numberWithInt:1], MMTextInsetBottomKey,
|
||||
[NSNumber numberWithBool:NO], MMTerminateAfterLastWindowClosedKey,
|
||||
@"MMTypesetter", MMTypesetterKey,
|
||||
[NSNumber numberWithFloat:1], MMCellWidthMultiplierKey,
|
||||
[NSNumber numberWithFloat:-1], MMBaselineOffsetKey,
|
||||
@@ -181,6 +182,8 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
[NSNumber numberWithInt:3], MMOpenLayoutKey,
|
||||
[NSNumber numberWithBool:NO], MMVerticalSplitKey,
|
||||
[NSNumber numberWithInt:0], MMPreloadCacheSizeKey,
|
||||
[NSNumber numberWithInt:0], MMLastWindowClosedBehaviorKey,
|
||||
[NSNumber numberWithBool:YES], MMLoadDefaultFontKey,
|
||||
nil];
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
|
||||
@@ -199,7 +202,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
{
|
||||
if (!(self = [super init])) return nil;
|
||||
|
||||
fontContainerRef = loadFonts();
|
||||
[self loadDefaultFont];
|
||||
|
||||
vimControllers = [NSMutableArray new];
|
||||
cachedVimControllers = [NSMutableArray new];
|
||||
@@ -227,11 +230,6 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
[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.
|
||||
NSString *name = [NSString stringWithFormat:@"%@-connection",
|
||||
@@ -312,6 +310,13 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
forEventClass:'KAHL'
|
||||
andEventID:'MOD '];
|
||||
#endif
|
||||
|
||||
// Register 'mvim://' URL handler
|
||||
[[NSAppleEventManager sharedAppleEventManager]
|
||||
setEventHandler:self
|
||||
andSelector:@selector(handleGetURLEvent:replyEvent:)
|
||||
forEventClass:kInternetEventClass
|
||||
andEventID:kAEGetURL];
|
||||
}
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||
@@ -336,14 +341,17 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
// The user default MMUntitledWindow can be set to control whether an
|
||||
// untitled window should open on 'Open' and 'Reopen' events.
|
||||
int untitledWindowFlag = [ud integerForKey:MMUntitledWindowKey];
|
||||
if ([desc eventID] == kAEOpenApplication
|
||||
&& (untitledWindowFlag & MMUntitledWindowOnOpen) == 0)
|
||||
|
||||
BOOL isAppOpenEvent = [desc eventID] == kAEOpenApplication;
|
||||
if (isAppOpenEvent && (untitledWindowFlag & MMUntitledWindowOnOpen) == 0)
|
||||
return NO;
|
||||
else if ([desc eventID] == kAEReopenApplication
|
||||
|
||||
BOOL isAppReopenEvent = [desc eventID] == kAEReopenApplication;
|
||||
if (isAppReopenEvent
|
||||
&& (untitledWindowFlag & MMUntitledWindowOnReopen) == 0)
|
||||
return NO;
|
||||
|
||||
// When a process is started from the command line, the 'Open' event will
|
||||
// When a process is started from the command line, the 'Open' event may
|
||||
// contain a parameter to surpress the opening of an untitled window.
|
||||
desc = [desc paramDescriptorForKeyword:keyAEPropData];
|
||||
desc = [desc paramDescriptorForKeyword:keyMMUntitledWindow];
|
||||
@@ -356,8 +364,12 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
return NO;
|
||||
|
||||
// NOTE! This way it possible to start the app with the command-line
|
||||
// argument '-nowindow yes' and no window will be opened by default.
|
||||
return ![ud boolForKey:MMNoWindowKey];
|
||||
// argument '-nowindow yes' and no window will be opened by default but
|
||||
// this argument will only be heeded when the application is opening.
|
||||
if (isAppOpenEvent && [ud boolForKey:MMNoWindowKey] == YES)
|
||||
return NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender
|
||||
@@ -368,150 +380,25 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
|
||||
{
|
||||
// Opening files works like this:
|
||||
// a) extract ODB/Xcode/Spotlight parameters from the current Apple event
|
||||
// b) filter out any already open files
|
||||
// c) open any remaining files
|
||||
//
|
||||
// A file is opened in an untitled window if there is one (it may be
|
||||
// currently launching, or it may already be visible), otherwise a new
|
||||
// window is opened.
|
||||
//
|
||||
// Each launching Vim process has a dictionary of arguments that are passed
|
||||
// to the process when in checks in (via connectBackend:pid:). The
|
||||
// arguments for each launching process can be looked up by its PID (in the
|
||||
// pidArguments dictionary).
|
||||
// Extract ODB/Xcode/Spotlight parameters from the current Apple event,
|
||||
// sort the filenames, and then let openFiles:withArguments: do the heavy
|
||||
// lifting.
|
||||
|
||||
if (!(filenames && [filenames count] > 0))
|
||||
return;
|
||||
|
||||
//
|
||||
// a) Extract ODB/Xcode/Spotlight parameters from the current Apple event
|
||||
//
|
||||
// Sort filenames since the Finder doesn't take care in preserving the
|
||||
// order in which files are selected anyway (and "sorted" is more
|
||||
// predictable than "random").
|
||||
if ([filenames count] > 1)
|
||||
filenames = [filenames sortedArrayUsingSelector:
|
||||
@selector(localizedCompare:)];
|
||||
|
||||
// Extract ODB/Xcode/Spotlight parameters from the current Apple event
|
||||
NSMutableDictionary *arguments = [self extractArgumentsFromOdocEvent:
|
||||
[[NSAppleEventManager sharedAppleEventManager] currentAppleEvent]];
|
||||
|
||||
//
|
||||
// b) Filter out any already open files
|
||||
//
|
||||
NSString *firstFile = [filenames objectAtIndex:0];
|
||||
MMVimController *firstController = nil;
|
||||
NSDictionary *openFilesDict = nil;
|
||||
filenames = [self filterOpenFiles:filenames openFilesDict:&openFilesDict];
|
||||
|
||||
// Pass arguments to vim controllers that had files open.
|
||||
id key;
|
||||
NSEnumerator *e = [openFilesDict keyEnumerator];
|
||||
|
||||
// (Indicate that we do not wish to open any files at the moment.)
|
||||
[arguments setObject:[NSNumber numberWithBool:YES] forKey:@"dontOpen"];
|
||||
|
||||
while ((key = [e nextObject])) {
|
||||
NSArray *files = [openFilesDict objectForKey:key];
|
||||
[arguments setObject:files forKey:@"filenames"];
|
||||
|
||||
MMVimController *vc = [key pointerValue];
|
||||
[vc passArguments:arguments];
|
||||
|
||||
// If this controller holds the first file, then remember it for later.
|
||||
if ([files containsObject:firstFile])
|
||||
firstController = vc;
|
||||
}
|
||||
|
||||
if ([filenames count] == 0) {
|
||||
// Raise the window containing the first file that was already open,
|
||||
// and make sure that the tab containing that file is selected. Only
|
||||
// do this when there are no more files to open, otherwise sometimes
|
||||
// the window with 'firstFile' will be raised, other times it might be
|
||||
// the window that will open with the files in the 'filenames' array.
|
||||
firstFile = [firstFile stringByEscapingSpecialFilenameCharacters];
|
||||
NSString *input = [NSString stringWithFormat:@"<C-\\><C-N>"
|
||||
":let oldswb=&swb|let &swb=\"useopen,usetab\"|"
|
||||
"tab sb %@|let &swb=oldswb|unl oldswb|"
|
||||
"cal foreground()|redr|f<CR>", firstFile];
|
||||
|
||||
[firstController addVimInput:input];
|
||||
|
||||
[NSApp replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
|
||||
return;
|
||||
}
|
||||
|
||||
// Add filenames to "Recent Files" menu, unless they are being edited
|
||||
// remotely (using ODB).
|
||||
if ([arguments objectForKey:@"remoteID"] == nil) {
|
||||
[[NSDocumentController sharedDocumentController]
|
||||
noteNewRecentFilePaths:filenames];
|
||||
}
|
||||
|
||||
//
|
||||
// c) Open any remaining files
|
||||
//
|
||||
MMVimController *vc;
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
BOOL openInCurrentWindow = [ud boolForKey:MMOpenInCurrentWindowKey];
|
||||
|
||||
// The meaning of "layout" is defined by the WIN_* defines in main.c.
|
||||
int layout = [ud integerForKey:MMOpenLayoutKey];
|
||||
BOOL splitVert = [ud boolForKey:MMVerticalSplitKey];
|
||||
if (splitVert && MMLayoutHorizontalSplit == layout)
|
||||
layout = MMLayoutVerticalSplit;
|
||||
if (layout < 0 || (layout > MMLayoutTabs && openInCurrentWindow))
|
||||
layout = MMLayoutTabs;
|
||||
|
||||
[arguments setObject:[NSNumber numberWithInt:layout] forKey:@"layout"];
|
||||
[arguments setObject:filenames forKey:@"filenames"];
|
||||
// (Indicate that files should be opened from now on.)
|
||||
[arguments setObject:[NSNumber numberWithBool:NO] forKey:@"dontOpen"];
|
||||
|
||||
if (openInCurrentWindow && (vc = [self topmostVimController])) {
|
||||
// Open files in an already open window.
|
||||
[[[vc windowController] window] makeKeyAndOrderFront:self];
|
||||
[vc passArguments:arguments];
|
||||
[NSApp replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL openOk = YES;
|
||||
int numFiles = [filenames count];
|
||||
if (MMLayoutWindows == layout && numFiles > 1) {
|
||||
// Open one file at a time in a new window, but don't open too many at
|
||||
// once (at most cap+1 windows will open). If the user has increased
|
||||
// the preload cache size we'll take that as a hint that more windows
|
||||
// should be able to open at once.
|
||||
int cap = [self maxPreloadCacheSize] - 1;
|
||||
if (cap < 4) cap = 4;
|
||||
if (cap > numFiles) cap = numFiles;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < cap; ++i) {
|
||||
NSArray *a = [NSArray arrayWithObject:[filenames objectAtIndex:i]];
|
||||
[arguments setObject:a forKey:@"filenames"];
|
||||
|
||||
// NOTE: We have to copy the args since we'll mutate them in the
|
||||
// next loop and the below call may retain the arguments while
|
||||
// waiting for a process to start.
|
||||
NSDictionary *args = [[arguments copy] autorelease];
|
||||
|
||||
openOk = [self openVimControllerWithArguments:args];
|
||||
if (!openOk) break;
|
||||
}
|
||||
|
||||
// Open remaining files in tabs in a new window.
|
||||
if (openOk && numFiles > cap) {
|
||||
NSRange range = { i, numFiles-cap };
|
||||
NSArray *a = [filenames subarrayWithRange:range];
|
||||
[arguments setObject:a forKey:@"filenames"];
|
||||
[arguments setObject:[NSNumber numberWithInt:MMLayoutTabs]
|
||||
forKey:@"layout"];
|
||||
|
||||
openOk = [self openVimControllerWithArguments:arguments];
|
||||
}
|
||||
} else {
|
||||
// Open all files at once.
|
||||
openOk = [self openVimControllerWithArguments:arguments];
|
||||
}
|
||||
|
||||
if (openOk) {
|
||||
if ([self openFiles:filenames withArguments:arguments]) {
|
||||
[NSApp replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
|
||||
} else {
|
||||
// TODO: Notify user of failure?
|
||||
@@ -521,8 +408,9 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
|
||||
{
|
||||
return [[NSUserDefaults standardUserDefaults]
|
||||
boolForKey:MMTerminateAfterLastWindowClosedKey];
|
||||
return (MMTerminateWhenLastWindowClosed ==
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
integerForKey:MMLastWindowClosedBehaviorKey]);
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:
|
||||
@@ -572,14 +460,8 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
// Count the number of open tabs
|
||||
e = [vimControllers objectEnumerator];
|
||||
id vc;
|
||||
while ((vc = [e nextObject])) {
|
||||
NSString *eval = [vc evaluateVimExpression:@"tabpagenr('$')"];
|
||||
if (eval) {
|
||||
int count = [eval intValue];
|
||||
if (count > 0 && count < INT_MAX)
|
||||
numTabs += count;
|
||||
}
|
||||
}
|
||||
while ((vc = [e nextObject]))
|
||||
numTabs += [[vc objectForVimStateKey:@"numTabs"] intValue];
|
||||
|
||||
if (numWindows > 1 || numTabs > 1) {
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
@@ -630,17 +512,34 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
if (NSTerminateNow == reply) {
|
||||
e = [vimControllers objectEnumerator];
|
||||
id vc;
|
||||
while ((vc = [e nextObject]))
|
||||
while ((vc = [e nextObject])) {
|
||||
//NSLog(@"Terminate pid=%d", [vc pid]);
|
||||
[vc sendMessage:TerminateNowMsgID data:nil];
|
||||
}
|
||||
|
||||
e = [cachedVimControllers objectEnumerator];
|
||||
while ((vc = [e nextObject]))
|
||||
while ((vc = [e nextObject])) {
|
||||
//NSLog(@"Terminate pid=%d (cached)", [vc pid]);
|
||||
[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);
|
||||
// If a Vim process is being preloaded as we quit we have to forcibly
|
||||
// kill it since we have not established a connection yet.
|
||||
if (preloadPid > 0) {
|
||||
//NSLog(@"INCOMPLETE preloaded process: preloadPid=%d", preloadPid);
|
||||
kill(preloadPid, SIGKILL);
|
||||
}
|
||||
|
||||
// If a Vim process was loading as we quit we also have to kill it.
|
||||
e = [[pidArguments allKeys] objectEnumerator];
|
||||
NSNumber *pidKey;
|
||||
while ((pidKey = [e nextObject])) {
|
||||
//NSLog(@"INCOMPLETE process: pid=%d", [pidKey intValue]);
|
||||
kill([pidKey intValue], SIGKILL);
|
||||
}
|
||||
|
||||
// Sleep a little to allow all the Vim processes to exit.
|
||||
usleep(10000);
|
||||
}
|
||||
|
||||
return reply;
|
||||
@@ -664,23 +563,41 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
// 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
|
||||
// the run-loop for this to happen).
|
||||
unsigned i, count = [vimControllers count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
MMVimController *controller = [vimControllers objectAtIndex:i];
|
||||
int pid = [controller pid];
|
||||
if (-1 != pid)
|
||||
kill(pid, SIGINT);
|
||||
}
|
||||
|
||||
// Deactivate the font we loaded from the app bundle.
|
||||
// NOTE: This can take quite a while (~500 ms), so termination will be
|
||||
// noticeably faster if loading of the default font is disabled.
|
||||
if (fontContainerRef) {
|
||||
ATSFontDeactivate(fontContainerRef, NULL, kATSOptionFlagsDefault);
|
||||
fontContainerRef = 0;
|
||||
}
|
||||
|
||||
[NSApp setDelegate:nil];
|
||||
|
||||
// Try to wait for all child processes to avoid leaving zombies behind (but
|
||||
// don't wait around for too long).
|
||||
NSDate *timeOutDate = [NSDate dateWithTimeIntervalSinceNow:2];
|
||||
while ([timeOutDate timeIntervalSinceNow] > 0) {
|
||||
[self reapChildProcesses:nil];
|
||||
if (numChildProcesses <= 0)
|
||||
break;
|
||||
|
||||
//NSLog(@"%d processes still left, sleep a bit...", numChildProcesses);
|
||||
|
||||
// Run in NSConnectionReplyMode while waiting instead of calling e.g.
|
||||
// usleep(). Otherwise incoming messages may clog up the DO queues and
|
||||
// the outgoing TerminateNowMsgID sent earlier never reaches the Vim
|
||||
// process.
|
||||
// This has at least one side-effect, namely we may receive the
|
||||
// annoying "dropping incoming DO message". (E.g. this may happen if
|
||||
// you quickly hit Cmd-n several times in a row and then immediately
|
||||
// press Cmd-q, Enter.)
|
||||
while (CFRunLoopRunInMode((CFStringRef)NSConnectionReplyMode,
|
||||
0.05, true) == kCFRunLoopRunHandledSource)
|
||||
; // do nothing
|
||||
}
|
||||
|
||||
if (numChildProcesses > 0)
|
||||
NSLog(@"%d ZOMBIES left behind", numChildProcesses);
|
||||
}
|
||||
|
||||
+ (MMAppController *)sharedInstance
|
||||
@@ -715,7 +632,21 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
// 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];
|
||||
|
||||
BOOL hide = (MMHideWhenLastWindowClosed ==
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
integerForKey:MMLastWindowClosedBehaviorKey]);
|
||||
if (hide)
|
||||
[NSApp hide:self];
|
||||
}
|
||||
|
||||
// There is a small delay before the Vim process actually exits so wait a
|
||||
// little before trying to reap the child process. If the process still
|
||||
// hasn't exited after this wait it won't be reaped until the next time
|
||||
// reapChildProcesses: is called (but this should be harmless).
|
||||
[self performSelector:@selector(reapChildProcesses:)
|
||||
withObject:nil
|
||||
afterDelay:0.1];
|
||||
}
|
||||
|
||||
- (void)windowControllerWillOpen:(MMWindowController *)windowController
|
||||
@@ -739,10 +670,28 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
}
|
||||
|
||||
if (!NSEqualPoints(topLeft, NSZeroPoint)) {
|
||||
NSPoint oldTopLeft = topLeft;
|
||||
if (topWin)
|
||||
topLeft = [win cascadeTopLeftFromPoint:topLeft];
|
||||
|
||||
[win setFrameTopLeftPoint:topLeft];
|
||||
|
||||
NSPoint screenOrigin = [[win screen] frame].origin;
|
||||
if ([win frame].origin.y < screenOrigin.y) {
|
||||
// Try to avoid shifting the new window downwards if it means that
|
||||
// the bottom of the window will be off the screen. E.g. if the
|
||||
// user has set windows to open maximized in the vertical direction
|
||||
// then the new window will cascade horizontally only.
|
||||
topLeft.y = oldTopLeft.y;
|
||||
[win setFrameTopLeftPoint:topLeft];
|
||||
}
|
||||
|
||||
if ([win frame].origin.y < screenOrigin.y) {
|
||||
// Move the window to the top of the screen if the bottom of the
|
||||
// window is still obscured.
|
||||
topLeft.y = NSMaxY([[win screen] frame]);
|
||||
[win setFrameTopLeftPoint:topLeft];
|
||||
}
|
||||
}
|
||||
|
||||
if (1 == [vimControllers count]) {
|
||||
@@ -843,6 +792,154 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
return [self filterOpenFiles:filenames openFilesDict:nil];
|
||||
}
|
||||
|
||||
- (BOOL)openFiles:(NSArray *)filenames withArguments:(NSDictionary *)args
|
||||
{
|
||||
// Opening files works like this:
|
||||
// a) filter out any already open files
|
||||
// b) open any remaining files
|
||||
//
|
||||
// A file is opened in an untitled window if there is one (it may be
|
||||
// currently launching, or it may already be visible), otherwise a new
|
||||
// window is opened.
|
||||
//
|
||||
// Each launching Vim process has a dictionary of arguments that are passed
|
||||
// to the process when in checks in (via connectBackend:pid:). The
|
||||
// arguments for each launching process can be looked up by its PID (in the
|
||||
// pidArguments dictionary).
|
||||
|
||||
NSMutableDictionary *arguments = (args ? [[args mutableCopy] autorelease]
|
||||
: [NSMutableDictionary dictionary]);
|
||||
|
||||
//
|
||||
// a) Filter out any already open files
|
||||
//
|
||||
NSString *firstFile = [filenames objectAtIndex:0];
|
||||
MMVimController *firstController = nil;
|
||||
NSDictionary *openFilesDict = nil;
|
||||
filenames = [self filterOpenFiles:filenames openFilesDict:&openFilesDict];
|
||||
|
||||
// Pass arguments to vim controllers that had files open.
|
||||
id key;
|
||||
NSEnumerator *e = [openFilesDict keyEnumerator];
|
||||
|
||||
// (Indicate that we do not wish to open any files at the moment.)
|
||||
[arguments setObject:[NSNumber numberWithBool:YES] forKey:@"dontOpen"];
|
||||
|
||||
while ((key = [e nextObject])) {
|
||||
NSArray *files = [openFilesDict objectForKey:key];
|
||||
[arguments setObject:files forKey:@"filenames"];
|
||||
|
||||
MMVimController *vc = [key pointerValue];
|
||||
[vc passArguments:arguments];
|
||||
|
||||
// If this controller holds the first file, then remember it for later.
|
||||
if ([files containsObject:firstFile])
|
||||
firstController = vc;
|
||||
}
|
||||
|
||||
// The meaning of "layout" is defined by the WIN_* defines in main.c.
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
int layout = [ud integerForKey:MMOpenLayoutKey];
|
||||
BOOL splitVert = [ud boolForKey:MMVerticalSplitKey];
|
||||
BOOL openInCurrentWindow = [ud boolForKey:MMOpenInCurrentWindowKey];
|
||||
|
||||
if (splitVert && MMLayoutHorizontalSplit == layout)
|
||||
layout = MMLayoutVerticalSplit;
|
||||
if (layout < 0 || (layout > MMLayoutTabs && openInCurrentWindow))
|
||||
layout = MMLayoutTabs;
|
||||
|
||||
if ([filenames count] == 0) {
|
||||
// Raise the window containing the first file that was already open,
|
||||
// and make sure that the tab containing that file is selected. Only
|
||||
// do this when there are no more files to open, otherwise sometimes
|
||||
// the window with 'firstFile' will be raised, other times it might be
|
||||
// the window that will open with the files in the 'filenames' array.
|
||||
firstFile = [firstFile stringByEscapingSpecialFilenameCharacters];
|
||||
|
||||
NSString *bufCmd = @"tab sb";
|
||||
switch (layout) {
|
||||
case MMLayoutHorizontalSplit: bufCmd = @"sb"; break;
|
||||
case MMLayoutVerticalSplit: bufCmd = @"vert sb"; break;
|
||||
case MMLayoutArglist: bufCmd = @"b"; break;
|
||||
}
|
||||
|
||||
NSString *input = [NSString stringWithFormat:@"<C-\\><C-N>"
|
||||
":let oldswb=&swb|let &swb=\"useopen,usetab\"|"
|
||||
"%@ %@|let &swb=oldswb|unl oldswb|"
|
||||
"cal foreground()<CR>", bufCmd, firstFile];
|
||||
|
||||
[firstController addVimInput:input];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Add filenames to "Recent Files" menu, unless they are being edited
|
||||
// remotely (using ODB).
|
||||
if ([arguments objectForKey:@"remoteID"] == nil) {
|
||||
[[NSDocumentController sharedDocumentController]
|
||||
noteNewRecentFilePaths:filenames];
|
||||
}
|
||||
|
||||
//
|
||||
// b) Open any remaining files
|
||||
//
|
||||
|
||||
[arguments setObject:[NSNumber numberWithInt:layout] forKey:@"layout"];
|
||||
[arguments setObject:filenames forKey:@"filenames"];
|
||||
// (Indicate that files should be opened from now on.)
|
||||
[arguments setObject:[NSNumber numberWithBool:NO] forKey:@"dontOpen"];
|
||||
|
||||
MMVimController *vc;
|
||||
if (openInCurrentWindow && (vc = [self topmostVimController])) {
|
||||
// Open files in an already open window.
|
||||
[[[vc windowController] window] makeKeyAndOrderFront:self];
|
||||
[vc passArguments:arguments];
|
||||
return YES;
|
||||
}
|
||||
|
||||
BOOL openOk = YES;
|
||||
int numFiles = [filenames count];
|
||||
if (MMLayoutWindows == layout && numFiles > 1) {
|
||||
// Open one file at a time in a new window, but don't open too many at
|
||||
// once (at most cap+1 windows will open). If the user has increased
|
||||
// the preload cache size we'll take that as a hint that more windows
|
||||
// should be able to open at once.
|
||||
int cap = [self maxPreloadCacheSize] - 1;
|
||||
if (cap < 4) cap = 4;
|
||||
if (cap > numFiles) cap = numFiles;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < cap; ++i) {
|
||||
NSArray *a = [NSArray arrayWithObject:[filenames objectAtIndex:i]];
|
||||
[arguments setObject:a forKey:@"filenames"];
|
||||
|
||||
// NOTE: We have to copy the args since we'll mutate them in the
|
||||
// next loop and the below call may retain the arguments while
|
||||
// waiting for a process to start.
|
||||
NSDictionary *args = [[arguments copy] autorelease];
|
||||
|
||||
openOk = [self openVimControllerWithArguments:args];
|
||||
if (!openOk) break;
|
||||
}
|
||||
|
||||
// Open remaining files in tabs in a new window.
|
||||
if (openOk && numFiles > cap) {
|
||||
NSRange range = { i, numFiles-cap };
|
||||
NSArray *a = [filenames subarrayWithRange:range];
|
||||
[arguments setObject:a forKey:@"filenames"];
|
||||
[arguments setObject:[NSNumber numberWithInt:MMLayoutTabs]
|
||||
forKey:@"layout"];
|
||||
|
||||
openOk = [self openVimControllerWithArguments:arguments];
|
||||
}
|
||||
} else {
|
||||
// Open all files at once.
|
||||
openOk = [self openVimControllerWithArguments:arguments];
|
||||
}
|
||||
|
||||
return openOk;
|
||||
}
|
||||
|
||||
#ifdef MM_ENABLE_PLUGINS
|
||||
- (void)addItemToPlugInMenu:(NSMenuItem *)item
|
||||
{
|
||||
@@ -887,7 +984,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
boolForKey:MMDialogsTrackPwdKey];
|
||||
if (trackPwd) {
|
||||
MMVimController *vc = [self keyVimController];
|
||||
if (vc) dir = [[vc vimState] objectForKey:@"pwd"];
|
||||
if (vc) dir = [vc objectForVimStateKey:@"pwd"];
|
||||
}
|
||||
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
@@ -1029,7 +1126,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
// MacVim would steal the focus if another app was activated while the
|
||||
// untitled window was loading.
|
||||
if (!args || args != [NSNull null])
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
[self activateWhenNextWindowOpens];
|
||||
|
||||
if (args)
|
||||
[pidArguments removeObjectForKey:pidKey];
|
||||
@@ -1094,16 +1191,17 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
return;
|
||||
}
|
||||
|
||||
MMVimController *vc = [self topmostVimController];
|
||||
if (vc) {
|
||||
// Open a new tab first, since dropString: does not do this.
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
BOOL openInCurrentWindow = [ud boolForKey:MMOpenInCurrentWindowKey];
|
||||
MMVimController *vc;
|
||||
|
||||
if (openInCurrentWindow && (vc = [self topmostVimController])) {
|
||||
[vc sendMessage:AddNewTabMsgID data:nil];
|
||||
[vc dropString:[pboard stringForType:NSStringPboardType]];
|
||||
} else {
|
||||
// NOTE: There is no window to paste the selection into, so save the
|
||||
// text, open a new window, and paste the text when the next window
|
||||
// opens. (If this is called several times in a row, then all but the
|
||||
// last call might be ignored.)
|
||||
// Save the text, open a new window, and paste the text when the next
|
||||
// window opens. (If this is called several times in a row, then all
|
||||
// but the last call may be ignored.)
|
||||
if (openSelectionString) [openSelectionString release];
|
||||
openSelectionString = [[pboard stringForType:NSStringPboardType] copy];
|
||||
|
||||
@@ -1128,16 +1226,55 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
NSArray *filenames = [self filterFilesAndNotify:
|
||||
[NSArray arrayWithObject:string]];
|
||||
if ([filenames count] > 0) {
|
||||
MMVimController *vc = nil;
|
||||
if (userData && [userData isEqual:@"Tab"])
|
||||
vc = [self topmostVimController];
|
||||
if ([filenames count] == 0)
|
||||
return;
|
||||
|
||||
if (vc) {
|
||||
[vc dropFiles:filenames forceOpen:YES];
|
||||
} else {
|
||||
[self application:NSApp openFiles:filenames];
|
||||
}
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
BOOL openInCurrentWindow = [ud boolForKey:MMOpenInCurrentWindowKey];
|
||||
MMVimController *vc;
|
||||
|
||||
if (openInCurrentWindow && (vc = [self topmostVimController])) {
|
||||
[vc dropFiles:filenames forceOpen:YES];
|
||||
} else {
|
||||
[self openFiles:filenames withArguments:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)newFileHere:(NSPasteboard *)pboard userData:(NSString *)userData
|
||||
error:(NSString **)error
|
||||
{
|
||||
if (![[pboard types] containsObject:NSStringPboardType]) {
|
||||
NSLog(@"WARNING: Pasteboard contains no object of type "
|
||||
"NSStringPboardType");
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *path = [pboard stringForType:NSStringPboardType];
|
||||
|
||||
BOOL dirIndicator;
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:path
|
||||
isDirectory:&dirIndicator]) {
|
||||
NSLog(@"Invalid path. Cannot open new document at: %@", path);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dirIndicator)
|
||||
path = [path stringByDeletingLastPathComponent];
|
||||
|
||||
path = [path stringByEscapingSpecialFilenameCharacters];
|
||||
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
BOOL openInCurrentWindow = [ud boolForKey:MMOpenInCurrentWindowKey];
|
||||
MMVimController *vc;
|
||||
|
||||
if (openInCurrentWindow && (vc = [self topmostVimController])) {
|
||||
NSString *input = [NSString stringWithFormat:@"<C-\\><C-N>"
|
||||
":tabe|cd %@<CR>", path];
|
||||
[vc addVimInput:input];
|
||||
} else {
|
||||
NSString *input = [NSString stringWithFormat:@":cd %@", path];
|
||||
[self launchVimProcessWithArguments:[NSArray arrayWithObjects:
|
||||
@"-c", input, nil]];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1184,7 +1321,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
if (useLoginShell) {
|
||||
// Run process with a login shell, roughly:
|
||||
// echo "exec Vim -g -f args" | ARGV0=-`basename $SHELL` $SHELL [-l]
|
||||
pid = executeInLoginShell(path, taskArgs);
|
||||
pid = [self executeInLoginShell:path arguments:taskArgs];
|
||||
} else {
|
||||
// Run process directly:
|
||||
// Vim -g -f args
|
||||
@@ -1194,9 +1331,18 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
}
|
||||
|
||||
if (-1 != pid) {
|
||||
// NOTE: If the process has no arguments, then add a null argument to
|
||||
// the pidArguments dictionary. This is later used to detect that a
|
||||
// process without arguments is being launched.
|
||||
// The 'pidArguments' dictionary keeps arguments to be passed to the
|
||||
// process when it connects (this is in contrast to arguments which are
|
||||
// passed on the command line, like '-f' and '-g').
|
||||
// If this method is called with nil arguments we take this as a hint
|
||||
// that this is an "untitled window" being launched and add a null
|
||||
// object to the 'pidArguments' dictionary. This way we can detect if
|
||||
// an untitled window is being launched by looking for null objects in
|
||||
// this dictionary.
|
||||
// If this method is called with non-nil arguments then it is assumed
|
||||
// that the caller takes care of adding items to 'pidArguments' as
|
||||
// necessary (only some arguments are passed on connect, e.g. files to
|
||||
// open).
|
||||
if (!args)
|
||||
[pidArguments setObject:[NSNull null]
|
||||
forKey:[NSNumber numberWithInt:pid]];
|
||||
@@ -1330,6 +1476,95 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
|
||||
replyEvent:(NSAppleEventDescriptor *)reply
|
||||
{
|
||||
NSString *urlString = [[event paramDescriptorForKeyword:keyDirectObject]
|
||||
stringValue];
|
||||
NSURL *url = [NSURL URLWithString:urlString];
|
||||
|
||||
// We try to be compatible with TextMate's URL scheme here, as documented
|
||||
// at http://blog.macromates.com/2007/the-textmate-url-scheme/ . Currently,
|
||||
// this means that:
|
||||
//
|
||||
// The format is: mvim://open?<arguments> where arguments can be:
|
||||
//
|
||||
// * url — the actual file to open (i.e. a file://… URL), if you leave
|
||||
// out this argument, the frontmost document is implied.
|
||||
// * line — line number to go to (one based).
|
||||
// * column — column number to go to (one based).
|
||||
//
|
||||
// Example: mvim://open?url=file:///etc/profile&line=20
|
||||
|
||||
if ([[url host] isEqualToString:@"open"]) {
|
||||
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
|
||||
|
||||
// Parse query ("url=file://...&line=14") into a dictionary
|
||||
NSArray *queries = [[url query] componentsSeparatedByString:@"&"];
|
||||
NSEnumerator *enumerator = [queries objectEnumerator];
|
||||
NSString *param;
|
||||
while( param = [enumerator nextObject] ) {
|
||||
NSArray *arr = [param componentsSeparatedByString:@"="];
|
||||
if ([arr count] == 2) {
|
||||
[dict setValue:[[arr lastObject]
|
||||
stringByReplacingPercentEscapesUsingEncoding:
|
||||
NSUTF8StringEncoding]
|
||||
forKey:[[arr objectAtIndex:0]
|
||||
stringByReplacingPercentEscapesUsingEncoding:
|
||||
NSUTF8StringEncoding]];
|
||||
}
|
||||
}
|
||||
|
||||
// Actually open the file.
|
||||
NSString *file = [dict objectForKey:@"url"];
|
||||
if (file != nil) {
|
||||
NSURL *fileUrl= [NSURL URLWithString:file];
|
||||
// TextMate only opens files that already exist.
|
||||
if ([fileUrl isFileURL]
|
||||
&& [[NSFileManager defaultManager] fileExistsAtPath:
|
||||
[fileUrl path]]) {
|
||||
// Strip 'file://' path, else application:openFiles: might think
|
||||
// the file is not yet open.
|
||||
NSArray *filenames = [NSArray arrayWithObject:[fileUrl path]];
|
||||
|
||||
// Look for the line and column options.
|
||||
NSDictionary *args = nil;
|
||||
NSString *line = [dict objectForKey:@"line"];
|
||||
if (line) {
|
||||
NSString *column = [dict objectForKey:@"column"];
|
||||
if (column)
|
||||
args = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
line, @"cursorLine",
|
||||
column, @"cursorColumn",
|
||||
nil];
|
||||
else
|
||||
args = [NSDictionary dictionaryWithObject:line
|
||||
forKey:@"cursorLine"];
|
||||
}
|
||||
|
||||
[self openFiles:filenames withArguments:args];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"OK",
|
||||
@"Dialog button")];
|
||||
|
||||
[alert setMessageText:NSLocalizedString(@"Unknown URL Scheme",
|
||||
@"Unknown URL Scheme dialog, title")];
|
||||
[alert setInformativeText:[NSString stringWithFormat:NSLocalizedString(
|
||||
@"This version of MacVim does not support \"%@\""
|
||||
@" in its URL scheme.",
|
||||
@"Unknown URL Scheme dialog, text"),
|
||||
[url host]]];
|
||||
|
||||
[alert setAlertStyle:NSWarningAlertStyle];
|
||||
[alert runModal];
|
||||
[alert release];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (int)findLaunchingProcessWithoutArguments
|
||||
{
|
||||
NSArray *keys = [pidArguments allKeysForObject:[NSNull null]];
|
||||
@@ -1346,7 +1581,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
NSEnumerator *e = [vimControllers objectEnumerator];
|
||||
id vc;
|
||||
while ((vc = [e nextObject])) {
|
||||
if ([[[vc vimState] objectForKey:@"unusedEditor"] boolValue])
|
||||
if ([[vc objectForVimStateKey:@"unusedEditor"] boolValue])
|
||||
return vc;
|
||||
}
|
||||
|
||||
@@ -1561,6 +1796,14 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
n = count;
|
||||
while (n-- > 0 && [cachedVimControllers count] > 0)
|
||||
[cachedVimControllers removeObjectAtIndex:0];
|
||||
|
||||
// There is a small delay before the Vim process actually exits so wait a
|
||||
// little before trying to reap the child process. If the process still
|
||||
// hasn't exited after this wait it won't be reaped until the next time
|
||||
// reapChildProcesses: is called (but this should be harmless).
|
||||
[self performSelector:@selector(reapChildProcesses:)
|
||||
withObject:nil
|
||||
afterDelay:0.1];
|
||||
}
|
||||
|
||||
- (void)rebuildPreloadCache
|
||||
@@ -1700,13 +1943,53 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
[self scheduleVimControllerPreloadAfterDelay:0.5];
|
||||
}
|
||||
|
||||
@end // MMAppController (Private)
|
||||
- (void)loadDefaultFont
|
||||
{
|
||||
// It is possible to set a user default to avoid loading the default font
|
||||
// (this cuts down on startup time).
|
||||
if (![[NSUserDefaults standardUserDefaults] boolForKey:MMLoadDefaultFontKey]
|
||||
|| fontContainerRef)
|
||||
return;
|
||||
|
||||
// Load all fonts in the Resouces folder of the app bundle.
|
||||
NSString *fontsFolder = [[NSBundle mainBundle] resourcePath];
|
||||
if (fontsFolder) {
|
||||
NSURL *fontsURL = [NSURL fileURLWithPath:fontsFolder];
|
||||
if (fontsURL) {
|
||||
FSRef fsRef;
|
||||
CFURLGetFSRef((CFURLRef)fontsURL, &fsRef);
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
// This is the font activation API for OS X 10.5. Only compile
|
||||
// this code if we're building on OS X 10.5 or later.
|
||||
if (NULL != ATSFontActivateFromFileReference) { // Weakly linked
|
||||
ATSFontActivateFromFileReference(&fsRef, kATSFontContextLocal,
|
||||
kATSFontFormatUnspecified,
|
||||
NULL, kATSOptionFlagsDefault,
|
||||
&fontContainerRef);
|
||||
}
|
||||
#endif
|
||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4)
|
||||
// The following font activation API was deprecated in OS X 10.5.
|
||||
// Don't compile this code unless we're targeting OS X 10.4.
|
||||
FSSpec fsSpec;
|
||||
if (fontContainerRef == 0 &&
|
||||
FSGetCatalogInfo(&fsRef, kFSCatInfoNone, NULL, NULL,
|
||||
&fsSpec, NULL) == noErr) {
|
||||
ATSFontActivateFromFileSpecification(&fsSpec,
|
||||
kATSFontContextLocal, kATSFontFormatUnspecified, NULL,
|
||||
kATSOptionFlagsDefault, &fontContainerRef);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!fontContainerRef)
|
||||
NSLog(@"WARNING: Failed to activate the default font (the app bundle "
|
||||
"may be incomplete)");
|
||||
}
|
||||
|
||||
static int
|
||||
executeInLoginShell(NSString *path, NSArray *args)
|
||||
- (int)executeInLoginShell:(NSString *)path arguments:(NSArray *)args
|
||||
{
|
||||
// Start a login shell and execute the command 'path' with arguments 'args'
|
||||
// in the shell. This ensures that user environment variables are set even
|
||||
@@ -1777,9 +2060,16 @@ executeInLoginShell(NSString *path, NSArray *args)
|
||||
return -1;
|
||||
} else if (pid == 0) {
|
||||
// Child process
|
||||
|
||||
if (close(ds[1]) == -1) exit(255);
|
||||
if (dup2(ds[0], 0) == -1) exit(255);
|
||||
|
||||
// Without the following call warning messages like this appear on the
|
||||
// console:
|
||||
// com.apple.launchd[69] : Stray process with PGID equal to this
|
||||
// dead job: PID 1589 PPID 1 Vim
|
||||
setsid();
|
||||
|
||||
execv(shellPath, shellArgv);
|
||||
|
||||
// Never reached unless execv fails
|
||||
@@ -1794,7 +2084,30 @@ executeInLoginShell(NSString *path, NSArray *args)
|
||||
|
||||
if (write(ds[1], [input UTF8String], bytes) != bytes) return -1;
|
||||
if (close(ds[1]) == -1) return -1;
|
||||
|
||||
++numChildProcesses;
|
||||
//NSLog(@"new process pid=%d (count=%d)", pid, numChildProcesses);
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
- (void)reapChildProcesses:(id)sender
|
||||
{
|
||||
// NOTE: numChildProcesses (currently) only counts the number of Vim
|
||||
// processes that have been started with executeInLoginShell::. If other
|
||||
// processes are spawned this code may need to be adjusted (or
|
||||
// numChildProcesses needs to be incremented when such a process is
|
||||
// started).
|
||||
while (numChildProcesses > 0) {
|
||||
int status = 0;
|
||||
int pid = waitpid(-1, &status, WNOHANG);
|
||||
if (pid <= 0)
|
||||
break;
|
||||
|
||||
//NSLog(@"WAIT for pid=%d complete", pid);
|
||||
--numChildProcesses;
|
||||
}
|
||||
}
|
||||
|
||||
@end // MMAppController (Private)
|
||||
|
||||
@@ -9,20 +9,21 @@
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "MMTextView.h"
|
||||
|
||||
enum { MMMaxCellsPerChar = 2 };
|
||||
|
||||
@class MMTextViewHelper;
|
||||
|
||||
|
||||
@interface MMAtsuiTextView : NSView {
|
||||
@interface MMAtsuiTextView : NSView <NSTextInput> {
|
||||
// From MMTextStorage
|
||||
int maxRows, maxColumns;
|
||||
NSColor *defaultBackgroundColor;
|
||||
NSColor *defaultForegroundColor;
|
||||
NSSize cellSize;
|
||||
NSFont *font;
|
||||
NSFont *fontWide;
|
||||
float linespace;
|
||||
float ascender;
|
||||
|
||||
@@ -44,28 +45,33 @@ enum { MMMaxCellsPerChar = 2 };
|
||||
// MMTextStorage methods
|
||||
//
|
||||
- (int)maxRows;
|
||||
- (int)maxColumns;
|
||||
- (void)getMaxRows:(int*)rows columns:(int*)cols;
|
||||
- (void)setMaxRows:(int)rows columns:(int)cols;
|
||||
- (void)setDefaultColorsBackground:(NSColor *)bgColor
|
||||
foreground:(NSColor *)fgColor;
|
||||
- (NSColor *)defaultBackgroundColor;
|
||||
- (NSColor *)defaultForegroundColor;
|
||||
- (NSRect)rectForRowsInRange:(NSRange)range;
|
||||
- (NSRect)rectForColumnsInRange:(NSRange)range;
|
||||
|
||||
- (void)setFont:(NSFont *)newFont;
|
||||
- (void)setWideFont:(NSFont *)newFont;
|
||||
- (NSFont *)font;
|
||||
- (NSFont *)fontWide;
|
||||
- (NSSize)cellSize;
|
||||
- (void)setLinespace:(float)newLinespace;
|
||||
|
||||
//
|
||||
// MMTextView methods
|
||||
//
|
||||
- (void)setShouldDrawInsertionPoint:(BOOL)on;
|
||||
- (void)setPreEditRow:(int)row column:(int)col;
|
||||
- (void)hideMarkedTextField;
|
||||
- (void)setMouseShape:(int)shape;
|
||||
- (void)setAntialias:(BOOL)state;
|
||||
- (BOOL)convertPoint:(NSPoint)point toRow:(int *)row column:(int *)column;
|
||||
- (NSPoint)pointForRow:(int)row column:(int)col;
|
||||
- (NSRect)rectForRow:(int)row column:(int)col numRows:(int)nr
|
||||
numColumns:(int)nc;
|
||||
|
||||
//
|
||||
// NSTextView methods
|
||||
|
||||
+194
-34
@@ -87,7 +87,7 @@
|
||||
column:(int)col2 color:(NSColor *)color;
|
||||
- (void)clearAll;
|
||||
- (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
|
||||
fraction:(int)percent color:(NSColor *)color;
|
||||
fraction:(int)percent;
|
||||
- (void)drawInvertedRectAtRow:(int)row column:(int)col numRows:(int)nrows
|
||||
numColumns:(int)ncols;
|
||||
@end
|
||||
@@ -139,6 +139,8 @@ defaultLineHeightForFont(NSFont *font)
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
LOG_DEALLOC
|
||||
|
||||
[self disposeAtsuStyles];
|
||||
[font release]; font = nil;
|
||||
[defaultBackgroundColor release]; defaultBackgroundColor = nil;
|
||||
@@ -155,6 +157,11 @@ defaultLineHeightForFont(NSFont *font)
|
||||
return maxRows;
|
||||
}
|
||||
|
||||
- (int)maxColumns
|
||||
{
|
||||
return maxColumns;
|
||||
}
|
||||
|
||||
- (void)getMaxRows:(int*)rows columns:(int*)cols
|
||||
{
|
||||
if (rows) *rows = maxRows;
|
||||
@@ -176,15 +183,22 @@ defaultLineHeightForFont(NSFont *font)
|
||||
defaultBackgroundColor = bgColor ? [bgColor retain] : nil;
|
||||
}
|
||||
|
||||
// NOTE: The default foreground color isn't actually used for anything, but
|
||||
// other class instances might want to be able to access it so it is stored
|
||||
// here.
|
||||
if (defaultForegroundColor != fgColor) {
|
||||
[defaultForegroundColor release];
|
||||
defaultForegroundColor = fgColor ? [fgColor retain] : nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSColor *)defaultBackgroundColor
|
||||
{
|
||||
return defaultBackgroundColor;
|
||||
}
|
||||
|
||||
- (NSColor *)defaultForegroundColor
|
||||
{
|
||||
return defaultForegroundColor;
|
||||
}
|
||||
|
||||
- (void)setTextContainerInset:(NSSize)size
|
||||
{
|
||||
insetSize = size;
|
||||
@@ -247,6 +261,18 @@ defaultLineHeightForFont(NSFont *font)
|
||||
|
||||
- (void)setWideFont:(NSFont *)newFont
|
||||
{
|
||||
if (!newFont) {
|
||||
if (font) [self setWideFont:font];
|
||||
} else if (newFont != fontWide) {
|
||||
float pointSize = [newFont pointSize];
|
||||
NSFontDescriptor *desc = [newFont fontDescriptor];
|
||||
NSDictionary *dictWide = [NSDictionary
|
||||
dictionaryWithObject:[NSNumber numberWithFloat:2*cellSize.width]
|
||||
forKey:NSFontFixedAdvanceAttribute];
|
||||
desc = [desc fontDescriptorByAddingAttributes:dictWide];
|
||||
fontWide = [NSFont fontWithDescriptor:desc size:pointSize];
|
||||
[fontWide retain];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSFont *)font
|
||||
@@ -254,6 +280,11 @@ defaultLineHeightForFont(NSFont *font)
|
||||
return font;
|
||||
}
|
||||
|
||||
- (NSFont *)fontWide
|
||||
{
|
||||
return fontWide;
|
||||
}
|
||||
|
||||
- (NSSize)cellSize
|
||||
{
|
||||
return cellSize;
|
||||
@@ -274,17 +305,13 @@ defaultLineHeightForFont(NSFont *font)
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)setShouldDrawInsertionPoint:(BOOL)on
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setPreEditRow:(int)row column:(int)col
|
||||
{
|
||||
}
|
||||
|
||||
- (void)hideMarkedTextField
|
||||
{
|
||||
[helper setPreEditRow:row column:col];
|
||||
}
|
||||
|
||||
- (void)setMouseShape:(int)shape
|
||||
@@ -297,9 +324,6 @@ defaultLineHeightForFont(NSFont *font)
|
||||
antialias = state;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)keyDown:(NSEvent *)event
|
||||
{
|
||||
[helper keyDown:event];
|
||||
@@ -322,11 +346,32 @@ defaultLineHeightForFont(NSFont *font)
|
||||
|
||||
- (BOOL)hasMarkedText
|
||||
{
|
||||
return NO;
|
||||
return [helper hasMarkedText];
|
||||
}
|
||||
|
||||
- (NSRange)markedRange
|
||||
{
|
||||
return [helper markedRange];
|
||||
}
|
||||
|
||||
- (NSDictionary *)markedTextAttributes
|
||||
{
|
||||
return [helper markedTextAttributes];
|
||||
}
|
||||
|
||||
- (void)setMarkedTextAttributes:(NSDictionary *)attr
|
||||
{
|
||||
[helper setMarkedTextAttributes:attr];
|
||||
}
|
||||
|
||||
- (void)setMarkedText:(id)text selectedRange:(NSRange)range
|
||||
{
|
||||
[helper setMarkedText:text selectedRange:range];
|
||||
}
|
||||
|
||||
- (void)unmarkText
|
||||
{
|
||||
[helper unmarkText];
|
||||
}
|
||||
|
||||
- (void)scrollWheel:(NSEvent *)event
|
||||
@@ -457,19 +502,68 @@ defaultLineHeightForFont(NSFont *font)
|
||||
|
||||
- (void)drawRect:(NSRect)rect
|
||||
{
|
||||
NSRect srcRect = NSMakeRect(0, 0, imageSize.width, imageSize.height);
|
||||
NSRect dstRect = srcRect;
|
||||
|
||||
dstRect.origin.x += insetSize.width;
|
||||
dstRect.origin.y += insetSize.height;
|
||||
|
||||
[defaultBackgroundColor set];
|
||||
NSRectFill(rect);
|
||||
|
||||
[contentImage drawInRect: dstRect
|
||||
fromRect: srcRect
|
||||
operation: NSCompositeCopy
|
||||
fraction: 1.0];
|
||||
NSPoint pt = { insetSize.width, insetSize.height };
|
||||
[contentImage compositeToPoint:pt operation:NSCompositeCopy];
|
||||
|
||||
if ([self hasMarkedText]) {
|
||||
int len = [[helper markedText] length];
|
||||
int rows = 0;
|
||||
int cols = maxColumns - [helper preEditColumn];
|
||||
NSFont *theFont = [[self markedTextAttributes]
|
||||
valueForKey:NSFontAttributeName];
|
||||
if (theFont == [self fontWide])
|
||||
cols = cols / 2;
|
||||
int done = 0;
|
||||
int lend = cols > len ? len : cols;
|
||||
NSAttributedString *aString = [[helper markedText]
|
||||
attributedSubstringFromRange:NSMakeRange(done, lend)];
|
||||
NSPoint pt = [self pointForRow:[helper preEditRow]
|
||||
column:[helper preEditColumn]];
|
||||
[aString drawAtPoint:pt];
|
||||
done = lend;
|
||||
if (done != len) {
|
||||
int r;
|
||||
rows = (len - done) / (maxColumns / 2) + 1;
|
||||
for (r = 1; r <= rows; r++) {
|
||||
lend = len - done > maxColumns / 2
|
||||
? maxColumns / 2 : len - done;
|
||||
aString = [[helper markedText] attributedSubstringFromRange:
|
||||
NSMakeRange(done, lend)];
|
||||
NSPoint pt = [self pointForRow:[helper preEditRow]+r
|
||||
column:0];
|
||||
[aString drawAtPoint:pt];
|
||||
done += lend;
|
||||
}
|
||||
}
|
||||
|
||||
rows = maxRows - 1 - [helper preEditRow];
|
||||
cols = [helper preEditColumn];
|
||||
if (theFont == fontWide) {
|
||||
cols += ([helper imRange].location+[helper imRange].length) * 2;
|
||||
if (cols >= maxColumns - 1) {
|
||||
rows -= cols / maxColumns;
|
||||
cols = cols % 2 ? cols % maxColumns + 1 :
|
||||
cols % maxColumns;
|
||||
}
|
||||
} else {
|
||||
cols += ([helper imRange].location+[helper imRange].length);
|
||||
if (cols >= maxColumns) {
|
||||
rows -= cols / maxColumns;
|
||||
cols = cols % 2 ? cols % maxColumns + 1 :
|
||||
cols % maxColumns;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Could IM be in "right-left" mode? If so the insertion point
|
||||
// will be on the wrong side.
|
||||
[self drawInsertionPointAtRow:rows
|
||||
column:cols
|
||||
shape:MMInsertionPointVertical
|
||||
fraction:25];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) wantsDefaultClipping
|
||||
@@ -588,9 +682,9 @@ defaultLineHeightForFont(NSFont *font)
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Draw cursor at (%d,%d)", row, col);
|
||||
#endif
|
||||
[helper setInsertionPointColor:[NSColor colorWithRgbInt:color]];
|
||||
[self drawInsertionPointAtRow:row column:col shape:shape
|
||||
fraction:percent
|
||||
color:[NSColor colorWithRgbInt:color]];
|
||||
fraction:percent];
|
||||
} else if (DrawInvertedRectDrawType == type) {
|
||||
int row = *((int*)bytes); bytes += sizeof(int);
|
||||
int col = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -616,10 +710,12 @@ defaultLineHeightForFont(NSFont *font)
|
||||
|
||||
[self endDrawing];
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
// NOTE: During resizing, Cocoa only sends draw messages before Vim's rows
|
||||
// and columns are changed (due to ipc delays). Force a redraw here.
|
||||
[self setNeedsDisplay:YES];
|
||||
// [self displayIfNeeded];
|
||||
if ([self inLiveResize])
|
||||
[self display];
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@"<==== END %s", _cmd);
|
||||
@@ -750,12 +846,76 @@ defaultLineHeightForFont(NSFont *font)
|
||||
if (row) *row = floor((point.y-origin.y-1) / cellSize.height);
|
||||
if (column) *column = floor((point.x-origin.x-1) / cellSize.width);
|
||||
|
||||
//NSLog(@"convertPoint:%@ toRow:%d column:%d", NSStringFromPoint(point),
|
||||
// *row, *column);
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSPoint)pointForRow:(int)row column:(int)col
|
||||
{
|
||||
// Return the lower left coordinate of the cell at (row,column).
|
||||
NSPoint pt;
|
||||
|
||||
pt.x = insetSize.width + col*cellSize.width;
|
||||
pt.y = [self frame].size.height -
|
||||
(insetSize.height + (1+row)*cellSize.height);
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
||||
- (NSRect)rectForRow:(int)row column:(int)col numRows:(int)nr
|
||||
numColumns:(int)nc
|
||||
{
|
||||
// Return the rect for the block which covers the specified rows and
|
||||
// columns. The lower-left corner is the origin of this rect.
|
||||
NSRect rect;
|
||||
|
||||
rect.origin.x = insetSize.width + col*cellSize.width;
|
||||
rect.origin.y = [self frame].size.height -
|
||||
(insetSize.height + (nr+row)*cellSize.height);
|
||||
rect.size.width = nc*cellSize.width;
|
||||
rect.size.height = nr*cellSize.height;
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (NSArray *)validAttributesForMarkedText
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSAttributedString *)attributedSubstringFromRange:(NSRange)range
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSUInteger)characterIndexForPoint:(NSPoint)point
|
||||
{
|
||||
return NSNotFound;
|
||||
}
|
||||
|
||||
// The return type of this message changed with OS X 10.5 so we need this
|
||||
// kludge in order to avoid compiler warnings on OS X 10.4.
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
- (NSInteger)conversationIdentifier
|
||||
{
|
||||
return (NSInteger)self;
|
||||
}
|
||||
#else
|
||||
- (long)conversationIdentifier
|
||||
{
|
||||
return (long)self;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (NSRange)selectedRange
|
||||
{
|
||||
return [helper imRange];
|
||||
}
|
||||
|
||||
- (NSRect)firstRectForCharacterRange:(NSRange)range
|
||||
{
|
||||
return [helper firstRectForCharacterRange:range];
|
||||
}
|
||||
|
||||
@end // MMAtsuiTextView
|
||||
|
||||
|
||||
@@ -869,7 +1029,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
- (NSRect)rectFromRow:(int)row1 column:(int)col1
|
||||
toRow:(int)row2 column:(int)col2
|
||||
{
|
||||
NSPoint origin = [self originForRow: row1 column: col1];
|
||||
NSPoint origin = [self originForRow:row1 column:col1];
|
||||
return NSMakeRect(origin.x, origin.y,
|
||||
(col2 + 1 - col1) * cellSize.width,
|
||||
(row2 + 1 - row1) * cellSize.height);
|
||||
@@ -887,7 +1047,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
//NSLog(@"resizeContentImage");
|
||||
[contentImage release];
|
||||
contentImage = [[NSImage alloc] initWithSize:[self textAreaSize]];
|
||||
[contentImage setFlipped: YES];
|
||||
[contentImage setFlipped:YES];
|
||||
imageSize = [self textAreaSize];
|
||||
}
|
||||
|
||||
@@ -1065,7 +1225,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
}
|
||||
|
||||
- (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
|
||||
fraction:(int)percent color:(NSColor *)color
|
||||
fraction:(int)percent
|
||||
{
|
||||
NSPoint origin = [self originForRow:row column:col];
|
||||
NSRect rect = NSMakeRect(origin.x, origin.y,
|
||||
@@ -1086,7 +1246,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
rect.size.width = frac;
|
||||
}
|
||||
|
||||
[color set];
|
||||
[[helper insertionPointColor] set];
|
||||
if (MMInsertionPointHollow == shape) {
|
||||
NSFrameRect(rect);
|
||||
} else {
|
||||
|
||||
@@ -25,14 +25,12 @@
|
||||
NSDictionary *colorDict;
|
||||
NSDictionary *sysColorDict;
|
||||
NSDictionary *actionDict;
|
||||
BOOL inputReceived;
|
||||
BOOL tabBarVisible;
|
||||
unsigned backgroundColor;
|
||||
unsigned foregroundColor;
|
||||
unsigned specialColor;
|
||||
unsigned defaultBackgroundColor;
|
||||
unsigned defaultForegroundColor;
|
||||
NSDate *lastFlushDate;
|
||||
id dialogReturn;
|
||||
NSTimer *blinkTimer;
|
||||
int blinkState;
|
||||
@@ -43,12 +41,13 @@
|
||||
NSMutableDictionary *clientProxyDict;
|
||||
NSMutableDictionary *serverReplyDict;
|
||||
NSString *alternateServerName;
|
||||
ATSFontContainerRef fontContainerRef;
|
||||
NSFont *oldWideFont;
|
||||
GuiFont oldWideFont;
|
||||
BOOL isTerminating;
|
||||
BOOL waitForAck;
|
||||
int initialWindowLayout;
|
||||
BOOL flushDisabled;
|
||||
unsigned numWholeLineChanges;
|
||||
unsigned offsetForDrawDataPrune;
|
||||
}
|
||||
|
||||
+ (MMBackend *)sharedInstance;
|
||||
@@ -97,8 +96,7 @@
|
||||
- (void)setScrollbarPosition:(int)pos length:(int)len identifier:(long)ident;
|
||||
- (void)setScrollbarThumbValue:(long)val size:(long)size max:(long)max
|
||||
identifier:(long)ident;
|
||||
- (void)setFont:(NSFont *)font;
|
||||
- (void)setWideFont:(NSFont *)font;
|
||||
- (void)setFont:(GuiFont)font wide:(BOOL)wide;
|
||||
- (void)executeActionWithName:(NSString *)name;
|
||||
- (void)setMouseShape:(int)shape;
|
||||
- (void)setBlinkWait:(int)wait on:(int)on off:(int)off;
|
||||
@@ -113,6 +111,7 @@
|
||||
|
||||
- (void)enterFullscreen:(int)fuoptions background:(int)bg;
|
||||
- (void)leaveFullscreen;
|
||||
- (void)setFullscreenBackgroundColor:(int)color;
|
||||
|
||||
- (void)setAntialias:(BOOL)antialias;
|
||||
|
||||
|
||||
+510
-374
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
||||
/* vi:set ts=8 sts=4 sw=4 ft=objc:
|
||||
*
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
*
|
||||
* Do ":help uganda" in Vim to read copying and usage conditions.
|
||||
* Do ":help credits" in Vim to see a list of people who contributed.
|
||||
* See README.txt for an overview of the Vim source code.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
|
||||
@interface MMFindReplaceController : NSWindowController {
|
||||
IBOutlet NSTextField *findBox;
|
||||
IBOutlet NSTextField *replaceBox;
|
||||
IBOutlet NSButton *ignoreCaseButton;
|
||||
IBOutlet NSButton *matchWordButton;
|
||||
}
|
||||
|
||||
+ (MMFindReplaceController *)sharedInstance;
|
||||
|
||||
- (void)showWithText:(NSString *)text flags:(int)flags;
|
||||
- (NSString *)findString;
|
||||
- (NSString *)replaceString;
|
||||
- (BOOL)ignoreCase;
|
||||
- (BOOL)matchWord;
|
||||
@end
|
||||
@@ -0,0 +1,63 @@
|
||||
/* vi:set ts=8 sts=4 sw=4 ft=objc:
|
||||
*
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
*
|
||||
* Do ":help uganda" in Vim to read copying and usage conditions.
|
||||
* Do ":help credits" in Vim to see a list of people who contributed.
|
||||
* See README.txt for an overview of the Vim source code.
|
||||
*/
|
||||
|
||||
#import "MMFindReplaceController.h"
|
||||
|
||||
|
||||
@implementation MMFindReplaceController
|
||||
|
||||
+ (MMFindReplaceController *)sharedInstance
|
||||
{
|
||||
static MMFindReplaceController *singleton = nil;
|
||||
if (!singleton) {
|
||||
singleton = [[MMFindReplaceController alloc]
|
||||
initWithWindowNibName:@"FindAndReplace"];
|
||||
[singleton setWindowFrameAutosaveName:@"FindAndReplace"];
|
||||
}
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
||||
- (void)showWithText:(NSString *)text flags:(int)flags
|
||||
{
|
||||
// Ensure that the window has been loaded by calling this first.
|
||||
NSWindow *window = [self window];
|
||||
|
||||
if (text && [text length] > 0)
|
||||
[findBox setStringValue:text];
|
||||
|
||||
// NOTE: The 'flags' values must match the FRD_ defines in gui.h.
|
||||
[matchWordButton setState:(flags & 0x08 ? NSOnState : NSOffState)];
|
||||
[ignoreCaseButton setState:(flags & 0x10 ? NSOffState : NSOnState)];
|
||||
|
||||
[window makeKeyAndOrderFront:self];
|
||||
}
|
||||
|
||||
- (NSString *)findString
|
||||
{
|
||||
return [findBox stringValue];
|
||||
}
|
||||
|
||||
- (NSString *)replaceString
|
||||
{
|
||||
return [replaceBox stringValue];
|
||||
}
|
||||
|
||||
- (BOOL)ignoreCase
|
||||
{
|
||||
return [ignoreCaseButton state] == NSOnState;
|
||||
}
|
||||
|
||||
- (BOOL)matchWord
|
||||
{
|
||||
return [matchWordButton state] == NSOnState;
|
||||
}
|
||||
|
||||
@end // MMFindReplaceController
|
||||
@@ -38,12 +38,10 @@
|
||||
#define FUOPT_BGCOLOR_HLGROUP 0x004
|
||||
|
||||
|
||||
static int numFullscreenWindows = 0;
|
||||
|
||||
@interface MMFullscreenWindow (Private)
|
||||
- (BOOL)isOnPrimaryScreen;
|
||||
- (void)hideDockIfAppropriate;
|
||||
- (void)revealDockIfAppropriate;
|
||||
- (void)handleWindowDidBecomeMainNotification:(NSNotification *)notification;
|
||||
- (void)handleWindowDidResignMainNotification:(NSNotification *)notification;
|
||||
@end
|
||||
|
||||
@implementation MMFullscreenWindow
|
||||
@@ -79,6 +77,18 @@ static int numFullscreenWindows = 0;
|
||||
[self setBackgroundColor:back];
|
||||
[self setReleasedWhenClosed:NO];
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(handleWindowDidBecomeMainNotification:)
|
||||
name:NSWindowDidBecomeMainNotification
|
||||
object:self];
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(handleWindowDidResignMainNotification:)
|
||||
name:NSWindowDidResignMainNotification
|
||||
object:self];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -86,6 +96,8 @@ static int numFullscreenWindows = 0;
|
||||
{
|
||||
LOG_DEALLOC
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
[target release]; target = nil;
|
||||
[view release]; view = nil;
|
||||
|
||||
@@ -94,8 +106,6 @@ static int numFullscreenWindows = 0;
|
||||
|
||||
- (void)enterFullscreen:(int)fuoptions
|
||||
{
|
||||
[self hideDockIfAppropriate];
|
||||
|
||||
// fade to black
|
||||
Boolean didBlend = NO;
|
||||
CGDisplayFadeReservationToken token;
|
||||
@@ -157,12 +167,30 @@ static int numFullscreenWindows = 0;
|
||||
|
||||
// if necessary, resize vim to target fu size
|
||||
if (currRows != fuRows || currColumns != fuColumns) {
|
||||
int newSize[2] = { fuRows, fuColumns };
|
||||
NSData *data = [NSData dataWithBytes:newSize length:2*sizeof(int)];
|
||||
|
||||
// The size sent here is queued and sent to vim when it's in
|
||||
// event processing mode again. Make sure to only send the values we
|
||||
// care about, as they override any changes that were made to 'lines'
|
||||
// and 'columns' after 'fu' was set but before the event loop is run.
|
||||
NSData *data = nil;
|
||||
int msgid = 0;
|
||||
if (currRows != fuRows && currColumns != fuColumns) {
|
||||
int newSize[2] = { fuRows, fuColumns };
|
||||
data = [NSData dataWithBytes:newSize length:2*sizeof(int)];
|
||||
msgid = SetTextDimensionsMsgID;
|
||||
} else if (currRows != fuRows) {
|
||||
data = [NSData dataWithBytes:&fuRows length:sizeof(int)];
|
||||
msgid = SetTextRowsMsgID;
|
||||
} else if (currColumns != fuColumns) {
|
||||
data = [NSData dataWithBytes:&fuColumns length:sizeof(int)];
|
||||
msgid = SetTextColumnsMsgID;
|
||||
}
|
||||
NSParameterAssert(data != nil && msgid != 0);
|
||||
|
||||
MMVimController *vimController =
|
||||
[[self windowController] vimController];
|
||||
|
||||
[vimController sendMessage:SetTextDimensionsMsgID data:data];
|
||||
[vimController sendMessage:msgid data:data];
|
||||
[[view textView] setMaxRows:fuRows columns:fuColumns];
|
||||
}
|
||||
|
||||
@@ -259,8 +287,6 @@ static int numFullscreenWindows = 0;
|
||||
CGReleaseDisplayFadeReservation(token);
|
||||
}
|
||||
|
||||
[self revealDockIfAppropriate];
|
||||
|
||||
[self autorelease]; // Balance the above retain
|
||||
}
|
||||
|
||||
@@ -329,38 +355,29 @@ static int numFullscreenWindows = 0;
|
||||
return [self screen] == [screens objectAtIndex:0];
|
||||
}
|
||||
|
||||
- (void)hideDockIfAppropriate
|
||||
- (void)handleWindowDidBecomeMainNotification:(NSNotification *)notification
|
||||
{
|
||||
// Hide menu and dock, both appear on demand.
|
||||
//
|
||||
// Don't hide the dock if going fullscreen on a non-primary screen. Also,
|
||||
// if there are several fullscreen windows on the primary screen, only
|
||||
// hide dock and friends for the first fullscreen window (and display
|
||||
// them again after the last fullscreen window has been closed).
|
||||
//
|
||||
// Another way to deal with several fullscreen windows would be to hide/
|
||||
// reveal the dock each time a fullscreen window gets/loses focus, but
|
||||
// this way it's less distracting.
|
||||
// reveal the dock only when the first fullscreen window is created and
|
||||
// show it again after the last one has been closed, but toggling on each
|
||||
// focus gain/loss works better with Spaces. The downside is that the
|
||||
// menu bar flashes shortly when switching between two fullscreen windows.
|
||||
|
||||
// XXX: If you have a fullscreen window on a secondary monitor and unplug
|
||||
// the monitor, this will probably not work right.
|
||||
|
||||
if ([self isOnPrimaryScreen]) {
|
||||
if (numFullscreenWindows == 0) {
|
||||
SetSystemUIMode(kUIModeAllSuppressed, 0); //requires 10.3
|
||||
}
|
||||
++numFullscreenWindows;
|
||||
SetSystemUIMode(kUIModeAllSuppressed, 0); //requires 10.3
|
||||
}
|
||||
}
|
||||
|
||||
- (void)revealDockIfAppropriate
|
||||
- (void)handleWindowDidResignMainNotification:(NSNotification *)notification
|
||||
{
|
||||
// order menu and dock back in
|
||||
// order menu and dock back in
|
||||
if ([self isOnPrimaryScreen]) {
|
||||
--numFullscreenWindows;
|
||||
if (numFullscreenWindows == 0) {
|
||||
SetSystemUIMode(kUIModeNormal, 0);
|
||||
}
|
||||
SetSystemUIMode(kUIModeNormal, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,9 +40,12 @@ static void loadSymbols()
|
||||
}
|
||||
|
||||
|
||||
static CFStringRef ODBEDITOR = CFSTR("org.slashpunt.edit_in_odbeditor");
|
||||
static CFStringRef ODB_BUNDLE_IDENTIFIER = CFSTR("ODBEditorBundleIdentifier");
|
||||
static CFStringRef ODB_EDITOR_NAME = CFSTR("ODBEditorName");
|
||||
// The compiler on OS X 10.4 balks at using CFSTR() for globals so we get
|
||||
// around with this some ugly type casting.
|
||||
static CFStringRef ODBEDITOR = (CFStringRef)@"org.slashpunt.edit_in_odbeditor";
|
||||
static CFStringRef ODB_BUNDLE_IDENTIFIER =
|
||||
(CFStringRef)@"ODBEditorBundleIdentifier";
|
||||
static CFStringRef ODB_EDITOR_NAME = (CFStringRef)@"ODBEditorName";
|
||||
static NSString *ODBEDITOR_DIR =
|
||||
@"/Library/InputManagers/Edit in ODBEditor";
|
||||
static NSString *ODBEDITOR_PATH =
|
||||
|
||||
@@ -19,12 +19,6 @@
|
||||
int insertionPointColumn;
|
||||
int insertionPointShape;
|
||||
int insertionPointFraction;
|
||||
NSRange imRange;
|
||||
NSRange markedRange;
|
||||
NSDictionary *markedTextAttributes;
|
||||
NSMutableAttributedString *markedText;
|
||||
int preEditRow;
|
||||
int preEditColumn;
|
||||
BOOL antialias;
|
||||
NSRect *invertRects;
|
||||
int numInvertRects;
|
||||
@@ -34,7 +28,6 @@
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame;
|
||||
|
||||
- (void)setShouldDrawInsertionPoint:(BOOL)on;
|
||||
- (void)setPreEditRow:(int)row column:(int)col;
|
||||
- (void)performBatchDrawWithData:(NSData *)data;
|
||||
- (void)setMouseShape:(int)shape;
|
||||
@@ -45,16 +38,20 @@
|
||||
//
|
||||
- (NSFont *)font;
|
||||
- (void)setFont:(NSFont *)newFont;
|
||||
- (NSFont *)fontWide;
|
||||
- (void)setWideFont:(NSFont *)newFont;
|
||||
- (NSSize)cellSize;
|
||||
- (void)setLinespace:(float)newLinespace;
|
||||
- (int)maxRows;
|
||||
- (int)maxColumns;
|
||||
- (void)getMaxRows:(int*)rows columns:(int*)cols;
|
||||
- (void)setMaxRows:(int)rows columns:(int)cols;
|
||||
- (NSRect)rectForRowsInRange:(NSRange)range;
|
||||
- (NSRect)rectForColumnsInRange:(NSRange)range;
|
||||
- (void)setDefaultColorsBackground:(NSColor *)bgColor
|
||||
foreground:(NSColor *)fgColor;
|
||||
- (NSColor *)defaultBackgroundColor;
|
||||
- (NSColor *)defaultForegroundColor;
|
||||
|
||||
- (NSSize)constrainRows:(int *)rows columns:(int *)cols toSize:(NSSize)size;
|
||||
- (NSSize)desiredSize;
|
||||
@@ -62,5 +59,8 @@
|
||||
|
||||
|
||||
- (BOOL)convertPoint:(NSPoint)point toRow:(int *)row column:(int *)column;
|
||||
- (NSPoint)pointForRow:(int)row column:(int)col;
|
||||
- (NSRect)rectForRow:(int)row column:(int)col numRows:(int)nr
|
||||
numColumns:(int)nc;
|
||||
|
||||
@end
|
||||
|
||||
+95
-162
@@ -35,13 +35,11 @@
|
||||
|
||||
|
||||
@interface MMTextView (Private)
|
||||
- (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;
|
||||
- (MMWindowController *)windowController;
|
||||
- (MMVimController *)vimController;
|
||||
- (void)setShouldDrawInsertionPoint:(BOOL)on;
|
||||
- (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
|
||||
fraction:(int)percent color:(NSColor *)color;
|
||||
fraction:(int)percent;
|
||||
- (void)drawInvertedRectAtRow:(int)row column:(int)col numRows:(int)nrows
|
||||
numColumns:(int)ncols invert:(int)invert;
|
||||
@end
|
||||
@@ -103,8 +101,6 @@
|
||||
helper = [[MMTextViewHelper alloc] init];
|
||||
[helper setTextView:self];
|
||||
|
||||
imRange = NSMakeRange(0, 0);
|
||||
markedRange = NSMakeRange(0, 0);
|
||||
// NOTE: If the default changes to 'NO' then the intialization of
|
||||
// p_antialias in option.c must change as well.
|
||||
antialias = YES;
|
||||
@@ -116,12 +112,6 @@
|
||||
{
|
||||
LOG_DEALLOC
|
||||
|
||||
if (markedText) {
|
||||
imRange = NSMakeRange(0, 0);
|
||||
[markedText release];
|
||||
markedText = nil;
|
||||
}
|
||||
|
||||
if (invertRects) {
|
||||
free(invertRects);
|
||||
invertRects = NULL;
|
||||
@@ -143,15 +133,9 @@
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)setShouldDrawInsertionPoint:(BOOL)on
|
||||
{
|
||||
shouldDrawInsertionPoint = on;
|
||||
}
|
||||
|
||||
- (void)setPreEditRow:(int)row column:(int)col
|
||||
{
|
||||
preEditRow = row;
|
||||
preEditColumn = col;
|
||||
[helper setPreEditRow:row column:col];
|
||||
}
|
||||
|
||||
#define MM_DEBUG_DRAWING 0
|
||||
@@ -231,13 +215,8 @@
|
||||
// NOTE: If this is a call to draw the (block) cursor, then cancel
|
||||
// any previous request to draw the insertion point, or it might
|
||||
// get drawn as well.
|
||||
if (flags & DRAW_CURSOR) {
|
||||
if (flags & DRAW_CURSOR)
|
||||
[self setShouldDrawInsertionPoint:NO];
|
||||
//NSColor *color = [NSColor colorWithRgbInt:bg];
|
||||
//[self drawInsertionPointAtRow:row column:col
|
||||
// shape:MMInsertionPointBlock
|
||||
// color:color];
|
||||
}
|
||||
|
||||
[textStorage drawString:string
|
||||
atRow:row column:col cells:cells
|
||||
@@ -271,9 +250,9 @@
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@" Draw cursor at (%d,%d)", row, col);
|
||||
#endif
|
||||
[helper setInsertionPointColor:[NSColor colorWithRgbInt:color]];
|
||||
[self drawInsertionPointAtRow:row column:col shape:shape
|
||||
fraction:percent
|
||||
color:[NSColor colorWithRgbInt:color]];
|
||||
fraction:percent];
|
||||
} else if (DrawInvertedRectDrawType == type) {
|
||||
int row = *((int*)bytes); bytes += sizeof(int);
|
||||
int col = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -308,7 +287,8 @@
|
||||
|
||||
// NOTE: During resizing, Cocoa only sends draw messages before Vim's rows
|
||||
// and columns are changed (due to ipc delays). Force a redraw here.
|
||||
[self displayIfNeeded];
|
||||
if ([self inLiveResize])
|
||||
[self display];
|
||||
|
||||
#if MM_DEBUG_DRAWING
|
||||
NSLog(@"<==== END %s", _cmd);
|
||||
@@ -335,6 +315,11 @@
|
||||
[(MMTextStorage*)[self textStorage] setFont:newFont];
|
||||
}
|
||||
|
||||
- (NSFont *)fontWide
|
||||
{
|
||||
return [(MMTextStorage*)[self textStorage] fontWide];
|
||||
}
|
||||
|
||||
- (void)setWideFont:(NSFont *)newFont
|
||||
{
|
||||
[(MMTextStorage*)[self textStorage] setWideFont:newFont];
|
||||
@@ -356,6 +341,12 @@
|
||||
return [ts maxRows];
|
||||
}
|
||||
|
||||
- (int)maxColumns
|
||||
{
|
||||
MMTextStorage *ts = (MMTextStorage *)[self textStorage];
|
||||
return [ts maxColumns];
|
||||
}
|
||||
|
||||
- (void)getMaxRows:(int*)rows columns:(int*)cols
|
||||
{
|
||||
return [(MMTextStorage*)[self textStorage] getMaxRows:rows columns:cols];
|
||||
@@ -384,6 +375,16 @@
|
||||
setDefaultColorsBackground:bgColor foreground:fgColor];
|
||||
}
|
||||
|
||||
- (NSColor *)defaultBackgroundColor
|
||||
{
|
||||
return [(MMTextStorage*)[self textStorage] defaultBackgroundColor];
|
||||
}
|
||||
|
||||
- (NSColor *)defaultForegroundColor
|
||||
{
|
||||
return [(MMTextStorage*)[self textStorage] defaultForegroundColor];
|
||||
}
|
||||
|
||||
- (NSSize)constrainRows:(int *)rows columns:(int *)cols toSize:(NSSize)size
|
||||
{
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
@@ -449,6 +450,39 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSPoint)pointForRow:(int)row column:(int)col
|
||||
{
|
||||
// Return the upper-left coordinate for (row,column).
|
||||
// NOTE: The coordinate system is flipped!
|
||||
NSPoint pt = [self textContainerOrigin];
|
||||
MMTextStorage *ts = (MMTextStorage*)[self textStorage];
|
||||
NSSize cellSize = [ts cellSize];
|
||||
|
||||
pt.x += col * cellSize.width;
|
||||
pt.y += row * cellSize.height;
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
||||
- (NSRect)rectForRow:(int)row column:(int)col numRows:(int)nr
|
||||
numColumns:(int)nc
|
||||
{
|
||||
// Return the rect for the block which covers the specified rows and
|
||||
// columns. The upper-left corner is the origin of this rect.
|
||||
// NOTE: The coordinate system is flipped!
|
||||
NSRect rect;
|
||||
MMTextStorage *ts = (MMTextStorage*)[self textStorage];
|
||||
NSSize cellSize = [ts cellSize];
|
||||
|
||||
rect.origin = [self textContainerOrigin];
|
||||
rect.origin.x += col * cellSize.width;
|
||||
rect.origin.y += row * cellSize.height;
|
||||
rect.size.width = cellSize.width * nc;
|
||||
rect.size.height = cellSize.height * nr;
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (BOOL)isOpaque
|
||||
{
|
||||
return NO;
|
||||
@@ -496,7 +530,7 @@
|
||||
|
||||
inset.height -= baseline;
|
||||
|
||||
int len = [markedText length];
|
||||
int len = [[helper markedText] length];
|
||||
// The following implementation should be re-written with
|
||||
// more efficient way...
|
||||
|
||||
@@ -509,11 +543,11 @@
|
||||
cols = cols / 2;
|
||||
int done = 0;
|
||||
int lend = cols > len ? len : cols;
|
||||
NSAttributedString *aString = [markedText attributedSubstringFromRange:
|
||||
NSMakeRange(done, lend)];
|
||||
NSAttributedString *aString = [[helper markedText]
|
||||
attributedSubstringFromRange:NSMakeRange(done, lend)];
|
||||
[aString drawAtPoint:NSMakePoint(
|
||||
preEditColumn*[ts cellSize].width + inset.width,
|
||||
preEditRow*[ts cellSize].height + inset.height)];
|
||||
[helper preEditColumn]*[ts cellSize].width + inset.width,
|
||||
[helper preEditRow]*[ts cellSize].height + inset.height)];
|
||||
|
||||
done = lend;
|
||||
// Check whether there're charecters that aren't drawn at
|
||||
@@ -527,11 +561,11 @@
|
||||
for (r = 1; r <= rows; r++) {
|
||||
lend = len - done > [ts actualColumns] / 2
|
||||
? [ts actualColumns] / 2 : len - done;
|
||||
aString = [markedText attributedSubstringFromRange:
|
||||
aString = [[helper markedText] attributedSubstringFromRange:
|
||||
NSMakeRange(done, lend)];
|
||||
[aString drawAtPoint:NSMakePoint(
|
||||
inset.width,
|
||||
(preEditRow + r)*[ts cellSize].height
|
||||
([helper preEditRow] + r)*[ts cellSize].height
|
||||
+ inset.height)];
|
||||
done += lend;
|
||||
}
|
||||
@@ -541,8 +575,8 @@
|
||||
if (shouldDrawInsertionPoint) {
|
||||
MMTextStorage *ts = (MMTextStorage*)[self textStorage];
|
||||
|
||||
NSRect ipRect = [ts boundingRectForCharacterAtRow:preEditRow
|
||||
column:preEditColumn];
|
||||
NSRect ipRect = [ts boundingRectForCharacterAtRow:[helper preEditRow]
|
||||
column:[helper preEditColumn]];
|
||||
ipRect.origin.x += [self textContainerOrigin].x;
|
||||
ipRect.origin.y += [self textContainerOrigin].y;
|
||||
|
||||
@@ -552,10 +586,12 @@
|
||||
valueForKey:NSFontAttributeName];
|
||||
if (theFont == [ts font])
|
||||
ipRect.origin.x += [ts cellSize].width *
|
||||
(imRange.location + imRange.length);
|
||||
([helper imRange].location +
|
||||
[helper imRange].length);
|
||||
else
|
||||
ipRect.origin.x += [ts cellSize].width * 2 *
|
||||
(imRange.location + imRange.length);
|
||||
([helper imRange].location +
|
||||
[helper imRange].length);
|
||||
}
|
||||
|
||||
if (MMInsertionPointHorizontal == insertionPointShape) {
|
||||
@@ -571,7 +607,7 @@
|
||||
ipRect.size.width = frac;
|
||||
}
|
||||
|
||||
[[self insertionPointColor] set];
|
||||
[[helper insertionPointColor] set];
|
||||
if (MMInsertionPointHollow == insertionPointShape) {
|
||||
NSFrameRect(ipRect);
|
||||
} else {
|
||||
@@ -584,7 +620,7 @@
|
||||
|
||||
//NSLog(@"%s draw insertion point %@ shape=%d color=%@", _cmd,
|
||||
// NSStringFromRect(ipRect), insertionPointShape,
|
||||
// [self insertionPointColor]);
|
||||
// [helper insertionPointColor]);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -627,109 +663,37 @@
|
||||
|
||||
- (BOOL)hasMarkedText
|
||||
{
|
||||
//NSLog(@"%s", _cmd);
|
||||
//return markedText && [markedText length] > 0;
|
||||
return markedRange.length > 0 ? YES : NO;
|
||||
return [helper hasMarkedText];
|
||||
}
|
||||
|
||||
- (NSRange)markedRange
|
||||
{
|
||||
if ([self hasMarkedText]) {
|
||||
return markedRange;
|
||||
} else
|
||||
return NSMakeRange(NSNotFound, 0);
|
||||
return [helper markedRange];
|
||||
}
|
||||
|
||||
- (NSDictionary *)markedTextAttributes
|
||||
{
|
||||
return markedTextAttributes;
|
||||
return [helper markedTextAttributes];
|
||||
}
|
||||
|
||||
- (void)setMarkedTextAttributes:(NSDictionary *)attr
|
||||
{
|
||||
if (attr != markedTextAttributes) {
|
||||
[markedTextAttributes release];
|
||||
markedTextAttributes = [attr retain];
|
||||
}
|
||||
[helper setMarkedTextAttributes:attr];
|
||||
}
|
||||
|
||||
|
||||
- (void)setMarkedText:(id)text selectedRange:(NSRange)range
|
||||
{
|
||||
//NSLog(@"setMarkedText:'%@' selectedRange:%@", text,
|
||||
// NSStringFromRange(range));
|
||||
|
||||
MMTextStorage *ts = (MMTextStorage*)[self textStorage];
|
||||
if (!ts)
|
||||
return;
|
||||
[self unmarkText];
|
||||
|
||||
if (text && [text length] > 0) {
|
||||
if ([text isKindOfClass:[NSAttributedString class]]) {
|
||||
[self setMarkedTextAttributes:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[ts fontWide], NSFontAttributeName,
|
||||
[ts defaultBackgroundColor], NSBackgroundColorAttributeName,
|
||||
[ts defaultForegroundColor], NSForegroundColorAttributeName,
|
||||
nil]];
|
||||
markedText = [[NSMutableAttributedString alloc]
|
||||
initWithString:[text string]
|
||||
attributes:[self markedTextAttributes]];
|
||||
} else {
|
||||
[self setMarkedTextAttributes:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[ts font], NSFontAttributeName,
|
||||
[ts defaultBackgroundColor], NSBackgroundColorAttributeName,
|
||||
[ts defaultForegroundColor], NSForegroundColorAttributeName,
|
||||
nil]];
|
||||
markedText = [[NSMutableAttributedString alloc]
|
||||
initWithString:text
|
||||
attributes:[self markedTextAttributes]];
|
||||
}
|
||||
|
||||
markedRange = NSMakeRange(0, [markedText length]);
|
||||
if (markedRange.length) {
|
||||
[markedText addAttribute:NSUnderlineStyleAttributeName
|
||||
value:[NSNumber numberWithInt:1]
|
||||
range:markedRange];
|
||||
}
|
||||
imRange = range;
|
||||
if (range.length) {
|
||||
[markedText addAttribute:NSUnderlineStyleAttributeName
|
||||
value:[NSNumber numberWithInt:2]
|
||||
range:range];
|
||||
}
|
||||
}
|
||||
[self setNeedsDisplay: YES];
|
||||
[helper setMarkedText:text selectedRange:range];
|
||||
}
|
||||
|
||||
- (void)unmarkText
|
||||
{
|
||||
//NSLog(@"%s", _cmd);
|
||||
imRange = NSMakeRange(0, 0);
|
||||
markedRange = NSMakeRange(NSNotFound, 0);
|
||||
[markedText release];
|
||||
markedText = nil;
|
||||
[helper unmarkText];
|
||||
}
|
||||
|
||||
- (NSRect)firstRectForCharacterRange:(NSRange)range
|
||||
{
|
||||
//NSLog(@"%s%@", _cmd, NSStringFromRange(range));
|
||||
// HACK! This method is called when the input manager wants to pop up an
|
||||
// auxiliary window. The position where this should be is controller by
|
||||
// Vim by sending SetPreEditPositionMsgID so compute a position based on
|
||||
// the pre-edit (row,column) pair.
|
||||
MMTextStorage *ts = (MMTextStorage*)[self textStorage];
|
||||
|
||||
NSRect rect = [ts boundingRectForCharacterAtRow:preEditRow
|
||||
column:preEditColumn];
|
||||
rect.origin.x += [self textContainerOrigin].x;
|
||||
rect.origin.y += [self textContainerOrigin].y + [ts cellSize].height;
|
||||
|
||||
rect.origin = [self convertPoint:rect.origin toView:nil];
|
||||
rect.origin = [[self window] convertBaseToScreen:rect.origin];
|
||||
|
||||
return rect;
|
||||
return [helper firstRectForCharacterRange:range];
|
||||
}
|
||||
|
||||
- (void)scrollWheel:(NSEvent *)event
|
||||
@@ -926,6 +890,7 @@
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end // MMTextView
|
||||
|
||||
|
||||
@@ -933,37 +898,6 @@
|
||||
|
||||
@implementation MMTextView (Private)
|
||||
|
||||
- (BOOL)convertRow:(int)row column:(int)column toPoint:(NSPoint *)point
|
||||
{
|
||||
MMTextStorage *ts = (MMTextStorage*)[self textStorage];
|
||||
NSSize cellSize = [ts cellSize];
|
||||
if (!(point && cellSize.width > 0 && cellSize.height > 0))
|
||||
return NO;
|
||||
|
||||
*point = [self textContainerOrigin];
|
||||
point->x += column * cellSize.width;
|
||||
point->y += row * cellSize.height;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
- (MMWindowController *)windowController
|
||||
{
|
||||
id windowController = [[self window] windowController];
|
||||
@@ -977,12 +911,14 @@
|
||||
return [[self windowController] vimController];
|
||||
}
|
||||
|
||||
- (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
|
||||
fraction:(int)percent color:(NSColor *)color
|
||||
- (void)setShouldDrawInsertionPoint:(BOOL)on
|
||||
{
|
||||
//NSLog(@"drawInsertionPointAtRow:%d column:%d shape:%d color:%@",
|
||||
// row, col, shape, color);
|
||||
shouldDrawInsertionPoint = on;
|
||||
}
|
||||
|
||||
- (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
|
||||
fraction:(int)percent
|
||||
{
|
||||
// This only stores where to draw the insertion point, the actual drawing
|
||||
// is done in drawRect:.
|
||||
shouldDrawInsertionPoint = YES;
|
||||
@@ -990,8 +926,6 @@
|
||||
insertionPointColumn = col;
|
||||
insertionPointShape = shape;
|
||||
insertionPointFraction = percent;
|
||||
|
||||
[self setInsertionPointColor:color];
|
||||
}
|
||||
|
||||
- (void)drawInvertedRectAtRow:(int)row column:(int)col numRows:(int)nrows
|
||||
@@ -1003,8 +937,8 @@
|
||||
invertRects = reallocf(invertRects,
|
||||
numInvertRects*sizeof(NSRect));
|
||||
if (NULL != invertRects) {
|
||||
[self convertRow:row column:col numRows:nrows numColumns:ncols
|
||||
toRect:&invertRects[n]];
|
||||
invertRects[n] = [self rectForRow:row column:col numRows:nrows
|
||||
numColumns:ncols];
|
||||
[self setNeedsDisplayInRect:invertRects[n]];
|
||||
} else {
|
||||
n = numInvertRects = 0;
|
||||
@@ -1012,9 +946,8 @@
|
||||
} 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];
|
||||
NSRect rect = [self rectForRow:row column:col numRows:nrows
|
||||
numColumns:ncols];
|
||||
[self setNeedsDisplayInRect:rect];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,10 +30,20 @@ enum {
|
||||
BOOL isAutoscrolling;
|
||||
int mouseShape;
|
||||
NSTrackingRectTag trackingRectTag;
|
||||
float scrollWheelAccumulator;
|
||||
NSColor *insertionPointColor;
|
||||
|
||||
// Input Manager
|
||||
NSRange imRange;
|
||||
NSRange markedRange;
|
||||
NSDictionary *markedTextAttributes;
|
||||
NSMutableAttributedString *markedText;
|
||||
int preEditRow;
|
||||
int preEditColumn;
|
||||
}
|
||||
|
||||
- (void)setTextView:(id)view;
|
||||
- (void)setInsertionPointColor:(NSColor *)color;
|
||||
- (NSColor *)insertionPointColor;
|
||||
|
||||
- (void)keyDown:(NSEvent *)event;
|
||||
- (void)insertText:(id)string;
|
||||
@@ -54,4 +64,20 @@ enum {
|
||||
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender;
|
||||
- (void)setMouseShape:(int)shape;
|
||||
|
||||
// Input Manager
|
||||
- (BOOL)hasMarkedText;
|
||||
- (NSRange)markedRange;
|
||||
- (NSDictionary *)markedTextAttributes;
|
||||
- (void)setMarkedTextAttributes:(NSDictionary *)attr;
|
||||
- (void)setMarkedText:(id)text selectedRange:(NSRange)range;
|
||||
- (void)unmarkText;
|
||||
- (NSMutableAttributedString *)markedText;
|
||||
- (void)setPreEditRow:(int)row column:(int)col;
|
||||
- (int)preEditRow;
|
||||
- (int)preEditColumn;
|
||||
- (void)setImRange:(NSRange)range;
|
||||
- (NSRange)imRange;
|
||||
- (void)setMarkedRange:(NSRange)range;
|
||||
- (NSRect)firstRectForCharacterRange:(NSRange)range;
|
||||
|
||||
@end
|
||||
|
||||
+245
-51
@@ -33,33 +33,51 @@ static NSTimeInterval MMDragTimerMinInterval = 0.01;
|
||||
// The number of pixels in which the drag timer interval changes
|
||||
static float MMDragAreaSize = 73.0f;
|
||||
|
||||
// Number of seconds to delay before sending scroll wheel events. (A delay of
|
||||
// 0.05 seconds equals an update frequency of 20 Hz.)
|
||||
static NSTimeInterval MMScrollWheelDelay = 0.05;
|
||||
|
||||
|
||||
@interface MMTextViewHelper (Private)
|
||||
- (MMWindowController *)windowController;
|
||||
- (MMVimController *)vimController;
|
||||
- (void)dispatchKeyEvent:(NSEvent *)event;
|
||||
- (void)sendKeyDown:(const char *)chars length:(int)len modifiers:(int)flags;
|
||||
- (void)sendKeyDown:(const char *)chars length:(int)len modifiers:(int)flags
|
||||
isARepeat:(BOOL)isARepeat;
|
||||
- (void)hideMouseCursor;
|
||||
- (void)startDragTimerWithInterval:(NSTimeInterval)t;
|
||||
- (void)dragTimerFired:(NSTimer *)timer;
|
||||
- (void)setCursor;
|
||||
- (NSRect)trackingRect;
|
||||
- (void)handleScrollWheelEvent:(id)event;
|
||||
@end
|
||||
|
||||
|
||||
@implementation MMTextViewHelper
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[insertionPointColor release]; insertionPointColor = nil;
|
||||
[markedText release]; markedText = nil;
|
||||
[markedTextAttributes release]; markedTextAttributes = nil;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)setTextView:(id)view
|
||||
{
|
||||
// Only keep a weak reference to owning text view.
|
||||
textView = view;
|
||||
}
|
||||
|
||||
- (void)setInsertionPointColor:(NSColor *)color
|
||||
{
|
||||
if (color != insertionPointColor) {
|
||||
[insertionPointColor release];
|
||||
insertionPointColor = [color retain];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSColor *)insertionPointColor
|
||||
{
|
||||
return insertionPointColor;
|
||||
}
|
||||
|
||||
- (void)keyDown:(NSEvent *)event
|
||||
{
|
||||
//NSLog(@"%s %@", _cmd, event);
|
||||
@@ -84,17 +102,27 @@ static NSTimeInterval MMScrollWheelDelay = 0.05;
|
||||
int flags = [event modifierFlags];
|
||||
if ((flags & NSControlKeyMask) ||
|
||||
((flags & NSAlternateKeyMask) && (flags & NSFunctionKeyMask))) {
|
||||
NSString *unmod = [event charactersIgnoringModifiers];
|
||||
if ([unmod length] == 1 && [unmod characterAtIndex:0] <= 0x7f
|
||||
&& [unmod characterAtIndex:0] >= 0x60) {
|
||||
// HACK! Send Ctrl-letter keys (and C-@, C-[, C-\, C-], C-^, C-_)
|
||||
// as normal text to be added to the Vim input buffer. This must
|
||||
// be done in order for the backend to be able to separate e.g.
|
||||
// Ctrl-i and Ctrl-tab.
|
||||
[self insertText:[event characters]];
|
||||
NSString *chars = [event characters];
|
||||
if ([chars length] == 1 && [chars characterAtIndex:0] < 0x20) {
|
||||
// HACK! Send unprintable characters (such as C-@, C-[, C-\, C-],
|
||||
// C-^, C-_) as normal text to be added to the Vim input buffer.
|
||||
// This must be done in order for the backend to be able to
|
||||
// separate e.g. Ctrl-i and Ctrl-tab.
|
||||
[self insertText:chars];
|
||||
} else {
|
||||
[self dispatchKeyEvent:event];
|
||||
}
|
||||
} else if ((flags & NSAlternateKeyMask) &&
|
||||
[[[[self vimController] vimState] objectForKey:@"p_mmta"]
|
||||
boolValue]) {
|
||||
// If the 'macmeta' option is set, then send Alt+key presses directly
|
||||
// to Vim without interpreting the key press.
|
||||
NSString *unmod = [event charactersIgnoringModifiers];
|
||||
int len = [unmod lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
const char *bytes = [unmod UTF8String];
|
||||
|
||||
[self sendKeyDown:bytes length:len modifiers:flags
|
||||
isARepeat:[event isARepeat]];
|
||||
} else {
|
||||
[textView interpretKeyEvents:[NSArray arrayWithObject:event]];
|
||||
}
|
||||
@@ -142,8 +170,17 @@ static NSTimeInterval MMScrollWheelDelay = 0.05;
|
||||
|
||||
//NSLog(@"send InsertTextMsgID: %@", string);
|
||||
|
||||
[[self vimController] sendMessage:InsertTextMsgID
|
||||
data:[string dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
int flags = [event modifierFlags] & 0xffff0000U;
|
||||
if ([event type] == NSKeyDown && [event isARepeat])
|
||||
flags |= 1;
|
||||
|
||||
[data appendBytes:&flags length:sizeof(int)];
|
||||
[data appendBytes:&len length:sizeof(int)];
|
||||
[data appendBytes:[string UTF8String] length:len];
|
||||
|
||||
[[self vimController] sendMessage:InsertTextMsgID data:data];
|
||||
}
|
||||
|
||||
- (void)doCommandBySelector:(SEL)selector
|
||||
@@ -178,7 +215,8 @@ static NSTimeInterval MMScrollWheelDelay = 0.05;
|
||||
chars = MMKeypadEnter;
|
||||
}
|
||||
|
||||
[self sendKeyDown:chars length:len modifiers:[event modifierFlags]];
|
||||
[self sendKeyDown:chars length:len modifiers:[event modifierFlags]
|
||||
isARepeat:[event isARepeat]];
|
||||
} else {
|
||||
[self dispatchKeyEvent:event];
|
||||
}
|
||||
@@ -199,7 +237,7 @@ static NSTimeInterval MMScrollWheelDelay = 0.05;
|
||||
// stroke (some input methods use e.g. arrow keys). The function key down
|
||||
// event will still reach Vim though (via keyDown:). The exceptions to
|
||||
// this rule are: PageUp/PageDown (keycode 116/121).
|
||||
int flags = [event modifierFlags];
|
||||
int flags = [event modifierFlags] & 0xffff0000U;
|
||||
if ([event type] != NSKeyDown || flags & NSFunctionKeyMask
|
||||
&& !(116 == [event keyCode] || 121 == [event keyCode]))
|
||||
return NO;
|
||||
@@ -227,6 +265,17 @@ static NSTimeInterval MMScrollWheelDelay = 0.05;
|
||||
if ([unmodchars isEqual:@"?"])
|
||||
return NO;
|
||||
|
||||
// Cmd-. is hard-wired to send SIGINT unlike Ctrl-C which is just another
|
||||
// key press which Vim has to interpret. This means that Cmd-. always
|
||||
// works to interrupt a Vim process whereas Ctrl-C can suffer from problems
|
||||
// such as dropped DO messages (or if Vim is stuck in a loop without
|
||||
// checking for keyboard input).
|
||||
if ((flags & NSDeviceIndependentModifierFlagsMask) == NSCommandKeyMask &&
|
||||
[unmodchars isEqual:@"."]) {
|
||||
kill([[self vimController] pid], SIGINT);
|
||||
return YES;
|
||||
}
|
||||
|
||||
//NSLog(@"%s%@", _cmd, event);
|
||||
|
||||
NSString *chars = [event characters];
|
||||
@@ -250,6 +299,9 @@ static NSTimeInterval MMScrollWheelDelay = 0.05;
|
||||
len = [unmodchars lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
if ([event isARepeat])
|
||||
flags |= 1;
|
||||
|
||||
[data appendBytes:&flags length:sizeof(int)];
|
||||
[data appendBytes:&len length:sizeof(int)];
|
||||
[data appendBytes:[unmodchars UTF8String] length:len];
|
||||
@@ -264,16 +316,20 @@ static NSTimeInterval MMScrollWheelDelay = 0.05;
|
||||
if ([event deltaY] == 0)
|
||||
return;
|
||||
|
||||
// Don't send the event straight away because lots of these events may be
|
||||
// received in rapid succession. Instead, accumulate the events and send
|
||||
// off the scroll total at a predetermined maximum rate. This avoids
|
||||
// clogging up the DO messaging system on faster machines.
|
||||
if (0 == scrollWheelAccumulator)
|
||||
[self performSelector:@selector(handleScrollWheelEvent:)
|
||||
withObject:event
|
||||
afterDelay:MMScrollWheelDelay];
|
||||
int row, col;
|
||||
NSPoint pt = [textView convertPoint:[event locationInWindow] fromView:nil];
|
||||
if ([textView convertPoint:pt toRow:&row column:&col]) {
|
||||
int flags = [event modifierFlags];
|
||||
float dy = [event deltaY];
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
|
||||
scrollWheelAccumulator += [event deltaY];
|
||||
[data appendBytes:&row length:sizeof(int)];
|
||||
[data appendBytes:&col length:sizeof(int)];
|
||||
[data appendBytes:&flags length:sizeof(int)];
|
||||
[data appendBytes:&dy length:sizeof(float)];
|
||||
|
||||
[[self vimController] sendMessage:ScrollWheelMsgID data:data];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseDown:(NSEvent *)event
|
||||
@@ -509,6 +565,158 @@ static NSTimeInterval MMScrollWheelDelay = 0.05;
|
||||
[self setCursor];
|
||||
}
|
||||
|
||||
- (BOOL)hasMarkedText
|
||||
{
|
||||
return markedRange.length > 0 ? YES : NO;
|
||||
}
|
||||
|
||||
- (NSRange)markedRange
|
||||
{
|
||||
if ([self hasMarkedText])
|
||||
return markedRange;
|
||||
else
|
||||
return NSMakeRange(NSNotFound, 0);
|
||||
}
|
||||
|
||||
- (NSDictionary *)markedTextAttributes
|
||||
{
|
||||
return markedTextAttributes;
|
||||
}
|
||||
|
||||
- (void)setMarkedTextAttributes:(NSDictionary *)attr
|
||||
{
|
||||
if (attr != markedTextAttributes) {
|
||||
[markedTextAttributes release];
|
||||
markedTextAttributes = [attr retain];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setMarkedText:(id)text selectedRange:(NSRange)range
|
||||
{
|
||||
[self unmarkText];
|
||||
|
||||
if (!(text && [text length] > 0))
|
||||
return;
|
||||
|
||||
// HACK! Determine if the marked text is wide or normal width. This seems
|
||||
// to always use 'wide' when there are both wide and normal width
|
||||
// characters.
|
||||
NSString *string = text;
|
||||
NSFont *theFont = [textView font];
|
||||
if ([text isKindOfClass:[NSAttributedString class]]) {
|
||||
theFont = [textView fontWide];
|
||||
string = [text string];
|
||||
}
|
||||
|
||||
// TODO: Use special colors for marked text.
|
||||
[self setMarkedTextAttributes:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
theFont, NSFontAttributeName,
|
||||
[textView defaultBackgroundColor], NSBackgroundColorAttributeName,
|
||||
[textView defaultForegroundColor], NSForegroundColorAttributeName,
|
||||
nil]];
|
||||
|
||||
markedText = [[NSMutableAttributedString alloc]
|
||||
initWithString:string
|
||||
attributes:[self markedTextAttributes]];
|
||||
|
||||
markedRange = NSMakeRange(0, [markedText length]);
|
||||
if (markedRange.length) {
|
||||
[markedText addAttribute:NSUnderlineStyleAttributeName
|
||||
value:[NSNumber numberWithInt:1]
|
||||
range:markedRange];
|
||||
}
|
||||
imRange = range;
|
||||
if (range.length) {
|
||||
[markedText addAttribute:NSUnderlineStyleAttributeName
|
||||
value:[NSNumber numberWithInt:2]
|
||||
range:range];
|
||||
}
|
||||
|
||||
[textView setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (void)unmarkText
|
||||
{
|
||||
imRange = NSMakeRange(0, 0);
|
||||
markedRange = NSMakeRange(NSNotFound, 0);
|
||||
[markedText release];
|
||||
markedText = nil;
|
||||
}
|
||||
|
||||
- (NSMutableAttributedString *)markedText
|
||||
{
|
||||
return markedText;
|
||||
}
|
||||
|
||||
- (void)setPreEditRow:(int)row column:(int)col
|
||||
{
|
||||
preEditRow = row;
|
||||
preEditColumn = col;
|
||||
}
|
||||
|
||||
- (int)preEditRow
|
||||
{
|
||||
return preEditRow;
|
||||
}
|
||||
|
||||
- (int)preEditColumn
|
||||
{
|
||||
return preEditColumn;
|
||||
}
|
||||
|
||||
- (void)setImRange:(NSRange)range
|
||||
{
|
||||
imRange = range;
|
||||
}
|
||||
|
||||
- (NSRange)imRange
|
||||
{
|
||||
return imRange;
|
||||
}
|
||||
|
||||
- (void)setMarkedRange:(NSRange)range
|
||||
{
|
||||
markedRange = range;
|
||||
}
|
||||
|
||||
- (NSRect)firstRectForCharacterRange:(NSRange)range
|
||||
{
|
||||
// This method is called when the input manager wants to pop up an
|
||||
// auxiliary window. The position where this should be is controlled by
|
||||
// Vim by sending SetPreEditPositionMsgID so compute a position based on
|
||||
// the pre-edit (row,column) pair.
|
||||
int col = preEditColumn;
|
||||
int row = preEditRow + 1;
|
||||
|
||||
NSFont *theFont = [[textView markedTextAttributes]
|
||||
valueForKey:NSFontAttributeName];
|
||||
if (theFont == [textView fontWide]) {
|
||||
col += imRange.location * 2;
|
||||
if (col >= [textView maxColumns] - 1) {
|
||||
row += (col / [textView maxColumns]);
|
||||
col = col % 2 ? col % [textView maxColumns] + 1 :
|
||||
col % [textView maxColumns];
|
||||
}
|
||||
} else {
|
||||
col += imRange.location;
|
||||
if (col >= [textView maxColumns]) {
|
||||
row += (col / [textView maxColumns]);
|
||||
col = col % [textView maxColumns];
|
||||
}
|
||||
}
|
||||
|
||||
NSRect rect = [textView rectForRow:row
|
||||
column:col
|
||||
numRows:1
|
||||
numColumns:range.length];
|
||||
|
||||
rect.origin = [textView convertPoint:rect.origin toView:nil];
|
||||
rect.origin = [[textView window] convertBaseToScreen:rect.origin];
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
@end // MMTextViewHelper
|
||||
|
||||
|
||||
@@ -538,7 +746,7 @@ static NSTimeInterval MMScrollWheelDelay = 0.05;
|
||||
NSString *chars = [event characters];
|
||||
NSString *unmodchars = [event charactersIgnoringModifiers];
|
||||
unichar c = [chars characterAtIndex:0];
|
||||
unichar imc = [unmodchars characterAtIndex:0];
|
||||
unichar imc = [unmodchars length] > 0 ? [unmodchars characterAtIndex:0] : 0;
|
||||
int len = 0;
|
||||
const char *bytes = 0;
|
||||
int mods = [event modifierFlags];
|
||||
@@ -570,14 +778,22 @@ static NSTimeInterval MMScrollWheelDelay = 0.05;
|
||||
bytes = [chars UTF8String];
|
||||
}
|
||||
|
||||
[self sendKeyDown:bytes length:len modifiers:mods];
|
||||
[self sendKeyDown:bytes length:len modifiers:mods
|
||||
isARepeat:[event isARepeat]];
|
||||
}
|
||||
|
||||
- (void)sendKeyDown:(const char *)chars length:(int)len modifiers:(int)flags
|
||||
isARepeat:(BOOL)isARepeat
|
||||
{
|
||||
if (chars && len > 0) {
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
|
||||
// The low 16 bits are not used for modifier flags by NSEvent. Use
|
||||
// these bits for custom flags.
|
||||
flags &= 0xffff0000;
|
||||
if (isARepeat)
|
||||
flags |= 1;
|
||||
|
||||
[data appendBytes:&flags length:sizeof(int)];
|
||||
[data appendBytes:&len length:sizeof(int)];
|
||||
[data appendBytes:chars length:len];
|
||||
@@ -706,26 +922,4 @@ static NSTimeInterval MMScrollWheelDelay = 0.05;
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (void)handleScrollWheelEvent:(id)event
|
||||
{
|
||||
if (0 == scrollWheelAccumulator)
|
||||
return;
|
||||
|
||||
int row, col;
|
||||
NSPoint pt = [textView convertPoint:[event locationInWindow] fromView:nil];
|
||||
if ([textView convertPoint:pt toRow:&row column:&col]) {
|
||||
int flags = [event modifierFlags];
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
|
||||
[data appendBytes:&row length:sizeof(int)];
|
||||
[data appendBytes:&col length:sizeof(int)];
|
||||
[data appendBytes:&flags length:sizeof(int)];
|
||||
[data appendBytes:&scrollWheelAccumulator length:sizeof(float)];
|
||||
|
||||
[[self vimController] sendMessage:ScrollWheelMsgID data:data];
|
||||
}
|
||||
|
||||
scrollWheelAccumulator = 0;
|
||||
}
|
||||
|
||||
@end // MMTextViewHelper (Private)
|
||||
|
||||
@@ -49,12 +49,15 @@
|
||||
- (NSString *)serverName;
|
||||
- (MMWindowController *)windowController;
|
||||
- (NSDictionary *)vimState;
|
||||
- (id)objectForVimStateKey:(NSString *)key;
|
||||
- (NSMenu *)mainMenu;
|
||||
- (BOOL)isPreloading;
|
||||
- (void)setIsPreloading:(BOOL)yn;
|
||||
- (NSDate *)creationDate;
|
||||
- (void)cleanup;
|
||||
- (void)dropFiles:(NSArray *)filenames forceOpen:(BOOL)force;
|
||||
- (void)file:(NSString *)filename draggedToTabAtIndex:(NSUInteger)tabIndex;
|
||||
- (void)filesDraggedToTabBar:(NSArray *)filenames;
|
||||
- (void)dropString:(NSString *)string;
|
||||
- (void)passArguments:(NSDictionary *)args;
|
||||
- (void)sendMessage:(int)msgid data:(NSData *)data;
|
||||
|
||||
@@ -18,13 +18,14 @@
|
||||
*
|
||||
* Output from the backend is received in processCommandQueue:. Input is sent
|
||||
* to the backend via sendMessage:data: or addVimInput:. The latter allows
|
||||
* execution of arbitrary stings in the Vim process, much like the Vim script
|
||||
* execution of arbitrary strings in the Vim process, much like the Vim script
|
||||
* function remote_send() does. The messages that may be passed between
|
||||
* frontend and backend are defined in an enum in MacVim.h.
|
||||
*/
|
||||
|
||||
#import "MMAppController.h"
|
||||
#import "MMAtsuiTextView.h"
|
||||
#import "MMFindReplaceController.h"
|
||||
#import "MMTextView.h"
|
||||
#import "MMVimController.h"
|
||||
#import "MMVimView.h"
|
||||
@@ -199,6 +200,11 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
return vimState;
|
||||
}
|
||||
|
||||
- (id)objectForVimStateKey:(NSString *)key
|
||||
{
|
||||
return [vimState objectForKey:key];
|
||||
}
|
||||
|
||||
- (NSMenu *)mainMenu
|
||||
{
|
||||
return mainMenu;
|
||||
@@ -246,6 +252,10 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
if (layout < 0 || layout > MMLayoutTabs)
|
||||
layout = MMLayoutTabs;
|
||||
|
||||
BOOL splitVert = [ud boolForKey:MMVerticalSplitKey];
|
||||
if (splitVert && MMLayoutHorizontalSplit == layout)
|
||||
layout = MMLayoutVerticalSplit;
|
||||
|
||||
NSDictionary *args = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithInt:layout], @"layout",
|
||||
filenames, @"filenames",
|
||||
@@ -255,6 +265,29 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
[self sendMessage:DropFilesMsgID data:[args dictionaryAsData]];
|
||||
}
|
||||
|
||||
- (void)file:(NSString *)filename draggedToTabAtIndex:(NSUInteger)tabIndex
|
||||
{
|
||||
NSString *fnEsc = [filename stringByEscapingSpecialFilenameCharacters];
|
||||
NSString *input = [NSString stringWithFormat:@"<C-\\><C-N>:silent "
|
||||
"tabnext %d |"
|
||||
"edit! %@<CR>", tabIndex + 1, fnEsc];
|
||||
[self addVimInput:input];
|
||||
}
|
||||
|
||||
- (void)filesDraggedToTabBar:(NSArray *)filenames
|
||||
{
|
||||
NSUInteger i, count = [filenames count];
|
||||
NSMutableString *input = [NSMutableString stringWithString:@"<C-\\><C-N>"
|
||||
":silent! tabnext 9999"];
|
||||
for (i = 0; i < count; i++) {
|
||||
NSString *fn = [filenames objectAtIndex:i];
|
||||
NSString *fnEsc = [fn stringByEscapingSpecialFilenameCharacters];
|
||||
[input appendFormat:@"|tabedit %@", fnEsc];
|
||||
}
|
||||
[input appendString:@"<CR>"];
|
||||
[self addVimInput:input];
|
||||
}
|
||||
|
||||
- (void)dropString:(NSString *)string
|
||||
{
|
||||
int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1;
|
||||
@@ -575,6 +608,13 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
// that did happen anyway, the command queue could get processed out of
|
||||
// order.
|
||||
|
||||
// See comment below why this is called here and not later.
|
||||
[windowController processCommandQueueDidFinish];
|
||||
|
||||
// NOTE: Ensure that no calls are made after this "if" clause that may call
|
||||
// sendMessage::. If this happens anyway, such messages will be put on the
|
||||
// send queue and then the queue will not be flushed until the next time
|
||||
// this method is called.
|
||||
if ([sendQueue count] > 0) {
|
||||
@try {
|
||||
[backendProxy processInputAndData:sendQueue];
|
||||
@@ -587,7 +627,6 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
[sendQueue removeAllObjects];
|
||||
}
|
||||
|
||||
[windowController processCommandQueueDidFinish];
|
||||
[receiveQueue removeAllObjects];
|
||||
inProcessCommandQueue = NO;
|
||||
}
|
||||
@@ -643,12 +682,12 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
BOOL inDefaultMode = [[[NSRunLoop currentRunLoop] currentMode]
|
||||
isEqual:NSDefaultRunLoopMode];
|
||||
if (!inDefaultMode && isUnsafeMessage(msgid)) {
|
||||
// NOTE: Because we listen to DO messages in 'event tracking'
|
||||
// mode we have to take extra care when doing things like
|
||||
// releasing view items (and other Cocoa objects). Messages
|
||||
// that may be potentially "unsafe" are delayed until the run
|
||||
// loop is back to default mode at which time they are safe to
|
||||
// call again.
|
||||
// NOTE: Because we may be listening to DO messages in "event
|
||||
// tracking mode" we have to take extra care when doing things
|
||||
// like releasing view items (and other Cocoa objects).
|
||||
// Messages that may be potentially "unsafe" are delayed until
|
||||
// the run loop is back to default mode at which time they are
|
||||
// safe to call again.
|
||||
// A problem with this approach is that it is hard to
|
||||
// classify which messages are unsafe. As a rule of thumb, if
|
||||
// a message may release an object used by the Cocoa framework
|
||||
@@ -712,13 +751,16 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
[windowController showTabBar:YES];
|
||||
} else if (HideTabBarMsgID == msgid) {
|
||||
[windowController showTabBar:NO];
|
||||
} else if (SetTextDimensionsMsgID == msgid || LiveResizeMsgID == msgid) {
|
||||
} else if (SetTextDimensionsMsgID == msgid || LiveResizeMsgID == msgid ||
|
||||
SetTextDimensionsReplyMsgID == msgid) {
|
||||
const void *bytes = [data bytes];
|
||||
int rows = *((int*)bytes); bytes += sizeof(int);
|
||||
int cols = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
[windowController setTextDimensionsWithRows:rows columns:cols
|
||||
live:(LiveResizeMsgID==msgid)];
|
||||
[windowController setTextDimensionsWithRows:rows
|
||||
columns:cols
|
||||
isLive:(LiveResizeMsgID==msgid)
|
||||
isReply:(SetTextDimensionsReplyMsgID==msgid)];
|
||||
} else if (SetWindowTitleMsgID == msgid) {
|
||||
const void *bytes = [data bytes];
|
||||
int len = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -826,10 +868,14 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
initWithBytes:(void*)bytes length:len
|
||||
encoding:NSUTF8StringEncoding];
|
||||
NSFont *font = [NSFont fontWithName:name size:size];
|
||||
if (!font) {
|
||||
// This should only happen if the default font was not loaded in
|
||||
// which case we fall back on using the Cocoa default fixed width
|
||||
// font.
|
||||
font = [NSFont userFixedPitchFontOfSize:size];
|
||||
}
|
||||
|
||||
if (font)
|
||||
[windowController setFont:font];
|
||||
|
||||
[windowController setFont:font];
|
||||
[name release];
|
||||
} else if (SetWideFontMsgID == msgid) {
|
||||
const void *bytes = [data bytes];
|
||||
@@ -923,6 +969,18 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
}
|
||||
} else if (CloseWindowMsgID == msgid) {
|
||||
[self scheduleClose];
|
||||
} else if (SetFullscreenColorMsgID == msgid) {
|
||||
const int *bg = (const int*)[data bytes];
|
||||
NSColor *color = [NSColor colorWithRgbInt:*bg];
|
||||
|
||||
[windowController setFullscreenBackgroundColor:color];
|
||||
} else if (ShowFindReplaceDialogMsgID == msgid) {
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithData:data];
|
||||
if (dict) {
|
||||
[[MMFindReplaceController sharedInstance]
|
||||
showWithText:[dict objectForKey:@"text"]
|
||||
flags:[[dict objectForKey:@"flags"] intValue]];
|
||||
}
|
||||
// IMPORTANT: When adding a new message, make sure to update
|
||||
// isUnsafeMessage() if necessary!
|
||||
} else {
|
||||
@@ -1457,17 +1515,26 @@ isUnsafeMessage(int msgid)
|
||||
// example, UpdateTabBarMsgID may delete NSTabViewItem objects so it goes
|
||||
// on this list.
|
||||
static int unsafeMessages[] = { // REASON MESSAGE IS ON THIS LIST:
|
||||
//OpenWindowMsgID, // Changes lots of state
|
||||
UpdateTabBarMsgID, // May delete NSTabViewItem
|
||||
RemoveMenuItemMsgID, // Deletes NSMenuItem
|
||||
DestroyScrollbarMsgID, // Deletes NSScroller
|
||||
ExecuteActionMsgID, // Impossible to predict
|
||||
ShowPopupMenuMsgID, // Enters modal loop
|
||||
ActivateMsgID, // ?
|
||||
EnterFullscreenMsgID, // Modifies delegate of window controller
|
||||
LeaveFullscreenMsgID, // Modifies delegate of window controller
|
||||
//OpenWindowMsgID, // Changes lots of state
|
||||
UpdateTabBarMsgID, // May delete NSTabViewItem
|
||||
RemoveMenuItemMsgID, // Deletes NSMenuItem
|
||||
DestroyScrollbarMsgID, // Deletes NSScroller
|
||||
ExecuteActionMsgID, // Impossible to predict
|
||||
ShowPopupMenuMsgID, // Enters modal loop
|
||||
ActivateMsgID, // ?
|
||||
EnterFullscreenMsgID, // Modifies delegate of window controller
|
||||
LeaveFullscreenMsgID, // Modifies delegate of window controller
|
||||
CloseWindowMsgID, // See note below
|
||||
};
|
||||
|
||||
// NOTE about CloseWindowMsgID: If this arrives at the same time as say
|
||||
// ExecuteActionMsgID, then the "execute" message will be lost due to it
|
||||
// being queued and handled after the "close" message has caused the
|
||||
// controller to cleanup...UNLESS we add CloseWindowMsgID to the list of
|
||||
// unsafe messages. This is the _only_ reason it is on this list (since
|
||||
// all that happens in response to it is that we schedule another message
|
||||
// for later handling).
|
||||
|
||||
int i, count = sizeof(unsafeMessages)/sizeof(unsafeMessages[0]);
|
||||
for (i = 0; i < count; ++i)
|
||||
if (msgid == unsafeMessages[i])
|
||||
|
||||
+91
-17
@@ -22,6 +22,7 @@
|
||||
#import "MMTextView.h"
|
||||
#import "MMVimController.h"
|
||||
#import "MMVimView.h"
|
||||
#import "MMWindowController.h"
|
||||
#import "Miscellaneous.h"
|
||||
#import <PSMTabBarControl.h>
|
||||
|
||||
@@ -87,7 +88,8 @@ enum {
|
||||
// frameSizeMayHaveChanged.
|
||||
[self setAutoresizesSubviews:YES];
|
||||
|
||||
if ([[NSUserDefaults standardUserDefaults] boolForKey:MMAtsuiRendererKey]) {
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
if ([ud boolForKey:MMAtsuiRendererKey]) {
|
||||
// Use ATSUI for text rendering.
|
||||
//
|
||||
// HACK! 'textView' has type MMTextView, but MMAtsuiTextView is not
|
||||
@@ -99,7 +101,6 @@ enum {
|
||||
}
|
||||
|
||||
// Allow control of text view inset via MMTextInset* user defaults.
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
int left = [ud integerForKey:MMTextInsetLeftKey];
|
||||
int top = [ud integerForKey:MMTextInsetTopKey];
|
||||
[textView setTextContainerInset:NSMakeSize(left, top)];
|
||||
@@ -128,10 +129,12 @@ enum {
|
||||
[tabBarControl setCellOptimumWidth:
|
||||
[ud integerForKey:MMTabOptimumWidthKey]];
|
||||
|
||||
[tabBarControl setShowAddTabButton:YES];
|
||||
[tabBarControl setShowAddTabButton:[ud boolForKey:MMShowAddTabButtonKey]];
|
||||
[[tabBarControl addTabButton] setTarget:self];
|
||||
[[tabBarControl addTabButton] setAction:@selector(addNewTab:)];
|
||||
[tabBarControl setAllowsDragBetweenWindows:NO];
|
||||
[tabBarControl registerForDraggedTypes:
|
||||
[NSArray arrayWithObject:NSFilenamesPboardType]];
|
||||
|
||||
[tabBarControl setAutoresizingMask:NSViewWidthSizable|NSViewMinYMargin];
|
||||
|
||||
@@ -278,24 +281,41 @@ enum {
|
||||
NSArray *tabViewItems = [[self tabBarControl] representedTabViewItems];
|
||||
|
||||
while (p < end) {
|
||||
NSTabViewItem *tvi = nil;
|
||||
|
||||
//int wincount = *((int*)p); p += sizeof(int);
|
||||
int length = *((int*)p); p += sizeof(int);
|
||||
int infoCount = *((int*)p); p += sizeof(int);
|
||||
unsigned i;
|
||||
for (i = 0; i < infoCount; ++i) {
|
||||
int length = *((int*)p); p += sizeof(int);
|
||||
if (length <= 0)
|
||||
continue;
|
||||
|
||||
NSString *label = [[NSString alloc]
|
||||
initWithBytes:(void*)p length:length
|
||||
encoding:NSUTF8StringEncoding];
|
||||
p += length;
|
||||
NSString *val = [[NSString alloc]
|
||||
initWithBytes:(void*)p length:length
|
||||
encoding:NSUTF8StringEncoding];
|
||||
p += length;
|
||||
|
||||
// Set the label of the tab; add a new tab when needed.
|
||||
NSTabViewItem *tvi = [[self tabView] numberOfTabViewItems] <= tabIdx
|
||||
? [self addNewTabViewItem]
|
||||
: [tabViewItems objectAtIndex:tabIdx];
|
||||
switch (i) {
|
||||
case MMTabLabel:
|
||||
// Set the label of the tab, adding a new tab when needed.
|
||||
tvi = [[self tabView] numberOfTabViewItems] <= tabIdx
|
||||
? [self addNewTabViewItem]
|
||||
: [tabViewItems objectAtIndex:tabIdx];
|
||||
[tvi setLabel:val];
|
||||
++tabIdx;
|
||||
break;
|
||||
case MMTabToolTip:
|
||||
if (tvi)
|
||||
[[self tabBarControl] setToolTip:val
|
||||
forTabViewItem:tvi];
|
||||
break;
|
||||
default:
|
||||
NSLog(@"WARNING: Unknown tab info for index: %d", i);
|
||||
}
|
||||
|
||||
[tvi setLabel:label];
|
||||
|
||||
[label release];
|
||||
|
||||
++tabIdx;
|
||||
[val release];
|
||||
}
|
||||
}
|
||||
|
||||
// Remove unused tabs from the NSTabView. Note that when a tab is closed
|
||||
@@ -498,6 +518,40 @@ enum {
|
||||
[vimController sendMessage:DraggedTabMsgID data:data];
|
||||
}
|
||||
|
||||
- (NSDragOperation)tabBarControl:(PSMTabBarControl *)theTabBarControl
|
||||
draggingEntered:(id <NSDraggingInfo>)sender
|
||||
forTabAtIndex:(unsigned)tabIndex
|
||||
{
|
||||
NSPasteboard *pb = [sender draggingPasteboard];
|
||||
return [[pb types] containsObject:NSFilenamesPboardType]
|
||||
? NSDragOperationCopy
|
||||
: NSDragOperationNone;
|
||||
}
|
||||
|
||||
- (BOOL)tabBarControl:(PSMTabBarControl *)theTabBarControl
|
||||
performDragOperation:(id <NSDraggingInfo>)sender
|
||||
forTabAtIndex:(unsigned)tabIndex
|
||||
{
|
||||
NSPasteboard *pb = [sender draggingPasteboard];
|
||||
if ([[pb types] containsObject:NSFilenamesPboardType]) {
|
||||
NSArray *filenames = [pb propertyListForType:NSFilenamesPboardType];
|
||||
if ([filenames count] == 0)
|
||||
return NO;
|
||||
if (tabIndex != NSNotFound) {
|
||||
// If dropping on a specific tab, only open one file
|
||||
[vimController file:[filenames objectAtIndex:0]
|
||||
draggedToTabAtIndex:tabIndex];
|
||||
} else {
|
||||
// Files were dropped on empty part of tab bar; open them all
|
||||
[vimController filesDraggedToTabBar:filenames];
|
||||
}
|
||||
return YES;
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- NSView customization ---------------------------------------------------
|
||||
|
||||
@@ -873,4 +927,24 @@ enum {
|
||||
[[(MMVimView*)vimView textView] scrollWheel:event];
|
||||
}
|
||||
|
||||
- (void)mouseDown:(NSEvent *)event
|
||||
{
|
||||
// TODO: This is an ugly way of getting the connection to the backend.
|
||||
NSConnection *connection = nil;
|
||||
id wc = [[self window] windowController];
|
||||
if ([wc isKindOfClass:[MMWindowController class]]) {
|
||||
MMVimController *vc = [(MMWindowController*)wc vimController];
|
||||
id proxy = [vc backendProxy];
|
||||
connection = [(NSDistantObject*)proxy connectionForProxy];
|
||||
}
|
||||
|
||||
// NOTE: The scroller goes into "event tracking mode" when the user clicks
|
||||
// (and holds) the mouse button. We have to manually add the backend
|
||||
// connection to this mode while the mouse button is held, else DO messages
|
||||
// from Vim will not be processed until the mouse button is released.
|
||||
[connection addRequestMode:NSEventTrackingRunLoopMode];
|
||||
[super mouseDown:event];
|
||||
[connection removeRequestMode:NSEventTrackingRunLoopMode];
|
||||
}
|
||||
|
||||
@end // MMScroller
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
@interface MMWindow : NSWindow {
|
||||
NSBox *tablineSeparator;
|
||||
NSRect userFrame;
|
||||
}
|
||||
|
||||
- (id)initWithContentRect:(NSRect)rect
|
||||
|
||||
@@ -140,4 +140,25 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (IBAction)zoom:(id)sender
|
||||
{
|
||||
NSRect frame = [self frame];
|
||||
NSRect defaultFrame = [[self screen] visibleFrame];
|
||||
defaultFrame = [[self delegate] windowWillUseStandardFrame:self
|
||||
defaultFrame:defaultFrame];
|
||||
|
||||
// TODO: Check if width & height differs by cellSize or more.
|
||||
BOOL isZoomed = ((abs(frame.size.width - defaultFrame.size.width) < 8) &&
|
||||
(abs(frame.size.height - defaultFrame.size.height) < 8));
|
||||
|
||||
if (isZoomed) {
|
||||
if (userFrame.size.width > 0 && userFrame.size.height > 0)
|
||||
defaultFrame = userFrame;
|
||||
} else {
|
||||
userFrame = frame;
|
||||
}
|
||||
|
||||
[self setFrame:defaultFrame display:YES];
|
||||
}
|
||||
|
||||
@end // MMWindow
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
MMVimView *vimView;
|
||||
BOOL setupDone;
|
||||
BOOL shouldResizeVimView;
|
||||
BOOL keepOnScreen;
|
||||
BOOL fullscreenEnabled;
|
||||
NSString *windowAutosaveKey;
|
||||
MMFullscreenWindow *fullscreenWindow;
|
||||
@@ -39,7 +40,8 @@
|
||||
- (void)showWindow;
|
||||
- (void)updateTabsWithData:(NSData *)data;
|
||||
- (void)selectTabWithIndex:(int)idx;
|
||||
- (void)setTextDimensionsWithRows:(int)rows columns:(int)cols live:(BOOL)live;
|
||||
- (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
|
||||
isReply:(BOOL)reply;
|
||||
- (void)setTitle:(NSString *)title;
|
||||
- (void)setDocumentFilename:(NSString *)filename;
|
||||
- (void)setToolbar:(NSToolbar *)toolbar;
|
||||
@@ -62,6 +64,8 @@
|
||||
|
||||
- (void)enterFullscreen:(int)fuoptions backgroundColor:(NSColor *)back;
|
||||
- (void)leaveFullscreen;
|
||||
- (void)setFullscreenBackgroundColor:(NSColor *)back;
|
||||
|
||||
- (void)setBuffersModified:(BOOL)mod;
|
||||
|
||||
- (IBAction)addNewTab:(id)sender;
|
||||
@@ -73,5 +77,6 @@
|
||||
- (IBAction)vimToolbarItemAction:(id)sender;
|
||||
- (IBAction)fontSizeUp:(id)sender;
|
||||
- (IBAction)fontSizeDown:(id)sender;
|
||||
- (IBAction)findAndReplace:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
+150
-20
@@ -57,6 +57,7 @@
|
||||
|
||||
#import "MMAppController.h"
|
||||
#import "MMAtsuiTextView.h"
|
||||
#import "MMFindReplaceController.h"
|
||||
#import "MMFullscreenWindow.h"
|
||||
#import "MMTextView.h"
|
||||
#import "MMTypesetter.h"
|
||||
@@ -71,8 +72,10 @@
|
||||
|
||||
@interface MMWindowController (Private)
|
||||
- (NSSize)contentSize;
|
||||
- (void)resizeWindowToFitContentSize:(NSSize)contentSize;
|
||||
- (void)resizeWindowToFitContentSize:(NSSize)contentSize
|
||||
keepOnScreen:(BOOL)onScreen;
|
||||
- (NSSize)constrainContentSizeToScreenSize:(NSSize)contentSize;
|
||||
- (NSRect)constrainFrame:(NSRect)frame;
|
||||
- (void)updateResizeConstraints;
|
||||
- (NSTabViewItem *)addNewTabViewItem;
|
||||
- (BOOL)askBackendForStarRegister:(NSPasteboard *)pb;
|
||||
@@ -270,7 +273,8 @@
|
||||
setupDone = YES;
|
||||
|
||||
[self updateResizeConstraints];
|
||||
[self resizeWindowToFitContentSize:[vimView desiredSize]];
|
||||
[self resizeWindowToFitContentSize:[vimView desiredSize]
|
||||
keepOnScreen:YES];
|
||||
}
|
||||
|
||||
- (void)showWindow
|
||||
@@ -294,10 +298,11 @@
|
||||
[vimView selectTabWithIndex:idx];
|
||||
}
|
||||
|
||||
- (void)setTextDimensionsWithRows:(int)rows columns:(int)cols live:(BOOL)live
|
||||
- (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live
|
||||
isReply:(BOOL)reply
|
||||
{
|
||||
//NSLog(@"setTextDimensionsWithRows:%d columns:%d live:%s", rows, cols,
|
||||
// live ? "YES" : "NO");
|
||||
//NSLog(@"setTextDimensionsWithRows:%d columns:%d isLive:%d isReply:%d",
|
||||
// rows, cols, live, reply);
|
||||
|
||||
// NOTE: The only place where the (rows,columns) of the vim view are
|
||||
// modified is here and when entering/leaving full-screen. Setting these
|
||||
@@ -309,11 +314,17 @@
|
||||
// resize when this message is received. We refrain from changing the view
|
||||
// size when this flag is set, otherwise the window might jitter when the
|
||||
// user drags to resize the window.
|
||||
//
|
||||
// The 'reply' flag indicates that this resize originated in MacVim and
|
||||
// that Vim is now replying to that resize to make sure that it comes into
|
||||
// effect.
|
||||
|
||||
[vimView setDesiredRows:rows columns:cols];
|
||||
|
||||
if (setupDone && !live)
|
||||
if (setupDone && !live) {
|
||||
shouldResizeVimView = YES;
|
||||
keepOnScreen = !reply;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setTitle:(NSString *)title
|
||||
@@ -431,8 +442,11 @@
|
||||
[[fullscreenWindow contentView] setNeedsDisplay:YES];
|
||||
[fullscreenWindow centerView];
|
||||
} else {
|
||||
[self resizeWindowToFitContentSize:contentSize];
|
||||
[self resizeWindowToFitContentSize:contentSize
|
||||
keepOnScreen:keepOnScreen];
|
||||
}
|
||||
|
||||
keepOnScreen = NO;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,16 +513,33 @@
|
||||
|
||||
- (void)liveResizeWillStart
|
||||
{
|
||||
if (!setupDone) return;
|
||||
|
||||
// Save the original title, if we haven't already.
|
||||
if (lastSetTitle == nil) {
|
||||
lastSetTitle = [[decoratedWindow title] retain];
|
||||
}
|
||||
|
||||
// NOTE: During live resize Cocoa goes into "event tracking mode". We have
|
||||
// to add the backend connection to this mode in order for resize messages
|
||||
// from Vim to reach MacVim. We do not wish to always listen to requests
|
||||
// in event tracking mode since then MacVim could receive DO messages at
|
||||
// unexpected times (e.g. when a key equivalent is pressed and the menu bar
|
||||
// momentarily lights up).
|
||||
id proxy = [vimController backendProxy];
|
||||
NSConnection *connection = [(NSDistantObject*)proxy connectionForProxy];
|
||||
[connection addRequestMode:NSEventTrackingRunLoopMode];
|
||||
}
|
||||
|
||||
- (void)liveResizeDidEnd
|
||||
{
|
||||
if (!setupDone) return;
|
||||
|
||||
// See comment above regarding event tracking mode.
|
||||
id proxy = [vimController backendProxy];
|
||||
NSConnection *connection = [(NSDistantObject*)proxy connectionForProxy];
|
||||
[connection removeRequestMode:NSEventTrackingRunLoopMode];
|
||||
|
||||
// NOTE: During live resize messages from MacVim to Vim are often dropped
|
||||
// (because too many messages are sent at once). This may lead to
|
||||
// inconsistent states between Vim and MacVim; to avoid this we send a
|
||||
@@ -532,7 +563,8 @@
|
||||
// Sending of synchronous message failed. Force the window size to
|
||||
// match the last dimensions received from Vim, otherwise we end up
|
||||
// with inconsistent states.
|
||||
[self resizeWindowToFitContentSize:[vimView desiredSize]];
|
||||
[self resizeWindowToFitContentSize:[vimView desiredSize]
|
||||
keepOnScreen:NO];
|
||||
}
|
||||
|
||||
// If we saved the original title while resizing, restore it.
|
||||
@@ -571,6 +603,12 @@
|
||||
shouldResizeVimView = YES;
|
||||
}
|
||||
|
||||
- (void)setFullscreenBackgroundColor:(NSColor *)back
|
||||
{
|
||||
if (fullscreenEnabled)
|
||||
[fullscreenWindow setBackgroundColor:back];
|
||||
}
|
||||
|
||||
- (void)setBuffersModified:(BOOL)mod
|
||||
{
|
||||
// NOTE: We only set the document edited flag on the decorated window since
|
||||
@@ -654,6 +692,34 @@
|
||||
[NSNumber numberWithInt:NSSizeDownFontAction]];
|
||||
}
|
||||
|
||||
- (IBAction)findAndReplace:(id)sender
|
||||
{
|
||||
int tag = [sender tag];
|
||||
MMFindReplaceController *fr = [MMFindReplaceController sharedInstance];
|
||||
int flags = 0;
|
||||
|
||||
// NOTE: The 'flags' values must match the FRD_ defines in gui.h (except
|
||||
// for 0x100 which we use to indicate a backward search).
|
||||
switch (tag) {
|
||||
case 1: flags = 0x100; break;
|
||||
case 2: flags = 3; break;
|
||||
case 3: flags = 4; break;
|
||||
}
|
||||
|
||||
if ([fr matchWord])
|
||||
flags |= 0x08;
|
||||
if (![fr ignoreCase])
|
||||
flags |= 0x10;
|
||||
|
||||
NSDictionary *args = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[fr findString], @"find",
|
||||
[fr replaceString], @"replace",
|
||||
[NSNumber numberWithInt:flags], @"flags",
|
||||
nil];
|
||||
|
||||
[vimController sendMessage:FindReplaceMsgID data:[args dictionaryAsData]];
|
||||
}
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item
|
||||
{
|
||||
if ([item action] == @selector(vimMenuItemAction:)
|
||||
@@ -701,6 +767,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (NSSize)windowWillResize:(NSWindow *)win toSize:(NSSize)proposedFrameSize
|
||||
{
|
||||
// Make sure the window isn't resized to be larger than the "visible frame"
|
||||
// for the current screen. Do this here instead of setting the window max
|
||||
// size in updateResizeConstraints since the screen's visible frame may
|
||||
// change at any time (dock could move, resolution could change, window
|
||||
// could be moved to another screen, ...).
|
||||
|
||||
NSRect maxFrame = [self constrainFrame:[[win screen] visibleFrame]];
|
||||
|
||||
if (proposedFrameSize.width > maxFrame.size.width)
|
||||
proposedFrameSize.width = maxFrame.size.width;
|
||||
if (proposedFrameSize.height > maxFrame.size.height)
|
||||
proposedFrameSize.height = maxFrame.size.height;
|
||||
|
||||
return proposedFrameSize;
|
||||
}
|
||||
|
||||
- (void)windowDidResize:(id)sender
|
||||
{
|
||||
if (!setupDone || fullscreenEnabled) return;
|
||||
@@ -727,6 +811,11 @@
|
||||
BOOL zoomBoth = [[NSUserDefaults standardUserDefaults]
|
||||
boolForKey:MMZoomBothKey];
|
||||
|
||||
// The "default frame" represents the maximal size of a zoomed window.
|
||||
// Constrain this frame so that the content fits an even number of rows and
|
||||
// columns.
|
||||
frame = [self constrainFrame:frame];
|
||||
|
||||
if (!((zoomBoth && !cmdLeftClick) || (!zoomBoth && cmdLeftClick))) {
|
||||
// Zoom in horizontal direction only.
|
||||
NSRect currentFrame = [win frame];
|
||||
@@ -734,16 +823,6 @@
|
||||
frame.origin.x = currentFrame.origin.x;
|
||||
}
|
||||
|
||||
// HACK! The window frame is often higher than the 'defaultFrame' (the fact
|
||||
// that 'defaultFrame' doesn't cover the entire area up to the menu bar
|
||||
// seems like a Cocoa bug). To ensure that the window doesn't move
|
||||
// downwards when the zoom button is clicked we check for this situation
|
||||
// and return a frame whose max Y coordinate is no lower than the current
|
||||
// max Y coordinate.
|
||||
float delta = NSMaxY([win frame]) - NSMaxY(frame);
|
||||
if (delta > 0)
|
||||
frame.origin.y += delta;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
@@ -771,6 +850,20 @@
|
||||
return [self askBackendForStarRegister:pboard];
|
||||
}
|
||||
|
||||
- (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pboard
|
||||
{
|
||||
// Replace the current selection with the text on the pasteboard.
|
||||
NSArray *types = [pboard types];
|
||||
if ([types containsObject:NSStringPboardType]) {
|
||||
NSString *input = [NSString stringWithFormat:@"s%@",
|
||||
[pboard stringForType:NSStringPboardType]];
|
||||
[vimController addVimInput:input];
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end // MMWindowController
|
||||
|
||||
|
||||
@@ -787,6 +880,7 @@
|
||||
}
|
||||
|
||||
- (void)resizeWindowToFitContentSize:(NSSize)contentSize
|
||||
keepOnScreen:(BOOL)onScreen
|
||||
{
|
||||
NSRect frame = [decoratedWindow frame];
|
||||
NSRect contentRect = [decoratedWindow contentRectForFrameRect:frame];
|
||||
@@ -795,8 +889,29 @@
|
||||
contentRect.origin.y -= contentSize.height - contentRect.size.height;
|
||||
contentRect.size = contentSize;
|
||||
|
||||
frame = [decoratedWindow frameRectForContentRect:contentRect];
|
||||
[decoratedWindow setFrame:frame display:YES];
|
||||
NSRect newFrame = [decoratedWindow frameRectForContentRect:contentRect];
|
||||
|
||||
// Ensure that the window fits inside the visible part of the screen.
|
||||
NSRect maxFrame = [[decoratedWindow screen] visibleFrame];
|
||||
maxFrame = [self constrainFrame:maxFrame];
|
||||
|
||||
if (newFrame.size.width > maxFrame.size.width) {
|
||||
newFrame.size.width = maxFrame.size.width;
|
||||
newFrame.origin.x = maxFrame.origin.x;
|
||||
}
|
||||
if (newFrame.size.height > maxFrame.size.height) {
|
||||
newFrame.size.height = maxFrame.size.height;
|
||||
newFrame.origin.y = maxFrame.origin.y;
|
||||
}
|
||||
|
||||
if (onScreen) {
|
||||
if (newFrame.origin.y < maxFrame.origin.y)
|
||||
newFrame.origin.y = maxFrame.origin.y;
|
||||
if (NSMaxX(newFrame) > NSMaxX(maxFrame))
|
||||
newFrame.origin.x = NSMaxX(maxFrame) - newFrame.size.width;
|
||||
}
|
||||
|
||||
[decoratedWindow setFrame:newFrame display:YES];
|
||||
}
|
||||
|
||||
- (NSSize)constrainContentSizeToScreenSize:(NSSize)contentSize
|
||||
@@ -812,6 +927,21 @@
|
||||
return contentSize;
|
||||
}
|
||||
|
||||
- (NSRect)constrainFrame:(NSRect)frame
|
||||
{
|
||||
// Constrain the given (window) frame so that it fits an even number of
|
||||
// rows and columns.
|
||||
NSRect contentRect = [decoratedWindow contentRectForFrameRect:frame];
|
||||
NSSize constrainedSize = [vimView constrainRows:NULL
|
||||
columns:NULL
|
||||
toSize:contentRect.size];
|
||||
|
||||
contentRect.origin.y += contentRect.size.height - constrainedSize.height;
|
||||
contentRect.size = constrainedSize;
|
||||
|
||||
return [decoratedWindow frameRectForContentRect:contentRect];
|
||||
}
|
||||
|
||||
- (void)updateResizeConstraints
|
||||
{
|
||||
if (!setupDone) return;
|
||||
|
||||
+28
-6
@@ -121,7 +121,11 @@ enum {
|
||||
UpdateTabBarMsgID,
|
||||
ShowTabBarMsgID,
|
||||
HideTabBarMsgID,
|
||||
SetTextRowsMsgID,
|
||||
SetTextColumnsMsgID,
|
||||
SetTextDimensionsMsgID,
|
||||
LiveResizeMsgID,
|
||||
SetTextDimensionsReplyMsgID,
|
||||
SetWindowTitleMsgID,
|
||||
ScrollWheelMsgID,
|
||||
MouseDownMsgID,
|
||||
@@ -164,13 +168,15 @@ enum {
|
||||
SetPreEditPositionMsgID,
|
||||
TerminateNowMsgID,
|
||||
XcodeModMsgID,
|
||||
LiveResizeMsgID,
|
||||
EnableAntialiasMsgID,
|
||||
DisableAntialiasMsgID,
|
||||
SetVimStateMsgID,
|
||||
SetDocumentFilenameMsgID,
|
||||
OpenWithArgumentsMsgID,
|
||||
CloseWindowMsgID,
|
||||
SetFullscreenColorMsgID,
|
||||
ShowFindReplaceDialogMsgID,
|
||||
FindReplaceMsgID,
|
||||
};
|
||||
|
||||
|
||||
@@ -202,6 +208,13 @@ enum {
|
||||
ToolbarSizeRegularFlag = 4
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
MMTabLabel = 0,
|
||||
MMTabToolTip,
|
||||
MMTabInfoCount
|
||||
};
|
||||
|
||||
// Argument used to stop MacVim from opening an empty window on startup
|
||||
// (techincally this is a user default but should not be used as such).
|
||||
extern NSString *MMNoWindowKey;
|
||||
@@ -211,11 +224,6 @@ extern NSString *VimPBoardType;
|
||||
|
||||
|
||||
|
||||
// Loads all fonts in the Resouces folder of the app bundle and returns a font
|
||||
// container reference (which should be used to deactivate the loaded fonts).
|
||||
ATSFontContainerRef loadFonts();
|
||||
|
||||
|
||||
|
||||
@interface NSString (MMExtras)
|
||||
- (NSString *)stringByEscapingSpecialFilenameCharacters;
|
||||
@@ -253,3 +261,17 @@ ATSFontContainerRef loadFonts();
|
||||
|
||||
// MacVim Apple Event Constants
|
||||
#define keyMMUntitledWindow 'MMuw'
|
||||
|
||||
|
||||
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
|
||||
// NSInteger was introduced in 10.5
|
||||
# if __LP64__ || NS_BUILD_32_LIKE_64
|
||||
typedef long NSInteger;
|
||||
typedef unsigned long NSUInteger;
|
||||
# else
|
||||
typedef int NSInteger;
|
||||
typedef unsigned int NSUInteger;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
+7
-34
@@ -28,7 +28,11 @@ char *MessageStrings[] =
|
||||
"UpdateTabBarMsgID",
|
||||
"ShowTabBarMsgID",
|
||||
"HideTabBarMsgID",
|
||||
"SetTextRowsMsgID",
|
||||
"SetTextColumnsMsgID",
|
||||
"SetTextDimensionsMsgID",
|
||||
"LiveResizeMsgID",
|
||||
"SetTextDimensionsReplyMsgID",
|
||||
"SetWindowTitleMsgID",
|
||||
"ScrollWheelMsgID",
|
||||
"MouseDownMsgID",
|
||||
@@ -71,13 +75,15 @@ char *MessageStrings[] =
|
||||
"SetPreEditPositionMsgID",
|
||||
"TerminateNowMsgID",
|
||||
"XcodeModMsgID",
|
||||
"LiveResizeMsgID",
|
||||
"EnableAntialiasMsgID",
|
||||
"DisableAntialiasMsgID",
|
||||
"SetVimStateMsgID",
|
||||
"SetDocumentFilenameMsgID",
|
||||
"OpenWithArgumentsMsgID",
|
||||
"CloseWindowMsgID",
|
||||
"SetFullscreenColorMsgID",
|
||||
"ShowFindReplaceDialogMsgID",
|
||||
"FindReplaceMsgID",
|
||||
};
|
||||
|
||||
|
||||
@@ -93,39 +99,6 @@ NSString *VimPBoardType = @"VimPBoardType";
|
||||
|
||||
|
||||
|
||||
ATSFontContainerRef
|
||||
loadFonts()
|
||||
{
|
||||
// This loads all fonts from the Resources folder. The fonts are only
|
||||
// available to the process which loaded them, so loading has to be done
|
||||
// once for MacVim and an additional time for each Vim process. The
|
||||
// returned container ref should be used to deactiave the font.
|
||||
//
|
||||
// (Code taken from cocoadev.com)
|
||||
ATSFontContainerRef fontContainerRef = 0;
|
||||
NSString *fontsFolder = [[NSBundle mainBundle] resourcePath];
|
||||
if (fontsFolder) {
|
||||
NSURL *fontsURL = [NSURL fileURLWithPath:fontsFolder];
|
||||
if (fontsURL) {
|
||||
FSRef fsRef;
|
||||
FSSpec fsSpec;
|
||||
CFURLGetFSRef((CFURLRef)fontsURL, &fsRef);
|
||||
|
||||
if (FSGetCatalogInfo(&fsRef, kFSCatInfoNone, NULL, NULL, &fsSpec,
|
||||
NULL) == noErr) {
|
||||
ATSFontActivateFromFileSpecification(&fsSpec,
|
||||
kATSFontContextLocal, kATSFontFormatUnspecified, NULL,
|
||||
kATSOptionFlagsDefault, &fontContainerRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fontContainerRef;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@implementation NSString (MMExtras)
|
||||
|
||||
- (NSString *)stringByEscapingSpecialFilenameCharacters
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
0395A95A0D74D47B00881434 /* Integration.png in Resources */ = {isa = PBXBuildFile; fileRef = 0395A9590D74D47B00881434 /* Integration.png */; };
|
||||
0395A9BF0D75D02400881434 /* AuthorizedShellCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 0395A9BE0D75D02400881434 /* AuthorizedShellCommand.m */; };
|
||||
0395A9C30D75D04D00881434 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0395A9C20D75D04D00881434 /* Security.framework */; };
|
||||
0395AA780D76E77800881434 /* Info in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0395AA770D76E77800881434 /* Info */; };
|
||||
0395AAAD0D76E94000881434 /* Edit in ODBEditor.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0395AA210D76E22700881434 /* Edit in ODBEditor.bundle */; };
|
||||
0395AA780D76E77800881434 /* Info in Copy ODBEditor */ = {isa = PBXBuildFile; fileRef = 0395AA770D76E77800881434 /* Info */; };
|
||||
0395AAAD0D76E94000881434 /* Edit in ODBEditor.bundle in Copy ODBEditor */ = {isa = PBXBuildFile; fileRef = 0395AA210D76E22700881434 /* Edit in ODBEditor.bundle */; };
|
||||
1D09AB420C6A4D520045497E /* MMTypesetter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D09AB400C6A4D520045497E /* MMTypesetter.m */; };
|
||||
1D0E051C0BA5F83800B6049E /* Colors.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1D0E051B0BA5F83800B6049E /* Colors.plist */; };
|
||||
1D145C7F0E5227CE00691AA0 /* MMTextViewHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D145C7E0E5227CE00691AA0 /* MMTextViewHelper.m */; };
|
||||
@@ -28,26 +28,18 @@
|
||||
1D3D19120CA690FF0004A0A5 /* DejaVuSansMono-BoldOblique.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 1D3D190E0CA690FF0004A0A5 /* DejaVuSansMono-BoldOblique.ttf */; };
|
||||
1D3D19130CA690FF0004A0A5 /* DejaVuSansMono-Oblique.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 1D3D190F0CA690FF0004A0A5 /* DejaVuSansMono-Oblique.ttf */; };
|
||||
1D3D19140CA690FF0004A0A5 /* DejaVuSansMono.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 1D3D19100CA690FF0004A0A5 /* DejaVuSansMono.ttf */; };
|
||||
1D493D580C5247BF00AB718C /* Vim in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1D493D570C5247BF00AB718C /* Vim */; };
|
||||
1D493DBA0C52534300AB718C /* PSMTabBarControl.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1D493DB90C52533B00AB718C /* PSMTabBarControl.framework */; };
|
||||
1D71ACB40BC702AB002F2B60 /* doc-bm-c.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACA90BC702AB002F2B60 /* doc-bm-c.icns */; };
|
||||
1D71ACB50BC702AC002F2B60 /* doc-bm-h.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACAA0BC702AB002F2B60 /* doc-bm-h.icns */; };
|
||||
1D71ACB60BC702AC002F2B60 /* doc-bm-html.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACAB0BC702AB002F2B60 /* doc-bm-html.icns */; };
|
||||
1D71ACB70BC702AC002F2B60 /* doc-bm-java.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACAC0BC702AB002F2B60 /* doc-bm-java.icns */; };
|
||||
1D71ACB80BC702AC002F2B60 /* doc-bm-php.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACAD0BC702AB002F2B60 /* doc-bm-php.icns */; };
|
||||
1D71ACB90BC702AC002F2B60 /* doc-bm-pl.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACAE0BC702AB002F2B60 /* doc-bm-pl.icns */; };
|
||||
1D71ACBA0BC702AC002F2B60 /* doc-bm-sh.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACAF0BC702AB002F2B60 /* doc-bm-sh.icns */; };
|
||||
1D71ACBB0BC702AC002F2B60 /* doc-bm-tex.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACB00BC702AB002F2B60 /* doc-bm-tex.icns */; };
|
||||
1D71ACBC0BC702AC002F2B60 /* doc-bm-txt.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACB10BC702AB002F2B60 /* doc-bm-txt.icns */; };
|
||||
1D71ACBD0BC702AC002F2B60 /* doc-bm-xml.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACB20BC702AB002F2B60 /* doc-bm-xml.icns */; };
|
||||
1D71ACBE0BC702AC002F2B60 /* doc-bm.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACB30BC702AB002F2B60 /* doc-bm.icns */; };
|
||||
1D493D580C5247BF00AB718C /* Vim in Copy Executables */ = {isa = PBXBuildFile; fileRef = 1D493D570C5247BF00AB718C /* Vim */; };
|
||||
1D493DBA0C52534300AB718C /* PSMTabBarControl.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 1D493DB90C52533B00AB718C /* PSMTabBarControl.framework */; };
|
||||
1D6008830E96886D003763F0 /* FindAndReplace.nib in Resources */ = {isa = PBXBuildFile; fileRef = 1D6008820E96886D003763F0 /* FindAndReplace.nib */; };
|
||||
1D60088B0E96A0B2003763F0 /* MMFindReplaceController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D60088A0E96A0B2003763F0 /* MMFindReplaceController.m */; };
|
||||
1D7F74580E4CE1AE003225C6 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D7F74570E4CE1AE003225C6 /* Sparkle.framework */; };
|
||||
1D7F745B0E4CE1CD003225C6 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1D7F74570E4CE1AE003225C6 /* Sparkle.framework */; };
|
||||
1D7F745B0E4CE1CD003225C6 /* Sparkle.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 1D7F74570E4CE1AE003225C6 /* Sparkle.framework */; };
|
||||
1D80591F0E1185EA001699D1 /* Miscellaneous.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D80591D0E1185EA001699D1 /* Miscellaneous.m */; };
|
||||
1D80FBD40CBBD3B700102A1C /* MMFullscreenWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D80FBD00CBBD3B700102A1C /* MMFullscreenWindow.m */; };
|
||||
1D80FBD60CBBD3B700102A1C /* MMVimView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D80FBD20CBBD3B700102A1C /* MMVimView.m */; };
|
||||
1D80FBE40CBBD6F200102A1C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D80FBE30CBBD6F200102A1C /* Carbon.framework */; };
|
||||
1D9918490D299F9900A96335 /* MMAtsuiTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D9918470D299F9900A96335 /* MMAtsuiTextView.m */; };
|
||||
1D9C60520EF79C0C0034AD44 /* MacVim.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D9C602E0EF79C0C0034AD44 /* MacVim.icns */; };
|
||||
1DCD00BF0E50B2B700460166 /* Attention.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DCD00AA0E50B2B700460166 /* Attention.png */; };
|
||||
1DCD00C00E50B2B700460166 /* Copy.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DCD00AB0E50B2B700460166 /* Copy.png */; };
|
||||
1DCD00C10E50B2B700460166 /* Cut.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DCD00AC0E50B2B700460166 /* Cut.png */; };
|
||||
@@ -70,18 +62,17 @@
|
||||
1DCD00D20E50B2B700460166 /* TagJump.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DCD00BD0E50B2B700460166 /* TagJump.png */; };
|
||||
1DCD00D30E50B2B700460166 /* Undo.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DCD00BE0E50B2B700460166 /* Undo.png */; };
|
||||
1DD04DEC0C529C5E006CDC2B /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 1DD04DEB0C529C5E006CDC2B /* Credits.rtf */; };
|
||||
1DD0C20C0C60FFB4008CD84A /* gvimrc in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1DD0C20A0C60FF9A008CD84A /* gvimrc */; };
|
||||
1DD0C20C0C60FFB4008CD84A /* gvimrc in Copy Vim Runtime Files */ = {isa = PBXBuildFile; fileRef = 1DD0C20A0C60FF9A008CD84A /* gvimrc */; };
|
||||
1DD3D51E0D82D4C9006E4320 /* ibeam.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DD3D51D0D82D4C9006E4320 /* ibeam.png */; };
|
||||
1DD66ECE0C803D3600EBDAB3 /* MMApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DD66ECC0C803D3600EBDAB3 /* MMApplication.m */; };
|
||||
1DD703B90BA9D15D008679E9 /* vim_gloss.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1DD703B80BA9D15D008679E9 /* vim_gloss.icns */; };
|
||||
1DD704310BA9F9C2008679E9 /* SpecialKeys.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DD704300BA9F9C2008679E9 /* SpecialKeys.plist */; };
|
||||
1DD9F5E50C85D60500E8D5A5 /* SystemColors.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DD9F5E40C85D60500E8D5A5 /* SystemColors.plist */; };
|
||||
1DE3F8E70D50F80500052B9E /* Preferences.nib in Resources */ = {isa = PBXBuildFile; fileRef = 1DE3F8E50D50F80500052B9E /* Preferences.nib */; };
|
||||
1DE3F8EB0D50F84600052B9E /* MMPreferenceController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DE3F8E90D50F84600052B9E /* MMPreferenceController.m */; };
|
||||
1DE608B40C587FDA0055263D /* runtime in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1DE602470C587FD10055263D /* runtime */; };
|
||||
1DE608B40C587FDA0055263D /* runtime in Copy Vim Runtime Files */ = {isa = PBXBuildFile; fileRef = 1DE602470C587FD10055263D /* runtime */; };
|
||||
1DE8CC620C5E2AAD003F56E3 /* Actions.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DE8CC610C5E2AAD003F56E3 /* Actions.plist */; };
|
||||
1DE9B9500D341AB8008FEDD4 /* MMWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DE9B94E0D341AB8008FEDD4 /* MMWindow.m */; };
|
||||
1DED78600C6DE43D0079945F /* vimrc in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1DED785F0C6DE43D0079945F /* vimrc */; };
|
||||
1DED78600C6DE43D0079945F /* vimrc in Copy Vim Runtime Files */ = {isa = PBXBuildFile; fileRef = 1DED785F0C6DE43D0079945F /* vimrc */; };
|
||||
1DFE25A50C527BC4003000F7 /* PSMTabBarControl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D493DB90C52533B00AB718C /* PSMTabBarControl.framework */; };
|
||||
8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; };
|
||||
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
|
||||
@@ -128,48 +119,52 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
0395AA790D76E77800881434 /* CopyFiles */ = {
|
||||
0395AA790D76E77800881434 /* Copy ODBEditor */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "Edit in ODBEditor";
|
||||
dstSubfolderSpec = 7;
|
||||
files = (
|
||||
0395AAAD0D76E94000881434 /* Edit in ODBEditor.bundle in CopyFiles */,
|
||||
0395AA780D76E77800881434 /* Info in CopyFiles */,
|
||||
0395AAAD0D76E94000881434 /* Edit in ODBEditor.bundle in Copy ODBEditor */,
|
||||
0395AA780D76E77800881434 /* Info in Copy ODBEditor */,
|
||||
);
|
||||
name = "Copy ODBEditor";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
1D0DCAD80BA3604D00B6CCFA /* CopyFiles */ = {
|
||||
1D0DCAD80BA3604D00B6CCFA /* Copy Executables */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 6;
|
||||
files = (
|
||||
1D493D580C5247BF00AB718C /* Vim in CopyFiles */,
|
||||
1D493D580C5247BF00AB718C /* Vim in Copy Executables */,
|
||||
);
|
||||
name = "Copy Executables";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
1D9EB2840C366D7B0074B739 /* CopyFiles */ = {
|
||||
1D9EB2840C366D7B0074B739 /* Copy Frameworks */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
1D7F745B0E4CE1CD003225C6 /* Sparkle.framework in CopyFiles */,
|
||||
1D493DBA0C52534300AB718C /* PSMTabBarControl.framework in CopyFiles */,
|
||||
1D7F745B0E4CE1CD003225C6 /* Sparkle.framework in Copy Frameworks */,
|
||||
1D493DBA0C52534300AB718C /* PSMTabBarControl.framework in Copy Frameworks */,
|
||||
);
|
||||
name = "Copy Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
1DE608B80C58807F0055263D /* CopyFiles */ = {
|
||||
1DE608B80C58807F0055263D /* Copy Vim Runtime Files */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = vim;
|
||||
dstSubfolderSpec = 7;
|
||||
files = (
|
||||
1DED78600C6DE43D0079945F /* vimrc in CopyFiles */,
|
||||
1DD0C20C0C60FFB4008CD84A /* gvimrc in CopyFiles */,
|
||||
1DE608B40C587FDA0055263D /* runtime in CopyFiles */,
|
||||
1DED78600C6DE43D0079945F /* vimrc in Copy Vim Runtime Files */,
|
||||
1DD0C20C0C60FFB4008CD84A /* gvimrc in Copy Vim Runtime Files */,
|
||||
1DE608B40C587FDA0055263D /* runtime in Copy Vim Runtime Files */,
|
||||
);
|
||||
name = "Copy Vim Runtime Files";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
@@ -188,7 +183,7 @@
|
||||
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
|
||||
1D09AB3F0C6A4D520045497E /* MMTypesetter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MMTypesetter.h; sourceTree = "<group>"; };
|
||||
1D09AB400C6A4D520045497E /* MMTypesetter.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMTypesetter.m; sourceTree = "<group>"; };
|
||||
1D0E051B0BA5F83800B6049E /* Colors.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Colors.plist; sourceTree = "<group>"; };
|
||||
1D0E051B0BA5F83800B6049E /* Colors.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Colors.plist; sourceTree = "<group>"; };
|
||||
1D145C7D0E5227CE00691AA0 /* MMTextViewHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMTextViewHelper.h; sourceTree = "<group>"; };
|
||||
1D145C7E0E5227CE00691AA0 /* MMTextViewHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMTextViewHelper.m; sourceTree = "<group>"; };
|
||||
1D1474950C56703C0038FA2B /* MacVim.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MacVim.h; sourceTree = "<group>"; };
|
||||
@@ -210,17 +205,9 @@
|
||||
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>"; };
|
||||
1D71ACAA0BC702AB002F2B60 /* doc-bm-h.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-h.icns"; sourceTree = "<group>"; };
|
||||
1D71ACAB0BC702AB002F2B60 /* doc-bm-html.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-html.icns"; sourceTree = "<group>"; };
|
||||
1D71ACAC0BC702AB002F2B60 /* doc-bm-java.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-java.icns"; sourceTree = "<group>"; };
|
||||
1D71ACAD0BC702AB002F2B60 /* doc-bm-php.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-php.icns"; sourceTree = "<group>"; };
|
||||
1D71ACAE0BC702AB002F2B60 /* doc-bm-pl.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-pl.icns"; sourceTree = "<group>"; };
|
||||
1D71ACAF0BC702AB002F2B60 /* doc-bm-sh.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-sh.icns"; sourceTree = "<group>"; };
|
||||
1D71ACB00BC702AB002F2B60 /* doc-bm-tex.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-tex.icns"; sourceTree = "<group>"; };
|
||||
1D71ACB10BC702AB002F2B60 /* doc-bm-txt.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-txt.icns"; sourceTree = "<group>"; };
|
||||
1D71ACB20BC702AB002F2B60 /* doc-bm-xml.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-xml.icns"; sourceTree = "<group>"; };
|
||||
1D71ACB30BC702AB002F2B60 /* doc-bm.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm.icns"; sourceTree = "<group>"; };
|
||||
1D6008820E96886D003763F0 /* FindAndReplace.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; path = FindAndReplace.nib; sourceTree = "<group>"; };
|
||||
1D6008890E96A0B2003763F0 /* MMFindReplaceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMFindReplaceController.h; sourceTree = "<group>"; };
|
||||
1D60088A0E96A0B2003763F0 /* MMFindReplaceController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMFindReplaceController.m; sourceTree = "<group>"; };
|
||||
1D7F74570E4CE1AE003225C6 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = "<group>"; };
|
||||
1D80591D0E1185EA001699D1 /* Miscellaneous.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Miscellaneous.m; sourceTree = "<group>"; };
|
||||
1D8059220E118663001699D1 /* Miscellaneous.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Miscellaneous.h; sourceTree = "<group>"; };
|
||||
@@ -231,6 +218,7 @@
|
||||
1D80FBE30CBBD6F200102A1C /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
|
||||
1D9918460D299F9900A96335 /* MMAtsuiTextView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MMAtsuiTextView.h; sourceTree = "<group>"; };
|
||||
1D9918470D299F9900A96335 /* MMAtsuiTextView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMAtsuiTextView.m; sourceTree = "<group>"; };
|
||||
1D9C602E0EF79C0C0034AD44 /* MacVim.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = MacVim.icns; path = icons/MacVim.icns; sourceTree = "<group>"; };
|
||||
1DCD00AA0E50B2B700460166 /* Attention.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Attention.png; path = Toolbar/Attention.png; sourceTree = "<group>"; };
|
||||
1DCD00AB0E50B2B700460166 /* Copy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Copy.png; path = Toolbar/Copy.png; sourceTree = "<group>"; };
|
||||
1DCD00AC0E50B2B700460166 /* Cut.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Cut.png; path = Toolbar/Cut.png; sourceTree = "<group>"; };
|
||||
@@ -257,14 +245,13 @@
|
||||
1DD3D51D0D82D4C9006E4320 /* ibeam.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ibeam.png; sourceTree = "<group>"; };
|
||||
1DD66ECB0C803D3600EBDAB3 /* MMApplication.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MMApplication.h; sourceTree = "<group>"; };
|
||||
1DD66ECC0C803D3600EBDAB3 /* MMApplication.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMApplication.m; sourceTree = "<group>"; };
|
||||
1DD703B80BA9D15D008679E9 /* vim_gloss.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = vim_gloss.icns; sourceTree = "<group>"; };
|
||||
1DD704300BA9F9C2008679E9 /* SpecialKeys.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = SpecialKeys.plist; sourceTree = "<group>"; };
|
||||
1DD9F5E40C85D60500E8D5A5 /* SystemColors.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = SystemColors.plist; sourceTree = "<group>"; };
|
||||
1DD704300BA9F9C2008679E9 /* SpecialKeys.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = SpecialKeys.plist; sourceTree = "<group>"; };
|
||||
1DD9F5E40C85D60500E8D5A5 /* SystemColors.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = SystemColors.plist; sourceTree = "<group>"; };
|
||||
1DE3F8E60D50F80500052B9E /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/Preferences.nib; sourceTree = "<group>"; };
|
||||
1DE3F8E80D50F84600052B9E /* MMPreferenceController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MMPreferenceController.h; sourceTree = "<group>"; };
|
||||
1DE3F8E90D50F84600052B9E /* MMPreferenceController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMPreferenceController.m; sourceTree = "<group>"; };
|
||||
1DE602470C587FD10055263D /* runtime */ = {isa = PBXFileReference; lastKnownFileType = folder; name = runtime; path = ../../runtime; sourceTree = SOURCE_ROOT; };
|
||||
1DE8CC610C5E2AAD003F56E3 /* Actions.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Actions.plist; sourceTree = "<group>"; };
|
||||
1DE8CC610C5E2AAD003F56E3 /* Actions.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Actions.plist; sourceTree = "<group>"; };
|
||||
1DE9B94D0D341AB8008FEDD4 /* MMWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MMWindow.h; sourceTree = "<group>"; };
|
||||
1DE9B94E0D341AB8008FEDD4 /* MMWindow.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMWindow.m; sourceTree = "<group>"; };
|
||||
1DED785F0C6DE43D0079945F /* vimrc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = vimrc; sourceTree = "<group>"; };
|
||||
@@ -328,6 +315,8 @@
|
||||
080E96DDFE201D6D7F000001 /* MacVim Source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1D6008890E96A0B2003763F0 /* MMFindReplaceController.h */,
|
||||
1D60088A0E96A0B2003763F0 /* MMFindReplaceController.m */,
|
||||
1D145C7D0E5227CE00691AA0 /* MMTextViewHelper.h */,
|
||||
1D145C7E0E5227CE00691AA0 /* MMTextViewHelper.m */,
|
||||
1D8059220E118663001699D1 /* Miscellaneous.h */,
|
||||
@@ -435,27 +424,6 @@
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1DCE78490C460C6C006305A6 /* Icons */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1D71ACA90BC702AB002F2B60 /* doc-bm-c.icns */,
|
||||
1D71ACAA0BC702AB002F2B60 /* doc-bm-h.icns */,
|
||||
1D71ACAB0BC702AB002F2B60 /* doc-bm-html.icns */,
|
||||
1D71ACAC0BC702AB002F2B60 /* doc-bm-java.icns */,
|
||||
1D71ACAD0BC702AB002F2B60 /* doc-bm-php.icns */,
|
||||
1D71ACAE0BC702AB002F2B60 /* doc-bm-pl.icns */,
|
||||
1D71ACAF0BC702AB002F2B60 /* doc-bm-sh.icns */,
|
||||
1D71ACB00BC702AB002F2B60 /* doc-bm-tex.icns */,
|
||||
1D71ACB10BC702AB002F2B60 /* doc-bm-txt.icns */,
|
||||
1D71ACB20BC702AB002F2B60 /* doc-bm-xml.icns */,
|
||||
1D71ACB30BC702AB002F2B60 /* doc-bm.icns */,
|
||||
0395A8A90D72D88B00881434 /* General.png */,
|
||||
0395A9590D74D47B00881434 /* Integration.png */,
|
||||
1DD703B80BA9D15D008679E9 /* vim_gloss.icns */,
|
||||
);
|
||||
name = Icons;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1DE602460C587F760055263D /* Vim Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -510,11 +478,14 @@
|
||||
29B97317FDCFA39411CA2CEA /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1D9C602E0EF79C0C0034AD44 /* MacVim.icns */,
|
||||
1D6008820E96886D003763F0 /* FindAndReplace.nib */,
|
||||
0395A8A90D72D88B00881434 /* General.png */,
|
||||
0395A9590D74D47B00881434 /* Integration.png */,
|
||||
1D22374A0E45DF4800E6FFFF /* Advanced.png */,
|
||||
BD9DF09F0DB2BA020025C97C /* PlugInView.nib */,
|
||||
1DD3D51D0D82D4C9006E4320 /* ibeam.png */,
|
||||
1D0F11480D58C77800D5DA09 /* Font */,
|
||||
1DCE78490C460C6C006305A6 /* Icons */,
|
||||
1DE9726C0C48050600F96A9F /* Toolbar */,
|
||||
1DD9F5E40C85D60500E8D5A5 /* SystemColors.plist */,
|
||||
1DE8CC610C5E2AAD003F56E3 /* Actions.plist */,
|
||||
@@ -552,10 +523,11 @@
|
||||
8D1107290486CEB800E47090 /* Resources */,
|
||||
8D11072C0486CEB800E47090 /* Sources */,
|
||||
8D11072E0486CEB800E47090 /* Frameworks */,
|
||||
1D0DCAD80BA3604D00B6CCFA /* CopyFiles */,
|
||||
1D9EB2840C366D7B0074B739 /* CopyFiles */,
|
||||
1DE608B80C58807F0055263D /* CopyFiles */,
|
||||
0395AA790D76E77800881434 /* CopyFiles */,
|
||||
1D0DCAD80BA3604D00B6CCFA /* Copy Executables */,
|
||||
1D9EB2840C366D7B0074B739 /* Copy Frameworks */,
|
||||
1DE608B80C58807F0055263D /* Copy Vim Runtime Files */,
|
||||
0395AA790D76E77800881434 /* Copy ODBEditor */,
|
||||
1D1C31F00EFFBFD6003FE9A5 /* Make Document Icons */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -621,19 +593,7 @@
|
||||
8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */,
|
||||
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
|
||||
1D0E051C0BA5F83800B6049E /* Colors.plist in Resources */,
|
||||
1DD703B90BA9D15D008679E9 /* vim_gloss.icns in Resources */,
|
||||
1DD704310BA9F9C2008679E9 /* SpecialKeys.plist in Resources */,
|
||||
1D71ACB40BC702AB002F2B60 /* doc-bm-c.icns in Resources */,
|
||||
1D71ACB50BC702AC002F2B60 /* doc-bm-h.icns in Resources */,
|
||||
1D71ACB60BC702AC002F2B60 /* doc-bm-html.icns in Resources */,
|
||||
1D71ACB70BC702AC002F2B60 /* doc-bm-java.icns in Resources */,
|
||||
1D71ACB80BC702AC002F2B60 /* doc-bm-php.icns in Resources */,
|
||||
1D71ACB90BC702AC002F2B60 /* doc-bm-pl.icns in Resources */,
|
||||
1D71ACBA0BC702AC002F2B60 /* doc-bm-sh.icns in Resources */,
|
||||
1D71ACBB0BC702AC002F2B60 /* doc-bm-tex.icns in Resources */,
|
||||
1D71ACBC0BC702AC002F2B60 /* doc-bm-txt.icns in Resources */,
|
||||
1D71ACBD0BC702AC002F2B60 /* doc-bm-xml.icns in Resources */,
|
||||
1D71ACBE0BC702AC002F2B60 /* doc-bm.icns in Resources */,
|
||||
1DD04DEC0C529C5E006CDC2B /* Credits.rtf in Resources */,
|
||||
1DE8CC620C5E2AAD003F56E3 /* Actions.plist in Resources */,
|
||||
1DD9F5E50C85D60500E8D5A5 /* SystemColors.plist in Resources */,
|
||||
@@ -668,11 +628,31 @@
|
||||
1DCD00D10E50B2B700460166 /* SaveSesn.png in Resources */,
|
||||
1DCD00D20E50B2B700460166 /* TagJump.png in Resources */,
|
||||
1DCD00D30E50B2B700460166 /* Undo.png in Resources */,
|
||||
1D6008830E96886D003763F0 /* FindAndReplace.nib in Resources */,
|
||||
1D9C60520EF79C0C0034AD44 /* MacVim.icns in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
1D1C31F00EFFBFD6003FE9A5 /* Make Document Icons */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Make Document Icons";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "# Clear deployment target, else the python script always thinks we're building on Tiger\nunset MACOSX_DEPLOYMENT_TARGET\n\n# Generate the icons (redirect stderr to ignore warnings)\ncd $PROJECT_DIR/icons/\nmake OUTDIR=$TARGET_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH 2> /dev/null\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
8D11072C0486CEB800E47090 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
@@ -702,6 +682,7 @@
|
||||
BD9DF0B00DB41E780025C97C /* PlugInGUI.m in Sources */,
|
||||
BD9DF0FB0DB48C860025C97C /* CTGradient.m in Sources */,
|
||||
1D145C7F0E5227CE00691AA0 /* MMTextViewHelper.m in Sources */,
|
||||
1D60088B0E96A0B2003763F0 /* MMFindReplaceController.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -756,7 +737,7 @@
|
||||
i386,
|
||||
);
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 34;
|
||||
CURRENT_PROJECT_VERSION = 43;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
@@ -797,7 +778,7 @@
|
||||
buildSettings = {
|
||||
ARCHS = "$(NATIVE_ARCH)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 34;
|
||||
CURRENT_PROJECT_VERSION = 43;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
@@ -816,7 +797,7 @@
|
||||
HEADER_SEARCH_PATHS = PSMTabBarControl/source/;
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = "$(HOME)/Applications";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.4;
|
||||
MACOSX_DEPLOYMENT_TARGET = "";
|
||||
PRODUCT_NAME = MacVim;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
WRAPPER_EXTENSION = app;
|
||||
@@ -829,7 +810,7 @@
|
||||
buildSettings = {
|
||||
ARCHS = "$(NATIVE_ARCH)";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 34;
|
||||
CURRENT_PROJECT_VERSION = 43;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
@@ -848,7 +829,7 @@
|
||||
HEADER_SEARCH_PATHS = PSMTabBarControl/source/;
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = "$(HOME)/Applications";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.4;
|
||||
MACOSX_DEPLOYMENT_TARGET = "";
|
||||
PRODUCT_NAME = MacVim;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
WRAPPER_EXTENSION = app;
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
extern NSString *MMTabMinWidthKey;
|
||||
extern NSString *MMTabMaxWidthKey;
|
||||
extern NSString *MMTabOptimumWidthKey;
|
||||
extern NSString *MMShowAddTabButtonKey;
|
||||
extern NSString *MMTextInsetLeftKey;
|
||||
extern NSString *MMTextInsetRightKey;
|
||||
extern NSString *MMTextInsetTopKey;
|
||||
extern NSString *MMTextInsetBottomKey;
|
||||
extern NSString *MMTerminateAfterLastWindowClosedKey;
|
||||
extern NSString *MMTypesetterKey;
|
||||
extern NSString *MMCellWidthMultiplierKey;
|
||||
extern NSString *MMBaselineOffsetKey;
|
||||
@@ -53,6 +53,8 @@ extern NSString *MMShowLeftPlugInContainerKey;
|
||||
extern NSString *MMOpenLayoutKey;
|
||||
extern NSString *MMVerticalSplitKey;
|
||||
extern NSString *MMPreloadCacheSizeKey;
|
||||
extern NSString *MMLastWindowClosedBehaviorKey;
|
||||
extern NSString *MMLoadDefaultFontKey;
|
||||
|
||||
|
||||
// Enum for MMUntitledWindowKey
|
||||
@@ -63,7 +65,6 @@ enum {
|
||||
MMUntitledWindowAlways = 3
|
||||
};
|
||||
|
||||
|
||||
// Enum for MMOpenLayoutKey (first 4 must match WIN_* defines in main.c)
|
||||
enum {
|
||||
MMLayoutArglist = 0,
|
||||
@@ -73,6 +74,13 @@ enum {
|
||||
MMLayoutWindows = 4,
|
||||
};
|
||||
|
||||
// Enum for MMLastWindowClosedBehaviorKey
|
||||
enum {
|
||||
MMDoNothingWhenLastWindowClosed = 0,
|
||||
MMHideWhenLastWindowClosed = 1,
|
||||
MMTerminateWhenLastWindowClosed = 2,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -17,12 +17,11 @@
|
||||
NSString *MMTabMinWidthKey = @"MMTabMinWidth";
|
||||
NSString *MMTabMaxWidthKey = @"MMTabMaxWidth";
|
||||
NSString *MMTabOptimumWidthKey = @"MMTabOptimumWidth";
|
||||
NSString *MMShowAddTabButtonKey = @"MMShowAddTabButton";
|
||||
NSString *MMTextInsetLeftKey = @"MMTextInsetLeft";
|
||||
NSString *MMTextInsetRightKey = @"MMTextInsetRight";
|
||||
NSString *MMTextInsetTopKey = @"MMTextInsetTop";
|
||||
NSString *MMTextInsetBottomKey = @"MMTextInsetBottom";
|
||||
NSString *MMTerminateAfterLastWindowClosedKey
|
||||
= @"MMTerminateAfterLastWindowClosed";
|
||||
NSString *MMTypesetterKey = @"MMTypesetter";
|
||||
NSString *MMCellWidthMultiplierKey = @"MMCellWidthMultiplier";
|
||||
NSString *MMBaselineOffsetKey = @"MMBaselineOffset";
|
||||
@@ -45,6 +44,8 @@ NSString *MMShowLeftPlugInContainerKey = @"MMShowLeftPlugInContainer";
|
||||
NSString *MMOpenLayoutKey = @"MMOpenLayout";
|
||||
NSString *MMVerticalSplitKey = @"MMVerticalSplit";
|
||||
NSString *MMPreloadCacheSizeKey = @"MMPreloadCacheSize";
|
||||
NSString *MMLastWindowClosedBehaviorKey = @"MMLastWindowClosedBehavior";
|
||||
NSString *MMLoadDefaultFontKey = @"MMLoadDefaultFont";
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
BOOL _isCloseButtonSuppressed;
|
||||
BOOL _hasIcon;
|
||||
int _count;
|
||||
NSString *_toolTip;
|
||||
}
|
||||
|
||||
// creation/destruction
|
||||
@@ -72,6 +73,8 @@
|
||||
- (void)setIsPlaceholder:(BOOL)value;
|
||||
- (int)currentStep;
|
||||
- (void)setCurrentStep:(int)value;
|
||||
- (NSString *)toolTip;
|
||||
- (void)setToolTip:(NSString *)tip;
|
||||
|
||||
// component attributes
|
||||
- (NSRect)indicatorRectForFrame:(NSRect)cellFrame;
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
- (void)dealloc
|
||||
{
|
||||
[_indicator release];
|
||||
[_toolTip release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -252,6 +253,19 @@
|
||||
_currentStep = value;
|
||||
}
|
||||
|
||||
- (NSString *)toolTip
|
||||
{
|
||||
return _toolTip;
|
||||
}
|
||||
|
||||
- (void)setToolTip:(NSString *)tip
|
||||
{
|
||||
if (tip != _toolTip) {
|
||||
[_toolTip release];
|
||||
_toolTip = [tip copy];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Component Attributes
|
||||
|
||||
|
||||
@@ -68,8 +68,10 @@ enum {
|
||||
|
||||
// drag and drop
|
||||
NSEvent *_lastMouseDownEvent; // keep this for dragging reference
|
||||
BOOL _allowsDragBetweenWindows;
|
||||
|
||||
BOOL _allowsDragBetweenWindows;
|
||||
BOOL _delegateHandlingDrag;
|
||||
NSDragOperation _delegateInitialDragOperation;
|
||||
|
||||
// MVC help
|
||||
IBOutlet id delegate;
|
||||
}
|
||||
@@ -97,6 +99,9 @@ enum {
|
||||
- (BOOL)allowsDragBetweenWindows;
|
||||
- (void)setAllowsDragBetweenWindows:(BOOL)flag;
|
||||
|
||||
// tool tips
|
||||
- (void)setToolTip:(NSString *)value forTabViewItem:(NSTabViewItem *)tvi;
|
||||
|
||||
// accessors
|
||||
- (NSTabView *)tabView;
|
||||
- (void)setTabView:(NSTabView *)view;
|
||||
@@ -121,4 +126,11 @@ enum {
|
||||
- (void)tabView:(NSTabView *)aTabView willCloseTabViewItem:(NSTabViewItem *)tabViewItem;
|
||||
- (void)tabView:(NSTabView *)aTabView didCloseTabViewItem:(NSTabViewItem *)tabViewItem;
|
||||
- (void)tabView:(NSTabView *)aTabView didDragTabViewItem:(NSTabViewItem *)tabViewItem toIndex:(int)idx;
|
||||
|
||||
- (NSDragOperation)tabBarControl:(PSMTabBarControl *)theTabBarControl draggingEntered:(id <NSDraggingInfo>)sender forTabAtIndex:(unsigned)tabIndex;
|
||||
- (NSDragOperation)tabBarControl:(PSMTabBarControl *)theTabBarControl draggingUpdated:(id <NSDraggingInfo>)sender forTabAtIndex:(unsigned)tabIndex;
|
||||
- (void)tabBarControl:(PSMTabBarControl *)theTabBarControl draggingExited:(id <NSDraggingInfo>)sender forTabAtIndex:(unsigned)tabIndex;
|
||||
- (BOOL)tabBarControl:(PSMTabBarControl *)theTabBarControl prepareForDragOperation:(id <NSDraggingInfo>)sender forTabAtIndex:(unsigned)tabIndex;
|
||||
- (BOOL)tabBarControl:(PSMTabBarControl *)theTabBarControl performDragOperation:(id <NSDraggingInfo>)sender forTabAtIndex:(unsigned)tabIndex;
|
||||
- (void)tabBarControl:(PSMTabBarControl *)theTabBarControl concludeDragOperation:(id <NSDraggingInfo>)sender forTabAtIndex:(unsigned)tabIndex;
|
||||
@end
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
|
||||
// convenience
|
||||
- (id)cellForPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame;
|
||||
- (unsigned)indexOfCellAtPoint:(NSPoint)point;
|
||||
- (unsigned)indexOfCellAtPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame;
|
||||
- (PSMTabBarCell *)lastVisibleTab;
|
||||
- (int)numberOfVisibleTabs;
|
||||
|
||||
@@ -98,6 +100,7 @@
|
||||
|
||||
// default config
|
||||
_allowsDragBetweenWindows = YES;
|
||||
_delegateHandlingDrag = NO;
|
||||
_canCloseOnlyTab = NO;
|
||||
_showAddTabButton = NO;
|
||||
_hideForSingleTab = NO;
|
||||
@@ -144,7 +147,7 @@
|
||||
[_addTabButton setNeedsDisplay:YES];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
@@ -377,6 +380,22 @@
|
||||
return _overflowPopUpButton;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Tool tips
|
||||
|
||||
- (void)setToolTip:(NSString *)value forTabViewItem:(NSTabViewItem *)tvi
|
||||
{
|
||||
int i, cellCount = [_cells count];
|
||||
for (i = 0; i < cellCount; i++) {
|
||||
PSMTabBarCell *cell = [_cells objectAtIndex:i];
|
||||
if ([cell representedObject] == tvi)
|
||||
[cell setToolTip:value];
|
||||
}
|
||||
|
||||
[self update];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Functionality
|
||||
- (void)addTabViewItem:(NSTabViewItem *)item
|
||||
@@ -644,7 +663,10 @@
|
||||
[self removeTrackingRect:[cell cellTrackingTag]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// nuke old tool tips
|
||||
[self removeAllToolTips];
|
||||
|
||||
// calculate number of cells to fit in control and cell widths
|
||||
float availableWidth = [self availableCellWidth];
|
||||
NSMutableArray *newWidths = [NSMutableArray arrayWithCapacity:cellCount];
|
||||
@@ -740,6 +762,7 @@
|
||||
NSRect cellRect = [self genericCellRect];
|
||||
for(i = 0; i < cellCount; i++){
|
||||
PSMTabBarCell *cell = [_cells objectAtIndex:i];
|
||||
NSTabViewItem *tvi = [cell representedObject];
|
||||
int tabState = 0;
|
||||
if (i < numberOfVisibleCells) {
|
||||
// set cell frame
|
||||
@@ -757,9 +780,14 @@
|
||||
tag = [self addTrackingRect:cellRect owner:cell userData:nil assumeInside:NO];
|
||||
[cell setCellTrackingTag:tag];
|
||||
[cell setEnabled:YES];
|
||||
|
||||
|
||||
// add tool tip
|
||||
NSString *tt = [cell toolTip];
|
||||
if (tt && [tt length] > 0)
|
||||
[self addToolTipRect:cellRect owner:tt userData:NULL];
|
||||
|
||||
// selected? set tab states...
|
||||
if([[cell representedObject] isEqualTo:[tabView selectedTabViewItem]]){
|
||||
if([tvi isEqualTo:[tabView selectedTabViewItem]]){
|
||||
[cell setState:NSOnState];
|
||||
tabState |= PSMTab_SelectedMask;
|
||||
// previous cell
|
||||
@@ -808,13 +836,13 @@
|
||||
}
|
||||
menuItem = [[[NSMenuItem alloc] initWithTitle:[[cell attributedStringValue] string] action:@selector(overflowMenuAction:) keyEquivalent:@""] autorelease];
|
||||
[menuItem setTarget:self];
|
||||
[menuItem setRepresentedObject:[cell representedObject]];
|
||||
[menuItem setRepresentedObject:tvi];
|
||||
[cell setIsInOverflowMenu:YES];
|
||||
[[cell indicator] removeFromSuperview];
|
||||
if ([[cell representedObject] isEqualTo:[tabView selectedTabViewItem]])
|
||||
if ([tvi isEqualTo:[tabView selectedTabViewItem]])
|
||||
[menuItem setState:NSOnState];
|
||||
if([cell hasIcon])
|
||||
[menuItem setImage:[[[[cell representedObject] identifier] content] icon]];
|
||||
[menuItem setImage:[[[tvi identifier] content] icon]];
|
||||
if([cell count] > 0)
|
||||
[menuItem setTitle:[[menuItem title] stringByAppendingFormat:@" (%d)",[cell count]]];
|
||||
[overflowMenu addItem:menuItem];
|
||||
@@ -975,16 +1003,28 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
|
||||
{
|
||||
[[PSMTabDragAssistant sharedDragAssistant] draggedImageEndedAt:aPoint operation:operation];
|
||||
}
|
||||
|
||||
// NSDraggingDestination
|
||||
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
{
|
||||
NSPoint point = [self convertPoint:[sender draggingLocation] fromView:nil];
|
||||
_delegateHandlingDrag = NO;
|
||||
if([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) {
|
||||
|
||||
if ([sender draggingSource] != self && ![self allowsDragBetweenWindows])
|
||||
return NSDragOperationNone;
|
||||
|
||||
[[PSMTabDragAssistant sharedDragAssistant] draggingEnteredTabBar:self atPoint:[self convertPoint:[sender draggingLocation] fromView:nil]];
|
||||
[[PSMTabDragAssistant sharedDragAssistant] draggingEnteredTabBar:self atPoint:point];
|
||||
return NSDragOperationMove;
|
||||
} else if (delegate && [delegate respondsToSelector:@selector(tabBarControl:draggingEntered:forTabAtIndex:)]) {
|
||||
NSDragOperation op = [delegate tabBarControl:self draggingEntered:sender forTabAtIndex:[self indexOfCellAtPoint:point]];
|
||||
_delegateHandlingDrag = (op != NSDragOperationNone);
|
||||
_delegateInitialDragOperation = op;
|
||||
return op;
|
||||
}
|
||||
|
||||
return NSDragOperationNone;
|
||||
@@ -992,13 +1032,19 @@
|
||||
|
||||
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSPoint point = [self convertPoint:[sender draggingLocation] fromView:nil];
|
||||
if ([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) {
|
||||
|
||||
if ([sender draggingSource] != self && ![self allowsDragBetweenWindows])
|
||||
return NSDragOperationNone;
|
||||
|
||||
[[PSMTabDragAssistant sharedDragAssistant] draggingUpdatedInTabBar:self atPoint:[self convertPoint:[sender draggingLocation] fromView:nil]];
|
||||
[[PSMTabDragAssistant sharedDragAssistant] draggingUpdatedInTabBar:self atPoint:point];
|
||||
return NSDragOperationMove;
|
||||
} else if (_delegateHandlingDrag) {
|
||||
if ([delegate respondsToSelector:@selector(tabBarControl:draggingUpdated:forTabAtIndex:)])
|
||||
return [delegate tabBarControl:self draggingUpdated:sender forTabAtIndex:[self indexOfCellAtPoint:point]];
|
||||
else
|
||||
return _delegateInitialDragOperation;
|
||||
}
|
||||
|
||||
return NSDragOperationNone;
|
||||
@@ -1006,44 +1052,61 @@
|
||||
|
||||
- (void)draggingExited:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
[[PSMTabDragAssistant sharedDragAssistant] draggingExitedTabBar:self];
|
||||
if (!_delegateHandlingDrag) {
|
||||
[[PSMTabDragAssistant sharedDragAssistant] draggingExitedTabBar:self];
|
||||
} else if ([delegate respondsToSelector:@selector(tabBarControl:draggingExited:forTabAtIndex:)]) {
|
||||
NSPoint point = [self convertPoint:[sender draggingLocation] fromView:nil];
|
||||
[delegate tabBarControl:self draggingExited:sender forTabAtIndex:[self indexOfCellAtPoint:point]];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
if (_delegateHandlingDrag && [delegate respondsToSelector:@selector(tabBarControl:prepareForDragOperation:forTabAtIndex:)]) {
|
||||
NSPoint point = [self convertPoint:[sender draggingLocation] fromView:nil];
|
||||
return [delegate tabBarControl:self prepareForDragOperation:sender forTabAtIndex:[self indexOfCellAtPoint:point]];
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
if (!_delegateHandlingDrag) {
|
||||
#if 1
|
||||
// HACK! Used below.
|
||||
NSTabViewItem *tvi = [[[PSMTabDragAssistant sharedDragAssistant] draggedCell] representedObject];
|
||||
// HACK! Used below.
|
||||
NSTabViewItem *tvi = [[[PSMTabDragAssistant sharedDragAssistant] draggedCell] representedObject];
|
||||
#endif
|
||||
|
||||
[[PSMTabDragAssistant sharedDragAssistant] performDragOperation];
|
||||
[[PSMTabDragAssistant sharedDragAssistant] performDragOperation];
|
||||
|
||||
#if 1
|
||||
// HACK! Notify the delegate that a tab was dragged to a new position.
|
||||
if (delegate && [delegate respondsToSelector:@selector(tabView:didDragTabViewItem:toIndex:)]) {
|
||||
int idx = [[self representedTabViewItems] indexOfObject:tvi];
|
||||
if (NSNotFound != idx) {
|
||||
[delegate tabView:[self tabView] didDragTabViewItem:tvi toIndex:idx];
|
||||
// HACK! Notify the delegate that a tab was dragged to a new position.
|
||||
if (delegate && [delegate respondsToSelector:@selector(tabView:didDragTabViewItem:toIndex:)]) {
|
||||
int idx = [[self representedTabViewItems] indexOfObject:tvi];
|
||||
if (NSNotFound != idx) {
|
||||
[delegate tabView:[self tabView] didDragTabViewItem:tvi toIndex:idx];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if ([delegate respondsToSelector:@selector(tabBarControl:performDragOperation:forTabAtIndex:)]) {
|
||||
NSPoint point = [self convertPoint:[sender draggingLocation] fromView:nil];
|
||||
return [delegate tabBarControl:self performDragOperation:sender forTabAtIndex:[self indexOfCellAtPoint:point]];
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
|
||||
{
|
||||
[[PSMTabDragAssistant sharedDragAssistant] draggedImageEndedAt:aPoint operation:operation];
|
||||
}
|
||||
|
||||
- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
|
||||
if (_delegateHandlingDrag && [delegate respondsToSelector:@selector(tabBarControl:concludeDragOperation:forTabAtIndex:)]) {
|
||||
NSPoint point = [self convertPoint:[sender draggingLocation] fromView:nil];
|
||||
[delegate tabBarControl:self concludeDragOperation:sender forTabAtIndex:[self indexOfCellAtPoint:point]];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@@ -1350,11 +1413,25 @@
|
||||
}
|
||||
|
||||
- (id)cellForPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame
|
||||
{
|
||||
unsigned i = [self indexOfCellAtPoint:point cellFrame:outFrame];
|
||||
if (i == NSNotFound)
|
||||
return nil;
|
||||
PSMTabBarCell *cell = [_cells objectAtIndex:i];
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (unsigned)indexOfCellAtPoint:(NSPoint)point
|
||||
{
|
||||
return [self indexOfCellAtPoint:point cellFrame:NULL];
|
||||
}
|
||||
|
||||
- (unsigned)indexOfCellAtPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame
|
||||
{
|
||||
NSRect aRect = [self genericCellRect];
|
||||
|
||||
if(!NSPointInRect(point,aRect)){
|
||||
return nil;
|
||||
return NSNotFound;
|
||||
}
|
||||
|
||||
int i, cnt = [_cells count];
|
||||
@@ -1367,11 +1444,11 @@
|
||||
if(outFrame){
|
||||
*outFrame = aRect;
|
||||
}
|
||||
return cell;
|
||||
return i;
|
||||
}
|
||||
aRect.origin.x += width;
|
||||
}
|
||||
return nil;
|
||||
return NSNotFound;
|
||||
}
|
||||
|
||||
- (PSMTabBarCell *)lastVisibleTab
|
||||
|
||||
+6
-6
@@ -70,14 +70,14 @@ MacVim:
|
||||
|
||||
The main nib of MacVim.app is MainMenu.nib which contains the default menu and
|
||||
an instance of MMAppController, which is connected as the delegate of
|
||||
NSApplication. That mens, when MacVim starts it will load this nib file and
|
||||
NSApplication. That means, when MacVim starts it will load this nib file and
|
||||
automatically create an instance of the MMAppController singleton.
|
||||
|
||||
A new editor window is opened by calling
|
||||
-[MMAppController launchVimProcessWithArguments:]. This functions starts a
|
||||
new Vim process (by executing the Vim binary). The Vim process lets MacVim
|
||||
know when it has launched by calling -[MMAppController connectBackend:pid:]
|
||||
and MacVim responds to this message by calling a new frontend object
|
||||
and MacVim responds to this message by creating a new frontend object
|
||||
(MMVimController) and returns a proxy to this object back to the Vim process.
|
||||
From this point onward the Vim process communicates directly with the
|
||||
MMVimController.
|
||||
@@ -87,8 +87,8 @@ It coordinates all communication with the Vim process and delegates output
|
||||
that affects visual presentation to a MMWindowController object. Read the
|
||||
Cocoa documentation on the responsibilities of a window controller.
|
||||
|
||||
Input (keyboard & mouse) handling and drawing is handled by a MMTextView
|
||||
object.
|
||||
Input (keyboard & mouse) handling and drawing is handled by a helper object
|
||||
(MMTextViewHelper) to the current text view (MMTextView, MMAtsuiTextView).
|
||||
|
||||
|
||||
Distributed Object dangers:
|
||||
@@ -149,7 +149,7 @@ Steps to build MacVim.app (the text before the '$' shows the folder you should
|
||||
be in when executing these commands):
|
||||
|
||||
1. Configure Vim
|
||||
src/$ configure --enable-gui=macvim
|
||||
src/$ ./configure --enable-gui=macvim
|
||||
|
||||
2. Build Vim executable
|
||||
src/$ make
|
||||
@@ -161,4 +161,4 @@ The application bundle can be found inside "src/MacVim/build/Release".
|
||||
|
||||
|
||||
Bjorn Winckler <bjorn.winckler@gmail.com>
|
||||
June 22, 2008
|
||||
November 22, 2008
|
||||
|
||||
-185
@@ -1,185 +0,0 @@
|
||||
Active:
|
||||
|
||||
- transparent text view
|
||||
- Listen to NSSystemColorsDidChangeNotification and update highlighting
|
||||
- Add support for 'mousehide' (needs to check p_mh)
|
||||
- Build Vim (make) from Xcode project
|
||||
- Cmd-W in about box sends vimMenuAction: instead of performClose:
|
||||
- Terminal support. :!bash -> no cursor, arrow keys mucks up display
|
||||
- Press Cmd-n multiple times and quickly press Cmd-q; sometimes two or more
|
||||
instances of MacVim opens up
|
||||
- hide toolbar, open new tab, show toolbar: baseline sepearator still visible
|
||||
(seems like a drawing bug in PSMTabBarControl)
|
||||
- file modified outside vim dialog sometimes only appear after pressing a key
|
||||
- let user choose file encoding and format in open/save dialogs
|
||||
- autosave settings ?
|
||||
- encoding -- convert strings from vim to utf-8
|
||||
- main menu (buffers menu, window menu)
|
||||
- standardize NSString usage (initialization & how it is passed in messages)
|
||||
- autosave window rows&columns?
|
||||
- improve drag and drop support (modifier keys are ignored)
|
||||
- grey out menus which can't be used: Tab Next/Prev/Close, Undo/Redo, etc.
|
||||
- find/replace toolbar item (FIND_REPLACE_DIALOG)
|
||||
- drag-to-resize, delay if mouse button held down
|
||||
- ability to modify key equivalents at any time (?)
|
||||
- validate menu actions for when no windows are open (e.g. selectNextWindow:)
|
||||
- need E??? numbers for vim errors
|
||||
- tab-completion for :action command?
|
||||
- proper font handling
|
||||
- check for memory leaks
|
||||
- i8n
|
||||
- change building procedure so that the Makefile compiles and links VimTask and
|
||||
then calls pbxbuild to build MacVim (and put MacVim.app) in the src folder
|
||||
- icons for all built in toolbar items
|
||||
- window title is never set when starting with terminal vim and typing :gui
|
||||
- forking doesn't work with :gui (i think)
|
||||
- make sure [NSMutableData appendByte:length:] is never called with 0 length
|
||||
(this will lead to a crash)
|
||||
- update speed whilst resizing with mouse is excruciatingly slow
|
||||
- window count should be typeset nicely in tab ?
|
||||
- track pad scrolling is jerky
|
||||
- sanity check all input in handlePortMessage: etc.
|
||||
- nice looking cursors (both the block and in insert mode) ?
|
||||
- support project builder external editor
|
||||
http://www.codingmonkeys.de/techpubs/externaleditor/pbxexternaleditor.html
|
||||
- dock icon menu
|
||||
- horizontal scrolling with trackpad does not work
|
||||
- got this error when clicking to close second last tab:
|
||||
2007-07-23 08:19:29.398 MacVim[335] *** Assertion failure in -[PSMTabBarControl lockFocus], AppKit.subproj/NSView.m:3248
|
||||
2007-07-23 08:19:29.410 MacVim[335] lockFocus sent to a view whose window is deferred and does not yet have a corresponding platform window
|
||||
|
||||
|
||||
Pending:
|
||||
|
||||
- marked text
|
||||
- set gfn=*
|
||||
- improve drag and drop support (drop in command line mode not working)
|
||||
- System colors don't come out the same as in other apps (as measure with
|
||||
Digital Color Meter)
|
||||
- Select-mode for <S-Key>
|
||||
- Insertion point blinking
|
||||
- Hollow insertion point drawing does not always work
|
||||
- cursor in replace mode
|
||||
- should ignore action message if is called too often (e.g. in addNewTab:)
|
||||
- application:openFiles: should open in tabs in current window instead of in a
|
||||
new window, only if user default is set
|
||||
- Mouse cursor changes depeding on context
|
||||
- Ctrl-C does not update screen until another key press (in command window)
|
||||
- Underline color is never set properly (sp_color)
|
||||
- Lock up when opening large session files (increasing MMFlushTimeoutInterval
|
||||
alleviates this problem)
|
||||
- Respond to "should change" instead of "will change" tab messages
|
||||
- scrolling when mouse is over scrollbar doesn't work
|
||||
- gui dialogs (FEAT_GUI_DIALOG)
|
||||
- no warning when buffer modified outside vim (implement gui_mch_dialog())
|
||||
- call gui_focus_change() when appropriate
|
||||
- ability to interrupt vim (needs to check the run-loop for interrupts)
|
||||
- got this error on Cmd-N with no other windows open:
|
||||
2007-07-27 22:00:17.680 MacVim[454] *** -[NSToolbarView frameDidChange:]: selector not recognized [self = 0x39ba80]
|
||||
2007-07-27 22:00:17.690 MacVim[454] Exception raised during posting of notification. Ignored. exception: *** -[NSToolbarView frameDidChange:]: selector not recognized [self = 0x39ba80]
|
||||
- got this error when opening MacVim from terminal (with 'gvim gvimrc&'):
|
||||
Frost:~/Projects/vim7/src/MacVim winckler$ 2007-08-05 13:25:01.151 MacVim[223] *** -[NSThemeFrame frameDidChange:]: selector not recognized [self = 0x3baa30]
|
||||
2007-08-05 13:25:01.152 MacVim[223] Exception raised during posting of notification. Ignored. exception: *** -[NSThemeFrame frameDidChange:]: selector not recognized [self = 0x3baa30]
|
||||
2007-08-05 13:25:01.155 MacVim[223] *** -[NSThemeFrame frameDidChange:]: selector not recognized [self = 0x3baa30]
|
||||
2007-08-05 13:25:01.156 MacVim[223] Exception raised during posting of notification. Ignored. exception: *** -[NSThemeFrame frameDidChange:]: selector not recognized [self = 0x3baa30]
|
||||
2007-08-05 13:25:01.246 MacVim[223] *** -[NSThemeFrame frameDidChange:]: selector not recognized [self = 0x3baa30]
|
||||
2007-08-05 13:25:01.247 MacVim[223] Exception raised during posting of notification. Ignored. exception: *** -[NSThemeFrame frameDidChange:]: selector not recognized [self = 0x3baa30]
|
||||
- toogle toolbar off, maximize window, toolbar on -> text view under toolbar
|
||||
- clicking pill button does not update 'guioptions'
|
||||
- detect Cmd-. (and Ctrl-C) for interrupt
|
||||
|
||||
|
||||
Done:
|
||||
|
||||
- :popup
|
||||
- popup menus
|
||||
- when only one tab open make <D-w> close window
|
||||
- cscope, ctags
|
||||
- Ctrl-O in insert mode
|
||||
- remember window position
|
||||
- font selection dialog (:set gfn=*)
|
||||
- services menu
|
||||
- wide characters are badly supported: they render as too wide
|
||||
- dropping directories does not work
|
||||
- memory leak with text view? (need to release text storage)
|
||||
- drag and drop inside view (FEAT_GUI_DND, gui_handle_drop())
|
||||
- hide baseline separator when tabbar is visible (and make sure clicking the
|
||||
hide/show toolbar button in the top right of the corner does not show it
|
||||
again)
|
||||
- toolbar drawing bug
|
||||
- Cmd-zoom -> no input received, drawing broken
|
||||
- scrollbars not positioned over resize box
|
||||
- offset text away from left edge
|
||||
- add menu options with key equiv:
|
||||
Cmd+Option+Left/Right to change tab, Cmd+x/c/v cut/copy/paste,
|
||||
Cmd+z/Z undo/redo, Cmd+o open, Cmd+w/W close tab/window,
|
||||
Cmd+Option+T special characters,
|
||||
etc.
|
||||
- menu key equivalents
|
||||
- startup is a bit flakey (up until openWindowWithRows:columns:)
|
||||
- background color of text view doesn't get set if :colorscheme is in .gvimrc,
|
||||
since textView=nil when setDefaultColorsBackground:foreground: is called
|
||||
- resize window on font change
|
||||
- don't clear the text storage on setMaxRows:: so that display does not go
|
||||
blank when dragging to resize
|
||||
- zoom&resize broken
|
||||
- add user default for min/max tab size
|
||||
- :colorscheme elflord, :set lines+=3 --> colors are not updated properly
|
||||
- use DO to communicate between GUI and Vim (only for two-way communication,
|
||||
one-way communication should still use mach ports)
|
||||
- make scrollbar inactive if it is too small to display properly
|
||||
- make vertical scrollbars cover command line as well
|
||||
- setting font in .gvimrc has no effect since textStorage has not been init'ed
|
||||
- fonts
|
||||
- scroll bars
|
||||
- Make MacVim project depend on PSMTabBarControl project
|
||||
- Change Makefile so that it builds a vim executable and copy this into the
|
||||
MacVim.app from the MacVim project
|
||||
- warning before closing modified buffer
|
||||
- On quitting, warn user if modified files are open
|
||||
- An untitled window should not open when the GUI is started from the terminal
|
||||
(figure out how to pass '-nowindow yes' option when launching GUI)
|
||||
- support using VimTask as a standalone terminal app, with support for :gui
|
||||
- path is set to / when not starting from command line, set it to $HOME instead
|
||||
- input of wide characters does not work
|
||||
- tab completion doesn't work on iMac
|
||||
- close icons on tabs don't appear on iMac
|
||||
- toolbar
|
||||
- copy runtime files to bundle properly (only works for debug at the moment)
|
||||
- don't resize to make window bigger than what can fit on screen
|
||||
- window resizing using mouse & zoom
|
||||
- cmd-click to maximize window, :tabnew...the text view overlaps the tabline
|
||||
- colorscheme changes are buggy (open two tabs, change colorscheme, open new
|
||||
tab; the new tab has wrong color on first and last lines.)
|
||||
- tab selection bug: open three tabs, selct middle, drag last tab so it becomes
|
||||
middle without selecting it, select middle tab...selects middle, then last
|
||||
- tab selection bug #2: :tabnew, drag tab #2 to pos #1, press enter. tab #2 is
|
||||
selected.
|
||||
- this stuffs up the display: set go-=e; :tabnew
|
||||
- with 2 tabs: closing one tab using mouse makes screen flash (does not happen
|
||||
if tab is closed using :q)
|
||||
- resize to fit every draw update
|
||||
- insertion point
|
||||
- copy/paste
|
||||
- compute text storage size based on actual content
|
||||
- color changes (:colorscheme)
|
||||
- set text storage dimensions properly when creating text view
|
||||
- text dimension changes
|
||||
- notify vim task when user closes/selects tabs
|
||||
- mouse handling in text view
|
||||
- file type associations (Info.plist)
|
||||
- drag and drop onto app icon
|
||||
- remove tab update hack when flushing (edit vim code to call update)
|
||||
- crash when typing :browse e $vim (but not :browse e $vim/)
|
||||
- maintain queue of messages to send from task (to ensure they are passed in
|
||||
the same order they arrive)
|
||||
- do not include shift flag in chars that are already shifted (%, A, etc.)
|
||||
- open file(s) in tab(s) (never open in new window?)
|
||||
- key handling:
|
||||
<M-Space> works, <M-S-Space> does not
|
||||
clean up dispatchKeyEvent
|
||||
- reordering tab pages (gui tabs must have same order as vim tabs)
|
||||
- make sure tab is wide enough to fit label
|
||||
- encoding (did_set_string_option, option.c, line 5675)
|
||||
in init:
|
||||
set_option_value((char_u *)"termencoding", 0L, (char_u *)"utf-8", 0);
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+223
-123
@@ -20,18 +20,14 @@
|
||||
|
||||
|
||||
|
||||
// This constant controls how often [MMBackend update] may get called (see
|
||||
// gui_mch_update()).
|
||||
static NSTimeInterval MMUpdateTimeoutInterval = 0.1f;
|
||||
|
||||
// NOTE: The default font is bundled with the application.
|
||||
static NSString *MMDefaultFontName = @"DejaVu Sans Mono";
|
||||
static float MMDefaultFontSize = 12.0f;
|
||||
static float MMMinFontSize = 6.0f;
|
||||
static float MMMaxFontSize = 100.0f;
|
||||
static int MMDefaultFontSize = 12;
|
||||
static int MMMinFontSize = 6;
|
||||
static int MMMaxFontSize = 100;
|
||||
|
||||
|
||||
static NSFont *gui_macvim_font_with_name(char_u *name);
|
||||
static GuiFont gui_macvim_font_with_name(char_u *name);
|
||||
static int specialKeyToNSKey(int key);
|
||||
static int vimModMaskToEventModifierFlags(int mods);
|
||||
|
||||
@@ -167,39 +163,23 @@ gui_mch_open(void)
|
||||
* nothing in the X event queue (& no timers pending), then we return
|
||||
* immediately.
|
||||
*/
|
||||
#define MM_LOG_UPDATE_STATS 0
|
||||
void
|
||||
gui_mch_update(void)
|
||||
{
|
||||
// NOTE: This function can get called A LOT (~1 call/ms) and unfortunately
|
||||
// checking the run loop takes a long time, resulting in noticable slow
|
||||
// downs if it is done every time this function is called. Therefore we
|
||||
// make sure that it is not done too often.
|
||||
static NSDate *lastUpdateDate = nil;
|
||||
#if MM_LOG_UPDATE_STATS
|
||||
static int skipCount = 0;
|
||||
#endif
|
||||
// This function is called extremely often. It is tempting to do nothing
|
||||
// here to avoid reduced frame-rates but then it would not be possible to
|
||||
// interrupt Vim by presssing Ctrl-C during lengthy operations (e.g. after
|
||||
// entering "10gs" it would not be possible to bring Vim out of the 10 s
|
||||
// sleep prematurely). As a compromise we check for Ctrl-C only once per
|
||||
// second. Note that Cmd-. sends SIGINT so it has higher success rate at
|
||||
// interrupting Vim.
|
||||
static CFAbsoluteTime lastTime = 0;
|
||||
|
||||
if (lastUpdateDate && -[lastUpdateDate timeIntervalSinceNow] <
|
||||
MMUpdateTimeoutInterval) {
|
||||
#if MM_LOG_UPDATE_STATS
|
||||
++skipCount;
|
||||
#endif
|
||||
return;
|
||||
CFAbsoluteTime nowTime = CFAbsoluteTimeGetCurrent();
|
||||
if (nowTime - lastTime > 1.0) {
|
||||
[[MMBackend sharedInstance] update];
|
||||
lastTime = nowTime;
|
||||
}
|
||||
|
||||
#if MM_LOG_UPDATE_STATS
|
||||
NSTimeInterval dt = -[lastUpdateDate timeIntervalSinceNow];
|
||||
NSLog(@"Updating (last update %.2f seconds ago, skipped %d updates, "
|
||||
"approx %.1f calls per second)",
|
||||
dt, skipCount, dt > 0 ? skipCount/dt : 0);
|
||||
skipCount = 0;
|
||||
#endif
|
||||
|
||||
[[MMBackend sharedInstance] update];
|
||||
|
||||
[lastUpdateDate release];
|
||||
lastUpdateDate = [[NSDate date] retain];
|
||||
}
|
||||
|
||||
|
||||
@@ -207,12 +187,56 @@ gui_mch_update(void)
|
||||
void
|
||||
gui_mch_flush(void)
|
||||
{
|
||||
[[MMBackend sharedInstance] flushQueue:NO];
|
||||
// This function is called way too often to be useful as a hint for
|
||||
// flushing. If we were to flush every time it was called the screen would
|
||||
// flicker.
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gui_macvim_flush(void)
|
||||
{
|
||||
// This function counts how many times it is called and only flushes the
|
||||
// draw queue if called sufficiently often. The first few times it is
|
||||
// called it will flush often, but the more it is called the less likely is
|
||||
// it that anything will be flushed. (The counter resets itself if the
|
||||
// function isn't called for a second.)
|
||||
//
|
||||
// NOTE: Should only be used in loops where it is impossible to know how
|
||||
// often Vim needs to flush. It was written to handle output from external
|
||||
// commands (see mch_call_shell() in os_unix.c).
|
||||
|
||||
static CFAbsoluteTime lastTime = 0;
|
||||
static int delay = 1;
|
||||
static int counter = 0;
|
||||
static int scrolls = 0;
|
||||
|
||||
CFAbsoluteTime nowTime = CFAbsoluteTimeGetCurrent();
|
||||
CFAbsoluteTime delta = nowTime - lastTime;
|
||||
if (delta > 1.0)
|
||||
delay = 1;
|
||||
|
||||
// We assume that each call corresponds roughly to one line of output.
|
||||
// When one page has scrolled by we increase the delay before the next
|
||||
// flush.
|
||||
if (++scrolls > gui.num_rows) {
|
||||
delay <<= 1;
|
||||
if (delay > 2048)
|
||||
delay = 2048;
|
||||
scrolls = 0;
|
||||
}
|
||||
|
||||
if (++counter > delay) {
|
||||
gui_macvim_force_flush();
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
lastTime = nowTime;
|
||||
}
|
||||
|
||||
|
||||
/* Force flush output to MacVim. Do not call this method unless absolutely
|
||||
* necessary (use gui_mch_flush() instead). */
|
||||
* necessary. */
|
||||
void
|
||||
gui_macvim_force_flush(void)
|
||||
{
|
||||
@@ -324,8 +348,10 @@ gui_macvim_draw_string(int row, int col, char_u *s, int len, int flags)
|
||||
// wide and vice versa.
|
||||
for (i = 0; i < len; i += cl) {
|
||||
c = utf_ptr2char(s + i);
|
||||
cl = utf_ptr2len(s + i);
|
||||
cn = utf_char2cells(c);
|
||||
cl = utf_ptr2len(s + i);
|
||||
if (0 == cl)
|
||||
len = i; // len must be wrong (shouldn't happen)
|
||||
|
||||
if (!utf_iscomposing(c)) {
|
||||
if ((cn > 1 && !wide) || (cn <= 1 && wide)) {
|
||||
@@ -694,6 +720,29 @@ gui_mch_add_menu(vimmenu_T *menu, int idx)
|
||||
}
|
||||
|
||||
|
||||
// Taken from gui_gtk.c (slightly modified)
|
||||
static int
|
||||
lookup_menu_iconfile(char_u *iconfile, char_u *dest)
|
||||
{
|
||||
expand_env(iconfile, dest, MAXPATHL);
|
||||
|
||||
if (mch_isFullName(dest))
|
||||
return vim_fexists(dest);
|
||||
|
||||
static const char suffixes[][4] = {"png", "bmp"};
|
||||
char_u buf[MAXPATHL];
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < sizeof(suffixes)/sizeof(suffixes[0]); ++i)
|
||||
if (gui_find_bitmap(dest, buf, (char *)suffixes[i]) == OK) {
|
||||
STRCPY(dest, buf);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add a menu item to a menu
|
||||
*/
|
||||
@@ -712,11 +761,17 @@ gui_mch_add_menu_item(vimmenu_T *menu, int idx)
|
||||
if (menu_is_toolbar(menu->parent->name)) {
|
||||
char_u fname[MAXPATHL];
|
||||
|
||||
// TODO: Ensure menu->iconfile exists (if != NULL)
|
||||
icon = menu->iconfile;
|
||||
if (!icon && gui_find_bitmap(menu->name, fname, "bmp") == OK)
|
||||
// Try to use the icon=.. argument
|
||||
if (menu->iconfile && lookup_menu_iconfile(menu->iconfile, fname))
|
||||
icon = fname;
|
||||
if (!icon && menu->iconidx >= 0)
|
||||
|
||||
// If not found and not builtin specified try using the menu name
|
||||
if (!icon && !menu->icon_builtin
|
||||
&& lookup_menu_iconfile(menu->name, fname))
|
||||
icon = fname;
|
||||
|
||||
// Last resort, use display name (usually signals a builtin icon)
|
||||
if (!icon)
|
||||
icon = menu->dname;
|
||||
}
|
||||
|
||||
@@ -867,11 +922,18 @@ gui_mch_free_font(font)
|
||||
{
|
||||
if (font != NOFONT) {
|
||||
//NSLog(@"gui_mch_free_font(font=0x%x)", font);
|
||||
[(NSFont*)font release];
|
||||
[(id)font release];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GuiFont
|
||||
gui_mch_retain_font(GuiFont font)
|
||||
{
|
||||
return (GuiFont)[(id)font retain];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get a font structure for highlighting.
|
||||
*/
|
||||
@@ -881,9 +943,9 @@ gui_mch_get_font(char_u *name, int giveErrorIfMissing)
|
||||
//NSLog(@"gui_mch_get_font(name=%s, giveErrorIfMissing=%d)", name,
|
||||
// giveErrorIfMissing);
|
||||
|
||||
NSFont *font = gui_macvim_font_with_name(name);
|
||||
if (font)
|
||||
return (GuiFont)[font retain];
|
||||
GuiFont font = gui_macvim_font_with_name(name);
|
||||
if (font != NOFONT)
|
||||
return font;
|
||||
|
||||
if (giveErrorIfMissing)
|
||||
EMSG2(_(e_font), name);
|
||||
@@ -895,14 +957,12 @@ gui_mch_get_font(char_u *name, int giveErrorIfMissing)
|
||||
#if defined(FEAT_EVAL) || defined(PROTO)
|
||||
/*
|
||||
* Return the name of font "font" in allocated memory.
|
||||
* Don't know how to get the actual name, thus use the provided name.
|
||||
* TODO: use 'font' instead of 'name'?
|
||||
*/
|
||||
char_u *
|
||||
gui_mch_get_fontname(GuiFont font, char_u *name)
|
||||
{
|
||||
if (name == NULL)
|
||||
return NULL;
|
||||
return vim_strsave(name);
|
||||
return name ? vim_strsave(name) : NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -922,24 +982,24 @@ gui_mch_init_font(char_u *font_name, int fontset)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
NSFont *font = gui_macvim_font_with_name(font_name);
|
||||
if (font) {
|
||||
[(NSFont*)gui.norm_font release];
|
||||
gui.norm_font = (GuiFont)[font retain];
|
||||
GuiFont font = gui_macvim_font_with_name(font_name);
|
||||
if (font == NOFONT)
|
||||
return FAIL;
|
||||
|
||||
// NOTE: MacVim keeps separate track of the normal and wide fonts.
|
||||
// Unless the user changes 'guifontwide' manually, they are based on
|
||||
// the same (normal) font. Also note that each time the normal font is
|
||||
// set, the advancement may change so the wide font needs to be updated
|
||||
// as well (so that it is always twice the width of the normal font).
|
||||
[[MMBackend sharedInstance] setFont:font];
|
||||
[[MMBackend sharedInstance] setWideFont:
|
||||
(NOFONT == gui.wide_font ? font : (NSFont*)gui.wide_font)];
|
||||
gui_mch_free_font(gui.norm_font);
|
||||
gui.norm_font = font;
|
||||
|
||||
return OK;
|
||||
}
|
||||
// NOTE: MacVim keeps separate track of the normal and wide fonts.
|
||||
// Unless the user changes 'guifontwide' manually, they are based on
|
||||
// the same (normal) font. Also note that each time the normal font is
|
||||
// set, the advancement may change so the wide font needs to be updated
|
||||
// as well (so that it is always twice the width of the normal font).
|
||||
[[MMBackend sharedInstance] setFont:font wide:NO];
|
||||
[[MMBackend sharedInstance] setFont:(NOFONT != gui.wide_font ? gui.wide_font
|
||||
: font)
|
||||
wide:YES];
|
||||
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -953,63 +1013,58 @@ gui_mch_set_font(GuiFont font)
|
||||
}
|
||||
|
||||
|
||||
NSFont *
|
||||
/*
|
||||
* Return GuiFont in allocated memory. The caller must free it using
|
||||
* gui_mch_free_font().
|
||||
*/
|
||||
GuiFont
|
||||
gui_macvim_font_with_name(char_u *name)
|
||||
{
|
||||
NSFont *font = nil;
|
||||
NSString *fontName = MMDefaultFontName;
|
||||
float size = MMDefaultFontSize;
|
||||
if (!name)
|
||||
return (GuiFont)[[NSString alloc] initWithFormat:@"%@:%d",
|
||||
MMDefaultFontName, MMDefaultFontSize];
|
||||
|
||||
NSString *fontName = [NSString stringWithVimString:name];
|
||||
int size = MMDefaultFontSize;
|
||||
BOOL parseFailed = NO;
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
name = CONVERT_TO_UTF8(name);
|
||||
#endif
|
||||
|
||||
if (name) {
|
||||
fontName = [NSString stringWithUTF8String:(char*)name];
|
||||
|
||||
NSArray *components = [fontName componentsSeparatedByString:@":"];
|
||||
if ([components count] == 2) {
|
||||
NSString *sizeString = [components lastObject];
|
||||
if ([sizeString length] > 0
|
||||
&& [sizeString characterAtIndex:0] == 'h') {
|
||||
sizeString = [sizeString substringFromIndex:1];
|
||||
if ([sizeString length] > 0) {
|
||||
size = [sizeString floatValue];
|
||||
fontName = [components objectAtIndex:0];
|
||||
}
|
||||
} else {
|
||||
parseFailed = YES;
|
||||
NSArray *components = [fontName componentsSeparatedByString:@":"];
|
||||
if ([components count] == 2) {
|
||||
NSString *sizeString = [components lastObject];
|
||||
if ([sizeString length] > 0
|
||||
&& [sizeString characterAtIndex:0] == 'h') {
|
||||
sizeString = [sizeString substringFromIndex:1];
|
||||
if ([sizeString length] > 0) {
|
||||
size = (int)round([sizeString floatValue]);
|
||||
fontName = [components objectAtIndex:0];
|
||||
}
|
||||
} else if ([components count] > 2) {
|
||||
} else {
|
||||
parseFailed = YES;
|
||||
}
|
||||
} else if ([components count] > 2) {
|
||||
parseFailed = YES;
|
||||
}
|
||||
|
||||
if (!parseFailed) {
|
||||
// Replace underscores with spaces.
|
||||
fontName = [[fontName componentsSeparatedByString:@"_"]
|
||||
componentsJoinedByString:@" "];
|
||||
}
|
||||
if (!parseFailed) {
|
||||
// Replace underscores with spaces.
|
||||
fontName = [[fontName componentsSeparatedByString:@"_"]
|
||||
componentsJoinedByString:@" "];
|
||||
}
|
||||
|
||||
if (!parseFailed && [fontName length] > 0) {
|
||||
if (size < MMMinFontSize) size = MMMinFontSize;
|
||||
if (size > MMMaxFontSize) size = MMMaxFontSize;
|
||||
|
||||
font = [NSFont fontWithName:fontName size:size];
|
||||
|
||||
if (!font && MMDefaultFontName == fontName) {
|
||||
// If for some reason the MacVim default font is not in the app
|
||||
// bundle, then fall back on the system default font.
|
||||
font = [NSFont userFixedPitchFontOfSize:0];
|
||||
}
|
||||
// If the default font is requested we don't check if NSFont can load
|
||||
// it since the font most likely isn't loaded anyway (it may only be
|
||||
// available to the MacVim binary). If it is not the default font we
|
||||
// ask NSFont if it can load it.
|
||||
if ([fontName isEqualToString:MMDefaultFontName]
|
||||
|| [NSFont fontWithName:fontName size:size])
|
||||
return [[NSString alloc] initWithFormat:@"%@:%d", fontName, size];
|
||||
}
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
CONVERT_TO_UTF8_FREE(name);
|
||||
#endif
|
||||
|
||||
return font;
|
||||
return NOFONT;
|
||||
}
|
||||
|
||||
// -- Scrollbars ------------------------------------------------------------
|
||||
@@ -1232,6 +1287,48 @@ im_get_status(void)
|
||||
|
||||
|
||||
|
||||
// -- Find & Replace dialog -------------------------------------------------
|
||||
|
||||
#ifdef FIND_REPLACE_DIALOG
|
||||
|
||||
static void
|
||||
macvim_find_and_replace(char_u *arg, BOOL replace)
|
||||
{
|
||||
// TODO: Specialized dialog for find without replace?
|
||||
int wholeWord = FALSE;
|
||||
int matchCase = !p_ic;
|
||||
char_u *text = get_find_dialog_text(arg, &wholeWord, &matchCase);
|
||||
|
||||
int flags = 0;
|
||||
if (wholeWord) flags |= FRD_WHOLE_WORD;
|
||||
if (matchCase) flags |= FRD_MATCH_CASE;
|
||||
|
||||
NSDictionary *args = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSString stringWithVimString:text], @"text",
|
||||
[NSNumber numberWithInt:flags], @"flags",
|
||||
nil];
|
||||
|
||||
[[MMBackend sharedInstance] queueMessage:ShowFindReplaceDialogMsgID
|
||||
properties:args];
|
||||
}
|
||||
|
||||
void
|
||||
gui_mch_find_dialog(exarg_T *eap)
|
||||
{
|
||||
macvim_find_and_replace(eap->arg, NO);
|
||||
}
|
||||
|
||||
void
|
||||
gui_mch_replace_dialog(exarg_T *eap)
|
||||
{
|
||||
macvim_find_and_replace(eap->arg, YES);
|
||||
}
|
||||
|
||||
#endif // FIND_REPLACE_DIALOG
|
||||
|
||||
|
||||
|
||||
|
||||
// -- Unsorted --------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1600,6 +1697,23 @@ gui_mch_leave_fullscreen()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gui_mch_fuopt_update()
|
||||
{
|
||||
if (!gui.in_use)
|
||||
return;
|
||||
|
||||
guicolor_T fg, bg;
|
||||
if (fuoptions_flags & FUOPT_BGCOLOR_HLGROUP) {
|
||||
syn_id2colors(fuoptions_bgcolor, &fg, &bg);
|
||||
} else {
|
||||
bg = fuoptions_bgcolor;
|
||||
}
|
||||
|
||||
[[MMBackend sharedInstance] setFullscreenBackgroundColor:bg];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gui_macvim_update_modified_flag()
|
||||
{
|
||||
@@ -1737,14 +1851,7 @@ serverGetVimNames(void)
|
||||
|
||||
if (list) {
|
||||
NSString *string = [list componentsJoinedByString:@"\n"];
|
||||
char_u *s = (char_u*)[string UTF8String];
|
||||
#ifdef FEAT_MBYTE
|
||||
s = CONVERT_FROM_UTF8(s);
|
||||
#endif
|
||||
names = vim_strsave(s);
|
||||
#ifdef FEAT_MBYTE
|
||||
CONVERT_FROM_UTF8_FREE(s);
|
||||
#endif
|
||||
names = [string vimStringSave];
|
||||
}
|
||||
|
||||
return names;
|
||||
@@ -1812,14 +1919,7 @@ serverReadReply(int port, char_u **str)
|
||||
{
|
||||
NSString *reply = [[MMBackend sharedInstance] waitForReplyOnPort:port];
|
||||
if (reply && str) {
|
||||
char_u *s = (char_u*)[reply UTF8String];
|
||||
#ifdef FEAT_MBYTE
|
||||
s = CONVERT_FROM_UTF8(s);
|
||||
#endif
|
||||
*str = vim_strsave(s);
|
||||
#ifdef FEAT_MBYTE
|
||||
CONVERT_FROM_UTF8_FREE(s);
|
||||
#endif
|
||||
*str = [reply vimStringSave];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+14
-7
@@ -1,7 +1,7 @@
|
||||
" System gvimrc file for MacVim
|
||||
"
|
||||
" Maintainer: Bjorn Winckler <bjorn.winckler@gmail.com>
|
||||
" Last Change: Sun Aug 03 2008
|
||||
" Last Change: Sun Oct 04 2008
|
||||
"
|
||||
" This is a work in progress. If you feel so inclined, please help me improve
|
||||
" this file.
|
||||
@@ -60,17 +60,21 @@ an 10.350 File.Save\ As\.\.\.<Tab>:sav :browse confirm saveas<CR>
|
||||
|
||||
" Edit menu
|
||||
|
||||
" The following function is aken from menu.vim
|
||||
fun! s:FixFText()
|
||||
" Fix text in nameless register to be used with :promptfind.
|
||||
return substitute(@", "[\r\n]", '\\n', 'g')
|
||||
endfun
|
||||
|
||||
aunmenu Edit.Find
|
||||
aunmenu Edit.Find\ and\ Replace
|
||||
|
||||
an 20.410.10 Edit.Find.Find\.\.\.<Tab>/ /
|
||||
an <silent> 20.410.10 Edit.Find.Find\.\.\. :promptfind<CR>
|
||||
vunmenu Edit.Find.Find\.\.\.
|
||||
vnoremenu <silent> Edit.Find.Find\.\.\. y:promptfind <C-R>=<SID>FixFText()<CR><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/
|
||||
vunmenu Edit.Find.Find\ and\ Replace\.\.\.<Tab>:%s
|
||||
vnoremenu Edit.Find.Find\ and\ Replace\.\.\.<Tab>:s :s/
|
||||
vmenu 20.410.35 Edit.Find.Use\ Selection\ for\ Find y:let @/=@"<CR>:<BS>
|
||||
|
||||
an 20.460 Edit.-SEP4- <Nop>
|
||||
an 20.465.10 Edit.Font.Show\ Fonts <Nop>
|
||||
@@ -157,6 +161,9 @@ if !exists("macvim_skip_cmd_opt_movement")
|
||||
ino <D-Down> <C-End>
|
||||
map <M-Down> }
|
||||
imap <M-Down> <C-o>}
|
||||
|
||||
imap <M-BS> <C-w>
|
||||
imap <D-BS> <C-u>
|
||||
endif " !exists("macvim_skip_cmd_opt_movement")
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
.PHONY: clean
|
||||
|
||||
OUTDIR ?= .
|
||||
|
||||
$(OUTDIR)/MacVim-generic.icns: make_icons.py vim-noshadow-512.png loadfont.so Envy\ Code\ R\ Bold.ttf
|
||||
$(MAKE) -C makeicns
|
||||
/usr/bin/python make_icons.py $(OUTDIR)
|
||||
|
||||
loadfont.so: loadfont.c
|
||||
python setup.py install --install-lib .
|
||||
|
||||
Envy\ Code\ R\ Bold.ttf: EnvyCodeR.zip
|
||||
unzip -jo EnvyCodeR.zip
|
||||
# unzip uses the file date from the zip file. Change the file date to
|
||||
# "now", so that the zip is not unzipped in every `make` run.`
|
||||
touch Envy\ Code\ R\ Bold.ttf
|
||||
|
||||
ENVYCODE_URL=http://download.damieng.com/latest/EnvyCodeR
|
||||
EnvyCodeR.zip:
|
||||
curl ${ENVYCODE_URL} --location -o EnvyCodeR.zip
|
||||
|
||||
clean:
|
||||
$(MAKE) -C makeicns clean
|
||||
rm -f $(OUTDIR)/MacVim-*.icns loadfont.so *.pyc \
|
||||
EnvyCodeR.zip *.ttf *.reg *.txt
|
||||
rm -rf *.egginfo build # Created by setup.py
|
||||
@@ -0,0 +1,605 @@
|
||||
from Foundation import *
|
||||
from AppKit import *
|
||||
|
||||
import itertools
|
||||
import math
|
||||
import operator
|
||||
import os
|
||||
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
# Resources
|
||||
DEFAULT_BACKGROUND = '/System/Library/CoreServices/CoreTypes.bundle/' + \
|
||||
'Contents/Resources/GenericDocumentIcon.icns' # might require leopard?
|
||||
|
||||
|
||||
# Cache both images and background renderers globally
|
||||
imageCache = {}
|
||||
bgCache = {}
|
||||
|
||||
|
||||
# Make us not crash
|
||||
# http://www.cocoabuilder.com/archive/message/cocoa/2008/8/6/214964
|
||||
NSApplicationLoad()
|
||||
|
||||
|
||||
class Surface(object):
|
||||
"""Represents a simple bitmapped image."""
|
||||
|
||||
def __init__(self, *p, **kw):
|
||||
if not 'premultiplyAlpha' in kw:
|
||||
kw['premultiplyAlpha'] = True
|
||||
if len(p) == 1 and isinstance(p[0], NSBitmapImageRep):
|
||||
self.bitmapRep = p[0]
|
||||
elif len(p) == 2 and isinstance(p[0], int) and isinstance(p[1], int):
|
||||
format = NSAlphaFirstBitmapFormat
|
||||
if not kw['premultiplyAlpha']:
|
||||
format += NSAlphaNonpremultipliedBitmapFormat
|
||||
self.bitmapRep = NSBitmapImageRep.alloc().initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel_(
|
||||
None, p[0], p[1], 8, 4, True, False, NSDeviceRGBColorSpace,
|
||||
format, 0, 0)
|
||||
|
||||
if not hasattr(self, 'bitmapRep') or not self.bitmapRep:
|
||||
raise Exception('Failed to create surface: ' + str(p))
|
||||
|
||||
def size(self):
|
||||
return map(int, self.bitmapRep.size()) # cocoa returns floats. cocoa ftw
|
||||
|
||||
def data(self):
|
||||
"""Returns data in ARGB order (on intel, at least)."""
|
||||
r = self.bitmapRep
|
||||
if r.bitmapFormat() != (NSAlphaNonpremultipliedBitmapFormat |
|
||||
NSAlphaFirstBitmapFormat) or \
|
||||
r.bitsPerPixel() != 32 or \
|
||||
r.isPlanar() or \
|
||||
r.samplesPerPixel() != 4:
|
||||
raise Exception("Unsupported image format")
|
||||
return self.bitmapRep.bitmapData()
|
||||
|
||||
def save(self, filename):
|
||||
"""Saves image as png file."""
|
||||
self.bitmapRep.representationUsingType_properties_(NSPNGFileType, None) \
|
||||
.writeToFile_atomically_(filename, True)
|
||||
|
||||
def draw(self):
|
||||
self.bitmapRep.draw()
|
||||
|
||||
def context(self):
|
||||
# Note: Cocoa only supports contexts with premultiplied alpha
|
||||
return NSGraphicsContext.graphicsContextWithBitmapImageRep_(self.bitmapRep)
|
||||
|
||||
def copy(self):
|
||||
return Surface(self.bitmapRep.copy())
|
||||
|
||||
|
||||
class Image(object):
|
||||
"""Represents an image that can consist of several Surfaces."""
|
||||
|
||||
def __init__(self, param):
|
||||
if isinstance(param, str):
|
||||
self.image = NSImage.alloc().initWithContentsOfFile_(param)
|
||||
elif isinstance(param, Surface):
|
||||
self.image = NSImage.alloc().initWithSize_( param.size() )
|
||||
self.image.addRepresentation_(param.bitmapRep)
|
||||
|
||||
if not self.image:
|
||||
raise Exception('Failed to load image: ' + str(param))
|
||||
|
||||
def surfaceOfSize(self, w, h):
|
||||
"""Returns an ARGB, non-premultiplied surface of size w*h or throws."""
|
||||
r = None
|
||||
for rep in self.image.representations():
|
||||
# Cocoa reports fraction widths for pngs (wtf?!), so use round()
|
||||
if map(lambda x: int(round(x)), rep.size()) == [w, h]:
|
||||
r = rep
|
||||
break
|
||||
|
||||
# XXX: Resample in this case? That'd make the program easier to use, but
|
||||
# can silently create blurry backgrounds. Since this happens with
|
||||
# the app icon anyways, this might not be a huge deal?
|
||||
if not r:
|
||||
raise Exception('Unsupported size %dx%d', w, h)
|
||||
return Surface(r)
|
||||
|
||||
def blend(self):
|
||||
self.compositeInRect( ((0, 0), self.image.size()) )
|
||||
|
||||
def compositeInRect(self, r, mode=NSCompositeSourceOver):
|
||||
self.image.drawInRect_fromRect_operation_fraction_(r, NSZeroRect,
|
||||
mode, 1.0)
|
||||
|
||||
def sizes(self):
|
||||
s = set()
|
||||
for rep in self.image.representations():
|
||||
s.add(tuple(map(lambda x: int(round(x)), rep.size())))
|
||||
return s
|
||||
|
||||
|
||||
class Context(object):
|
||||
# Tiger has only Python2.3, so we can't use __enter__ / __exit__ for this :-(
|
||||
|
||||
def __init__(self, surface):
|
||||
NSGraphicsContext.saveGraphicsState()
|
||||
c = surface.context()
|
||||
c.setShouldAntialias_(True);
|
||||
c.setImageInterpolation_(NSImageInterpolationHigh);
|
||||
NSGraphicsContext.setCurrentContext_(c)
|
||||
|
||||
def done(self):
|
||||
NSGraphicsContext.restoreGraphicsState()
|
||||
|
||||
|
||||
class SplittableBackground(object):
|
||||
|
||||
def __init__(self, unsplitted, shouldSplit=True):
|
||||
self.unsplitted = unsplitted
|
||||
self.shouldSplit = shouldSplit
|
||||
self.ground = {}
|
||||
self.shadow = {}
|
||||
|
||||
def rawGroundAtSize(self, s):
|
||||
return self.unsplitted.surfaceOfSize(s, s)
|
||||
|
||||
def groundAtSize(self, s):
|
||||
if not self.shouldSplit:
|
||||
return self.rawGroundAtSize(s)
|
||||
self._performSplit(s)
|
||||
return self.ground[s]
|
||||
|
||||
def shadowAtSize(self, s):
|
||||
if not self.shouldSplit:
|
||||
return None
|
||||
self._performSplit(s)
|
||||
return self.shadow[s]
|
||||
|
||||
def _performSplit(self, s):
|
||||
if s in self.ground:
|
||||
assert s in self.shadow
|
||||
return
|
||||
assert s not in self.shadow
|
||||
ground, shadow = splitGenericDocumentIcon(self.unsplitted, s)
|
||||
self.ground[s] = ground
|
||||
self.shadow[s] = shadow
|
||||
|
||||
|
||||
class BackgroundRenderer(object):
|
||||
|
||||
def __init__(self, bg, icon=None, r={}):
|
||||
self.bgRenderer = bg
|
||||
self.icon = icon
|
||||
self.cache = {}
|
||||
self.rect = r
|
||||
|
||||
def drawIcon(self, s):
|
||||
if not self.icon:
|
||||
return
|
||||
|
||||
assert s in [16, 32, 128, 256, 512]
|
||||
a = list(self.rect[s])
|
||||
|
||||
# convert from `flow` coords to cocoa
|
||||
a[2] = -a[2] # mirror y
|
||||
|
||||
w, h = s*a[1], s*a[3]
|
||||
self.icon.compositeInRect( (((s-w)/2 + a[0], (s-h)/2 + a[2]), (w, h)) )
|
||||
|
||||
def drawAtSize(self, s):
|
||||
if not self.icon:
|
||||
# No need to split the background if no icons is interleaved -- take
|
||||
# the faster code path in that case.
|
||||
self.bgRenderer.rawGroundAtSize(s).draw()
|
||||
return
|
||||
|
||||
self.bgRenderer.groundAtSize(s).draw()
|
||||
self.drawIcon(s)
|
||||
if self.bgRenderer.shouldSplit:
|
||||
# shadow needs to be composited, so it needs to be in an image
|
||||
Image(self.bgRenderer.shadowAtSize(s)).blend()
|
||||
|
||||
def backgroundAtSize(self, s):
|
||||
if not s in self.cache:
|
||||
result = Surface(s, s)
|
||||
context = Context(result)
|
||||
self.drawAtSize(s)
|
||||
context.done()
|
||||
self.cache[s] = result
|
||||
return self.cache[s]
|
||||
|
||||
|
||||
def splitGenericDocumentIcon(img, s):
|
||||
"""Takes the generic document icon and splits it into a background and a
|
||||
shadow layer. For the 32x32 and 16x16 variants, the white pixels of the page
|
||||
curl are hardcoded into the otherwise transparent shadow layer."""
|
||||
|
||||
w, h = s, s
|
||||
r = img.surfaceOfSize(w, h)
|
||||
bps = 4*w
|
||||
data = r.data()
|
||||
|
||||
ground = Surface(w, h, premultiplyAlpha=False)
|
||||
shadow = Surface(w, h, premultiplyAlpha=False)
|
||||
|
||||
grounddata = ground.data()
|
||||
shadowdata = shadow.data()
|
||||
|
||||
for y in xrange(h):
|
||||
for x in xrange(w):
|
||||
idx = y*bps + 4*x
|
||||
ia, ir, ig, ib = data[idx:idx + 4]
|
||||
if ia != chr(255):
|
||||
# buffer objects don't support slice assignment :-(
|
||||
grounddata[idx] = ia
|
||||
grounddata[idx + 1] = ir
|
||||
grounddata[idx + 2] = ig
|
||||
grounddata[idx + 3] = ib
|
||||
shadowdata[idx] = chr(0)
|
||||
shadowdata[idx + 1] = chr(0)
|
||||
shadowdata[idx + 2] = chr(0)
|
||||
shadowdata[idx + 3] = chr(0)
|
||||
continue
|
||||
|
||||
assert ir == ig == ib
|
||||
grounddata[idx] = chr(255)
|
||||
grounddata[idx + 1] = chr(255)
|
||||
grounddata[idx + 2] = chr(255)
|
||||
grounddata[idx + 3] = chr(255)
|
||||
shadowdata[idx] = chr(255 - ord(ir))
|
||||
shadowdata[idx + 1] = chr(0)
|
||||
shadowdata[idx + 2] = chr(0)
|
||||
shadowdata[idx + 3] = chr(0)
|
||||
|
||||
# Special-case 16x16 and 32x32 cases: Make some pixels on the fold white.
|
||||
# Ideally, I could make the fold whiteish in all variants, but I can't.
|
||||
whitePix = { 16: [(10, 2), (10, 3), (11, 3), (10, 4), (11, 4), (12, 4)],
|
||||
32: [(21, 4), (21, 5), (22, 5), (21, 6), (22, 6), (23, 6)]}
|
||||
if (w, h) in [(16, 16), (32, 32)]:
|
||||
for x, y in whitePix[w]:
|
||||
idx = y*bps + 4*x
|
||||
shadowdata[idx] = chr(255)
|
||||
shadowdata[idx + 1] = chr(255)
|
||||
shadowdata[idx + 2] = chr(255)
|
||||
shadowdata[idx + 3] = chr(255)
|
||||
|
||||
return ground, shadow
|
||||
|
||||
|
||||
class TextRenderer(object):
|
||||
|
||||
def __init__(self):
|
||||
self.cache = {}
|
||||
|
||||
def attribsAtSize(self, s):
|
||||
if s not in self.cache:
|
||||
self.cache[s] = self._attribsAtSize(s)
|
||||
return self.cache[s]
|
||||
|
||||
def centeredStyle(self):
|
||||
style = NSMutableParagraphStyle.new()
|
||||
style.setParagraphStyle_(NSParagraphStyle.defaultParagraphStyle())
|
||||
style.setAlignment_(NSCenterTextAlignment)
|
||||
return style
|
||||
|
||||
def _attribsAtSize(self, s):
|
||||
# This looks not exactly like the font on Preview.app's document icons,
|
||||
# but I believe that's because Preview's icons are drawn by Photoshop,
|
||||
# and Adobe's font rendering is different from Apple's.
|
||||
fontname = 'LucidaGrande-Bold'
|
||||
|
||||
# Prepare text format
|
||||
fontsizes = { 512: 72.0, 256: 36.0, 128: 18.0, 32: 7.0, 16: 3.0 }
|
||||
# http://developer.apple.com/documentation/Cocoa/Conceptual/AttributedStrings/Articles/standardAttributes.html#//apple_ref/doc/uid/TP40004903
|
||||
attribs = {
|
||||
NSParagraphStyleAttributeName: self.centeredStyle(),
|
||||
NSForegroundColorAttributeName: NSColor.colorWithDeviceWhite_alpha_(
|
||||
0.34, 1),
|
||||
NSFontAttributeName: NSFont.fontWithName_size_(fontname, fontsizes[s])
|
||||
}
|
||||
|
||||
# tighten font a bit for some sizes
|
||||
if s in [256, 512]:
|
||||
attribs[NSKernAttributeName] = -1.0
|
||||
elif s == 32:
|
||||
attribs[NSKernAttributeName] = -0.25
|
||||
|
||||
if not attribs[NSFontAttributeName]:
|
||||
raise Exception('Failed to load font %s' % fontname)
|
||||
return attribs
|
||||
|
||||
def drawTextAtSize(self, text, s):
|
||||
"""Draws text `s` into the current context of size `s`."""
|
||||
|
||||
textRects = {
|
||||
512: ((0, 7), (512, 119)),
|
||||
128: ((0, 6), (128, 26.5)),
|
||||
256: ((0, 7), (256, 57)),
|
||||
16: ((1, 1), (15, 5)),
|
||||
#32: ((1, 1), (31, 9))
|
||||
}
|
||||
|
||||
attribs = self.attribsAtSize(s)
|
||||
text = NSString.stringWithString_(text)
|
||||
if s in [16, 128, 256, 512]:
|
||||
text.drawInRect_withAttributes_(textRects[s], attribs)
|
||||
elif s == 32:
|
||||
# Try to align text on pixel boundary:
|
||||
attribs = attribs.copy()
|
||||
attribs[NSParagraphStyleAttributeName] = \
|
||||
NSParagraphStyle.defaultParagraphStyle()
|
||||
ts = text.sizeWithAttributes_(attribs)
|
||||
text.drawAtPoint_withAttributes_( (math.floor((32.0-ts[0])/2) + 0.5, 1.5),
|
||||
attribs)
|
||||
|
||||
|
||||
class OfficeTextRenderer(TextRenderer):
|
||||
"""Uses Office's LucidaSans font for 32x32.
|
||||
|
||||
This font looks much better for certain strings (e.g. "PDF") but much worse
|
||||
for most others (e.g. "VIM", "JAVA") -- and office fonts are usually not
|
||||
installed. Hence, this class is better not used.
|
||||
"""
|
||||
|
||||
def _attribsAtSize(self, s):
|
||||
self.useOfficeFont = False
|
||||
attribs = TextRenderer._attribsAtSize(self, s)
|
||||
if s == 32:
|
||||
font = NSFont.fontWithName_size_('LucidaSans-Demi', 7.0)
|
||||
if font:
|
||||
attribs[NSFontAttributeName] = font
|
||||
attribs[NSKernAttributeName] = 0
|
||||
self.useOfficeFont = True
|
||||
return attribs
|
||||
|
||||
def drawTextAtSize(self, text, s):
|
||||
attribs = self.attribsAtSize(s)
|
||||
if not self.useOfficeFont or s != 32:
|
||||
TextRenderer.drawTextAtSize(self, text, s)
|
||||
return
|
||||
text = NSString.stringWithString_(text)
|
||||
text.drawInRect_withAttributes_( ((0, 1), (31, 11)), attribs)
|
||||
|
||||
|
||||
def createIcon(s, bg, textRenderer, text):
|
||||
|
||||
# Fill in background
|
||||
output = bg.backgroundAtSize(s).copy()
|
||||
|
||||
# Draw text on top of shadow
|
||||
context = Context(output)
|
||||
if s in text and text[s]:
|
||||
textRenderer.drawTextAtSize(text[s], s)
|
||||
context.done()
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def textDictFromTextList(l):
|
||||
assert 1 <= len(l) <= 3
|
||||
if len(l) == 1:
|
||||
return dict.fromkeys([16, 32, 128, 256, 512], l[0])
|
||||
elif len(l) == 2:
|
||||
return dict(zip([16, 32], 2*[l[1]]) + zip((128, 256, 512), 3*[l[0]]))
|
||||
elif len(l) == 3:
|
||||
return dict([(16, l[2]), (32, l[1])] + zip((128, 256, 512), 3*[l[0]]))
|
||||
|
||||
|
||||
def saveIcns(icons, icnsName, makeIcns='./makeicns'):
|
||||
"""Creates an icns file with several variants.
|
||||
|
||||
Params:
|
||||
icons: A dict that contains icon size as key and Surface as value.
|
||||
Valid keys are 512, 256, 128, 32, 16
|
||||
icnsname: Name of the output file
|
||||
"""
|
||||
# If IconFamily was less buggy, we could wrap it into a python module and
|
||||
# call it directly, which is about a lot faster. However, IconFamily does not
|
||||
# work with NSAlphaNonpremultipliedBitmapFormat correctly, so this has to
|
||||
# wait.
|
||||
#import IconFamily
|
||||
#typeDict = {
|
||||
#16: IconFamily.kSmall32BitData,
|
||||
#32: IconFamily.kLarge32BitData,
|
||||
#128: IconFamily.kThumbnail32BitData,
|
||||
#256: IconFamily.kIconServices256PixelDataARGB,
|
||||
#512: IconFamily.IconServices512PixelDataARGB,
|
||||
#}
|
||||
#maskDict = {
|
||||
#16: IconFamily.kSmall8BitMask,
|
||||
#32: IconFamily.kLarge8BitMask,
|
||||
#128: IconFamily.kThumbnail8BitMask,
|
||||
#}
|
||||
#output = IconFamily.IconFamily.iconFamily()
|
||||
#for s, icon in icons.items():
|
||||
#output.setIconFamilyElement_fromBitmapImageRep_(typeDict[s], icon.bitmapRep)
|
||||
#if s in maskDict:
|
||||
#output.setIconFamilyElement_fromBitmapImageRep_(
|
||||
#maskDict[s], icon.bitmapRep)
|
||||
#output.writeToFile_(icnsName)
|
||||
TMPFILE = 'docerator_tmp_%d.png'
|
||||
try:
|
||||
args = []
|
||||
for s, icon in icons.items():
|
||||
assert s in [512, 256, 128, 32, 16]
|
||||
assert icon.size() == [s, s]
|
||||
icon.save(TMPFILE % s)
|
||||
args.append('-%d %s' % (s, TMPFILE % s))
|
||||
return \
|
||||
os.system('%s %s -out %s' % (makeIcns, ' '.join(args), icnsName)) == 0
|
||||
finally:
|
||||
for s in icons:
|
||||
if os.access(TMPFILE % s, os.F_OK):
|
||||
os.remove(TMPFILE % s)
|
||||
|
||||
|
||||
def getOutname(options):
|
||||
def saneBasename(p):
|
||||
""" '/my/path/to/file.txt' -> 'file' """
|
||||
return os.path.splitext(os.path.basename(p))[0]
|
||||
textPart = 'Generic'
|
||||
if options.text:
|
||||
textPart = options.text.split(',')[0]
|
||||
if options.appicon:
|
||||
base = saneBasename(options.appicon)
|
||||
else:
|
||||
base = saneBasename(getBgName(options))
|
||||
return '%s-%s.icns' % (base, textPart)
|
||||
|
||||
|
||||
def cachedImage(filename):
|
||||
absPath = os.path.abspath(filename)
|
||||
if not absPath in imageCache:
|
||||
imageCache[absPath] = Image(absPath)
|
||||
return imageCache[absPath]
|
||||
|
||||
|
||||
def cachedBackground(img, split):
|
||||
key = (img, split)
|
||||
if not key in bgCache:
|
||||
bgCache[key] = SplittableBackground(img, shouldSplit=split)
|
||||
return bgCache[key]
|
||||
|
||||
|
||||
# taken from running flow on preview
|
||||
defaultRects = {
|
||||
16: (-0.30890000000000001, 0.4919, -1.2968, 0.4743),
|
||||
32: (-0.27810000000000001,
|
||||
0.58930000000000005,
|
||||
-2.2292999999999998,
|
||||
0.57140000000000002),
|
||||
128: (1.1774, 0.56820000000000004, -0.8246, 0.56799999999999995),
|
||||
256: (0.5917, 0.56489999999999996, -1.8994, 0.56499999999999995),
|
||||
512: (0.68700000000000006,
|
||||
0.56530000000000002,
|
||||
-4.2813999999999997,
|
||||
0.56540000000000001)
|
||||
}
|
||||
|
||||
|
||||
def getBgName(options):
|
||||
if not hasattr(options, 'background') \
|
||||
or options.background in ['default-split', 'default-unsplit']:
|
||||
return DEFAULT_BACKGROUND
|
||||
else:
|
||||
return options.background
|
||||
|
||||
|
||||
class IconGenerator(object):
|
||||
def __init__(self, options):
|
||||
if hasattr(options, 'textrenderer') and options.textrenderer:
|
||||
self.textRenderer = options.textrenderer()
|
||||
else:
|
||||
self.textRenderer = TextRenderer()
|
||||
|
||||
# Prepare input images
|
||||
splitBackground = options.background == 'default-split'
|
||||
self.bgIcon = cachedImage(getBgName(options))
|
||||
|
||||
self.testIcon = None
|
||||
if options.appicon:
|
||||
self.testIcon = cachedImage(options.appicon)
|
||||
|
||||
rects = defaultRects.copy()
|
||||
rects[16] = [ 0.0000, 0.5000, -1.0000, 0.5000] # manually, better
|
||||
if hasattr(options, 'rects'):
|
||||
rects.update(options.rects)
|
||||
|
||||
bg = cachedBackground(self.bgIcon, splitBackground)
|
||||
|
||||
if hasattr(options, 'backgroundrenderer') and options.backgroundrenderer:
|
||||
self.bgRenderer = options.backgroundrenderer(bg, self.testIcon, rects)
|
||||
else:
|
||||
self.bgRenderer = BackgroundRenderer(bg, self.testIcon, rects)
|
||||
|
||||
self.testtext = textDictFromTextList(options.text.split(','))
|
||||
|
||||
def createIconAtSize(self, s):
|
||||
return createIcon(s, self.bgRenderer, self.textRenderer, self.testtext)
|
||||
|
||||
|
||||
def iconGenerator(**kwargs):
|
||||
return IconGenerator(optsFromDict(**kwargs))
|
||||
|
||||
|
||||
def makedocicon_opts(options):
|
||||
renderer = IconGenerator(options)
|
||||
|
||||
if hasattr(options, 'sizes') and options.sizes:
|
||||
if isinstance(options.sizes, list):
|
||||
sizes = options.sizes
|
||||
else:
|
||||
sizes = map(int, options.sizes.split(','))
|
||||
else:
|
||||
sizes = renderer.bgIcon.sizes()
|
||||
if renderer.testIcon:
|
||||
sizes = sizes.intersection(renderer.testIcon.sizes())
|
||||
sizes = sorted(map(operator.itemgetter(0), sizes))
|
||||
|
||||
icons = dict([(s, renderer.createIconAtSize(s)) for s in sizes])
|
||||
|
||||
if options.debug:
|
||||
for s, icon in icons.iteritems():
|
||||
icon.save(options.debug % s)
|
||||
|
||||
if hasattr(options, 'outname') and options.outname:
|
||||
outname = options.outname
|
||||
else:
|
||||
outname = getOutname(options)
|
||||
if saveIcns(icons, outname, options.makeicns):
|
||||
print 'Wrote', outname
|
||||
else:
|
||||
print 'Failed to write %s. Make sure makeicns is in your path.' % outname
|
||||
|
||||
|
||||
def optsFromDict(**kwargs):
|
||||
options, _ = getopts().parse_args([]) # get default options
|
||||
for k in kwargs:
|
||||
setattr(options, k, kwargs[k])
|
||||
return options
|
||||
|
||||
|
||||
def makedocicon(**kwargs):
|
||||
makedocicon_opts(optsFromDict(**kwargs))
|
||||
|
||||
|
||||
def makedocicons_opts(options):
|
||||
if not hasattr(options, 'text') or not options.text:
|
||||
options.text = ['']
|
||||
texts = options.text
|
||||
for text in texts:
|
||||
options.text = text
|
||||
makedocicon_opts(options)
|
||||
|
||||
|
||||
def makedocicons(**kwargs):
|
||||
makedocicons_opts(optsFromDict(**kwargs))
|
||||
|
||||
|
||||
def getopts():
|
||||
parser = OptionParser(usage='%prog [options]', version='%prog 1.01')
|
||||
parser.add_option('--background', '--bg', default='default-split',
|
||||
help='Used as background (special values: "default-split" (default), ' \
|
||||
'"default-unsplit").')
|
||||
parser.add_option('--appicon', help='App icon, defaults to no icon.')
|
||||
|
||||
parser.add_option('--text', help='Text on icon. Defaults to empty. '
|
||||
'More than one text is supported, multiple docicons are generated in '
|
||||
'that case.', action='append')
|
||||
parser.add_option('--sizes', help='Sizes of icons. ' \
|
||||
'Defaults to all sizes available in input appicon. Example: "512,128,16"')
|
||||
# XXX(Nico): This has to go
|
||||
parser.add_option('--debug', help='If set, write out pngs for all variants.' \
|
||||
' This needs to look like "debug%d.png".')
|
||||
# XXX(Nico): This has to go once IconFamily is less buggy and can be used
|
||||
# directly
|
||||
parser.add_option('--makeicns', help='Path to makeicns binary',
|
||||
default='./makeicns')
|
||||
return parser
|
||||
|
||||
|
||||
def main():
|
||||
options, args = getopts().parse_args()
|
||||
makedocicons_opts(options)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,65 @@
|
||||
import docerator
|
||||
import unittest
|
||||
|
||||
|
||||
class TextDictFromTextListTest(unittest.TestCase):
|
||||
|
||||
def testBasic(self):
|
||||
|
||||
self.assertEquals({16: 'a', 32: 'a', 128: 'a', 256: 'a', 512: 'a'},
|
||||
docerator.textDictFromTextList(['a']))
|
||||
self.assertEquals({16: 'b', 32: 'b', 128: 'a', 256: 'a', 512: 'a'},
|
||||
docerator.textDictFromTextList(['a', 'b']))
|
||||
self.assertEquals({16: 'c', 32: 'b', 128: 'a', 256: 'a', 512: 'a'},
|
||||
docerator.textDictFromTextList(['a', 'b', 'c']))
|
||||
|
||||
|
||||
class OutnameTest(unittest.TestCase):
|
||||
|
||||
class FakeOptions(object):
|
||||
def __init__(self, **kwargs):
|
||||
for k in kwargs:
|
||||
self.__setattr__(k, kwargs[k])
|
||||
|
||||
def testBasic(self):
|
||||
options = OutnameTest.FakeOptions(
|
||||
appicon = '/Applications/iTunes.app/Contents/Resources/iTunes.icns',
|
||||
text='MP3')
|
||||
self.assertEquals('iTunes-MP3.icns', docerator.getOutname(options))
|
||||
|
||||
def testTextList(self):
|
||||
options = OutnameTest.FakeOptions(
|
||||
appicon = '/Applications/iTunes.app/Contents/Resources/iTunes.icns',
|
||||
text='PYTHON,PY')
|
||||
self.assertEquals('iTunes-PYTHON.icns',
|
||||
docerator.getOutname(options))
|
||||
|
||||
def testEmptyText(self):
|
||||
options = OutnameTest.FakeOptions(
|
||||
appicon = '/Applications/iTunes.app/Contents/Resources/iTunes.icns',
|
||||
text='')
|
||||
self.assertEquals('iTunes-Generic.icns', docerator.getOutname(options))
|
||||
options = OutnameTest.FakeOptions(
|
||||
appicon = '/Applications/iTunes.app/Contents/Resources/iTunes.icns',
|
||||
text=None)
|
||||
self.assertEquals('iTunes-Generic.icns',
|
||||
docerator.getOutname(options))
|
||||
|
||||
def testEmptyIcon(self):
|
||||
options = OutnameTest.FakeOptions(appicon=None, text='MP3')
|
||||
self.assertEquals('GenericDocumentIcon-MP3.icns',
|
||||
docerator.getOutname(options))
|
||||
options = OutnameTest.FakeOptions(appicon=None, text='')
|
||||
self.assertEquals('GenericDocumentIcon-Generic.icns',
|
||||
docerator.getOutname(options))
|
||||
options = OutnameTest.FakeOptions(appicon=None, text='',
|
||||
background='/Applications/Bla/bgicon.icns')
|
||||
self.assertEquals('bgicon-Generic.icns',
|
||||
docerator.getOutname(options))
|
||||
|
||||
|
||||
# XXX(Nico): Look at the doctest module.
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,56 @@
|
||||
// A small python module that registers a font with ATS, given the name of
|
||||
// the font.
|
||||
|
||||
#include <Python/Python.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
static PyObject* loadfont(PyObject* self, PyObject* args) {
|
||||
PyObject* result = Py_False;
|
||||
const char* path = NULL;
|
||||
int ok = PyArg_ParseTuple(args, "s", &path);
|
||||
|
||||
if (ok) {
|
||||
CFStringRef componentPath = CFStringCreateWithCString(kCFAllocatorDefault,
|
||||
path, kCFStringEncodingUTF8);
|
||||
CFURLRef componentURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
|
||||
componentPath, kCFURLPOSIXPathStyle, false);
|
||||
FSRef fsref;
|
||||
|
||||
if (CFURLGetFSRef(componentURL, &fsref)) {
|
||||
OSStatus err = noErr;
|
||||
ATSFontContainerRef fontContainerRef; // we don't deactivate the font
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
err = ATSFontActivateFromFileReference(&fsref,
|
||||
kATSFontContextLocal, kATSFontFormatUnspecified, NULL,
|
||||
kATSOptionFlagsDefault, &fontContainerRef);
|
||||
#else
|
||||
FSSpec fsSpec;
|
||||
FSRef fsRef;
|
||||
if ((err = FSGetCatalogInfo(
|
||||
&fsRef, kFSCatInfoNone, NULL, NULL, &fsSpec, NULL)) == noErr) {
|
||||
err = ATSFontActivateFromFileSpecification(&fsSpec,
|
||||
kATSFontContextLocal, kATSFontFormatUnspecified, NULL,
|
||||
kATSOptionFlagsDefault, &fontContainerRef);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (err == noErr) {
|
||||
result = Py_True;
|
||||
}
|
||||
}
|
||||
CFRelease(componentURL);
|
||||
CFRelease(componentPath);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyMethodDef LoadfontMethods[] = {
|
||||
{ "loadfont", loadfont, METH_VARARGS, "Locally activates font from file." },
|
||||
{ NULL, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC initloadfont(void) {
|
||||
Py_InitModule("loadfont", LoadfontMethods);
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
# Creates all of MacVim document icons.
|
||||
|
||||
# http://www.macresearch.org/cocoa-scientists-part-xx-python-scriptersmeet-cocoa
|
||||
try:
|
||||
# Make us independent of sysprefs->appearance->antialias fonts smaller than...
|
||||
# Needs to happen before docerator is imported.
|
||||
from AppKit import NSUserDefaults
|
||||
prefs = NSUserDefaults.standardUserDefaults()
|
||||
prefs.setInteger_forKey_(4, 'AppleAntiAliasingThreshold')
|
||||
|
||||
import docerator
|
||||
|
||||
# Load Envy Code R from a file and register it under its postscript name
|
||||
# Thanks to DamienG for this font (redistributed with permission):
|
||||
# http://damieng.com/blog/2008/05/26/envy-code-r-preview-7-coding-font-released
|
||||
import loadfont
|
||||
loadfont.loadfont('Envy Code R Bold.ttf')
|
||||
|
||||
from Foundation import NSString
|
||||
from AppKit import *
|
||||
|
||||
dont_create = False
|
||||
except:
|
||||
dont_create = True # most likely because we're on tiger
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
# icon types
|
||||
LARGE = 0 # 512, 128, 32, 16; about 96kB
|
||||
SMALL = 1 # 128, 32, 16; about 36kB
|
||||
LINK = 2 # Create link to generic icon; 4kB (== smallest block size on HFS+)
|
||||
|
||||
iconsizes = {
|
||||
SMALL: [128, 32, 16],
|
||||
LARGE: [512, 128, 32, 16],
|
||||
}
|
||||
|
||||
|
||||
# Resources
|
||||
MAKEICNS = 'makeicns/makeicns'
|
||||
APPICON = 'vim-noshadow-512.png'
|
||||
DEFAULT_BACKGROUND = '/System/Library/CoreServices/CoreTypes.bundle/' + \
|
||||
'Contents/Resources/GenericDocumentIcon.icns'
|
||||
|
||||
|
||||
# List of icons to create
|
||||
GENERIC_ICON_NAME = 'MacVim-generic'
|
||||
vimIcons = {
|
||||
GENERIC_ICON_NAME: [u'', LARGE],
|
||||
'MacVim-vim': [u'VIM', LARGE],
|
||||
'MacVim-txt': [u'TXT', SMALL],
|
||||
'MacVim-tex': [u'TEX', SMALL],
|
||||
'MacVim-h': [u'H', SMALL],
|
||||
'MacVim-c': [u'C', SMALL],
|
||||
'MacVim-m': [u'M', SMALL],
|
||||
'MacVim-mm': [u'MM', SMALL],
|
||||
'MacVim-cpp': [u'C\uff0b\uff0b,C++,C++', SMALL], # fullwidth plusses
|
||||
'MacVim-java': [u'JAVA', SMALL],
|
||||
'MacVim-f': [u'FTRAN', SMALL],
|
||||
'MacVim-html': [u'HTML', SMALL],
|
||||
'MacVim-xml': [u'XML', SMALL],
|
||||
'MacVim-js': [u'JS', SMALL],
|
||||
'MacVim-perl': [u'PERL,PL', SMALL],
|
||||
'MacVim-py': [u'PYTHON,PY', SMALL],
|
||||
'MacVim-php': [u'PHP', SMALL],
|
||||
'MacVim-rb': [u'RUBY,RB', SMALL],
|
||||
'MacVim-bash': [u'SH', SMALL],
|
||||
'MacVim-patch': [u'DIFF', SMALL],
|
||||
'MacVim-applescript': [u'\uf8ffSCPT,\uf8ffS', SMALL], # apple sign
|
||||
'MacVim-as': [u'FLASH', LINK],
|
||||
'MacVim-asp': [u'ASP', LINK],
|
||||
'MacVim-bib': [u'BIB', LINK],
|
||||
'MacVim-cs': [u'C#', LINK],
|
||||
'MacVim-csfg': [u'CFDG', LINK],
|
||||
'MacVim-csv': [u'CSV', LINK],
|
||||
'MacVim-tsv': [u'TSV', LINK],
|
||||
'MacVim-cgi': [u'CGI', LINK],
|
||||
'MacVim-cfg': [u'CFG', LINK],
|
||||
'MacVim-css': [u'CSS', SMALL],
|
||||
'MacVim-dtd': [u'DTD', LINK],
|
||||
'MacVim-dylan': [u'DYLAN', LINK],
|
||||
'MacVim-erl': [u'ERLANG,ERL', SMALL],
|
||||
'MacVim-fscript': [u'FSCPT,FSCR,FS', SMALL],
|
||||
'MacVim-hs': [u'HS', SMALL],
|
||||
'MacVim-inc': [u'INC', LINK],
|
||||
'MacVim-ics': [u'ICS', SMALL],
|
||||
'MacVim-ini': [u'INI', LINK],
|
||||
'MacVim-io': [u'IO', LINK],
|
||||
'MacVim-bsh': [u'BSH', LINK],
|
||||
'MacVim-properties': [u'PROP', LINK],
|
||||
'MacVim-jsp': [u'JSP', SMALL],
|
||||
'MacVim-lisp': [u'LISP,LISP,LSP', SMALL],
|
||||
'MacVim-log': [u'LOG', SMALL],
|
||||
'MacVim-wiki': [u'WIKI', SMALL],
|
||||
'MacVim-ps': [u'PS', LINK],
|
||||
#'MacVim-plist': [u'PLIST', SMALL],
|
||||
'MacVim-sch': [u'SCHEME,SCM', SMALL],
|
||||
'MacVim-sql': [u'SQL', SMALL],
|
||||
'MacVim-tcl': [u'TCL', SMALL],
|
||||
'MacVim-xsl': [u'XSL', LINK],
|
||||
'MacVim-vcf': [u'VCARD,VCF', SMALL],
|
||||
'MacVim-vb': [u'VBASIC,VB', LINK],
|
||||
'MacVim-yaml': [u'YAML,YAML,YML', SMALL],
|
||||
'MacVim-gtd': [u'GTD', LINK],
|
||||
}
|
||||
|
||||
|
||||
def createLinks(icons, target):
|
||||
assert len(icons) > 0
|
||||
for name in icons:
|
||||
icnsName = '%s.icns' % name
|
||||
if os.access(icnsName, os.F_OK):
|
||||
os.remove(icnsName)
|
||||
os.symlink(target, icnsName)
|
||||
|
||||
|
||||
if not dont_create:
|
||||
# define a few classes to render custom 16x16 icons
|
||||
|
||||
class NoTextRenderer(docerator.TextRenderer):
|
||||
def drawTextAtSize(self, text, s):
|
||||
if s == 16: return # No text at 16x16
|
||||
docerator.TextRenderer.drawTextAtSize(self, text, s)
|
||||
|
||||
class NoIconRenderer(docerator.BackgroundRenderer):
|
||||
def drawIcon(self, s):
|
||||
if s == 16: return # no "MacVim" icon on the sheet at 16x16
|
||||
docerator.BackgroundRenderer.drawIcon(self, s)
|
||||
|
||||
class SmallTextRenderer(docerator.TextRenderer):
|
||||
def _attribsAtSize(self, s):
|
||||
attribs = docerator.TextRenderer._attribsAtSize(self, s)
|
||||
if s == 16:
|
||||
font = NSFont.fontWithName_size_('EnvyCodeR-Bold', 7.0)
|
||||
assert font
|
||||
attribs[NSFontAttributeName] = font
|
||||
attribs[NSForegroundColorAttributeName] = \
|
||||
NSColor.colorWithDeviceRed_green_blue_alpha_(
|
||||
0/255.0, 82/255.0, 0/255.0, 1)
|
||||
return attribs
|
||||
|
||||
def drawTextAtSize(self, text, s):
|
||||
if s != 16:
|
||||
docerator.TextRenderer.drawTextAtSize(self, text, s)
|
||||
return
|
||||
text = NSString.stringWithString_(text.lower()[0:3]) # at most 3 chars
|
||||
attribs = self.attribsAtSize(s)
|
||||
if len(text) <= 2:
|
||||
attribs[NSKernAttributeName] = 0 # we have some space
|
||||
else:
|
||||
attribs[NSKernAttributeName] = -1 # we need all the room we can get
|
||||
text.drawInRect_withAttributes_( ((1, 2), (15, 11)), attribs)
|
||||
|
||||
|
||||
def main():
|
||||
if dont_create:
|
||||
print "PyObjC not found, only using a stock icon for document icons."
|
||||
# Can't use the constants from docerator in this case
|
||||
import shutil
|
||||
shutil.copyfile(DEFAULT_BACKGROUND, '%s.icns' % GENERIC_ICON_NAME)
|
||||
createLinks([name for name in vimIcons if name != GENERIC_ICON_NAME],
|
||||
'%s.icns' % GENERIC_ICON_NAME)
|
||||
return
|
||||
|
||||
srcdir = os.getcwd()
|
||||
if len(sys.argv) > 1:
|
||||
os.chdir(sys.argv[1])
|
||||
appIcon = os.path.join(srcdir, APPICON)
|
||||
makeIcns = os.path.join(srcdir, MAKEICNS)
|
||||
|
||||
# create LARGE and SMALL icons first...
|
||||
for name, t in vimIcons.iteritems():
|
||||
text, size = t
|
||||
if size == LINK: continue
|
||||
print name
|
||||
if name == GENERIC_ICON_NAME:
|
||||
# The generic icon has no text; make the appicon a bit larger
|
||||
docerator.makedocicon(outname='%s.icns' % name, appicon=appIcon,
|
||||
text=text, sizes=iconsizes[size], makeicns=makeIcns,
|
||||
textrenderer=NoTextRenderer, rects={16:(0.0, 0.5533, 0.0, 0.5533)})
|
||||
else:
|
||||
# For the other icons, leave out appicon and render text in Envy Code R
|
||||
docerator.makedocicon(outname='%s.icns' % name, appicon=appIcon,
|
||||
text=text, sizes=iconsizes[size], makeicns=makeIcns,
|
||||
textrenderer=SmallTextRenderer, backgroundrenderer=NoIconRenderer)
|
||||
|
||||
# ...create links later (to make sure the link targets exist)
|
||||
createLinks([name for (name, t) in vimIcons.items() if t[1] == LINK],
|
||||
'%s.icns' % GENERIC_ICON_NAME)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,186 @@
|
||||
// IconFamily.h
|
||||
// IconFamily class interface
|
||||
// by Troy Stephens, Thomas Schnitzer, David Remahl, Nathan Day, Ben Haller, Sven Janssen, Peter Hosey, Conor Dearden, Elliot Glaysher, and Dave MacLachlan
|
||||
// version 0.9.3
|
||||
//
|
||||
// Project Home Page:
|
||||
// http://iconfamily.sourceforge.net/
|
||||
//
|
||||
// Problems, shortcomings, and uncertainties that I'm aware of are flagged with "NOTE:". Please address bug reports, bug fixes, suggestions, etc. to the project Forums and bug tracker at https://sourceforge.net/projects/iconfamily/
|
||||
|
||||
/*
|
||||
Copyright (c) 2001-2006 Troy N. Stephens
|
||||
Portions Copyright (c) 2007 Google Inc.
|
||||
|
||||
Use and distribution of this source code is governed by the MIT License, whose terms are as follows.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
// This class is a Cocoa/Objective-C wrapper for the Mac OS X Carbon API's
|
||||
// "icon family" data type. Its main purpose is to enable Cocoa applications
|
||||
// to easily create custom file icons from NSImage instances, and thus take
|
||||
// advantage of Mac OS X's new larger RGBA "thumbnail" icon format to provide
|
||||
// richly detailed thumbnail previews of the files' contents.
|
||||
//
|
||||
// Using IconFamily, this becomes as simple as:
|
||||
//
|
||||
// id iconFamily = [IconFamily iconFamilyWithThumbnailsOfImage:anImage];
|
||||
// [iconFamily setAsCustomIconForFile:anExistingFile];
|
||||
//
|
||||
// You can also write an icon family to an .icns file using the -writeToFile:
|
||||
// method.
|
||||
|
||||
@interface IconFamily : NSObject
|
||||
{
|
||||
IconFamilyHandle hIconFamily;
|
||||
}
|
||||
|
||||
// Convenience methods. These use the corresponding -init... methods to return
|
||||
// an autoreleased IconFamily instance.
|
||||
|
||||
+ (IconFamily*) iconFamily;
|
||||
+ (IconFamily*) iconFamilyWithContentsOfFile:(NSString*)path;
|
||||
+ (IconFamily*) iconFamilyWithIconOfFile:(NSString*)path;
|
||||
+ (IconFamily*) iconFamilyWithIconFamilyHandle:(IconFamilyHandle)hNewIconFamily;
|
||||
+ (IconFamily*) iconFamilyWithSystemIcon:(int)fourByteCode;
|
||||
+ (IconFamily*) iconFamilyWithThumbnailsOfImage:(NSImage*)image;
|
||||
+ (IconFamily*) iconFamilyWithThumbnailsOfImage:(NSImage*)image usingImageInterpolation:(NSImageInterpolation)imageInterpolation;
|
||||
|
||||
// Initializes as a new, empty IconFamily. This is IconFamily's designated
|
||||
// initializer method.
|
||||
|
||||
- init;
|
||||
|
||||
// Initializes an IconFamily by loading the contents of an .icns file.
|
||||
|
||||
- initWithContentsOfFile:(NSString*)path;
|
||||
|
||||
// Initializes an IconFamily from an existing Carbon IconFamilyHandle.
|
||||
|
||||
- initWithIconFamilyHandle:(IconFamilyHandle)hNewIconFamily;
|
||||
|
||||
// Initializes an IconFamily by loading the Finder icon that's assigned to a
|
||||
// file.
|
||||
|
||||
- initWithIconOfFile:(NSString*)path;
|
||||
|
||||
// Initializes an IconFamily by referencing a standard system icon.
|
||||
|
||||
- initWithSystemIcon:(int)fourByteCode;
|
||||
|
||||
// Initializes an IconFamily by creating its elements from a resampled
|
||||
// NSImage. The second form of this method allows you to specify the degree
|
||||
// of antialiasing to be used in resampling the image, by passing in one of
|
||||
// the NSImageInterpolation... constants that are defined in
|
||||
// NSGraphicsContext.h. The first form of this initializer simply calls the
|
||||
// second form with imageInterpolation set to NSImageInterpolationHigh, which
|
||||
// produces highly smoothed thumbnails.
|
||||
|
||||
- initWithThumbnailsOfImage:(NSImage*)image;
|
||||
- initWithThumbnailsOfImage:(NSImage*)image usingImageInterpolation:(NSImageInterpolation)imageInterpolation;
|
||||
|
||||
// Writes the icon family to an .icns file.
|
||||
|
||||
- (BOOL) writeToFile:(NSString*)path;
|
||||
|
||||
// Sets the image data for one of the icon family's elements from an
|
||||
// NSBitmapImageRep. The "elementType" parameter must be one of the icon
|
||||
// family element types listed below, and the format of the "bitmapImageRep"
|
||||
// must match the corresponding requirements specified below. Regardless of
|
||||
// the elementType, the bitmapImageRep must also be non-planar and have 8 bits
|
||||
// per sample.
|
||||
//
|
||||
// elementType dimensions format
|
||||
// ------------------- ---------- ---------------------------------------
|
||||
// kIconServices512PixelDataARGB 512 x 512 32-bit RGBA, 32-bit RGB, or 24-bit RGB
|
||||
// kIconServices256PixelDataARGB 256 x 256 32-bit RGBA, 32-bit RGB, or 24-bit RGB
|
||||
// kThumbnail32BitData 128 x 128 32-bit RGBA, 32-bit RGB, or 24-bit RGB
|
||||
// kThumbnail8BitMask 128 x 128 32-bit RGBA or 8-bit intensity
|
||||
// kLarge32BitData 32 x 32 32-bit RGBA, 32-bit RGB, or 24-bit RGB
|
||||
// kLarge8BitMask 32 x 32 32-bit RGBA or 8-bit intensity
|
||||
// kLarge1BitMask 32 x 32 32-bit RGBA, 8-bit intensity, or 1-bit
|
||||
// kSmall32BitData 16 x 16 32-bit RGBA, 32-bit RGB, or 24-bit RGB
|
||||
// kSmall8BitMask 16 x 16 32-bit RGBA or 8-bit intensity
|
||||
// kSmall1BitMask 16 x 16 32-bit RGBA, 8-bit intensity, or 1-bit
|
||||
//
|
||||
// When an RGBA image is supplied to set a "Mask" element, the mask data is
|
||||
// taken from the image's alpha channel.
|
||||
//
|
||||
// NOTE: Setting an IconFamily's kLarge1BitMask seems to damage the IconFamily
|
||||
// for some as yet unknown reason. (If you then assign the icon family
|
||||
// as a file's custom icon using -setAsCustomIconForFile:, the custom
|
||||
// icon doesn't appear for the file in the Finder.) However, both
|
||||
// custom icon display and mouse-click hit-testing in the Finder seem to
|
||||
// work fine when we only set the other four elements (thus keeping the
|
||||
// existing kLarge1BitMask from the valid icon family from which we
|
||||
// initialized the IconFamily via -initWithContentsOfFile:, since
|
||||
// IconFamily's -init method is currently broken...), so it seems safe
|
||||
// to just leave the kLarge1BitMask alone.
|
||||
|
||||
- (BOOL) setIconFamilyElement:(OSType)elementType
|
||||
fromBitmapImageRep:(NSBitmapImageRep*)bitmapImageRep;
|
||||
|
||||
// Gets the image data for one of the icon family's elements as a new, 32-bit
|
||||
// RGBA NSBitmapImageRep. The specified elementType should be one of
|
||||
// kIconServices512PixelDataARGB, kIconServices256PixelDataARGB,
|
||||
// kThumbnail32BitData, kLarge32BitData, or kSmall32BitData.
|
||||
//
|
||||
// The returned NSBitmapImageRep will have the corresponding 8-bit mask data
|
||||
// in its alpha channel, or a fully opaque alpha channel if the icon family
|
||||
// has no 8-bit mask data for the specified alpha channel.
|
||||
//
|
||||
// Returns nil if the requested element cannot be retrieved (e.g. if the
|
||||
// icon family has no such 32BitData element).
|
||||
|
||||
- (NSBitmapImageRep*) bitmapImageRepWithAlphaForIconFamilyElement:(OSType)elementType;
|
||||
|
||||
// Creates and returns an NSImage that contains the icon family's various
|
||||
// elements as its NSImageReps.
|
||||
|
||||
- (NSImage*) imageWithAllReps;
|
||||
|
||||
// NOTE: Planned method -- not yet implemented.
|
||||
//
|
||||
// Gets the image data for one of the icon family's elements as a new
|
||||
// NSBitmapImageRep. The specified elementType should be one of
|
||||
// kThumbnail32BitData, kThumbnail8BitMask, kLarge32BitData, kLarge8BitMask,
|
||||
// kLarge1BitMask, kSmall32BitData, kSmall8BitMask, or kSmall1BitMask.
|
||||
|
||||
// - (NSBitmapImageRep*) bitmapImageRepForIconFamilyElement:(OSType)elementType;
|
||||
|
||||
// Writes the icon family to the resource fork of the specified file as its
|
||||
// kCustomIconResource, and sets the necessary Finder bits so the icon will
|
||||
// be displayed for the file in Finder views.
|
||||
|
||||
- (BOOL) setAsCustomIconForFile:(NSString*)path;
|
||||
- (BOOL) setAsCustomIconForFile:(NSString*)path withCompatibility:(BOOL)compat;
|
||||
|
||||
// Same as the -setAsCustomIconForFile:... methods, but for folders (directories).
|
||||
|
||||
- (BOOL) setAsCustomIconForDirectory:(NSString*)path;
|
||||
- (BOOL) setAsCustomIconForDirectory:(NSString*)path withCompatibility:(BOOL)compat;
|
||||
|
||||
// Removes the custom icon (if any) from the specified file's resource fork,
|
||||
// and clears the necessary Finder bits for the file. (Note that this is a
|
||||
// class method, so you don't need an instance of IconFamily to invoke it.)
|
||||
|
||||
+ (BOOL) removeCustomIconFromFile:(NSString*)path;
|
||||
|
||||
@end
|
||||
|
||||
// Methods for interfacing with the Carbon Scrap Manager (analogous to and
|
||||
// interoperable with the Cocoa Pasteboard).
|
||||
@interface IconFamily (ScrapAdditions)
|
||||
+ (BOOL) canInitWithScrap;
|
||||
+ (IconFamily*) iconFamilyWithScrap;
|
||||
- initWithScrap;
|
||||
- (BOOL) putOnScrap;
|
||||
@end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,16 @@
|
||||
CFLAGS = -fpascal-strings -O2
|
||||
|
||||
.PHONY: clean dist
|
||||
|
||||
makeicns: makeicns.o IconFamily.o NSString+CarbonFSRefCreation.o
|
||||
g++ -o makeicns $^ -O2 \
|
||||
-framework Foundation -framework AppKit -framework Carbon
|
||||
|
||||
clean:
|
||||
rm -rf makeicns.o IconFamily.o NSString+CarbonFSRefCreation.o
|
||||
|
||||
dist: makeicns
|
||||
rm -rf makeicns-1.0.zip
|
||||
zip makeicns-1.0.zip Makefile makeicns.m IconFamily.m IconFamily.h \
|
||||
NSString+CarbonFSRefCreation.m NSString+CarbonFSRefCreation.h \
|
||||
makeicns
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright (c) 2001-2006 Troy N. Stephens
|
||||
|
||||
Use and distribution of this source code is governed by the MIT License, whose terms are as follows.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
@interface NSString (CarbonFSRefCreation)
|
||||
|
||||
// Fills in the given FSRef struct so it specifies the file whose path is in this string.
|
||||
// If the file doesn't exist, and "createFile" is YES, this method will attempt to create
|
||||
// an empty file with the specified path. (The caller should insure that the directory
|
||||
// the file is to be placed in already exists.)
|
||||
|
||||
- (BOOL) getFSRef:(FSRef*)fsRef createFileIfNecessary:(BOOL)createFile;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright (c) 2001-2006 Troy N. Stephens
|
||||
|
||||
Use and distribution of this source code is governed by the MIT License, whose terms are as follows.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import "NSString+CarbonFSRefCreation.h"
|
||||
|
||||
@implementation NSString (CarbonFSRefCreation)
|
||||
|
||||
- (BOOL) getFSRef:(FSRef*)fsRef createFileIfNecessary:(BOOL)createFile
|
||||
{
|
||||
NSFileManager* fileManager = [NSFileManager defaultManager];
|
||||
CFURLRef urlRef;
|
||||
Boolean gotFSRef;
|
||||
|
||||
// Check whether the file exists already. If not, create an empty file if requested.
|
||||
if (![fileManager fileExistsAtPath:self]) {
|
||||
if (createFile) {
|
||||
if (![@"" writeToFile:self atomically:YES]) {
|
||||
return NO;
|
||||
}
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a CFURL with the specified POSIX path.
|
||||
urlRef = CFURLCreateWithFileSystemPath( kCFAllocatorDefault,
|
||||
(CFStringRef) self,
|
||||
kCFURLPOSIXPathStyle,
|
||||
FALSE /* isDirectory */ );
|
||||
if (urlRef == NULL) {
|
||||
// printf( "** Couldn't make a CFURLRef for the file.\n" );
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Try to create an FSRef from the URL. (If the specified file doesn't exist, this
|
||||
// function will return false, but if we've reached this code we've already insured
|
||||
// that the file exists.)
|
||||
gotFSRef = CFURLGetFSRef( urlRef, fsRef );
|
||||
CFRelease( urlRef );
|
||||
|
||||
if (!gotFSRef) {
|
||||
// printf( "** Couldn't get an FSRef for the file.\n" );
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,173 @@
|
||||
// makeicns
|
||||
// Converts images to Apple's icns format.
|
||||
// Written by nicolasweber@gmx.de, released under MIT license.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "IconFamily.h"
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
|
||||
// This is defined in 10.5 and beyond in IconStorage.h
|
||||
enum {
|
||||
kIconServices512PixelDataARGB = 'ic09' /* non-premultiplied 512x512 ARGB bitmap*/
|
||||
};
|
||||
#endif
|
||||
|
||||
#define VERSION "1.0 (20081122)"
|
||||
|
||||
void usage() {
|
||||
fprintf(stderr,
|
||||
"makeicns v%s\n\n", VERSION);
|
||||
fprintf(stderr,
|
||||
"Usage: makeicns [k1=v1] [k2=v2] ...\n\n");
|
||||
fprintf(stderr,
|
||||
"Keys and values include:\n");
|
||||
fprintf(stderr,
|
||||
" 512: Name of input image for 512x512 variant of icon\n");
|
||||
fprintf(stderr,
|
||||
" 256: Name of input image for 256x256 variant of icon\n");
|
||||
fprintf(stderr,
|
||||
" 128: Name of input image for 128x128 variant of icon\n");
|
||||
fprintf(stderr,
|
||||
" 32: Name of input image for 32x32 variant of icon\n");
|
||||
fprintf(stderr,
|
||||
" 16: Name of input image for 16x16 variant of icon\n");
|
||||
fprintf(stderr,
|
||||
" in: Name of input image for all variants not having an explicit name\n");
|
||||
fprintf(stderr,
|
||||
" out: Name of output file, defaults to first nonempty input name,\n"
|
||||
" but with icns extension\n\n");
|
||||
fprintf(stderr,
|
||||
"Examples:\n\n"
|
||||
" icns -512 image.png -32 image.png\n"
|
||||
" Creates image.icns with only a 512x512 and a 32x32 variant.\n\n"
|
||||
" icns -in myfile.jpg -32 otherfile.png -out outfile.icns\n"
|
||||
" Creates outfile.icns with sizes 512, 256, 128, and 16 containing data\n"
|
||||
" from myfile.jpg and with size 32 containing data from otherfile.png.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
NSBitmapImageRep* getBitmapImageRepOfSize(NSImage* img, int size) {
|
||||
|
||||
// Don't resample if it's not necessary
|
||||
#if 0
|
||||
// IconFamily does not work correctly with
|
||||
// NSAlphaNonpremultipliedBitmapFormat images, so this has to stay disabled
|
||||
// until IconFamily is fixed (if ever).
|
||||
NSEnumerator* e = [[img representations] objectEnumerator];
|
||||
NSImageRep* ir;
|
||||
while ((ir = [e nextObject])) {
|
||||
if (![ir isKindOfClass:[NSBitmapImageRep class]]) continue;
|
||||
|
||||
NSBitmapImageRep* br = (NSBitmapImageRep*)ir;
|
||||
//NSLog(@"%@", br);
|
||||
if ([br pixelsWide] == size && [br pixelsHigh] == size
|
||||
&& ([[br colorSpaceName] isEqualToString:NSDeviceRGBColorSpace]
|
||||
|| [[br colorSpaceName] isEqualToString:NSCalibratedRGBColorSpace])
|
||||
&& ([br bitsPerPixel] == 24 || [br bitsPerPixel] == 32)
|
||||
)
|
||||
return br;
|
||||
}
|
||||
#endif
|
||||
|
||||
NSLog(@"Resampling for size %d", size);
|
||||
NSBitmapImageRep* r = [[NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes:NULL
|
||||
pixelsWide:size
|
||||
pixelsHigh:size
|
||||
bitsPerSample:8
|
||||
samplesPerPixel:4
|
||||
hasAlpha:YES
|
||||
isPlanar:NO
|
||||
colorSpaceName:NSDeviceRGBColorSpace
|
||||
bitmapFormat:0
|
||||
bytesPerRow:0
|
||||
bitsPerPixel:0];
|
||||
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
NSGraphicsContext* context = [NSGraphicsContext
|
||||
graphicsContextWithBitmapImageRep:r];
|
||||
[context setShouldAntialias:YES];
|
||||
[context setImageInterpolation:NSImageInterpolationHigh];
|
||||
[NSGraphicsContext setCurrentContext:context];
|
||||
|
||||
[img drawInRect:NSMakeRect(0, 0, size, size)
|
||||
fromRect:NSZeroRect
|
||||
operation:NSCompositeCopy
|
||||
fraction:1.0];
|
||||
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int i;
|
||||
|
||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||
NSApplicationLoad();
|
||||
|
||||
struct {
|
||||
NSString* paramName;
|
||||
OSType type, mask;
|
||||
int size;
|
||||
NSString* inputName;
|
||||
} inputs[] = {
|
||||
{ @"512", kIconServices512PixelDataARGB, 0, 512, nil },
|
||||
{ @"256", kIconServices256PixelDataARGB, 0, 256, nil },
|
||||
{ @"128", kThumbnail32BitData, kThumbnail8BitMask, 128, nil },
|
||||
{ @"32", kLarge32BitData, kLarge8BitMask, 32, nil },
|
||||
{ @"16", kSmall32BitData, kSmall8BitMask, 16, nil },
|
||||
};
|
||||
const int N = sizeof(inputs)/sizeof(inputs[0]);
|
||||
|
||||
// Process arguments -- Thanks Greg!
|
||||
//http://unixjunkie.blogspot.com/2006/07/command-line-processing-in-cocoa.html
|
||||
NSUserDefaults* args = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
BOOL foundInputParam = NO;
|
||||
NSString* outputName = [args stringForKey:@"out"];
|
||||
NSString* defaultIn = [args stringForKey:@"in"];
|
||||
for (i = 0; i < N; ++i) {
|
||||
inputs[i].inputName = [args stringForKey:inputs[i].paramName];
|
||||
if (inputs[i].inputName == nil)
|
||||
inputs[i].inputName = defaultIn;
|
||||
foundInputParam = foundInputParam || inputs[i].inputName != nil;
|
||||
|
||||
// Create default output name if necessary
|
||||
if (outputName == nil && inputs[i].inputName != nil)
|
||||
outputName = [[inputs[i].inputName stringByDeletingPathExtension]
|
||||
stringByAppendingPathExtension:@"icns"];
|
||||
}
|
||||
|
||||
if (!foundInputParam)
|
||||
usage();
|
||||
|
||||
// Create output
|
||||
IconFamily* output = [IconFamily iconFamily];
|
||||
|
||||
for (i = 0; i < N; ++i) {
|
||||
if (inputs[i].inputName == nil) continue;
|
||||
NSImage* img = [[[NSImage alloc] initWithContentsOfFile:inputs[i].inputName]
|
||||
autorelease];
|
||||
|
||||
NSBitmapImageRep* rep = getBitmapImageRepOfSize(img, inputs[i].size);
|
||||
[output setIconFamilyElement:inputs[i].type fromBitmapImageRep:rep];
|
||||
if (inputs[i].mask != 0)
|
||||
[output setIconFamilyElement:inputs[i].mask fromBitmapImageRep:rep];
|
||||
}
|
||||
|
||||
// Write output
|
||||
if ([output writeToFile:outputName])
|
||||
NSLog(@"Wrote output file \"%@\"", outputName);
|
||||
else
|
||||
NSLog(@"Failed to write \"%@\"", outputName);
|
||||
|
||||
[pool drain];
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
from distutils.core import setup, Extension
|
||||
|
||||
setup(name="loadfont", version="1.0",
|
||||
ext_modules = [Extension("loadfont", ["loadfont.c"])])
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
@@ -40,12 +40,221 @@
|
||||
Sparkle supports updates in zip, tar, tbz, tgz, or dmg format.
|
||||
-->
|
||||
|
||||
<item>
|
||||
<title>Snapshot 43 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 43 released</h1>
|
||||
|
||||
<p><b>The automatic updating feature is broken in snapshots 39 and 40. If the automatic updating never finishes extracting then you are affected by this bug and will have to upgrade manually. To do so, simply go to the <a href="http://code.google.com/p/macvim/wiki/Snapshot">Snapshot page</a> to download the latest version.</b></p>
|
||||
|
||||
<p> Changes since snapshot 42:
|
||||
<ul>
|
||||
<li> Do inclusive search when opening files (Jonathon Mah) </li>
|
||||
<li> Respect layout prefs when double-clicking an already open file </li>
|
||||
<li> Fix two minor memory leaks </li>
|
||||
<li> Ctrl-] works on German keyboard layout </li>
|
||||
<li> The .viminfo file is written on Cmd-q </li>
|
||||
<li> New 16x16 icons (Nico Weber) </li>
|
||||
<li> Untitled window again opens on reopen event if requested in prefs </li>
|
||||
<li> Fork earlier; fixes bug with 'autochdir', faster startup, "f" no longer supported in 'guioptions' </li>
|
||||
<li> Some other minor bug fixes </li>
|
||||
<li> Use latest runtime files and Vim patches </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Fri, 20 Feb 2009 13:49 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-43.tbz"
|
||||
length="8136440"
|
||||
sparkle:version="43"
|
||||
sparkle:shortVersionString="7.2"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 42 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 42 released</h1>
|
||||
|
||||
<p><b>The automatic updating feature is broken in snapshots 39 and 40. If the automatic updating never finishes extracting then you are affected by this bug and will have to upgrade manually. To do so, simply go to the <a href="http://code.google.com/p/macvim/wiki/Snapshot">Snapshot page</a> to download the latest version.</b></p>
|
||||
|
||||
<p> Changes since snapshot 40:
|
||||
<ul>
|
||||
<li> The menu bar behaves better when using full-screen and switching Spaces (Nico Weber) </li>
|
||||
<li> Don't switch Spaces when using "mvim" on one Space and a MacVim window is open on another Space </li>
|
||||
<li> Add user default to toggle the "add tab" button on the tabline (to disable, enter "defaults org.vim.MacVim MMShowAddTabButton 0" in Terminal) </li>
|
||||
<li> Avoid the "Press ENTER..." prompt when dragging and dropping </li>
|
||||
<li> Faster startup (and shutdown, but you're not likely to notice that unless you are me ;-) </li>
|
||||
<li> Automatic updating works again </li>
|
||||
<li> Possible to interrupt external commands (e.g. you can Ctrl-C during a lenghty :grep now) </li>
|
||||
<li> The output from external commands is displayed "interactively" (i.e. you don't have to wait for the command to finish before any output is drawn; try ":!ls -l /usr/lib" and compare with snap 40 to see what I mean) </li>
|
||||
<li> Cmd-. sends SIGINT (so that if a Vim process is stuck you should always be able to interrupt it with Cmd-. even if Ctrl-C doesn't work) </li>
|
||||
<li> Fix crashing bug: e.g. with snap 40 if you go to the src/ folder of Vim and type ":grep a *.c" MacVim would crash </li>
|
||||
<li> Toggle loading of default font with user default MMLoadDefaultFont </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Sat, 12 Jan 2009 16:12 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-42.tbz"
|
||||
length="8131516"
|
||||
sparkle:version="42"
|
||||
sparkle:shortVersionString="7.2"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 40 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 40 released</h1>
|
||||
|
||||
<p> Changes since snapshot 39:
|
||||
<ul>
|
||||
<li> Fix problems with Quickstart "leaking" Vim processes </li>
|
||||
<li> 'imdisable' now on by default (i.e. IM is disabled by default) </li>
|
||||
<li> Clipboard support in non-GUI mode (Kent Sibilev) </li>
|
||||
<li> New document icons, more filetype associations (Nico Weber) </li>
|
||||
<li> Add support for 'guitabtooltip' (hint: add the line "set gtl=%t gtt=%F" to your .gvimrc to make tabs display the name of the file and have the tooltip display the full path) (Jonathon Mah) </li>
|
||||
<li> Look for toolbar icons in runtime path (plugins such as TVO now display toolbar icons properly) </li>
|
||||
<li> Show dialog when clicking to close tab with modified buffers </li>
|
||||
<li> Update documentation </li>
|
||||
<li> Latest runtime files, and Vim patches </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Sun, 28 Dec 2008 17:26 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-40.tbz"
|
||||
length="8138981"
|
||||
sparkle:version="40"
|
||||
sparkle:shortVersionString="7.2"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 39 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 39 released</h1>
|
||||
|
||||
<p> Changes since snapshot 36 (snapshots 37 and 38 were skipped):
|
||||
<ul>
|
||||
<li> Avoid "Stray process..." warning messages (Ben Schmidt) </li>
|
||||
<li> Add Cmd-BackSpace and Alt-BackSpace insert mode mappings (Nico Weber) </li>
|
||||
<li> Dropping multiple files on a window no longer results in an error </li>
|
||||
<li> Fix "Login shell" problems (Ben Schmidt) </li>
|
||||
<li> Exit Vim process if connection becomes invalid -- this should avoid the system log filling up with error messages, but please let me know when it happens (and send me the output from Console.app) </li>
|
||||
<li> Fix bug where Vim would crash when resizing a window with double-width characters </li>
|
||||
<li> Add option 'macmeta' to use "alt/option" as meta key to allow bindings to <M-..> (see ":h 'macmeta') </li>
|
||||
<li> Add basic support for AppleScript (Jason Foreman). E.g. to zoom a window:
|
||||
<pre>
|
||||
tell application MacVim
|
||||
set zoomed of first window to true
|
||||
end tell
|
||||
</pre>
|
||||
</li>
|
||||
<li> Fix various bugs relating to initial window positioning </li>
|
||||
<li> Keep window is visible on ":set lines=..." and "set columns=..." </li>
|
||||
<li> Inserting text from "Special Characters" palette works again </li>
|
||||
<li> Remove the functionality to use a modifier key as Esc (use the PCKeyboardHack app instead, see ":h macvim-hints | /esc") </li>
|
||||
<li> More help on keyboard shortcuts (":h macvim-shortcuts") and the mvim script (see ":h mvim") </li>
|
||||
<li> Speed up live resize </li>
|
||||
<li> Support mvim script symlinks to [m|g]ex and rmvim (see ":h mvim") </li>
|
||||
<li> Tentative support for receiving input from system services (Try this: insert "2+3", select the text, then hit Cmd-*. Result: "2+3" is replaced with "5". Sometimes it seems you have to choose "MacVim->Services->Script Editor->Get Result of AppleScript" instead of pressing Cmd-* for this to work.) </li>
|
||||
<li> No more Vim zombie processes </li>
|
||||
<li> Add "Reload"/"Ignore All" buttons to the file changed dialog </li>
|
||||
<li> Latest runtime files, and Vim patches </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Sun, 23 Nov 2008 18:09 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-39.tbz"
|
||||
length="8012682"
|
||||
sparkle:version="39"
|
||||
sparkle:shortVersionString="7.2"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 36 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 36 released</h1>
|
||||
|
||||
<p> This snapshot fixes a problem with dropped characters that was introduced with snapshot 35. Other changes since snapshot 35:
|
||||
<ul>
|
||||
<li> More help file updates </li>
|
||||
<li> Fixed memory leak (Jonathon Mah) </li>
|
||||
<li> Tool tips for truncated tab labels (Jonathon Mah) </li>
|
||||
<li> Support drag and drop on tabs and on tabline (Jonathon Mah) </li>
|
||||
<li> Modifier key can be used as Esc (useful for turning Caps Lock into Esc, see ":h macvim-esc") </li>
|
||||
<li> Added "Find & Replace" dialog box (Cmd-f) </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Sat, 04 Oct 2008 18:38 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-36.tbz"
|
||||
length="8005820"
|
||||
sparkle:version="36"
|
||||
sparkle:shortVersionString="7.2"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 35 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 35 released</h1>
|
||||
|
||||
<p> With this snapshot I have focused on making MacVim faster, fixing bugs, and updating the documentation. As a result MacVim now feels snappier, flickers less, takes less time to startup from Terminal, and in some cases there are tremendous speed increases. </p>
|
||||
|
||||
<p> Here is a summary of the changes since snapshot 34:
|
||||
<ul>
|
||||
<li> Faster startup times </li>
|
||||
<li> Overall faster drawing </li>
|
||||
<li> Quicker response to key presses </li>
|
||||
<li> Fix bug where key presses were ignored when mouse was moved simultaneously </li>
|
||||
<li> Update ":h macvim" docs </li>
|
||||
<li> Add mvim:// URL handler support (Nico Weber) </li>
|
||||
<li> The VimLeave autocommand works with :maca (see ":h macvim-hints") </li>
|
||||
<li> Multiple files opened from Finder are sorted </li>
|
||||
<li> Don't shift new windows downwards if they are vertically maximized </li>
|
||||
<li> Add option to hide MacVim when last window closes </li>
|
||||
<li> The "Save changes" dialog conforms to the Apple HIG (works with Cmd-D) </li>
|
||||
<li> Fix problems with 'fullscreen' and :mksession (Nico Weber) </li>
|
||||
<li> Cmd-e copies selection to Find Pasteboard without searching </li>
|
||||
<li> Fix bug with blurry text in full-screen with ATSUI (Jjgod Jiang) </li>
|
||||
<li> Cmd-. can be used to interrupt Vim (and to exit insert mode) </li>
|
||||
<li> Add "New Document Here" system service (Ron Olson) </li>
|
||||
<li> Simplify system services menu (honors the "Open files..." pref) </li>
|
||||
<li> Full-screen background color is updated immediately when 'fuopt' changes </li>
|
||||
<li> Cursor no longer escapes the command line on Cmd-=/Cmd-- </li>
|
||||
<li> Add Input Manager support to ATSUI renderer (Kaoru Yoshida) </li>
|
||||
<li> Use latest Vim source code and runtime files </li>
|
||||
<li> Minor bug fixes </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Fri, 26 Sep 2008 20:29 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-35.tbz"
|
||||
length="7986836"
|
||||
sparkle:version="35"
|
||||
sparkle:shortVersionString="7.2"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 34 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 34 released</h1>
|
||||
|
||||
<p> Notice that there are now two prebuilt binaries of MacVim: a stable build and the snapshot build. The snapshot build will be updated fairly often whereas the stable build will not.</p>
|
||||
<p> Notice that there are now two prebuilt binaries of MacVim: a stable build and the snapshot build. The snapshot build will be updated fairly often whereas the stable build will not. If you want to use the stable build you will have to download it manually from <a href="http://code.google.com/p/macvim">http://code.google.com/p/macvim</a>.</p>
|
||||
|
||||
<p> This snapshot is based on the recently released Vim 7.2 and it contains some new features and bug fixes. Here's a partial list of changes since snapshot 33:
|
||||
|
||||
@@ -68,7 +277,7 @@
|
||||
]]></description>
|
||||
<pubDate>Sat, 16 Aug 2008 16:59 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-34.tbz"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-34.tbz"
|
||||
length="7959893"
|
||||
sparkle:version="34"
|
||||
sparkle:shortVersionString="7.2"
|
||||
|
||||
+5
-2
@@ -39,12 +39,12 @@ gui=
|
||||
opts=
|
||||
|
||||
# GUI mode, implies forking
|
||||
case "$name" in m*|g*|rg*) gui=true ;; esac
|
||||
case "$name" in m*|g*|rm*|rg*) gui=true ;; esac
|
||||
|
||||
# Restricted mode
|
||||
case "$name" in r*) opts="$opts -Z";; esac
|
||||
|
||||
# vimdiff and view
|
||||
# vimdiff, view, and ex mode
|
||||
case "$name" in
|
||||
*vimdiff)
|
||||
opts="$opts -dO"
|
||||
@@ -52,6 +52,9 @@ case "$name" in
|
||||
*view)
|
||||
opts="$opts -R"
|
||||
;;
|
||||
*ex)
|
||||
opts="$opts -e"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Last step: fire up vim.
|
||||
|
||||
@@ -354,6 +354,9 @@ MSVCVER = 9.0
|
||||
!if "$(_NMAKE_VER)" == "9.00.21022.08"
|
||||
MSVCVER = 9.0
|
||||
!endif
|
||||
!if "$(_NMAKE_VER)" == "9.00.30729.01"
|
||||
MSVCVER = 9.0
|
||||
!endif
|
||||
!endif
|
||||
|
||||
# Abort bulding VIM if version of VC is unrecognised.
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
# Makefile for Vim on OpenVMS
|
||||
#
|
||||
# Maintainer: Zoltan Arpadffy <arpadffy@polarhome.com>
|
||||
# Last change: 2007 Oct 22
|
||||
# Last change: 2008 Aug 16
|
||||
#
|
||||
# This has script been tested on VMS 6.2 to 8.2 on DEC Alpha, VAX and IA64
|
||||
# with MMS and MMK
|
||||
@@ -36,7 +36,7 @@ DECC = YES
|
||||
# BIG - Many features enabled, as rich as possible. (default)
|
||||
# HUGE - All possible featues enabled.
|
||||
# Please select one of these alternatives above.
|
||||
MODEL = BIG
|
||||
MODEL = HUGE
|
||||
|
||||
# GUI or terminal mode executable.
|
||||
# Comment out if you want just the character terminal mode only.
|
||||
|
||||
Vendored
+17
-9
@@ -16819,21 +16819,29 @@ if test "x$MACARCH" = "xboth"; then
|
||||
LDFLAGS="$LDFLAGS -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc"
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:$LINENO: checking for GCC 3 or later" >&5
|
||||
$as_echo_n "checking for GCC 3 or later... " >&6; }
|
||||
DEPEND_CFLAGS_FILTER=
|
||||
if test "$GCC" = yes; then
|
||||
{ $as_echo "$as_me:$LINENO: checking for GCC 3 or later" >&5
|
||||
$as_echo_n "checking for GCC 3 or later... " >&6; }
|
||||
gccmajor=`echo "$gccversion" | sed -e 's/^\([1-9]\)\..*$/\1/g'`
|
||||
if test "$gccmajor" -gt "2"; then
|
||||
DEPEND_CFLAGS_FILTER="| sed 's+-I */+-isystem /+g'"
|
||||
fi
|
||||
fi
|
||||
if test "$DEPEND_CFLAGS_FILTER" = ""; then
|
||||
{ $as_echo "$as_me:$LINENO: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:$LINENO: result: yes" >&5
|
||||
{ $as_echo "$as_me:$LINENO: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:$LINENO: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
{ $as_echo "$as_me:$LINENO: checking whether we need -D_FORTIFY_SOURCE=1" >&5
|
||||
$as_echo_n "checking whether we need -D_FORTIFY_SOURCE=1... " >&6; }
|
||||
if test "$gccmajor" -gt "3"; then
|
||||
CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=1"
|
||||
{ $as_echo "$as_me:$LINENO: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:$LINENO: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
+81
-31
@@ -33,7 +33,7 @@ static char_u *buflist_match __ARGS((regprog_T *prog, buf_T *buf));
|
||||
static char_u *fname_match __ARGS((regprog_T *prog, char_u *name));
|
||||
#endif
|
||||
static void buflist_setfpos __ARGS((buf_T *buf, win_T *win, linenr_T lnum, colnr_T col, int copy_options));
|
||||
static wininfo_T *find_wininfo __ARGS((buf_T *buf));
|
||||
static wininfo_T *find_wininfo __ARGS((buf_T *buf, int skip_diff_buffer));
|
||||
#ifdef UNIX
|
||||
static buf_T *buflist_findname_stat __ARGS((char_u *ffname, struct stat *st));
|
||||
static int otherfile_buf __ARGS((buf_T *buf, char_u *ffname, struct stat *stp));
|
||||
@@ -437,10 +437,6 @@ close_buffer(win, buf, action)
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
if (usingNetbeans)
|
||||
netbeans_file_closed(buf);
|
||||
#endif
|
||||
#ifdef FEAT_ODB_EDITOR
|
||||
odb_buffer_close(buf);
|
||||
#endif
|
||||
@@ -643,6 +639,10 @@ free_buffer_stuff(buf, free_options)
|
||||
#ifdef FEAT_SIGNS
|
||||
buf_delete_signs(buf); /* delete any signs */
|
||||
#endif
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
if (usingNetbeans)
|
||||
netbeans_file_killed(buf);
|
||||
#endif
|
||||
#ifdef FEAT_LOCALMAP
|
||||
map_clear_int(buf, MAP_ALL_MODES, TRUE, FALSE); /* clear local mappings */
|
||||
map_clear_int(buf, MAP_ALL_MODES, TRUE, TRUE); /* clear local abbrevs */
|
||||
@@ -651,6 +651,9 @@ free_buffer_stuff(buf, free_options)
|
||||
vim_free(buf->b_start_fenc);
|
||||
buf->b_start_fenc = NULL;
|
||||
#endif
|
||||
#ifdef FEAT_SPELL
|
||||
ga_clear(&buf->b_langp);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -816,9 +819,6 @@ do_bufdel(command, arg, addr_count, start_bnr, end_bnr, forceit)
|
||||
int bnr; /* buffer number */
|
||||
char_u *p;
|
||||
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
netbeansCloseFile = 1;
|
||||
#endif
|
||||
if (addr_count == 0)
|
||||
{
|
||||
(void)do_buffer(command, DOBUF_CURRENT, FORWARD, 0, forceit);
|
||||
@@ -913,9 +913,6 @@ do_bufdel(command, arg, addr_count, start_bnr, end_bnr, forceit)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
netbeansCloseFile = 0;
|
||||
#endif
|
||||
|
||||
return errormsg;
|
||||
}
|
||||
@@ -1094,7 +1091,7 @@ do_buffer(action, start, dir, count, forceit)
|
||||
#endif
|
||||
setpcmark();
|
||||
retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE,
|
||||
forceit ? ECMD_FORCEIT : 0);
|
||||
forceit ? ECMD_FORCEIT : 0, curwin);
|
||||
|
||||
/*
|
||||
* do_ecmd() may create a new buffer, then we have to delete
|
||||
@@ -1241,7 +1238,7 @@ do_buffer(action, start, dir, count, forceit)
|
||||
* "buf" if one exists */
|
||||
if ((swb_flags & SWB_USEOPEN) && buf_jump_open_win(buf))
|
||||
return OK;
|
||||
/* If 'switchbuf' contians "usetab": jump to first window in any tab
|
||||
/* If 'switchbuf' contains "usetab": jump to first window in any tab
|
||||
* page containing "buf" if one exists */
|
||||
if ((swb_flags & SWB_USETAB) && buf_jump_open_tab(buf))
|
||||
return OK;
|
||||
@@ -1317,7 +1314,7 @@ set_curbuf(buf, action)
|
||||
setpcmark();
|
||||
if (!cmdmod.keepalt)
|
||||
curwin->w_alt_fnum = curbuf->b_fnum; /* remember alternate file */
|
||||
buflist_altfpos(); /* remember curpos */
|
||||
buflist_altfpos(curwin); /* remember curpos */
|
||||
|
||||
#ifdef FEAT_VISUAL
|
||||
/* Don't restart Select mode after switching to another buffer. */
|
||||
@@ -1355,11 +1352,12 @@ set_curbuf(buf, action)
|
||||
}
|
||||
}
|
||||
#ifdef FEAT_AUTOCMD
|
||||
/* An autocommand may have deleted "buf", already entered it (e.g., when
|
||||
* it did ":bunload") or aborted the script processing! */
|
||||
# ifdef FEAT_EVAL
|
||||
/* An autocommand may have deleted buf or aborted the script processing! */
|
||||
if (buf_valid(buf) && !aborting())
|
||||
if (buf_valid(buf) && buf != curbuf && !aborting())
|
||||
# else
|
||||
if (buf_valid(buf)) /* an autocommand may have deleted buf! */
|
||||
if (buf_valid(buf) && buf != curbuf)
|
||||
# endif
|
||||
#endif
|
||||
enter_buffer(buf);
|
||||
@@ -1401,6 +1399,9 @@ enter_buffer(buf)
|
||||
curwin->w_cursor.coladd = 0;
|
||||
#endif
|
||||
curwin->w_set_curswant = TRUE;
|
||||
#ifdef FEAT_AUTOCMD
|
||||
curwin->w_topline_was_set = FALSE;
|
||||
#endif
|
||||
|
||||
/* Make sure the buffer is loaded. */
|
||||
if (curbuf->b_ml.ml_mfp == NULL) /* need to load the file */
|
||||
@@ -1440,7 +1441,8 @@ enter_buffer(buf)
|
||||
maketitle();
|
||||
#endif
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (curwin->w_topline == 1) /* when autocmds didn't change it */
|
||||
/* when autocmds didn't change it */
|
||||
if (curwin->w_topline == 1 && !curwin->w_topline_was_set)
|
||||
#endif
|
||||
scroll_cursor_halfway(FALSE); /* redisplay at correct position */
|
||||
|
||||
@@ -2404,22 +2406,70 @@ buflist_setfpos(buf, win, lnum, col, copy_options)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef FEAT_DIFF
|
||||
static int wininfo_other_tab_diff __ARGS((wininfo_T *wip));
|
||||
|
||||
/*
|
||||
* Return TRUE when "wip" has 'diff' set and the diff is only for another tab
|
||||
* page. That's because a diff is local to a tab page.
|
||||
*/
|
||||
static int
|
||||
wininfo_other_tab_diff(wip)
|
||||
wininfo_T *wip;
|
||||
{
|
||||
win_T *wp;
|
||||
|
||||
if (wip->wi_opt.wo_diff)
|
||||
{
|
||||
for (wp = firstwin; wp != NULL; wp = wp->w_next)
|
||||
/* return FALSE when it's a window in the current tab page, thus
|
||||
* the buffer was in diff mode here */
|
||||
if (wip->wi_win == wp)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Find info for the current window in buffer "buf".
|
||||
* If not found, return the info for the most recently used window.
|
||||
* When "skip_diff_buffer" is TRUE avoid windows with 'diff' set that is in
|
||||
* another tab page.
|
||||
* Returns NULL when there isn't any info.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static wininfo_T *
|
||||
find_wininfo(buf)
|
||||
find_wininfo(buf, skip_diff_buffer)
|
||||
buf_T *buf;
|
||||
int skip_diff_buffer;
|
||||
{
|
||||
wininfo_T *wip;
|
||||
|
||||
for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next)
|
||||
if (wip->wi_win == curwin)
|
||||
if (wip->wi_win == curwin
|
||||
#ifdef FEAT_DIFF
|
||||
&& (!skip_diff_buffer || !wininfo_other_tab_diff(wip))
|
||||
#endif
|
||||
)
|
||||
break;
|
||||
if (wip == NULL) /* if no fpos for curwin, use the first in the list */
|
||||
wip = buf->b_wininfo;
|
||||
|
||||
/* If no wininfo for curwin, use the first in the list (that doesn't have
|
||||
* 'diff' set and is in another tab page). */
|
||||
if (wip == NULL)
|
||||
{
|
||||
#ifdef FEAT_DIFF
|
||||
if (skip_diff_buffer)
|
||||
{
|
||||
for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next)
|
||||
if (!wininfo_other_tab_diff(wip))
|
||||
break;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
wip = buf->b_wininfo;
|
||||
}
|
||||
return wip;
|
||||
}
|
||||
|
||||
@@ -2440,7 +2490,7 @@ get_winopts(buf)
|
||||
clearFolding(curwin);
|
||||
#endif
|
||||
|
||||
wip = find_wininfo(buf);
|
||||
wip = find_wininfo(buf, TRUE);
|
||||
if (wip != NULL && wip->wi_optset)
|
||||
{
|
||||
copy_winopt(&wip->wi_opt, &curwin->w_onebuf_opt);
|
||||
@@ -2472,7 +2522,7 @@ buflist_findfpos(buf)
|
||||
wininfo_T *wip;
|
||||
static pos_T no_position = {1, 0};
|
||||
|
||||
wip = find_wininfo(buf);
|
||||
wip = find_wininfo(buf, FALSE);
|
||||
if (wip != NULL)
|
||||
return &(wip->wi_fpos);
|
||||
else
|
||||
@@ -2793,14 +2843,14 @@ buflist_slash_adjust()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set alternate cursor position for current window.
|
||||
* Set alternate cursor position for the current buffer and window "win".
|
||||
* Also save the local window option values.
|
||||
*/
|
||||
void
|
||||
buflist_altfpos()
|
||||
buflist_altfpos(win)
|
||||
win_T *win;
|
||||
{
|
||||
buflist_setfpos(curbuf, curwin, curwin->w_cursor.lnum,
|
||||
curwin->w_cursor.col, TRUE);
|
||||
buflist_setfpos(curbuf, win, win->w_cursor.lnum, win->w_cursor.col, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3973,7 +4023,7 @@ build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar, maxwidth, hltab, t
|
||||
width = vim_strsize(out);
|
||||
if (maxwidth > 0 && width > maxwidth)
|
||||
{
|
||||
/* Result is too long, must trunctate somewhere. */
|
||||
/* Result is too long, must truncate somewhere. */
|
||||
l = 0;
|
||||
if (itemcnt == 0)
|
||||
s = out;
|
||||
@@ -4498,7 +4548,7 @@ do_arg_all(count, forceit, keep_tabs)
|
||||
ECMD_ONE,
|
||||
((P_HID(curwin->w_buffer)
|
||||
|| bufIsChanged(curwin->w_buffer)) ? ECMD_HIDE : 0)
|
||||
+ ECMD_OLDBUF);
|
||||
+ ECMD_OLDBUF, curwin);
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (use_firstwin)
|
||||
++autocmd_no_leave;
|
||||
@@ -5072,7 +5122,7 @@ buf_spname(buf)
|
||||
{
|
||||
if (buf->b_sfname != NULL)
|
||||
return (char *)buf->b_sfname;
|
||||
return "[Scratch]";
|
||||
return _("[Scratch]");
|
||||
}
|
||||
#endif
|
||||
if (buf->b_fname == NULL)
|
||||
|
||||
+13
-6
@@ -3188,18 +3188,25 @@ dnl use "-isystem" instead of "-I" for all non-Vim include dirs.
|
||||
dnl But only when making dependencies, cproto and lint don't take "-isystem".
|
||||
dnl Mac gcc returns "powerpc-apple-darwin8-gcc-4.0.1 (GCC)...", need to allow
|
||||
dnl the number before the version number.
|
||||
AC_MSG_CHECKING(for GCC 3 or later)
|
||||
DEPEND_CFLAGS_FILTER=
|
||||
if test "$GCC" = yes; then
|
||||
AC_MSG_CHECKING(for GCC 3 or later)
|
||||
gccmajor=`echo "$gccversion" | sed -e 's/^\([[1-9]]\)\..*$/\1/g'`
|
||||
if test "$gccmajor" -gt "2"; then
|
||||
DEPEND_CFLAGS_FILTER="| sed 's+-I */+-isystem /+g'"
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
dnl -D_FORTIFY_SOURCE=2 crashes Vim on strcpy(buf, "000") when buf is
|
||||
dnl declared as char x[1] but actually longer. Introduced in gcc 4.0.
|
||||
AC_MSG_CHECKING(whether we need -D_FORTIFY_SOURCE=1)
|
||||
if test "$gccmajor" -gt "3"; then
|
||||
CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=1"
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
fi
|
||||
if test "$DEPEND_CFLAGS_FILTER" = ""; then
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
fi
|
||||
AC_SUBST(DEPEND_CFLAGS_FILTER)
|
||||
|
||||
|
||||
+27
-10
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* diff.c: code for diff'ing two or three buffers.
|
||||
* diff.c: code for diff'ing two, three or four buffers.
|
||||
*/
|
||||
|
||||
#include "vim.h"
|
||||
@@ -73,6 +73,8 @@ diff_buf_delete(buf)
|
||||
{
|
||||
tp->tp_diffbuf[i] = NULL;
|
||||
tp->tp_diff_invalid = TRUE;
|
||||
if (tp == curtab)
|
||||
diff_redraw(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,6 +104,7 @@ diff_buf_adjust(win)
|
||||
{
|
||||
curtab->tp_diffbuf[i] = NULL;
|
||||
curtab->tp_diff_invalid = TRUE;
|
||||
diff_redraw(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,7 +116,7 @@ diff_buf_adjust(win)
|
||||
* Add a buffer to make diffs for.
|
||||
* Call this when a new buffer is being edited in the current window where
|
||||
* 'diff' is set.
|
||||
* Marks the current buffer as being part of the diff and requireing updating.
|
||||
* Marks the current buffer as being part of the diff and requiring updating.
|
||||
* This must be done before any autocmd, because a command may use info
|
||||
* about the screen contents.
|
||||
*/
|
||||
@@ -131,6 +134,7 @@ diff_buf_add(buf)
|
||||
{
|
||||
curtab->tp_diffbuf[i] = buf;
|
||||
curtab->tp_diff_invalid = TRUE;
|
||||
diff_redraw(TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -661,6 +665,7 @@ ex_diffupdate(eap)
|
||||
char_u *tmp_diff;
|
||||
FILE *fd;
|
||||
int ok;
|
||||
int io_error = FALSE;
|
||||
|
||||
/* Delete all diffblocks. */
|
||||
diff_clear(curtab);
|
||||
@@ -697,18 +702,26 @@ ex_diffupdate(eap)
|
||||
{
|
||||
ok = FALSE;
|
||||
fd = mch_fopen((char *)tmp_orig, "w");
|
||||
if (fd != NULL)
|
||||
if (fd == NULL)
|
||||
io_error = TRUE;
|
||||
else
|
||||
{
|
||||
fwrite("line1\n", (size_t)6, (size_t)1, fd);
|
||||
if (fwrite("line1\n", (size_t)6, (size_t)1, fd) != 1)
|
||||
io_error = TRUE;
|
||||
fclose(fd);
|
||||
fd = mch_fopen((char *)tmp_new, "w");
|
||||
if (fd != NULL)
|
||||
if (fd == NULL)
|
||||
io_error = TRUE;
|
||||
else
|
||||
{
|
||||
fwrite("line2\n", (size_t)6, (size_t)1, fd);
|
||||
if (fwrite("line2\n", (size_t)6, (size_t)1, fd) != 1)
|
||||
io_error = TRUE;
|
||||
fclose(fd);
|
||||
diff_file(tmp_orig, tmp_new, tmp_diff);
|
||||
fd = mch_fopen((char *)tmp_diff, "r");
|
||||
if (fd != NULL)
|
||||
if (fd == NULL)
|
||||
io_error = TRUE;
|
||||
else
|
||||
{
|
||||
char_u linebuf[LBUFLEN];
|
||||
|
||||
@@ -761,6 +774,8 @@ ex_diffupdate(eap)
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
if (io_error)
|
||||
EMSG(_("E810: Cannot read or write temp files"));
|
||||
EMSG(_("E97: Cannot create diffs"));
|
||||
diff_a_works = MAYBE;
|
||||
#if defined(MSWIN) || defined(MSDOS)
|
||||
@@ -914,7 +929,7 @@ ex_diffpatch(eap)
|
||||
goto theend;
|
||||
|
||||
#ifdef UNIX
|
||||
/* Temporaraly chdir to /tmp, to avoid patching files in the current
|
||||
/* Temporarily chdir to /tmp, to avoid patching files in the current
|
||||
* directory when the patch file contains more than one patch. When we
|
||||
* have our own temp dir use that instead, it will be cleaned up when we
|
||||
* exit (any .rej files created). Don't change directory if we can't
|
||||
@@ -925,10 +940,10 @@ ex_diffpatch(eap)
|
||||
{
|
||||
# ifdef TEMPDIRNAMES
|
||||
if (vim_tempdir != NULL)
|
||||
mch_chdir((char *)vim_tempdir);
|
||||
ignored = mch_chdir((char *)vim_tempdir);
|
||||
else
|
||||
# endif
|
||||
mch_chdir("/tmp");
|
||||
ignored = mch_chdir("/tmp");
|
||||
shorten_fnames(TRUE);
|
||||
}
|
||||
#endif
|
||||
@@ -2114,6 +2129,8 @@ ex_diffgetput(eap)
|
||||
EMSG2(_("E102: Can't find buffer \"%s\""), eap->arg);
|
||||
return;
|
||||
}
|
||||
if (buf == curbuf)
|
||||
return; /* nothing to do */
|
||||
idx_other = diff_buf_idx(buf);
|
||||
if (idx_other == DB_COUNT)
|
||||
{
|
||||
|
||||
+77
-20
@@ -147,6 +147,7 @@ static void ins_compl_clear __ARGS((void));
|
||||
static int ins_compl_bs __ARGS((void));
|
||||
static void ins_compl_new_leader __ARGS((void));
|
||||
static void ins_compl_addleader __ARGS((int c));
|
||||
static int ins_compl_len __ARGS((void));
|
||||
static void ins_compl_restart __ARGS((void));
|
||||
static void ins_compl_set_original_text __ARGS((char_u *str));
|
||||
static void ins_compl_addfrommatch __ARGS((void));
|
||||
@@ -197,7 +198,8 @@ static void replace_pop_ins __ARGS((void));
|
||||
static void mb_replace_pop_ins __ARGS((int cc));
|
||||
#endif
|
||||
static void replace_flush __ARGS((void));
|
||||
static void replace_do_bs __ARGS((void));
|
||||
static void replace_do_bs __ARGS((int limit_col));
|
||||
static int del_char_after_col __ARGS((int limit_col));
|
||||
#ifdef FEAT_CINDENT
|
||||
static int cindent_on __ARGS((void));
|
||||
#endif
|
||||
@@ -1933,6 +1935,8 @@ truncate_spaces(line)
|
||||
/*
|
||||
* Backspace the cursor until the given column. Handles REPLACE and VREPLACE
|
||||
* modes correctly. May also be used when not in insert mode at all.
|
||||
* Will attempt not to go before "col" even when there is a composing
|
||||
* character.
|
||||
*/
|
||||
void
|
||||
backspace_until_column(col)
|
||||
@@ -1942,13 +1946,50 @@ backspace_until_column(col)
|
||||
{
|
||||
curwin->w_cursor.col--;
|
||||
if (State & REPLACE_FLAG)
|
||||
replace_do_bs();
|
||||
else
|
||||
(void)del_char(FALSE);
|
||||
replace_do_bs(col);
|
||||
else if (!del_char_after_col(col))
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Like del_char(), but make sure not to go before column "limit_col".
|
||||
* Only matters when there are composing characters.
|
||||
* Return TRUE when something was deleted.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
del_char_after_col(limit_col)
|
||||
int limit_col;
|
||||
{
|
||||
#ifdef FEAT_MBYTE
|
||||
if (enc_utf8 && limit_col >= 0)
|
||||
{
|
||||
int ecol = curwin->w_cursor.col + 1;
|
||||
|
||||
/* Make sure the cursor is at the start of a character, but
|
||||
* skip forward again when going too far back because of a
|
||||
* composing character. */
|
||||
mb_adjust_cursor();
|
||||
while (curwin->w_cursor.col < (colnr_T)limit_col)
|
||||
{
|
||||
int l = utf_ptr2len(ml_get_cursor());
|
||||
|
||||
if (l == 0) /* end of line */
|
||||
break;
|
||||
curwin->w_cursor.col += l;
|
||||
}
|
||||
if (*ml_get_cursor() == NUL || curwin->w_cursor.col == ecol)
|
||||
return FALSE;
|
||||
del_bytes((long)(ecol - curwin->w_cursor.col), FALSE, TRUE);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
(void)del_char(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if defined(FEAT_INS_EXPAND) || defined(PROTO)
|
||||
/*
|
||||
* CTRL-X pressed in Insert mode.
|
||||
@@ -2418,7 +2459,7 @@ ins_compl_longest_match(match)
|
||||
{
|
||||
had_match = (curwin->w_cursor.col > compl_col);
|
||||
ins_compl_delete();
|
||||
ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
|
||||
ins_bytes(compl_leader + ins_compl_len());
|
||||
ins_redraw(FALSE);
|
||||
|
||||
/* When the match isn't there (to avoid matching itself) remove it
|
||||
@@ -2470,7 +2511,7 @@ ins_compl_longest_match(match)
|
||||
*p = NUL;
|
||||
had_match = (curwin->w_cursor.col > compl_col);
|
||||
ins_compl_delete();
|
||||
ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
|
||||
ins_bytes(compl_leader + ins_compl_len());
|
||||
ins_redraw(FALSE);
|
||||
|
||||
/* When the match isn't there (to avoid matching itself) remove it
|
||||
@@ -3209,7 +3250,7 @@ ins_compl_new_leader()
|
||||
{
|
||||
ins_compl_del_pum();
|
||||
ins_compl_delete();
|
||||
ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
|
||||
ins_bytes(compl_leader + ins_compl_len());
|
||||
compl_used_match = FALSE;
|
||||
|
||||
if (compl_started)
|
||||
@@ -3263,6 +3304,20 @@ ins_compl_new_leader()
|
||||
compl_enter_selects = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the length of the completion, from the completion start column to
|
||||
* the cursor column. Making sure it never goes below zero.
|
||||
*/
|
||||
static int
|
||||
ins_compl_len()
|
||||
{
|
||||
int off = curwin->w_cursor.col - compl_col;
|
||||
|
||||
if (off < 0)
|
||||
return 0;
|
||||
return off;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append one character to the match leader. May reduce the number of
|
||||
* matches.
|
||||
@@ -3621,10 +3676,9 @@ ins_compl_prep(c)
|
||||
{
|
||||
ins_compl_delete();
|
||||
if (compl_leader != NULL)
|
||||
ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
|
||||
ins_bytes(compl_leader + ins_compl_len());
|
||||
else if (compl_first_match != NULL)
|
||||
ins_bytes(compl_orig_text
|
||||
+ curwin->w_cursor.col - compl_col);
|
||||
ins_bytes(compl_orig_text + ins_compl_len());
|
||||
retval = TRUE;
|
||||
}
|
||||
|
||||
@@ -4187,7 +4241,7 @@ ins_compl_get_exp(ini)
|
||||
}
|
||||
|
||||
/* check if compl_curr_match has changed, (e.g. other type of
|
||||
* expansion added somenthing) */
|
||||
* expansion added something) */
|
||||
if (type != 0 && compl_curr_match != old_match)
|
||||
found_new_match = OK;
|
||||
|
||||
@@ -4256,7 +4310,7 @@ ins_compl_delete()
|
||||
static void
|
||||
ins_compl_insert()
|
||||
{
|
||||
ins_bytes(compl_shown_match->cp_str + curwin->w_cursor.col - compl_col);
|
||||
ins_bytes(compl_shown_match->cp_str + ins_compl_len());
|
||||
if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
|
||||
compl_used_match = FALSE;
|
||||
else
|
||||
@@ -4425,7 +4479,7 @@ ins_compl_next(allow_get_expansion, count, insert_match)
|
||||
if (!compl_get_longest || compl_used_match)
|
||||
ins_compl_insert();
|
||||
else
|
||||
ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
|
||||
ins_bytes(compl_leader + ins_compl_len());
|
||||
}
|
||||
else
|
||||
compl_used_match = FALSE;
|
||||
@@ -4688,7 +4742,7 @@ ins_complete(c)
|
||||
}
|
||||
compl_length = curwin->w_cursor.col - (int)compl_col;
|
||||
/* IObuff is used to add a "word from the next line" would we
|
||||
* have enough space? just being paranoic */
|
||||
* have enough space? just being paranoid */
|
||||
#define MIN_SPACE 75
|
||||
if (compl_length > (IOSIZE - MIN_SPACE))
|
||||
{
|
||||
@@ -7123,9 +7177,12 @@ replace_flush()
|
||||
* cc == 0: character was inserted, delete it
|
||||
* cc > 0: character was replaced, put cc (first byte of original char) back
|
||||
* and check for more characters to be put back
|
||||
* When "limit_col" is >= 0, don't delete before this column. Matters when
|
||||
* using composing characters, use del_char_after_col() instead of del_char().
|
||||
*/
|
||||
static void
|
||||
replace_do_bs()
|
||||
replace_do_bs(limit_col)
|
||||
int limit_col;
|
||||
{
|
||||
int cc;
|
||||
#ifdef FEAT_VREPLACE
|
||||
@@ -7153,7 +7210,7 @@ replace_do_bs()
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte)
|
||||
{
|
||||
del_char(FALSE);
|
||||
(void)del_char_after_col(limit_col);
|
||||
# ifdef FEAT_VREPLACE
|
||||
if (State & VREPLACE_FLAG)
|
||||
orig_len = (int)STRLEN(ml_get_cursor());
|
||||
@@ -7203,7 +7260,7 @@ replace_do_bs()
|
||||
changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
|
||||
}
|
||||
else if (cc == 0)
|
||||
(void)del_char(FALSE);
|
||||
(void)del_char_after_col(limit_col);
|
||||
}
|
||||
|
||||
#ifdef FEAT_CINDENT
|
||||
@@ -8150,7 +8207,7 @@ ins_ctrl_o()
|
||||
/*
|
||||
* If the cursor is on an indent, ^T/^D insert/delete one
|
||||
* shiftwidth. Otherwise ^T/^D behave like a "<<" or ">>".
|
||||
* Always round the indent to 'shiftwith', this is compatible
|
||||
* Always round the indent to 'shiftwidth', this is compatible
|
||||
* with vi. But vi only supports ^T and ^D after an
|
||||
* autoindent, we support it everywhere.
|
||||
*/
|
||||
@@ -8239,7 +8296,7 @@ ins_bs_one(vcolp)
|
||||
* Replace mode */
|
||||
if (curwin->w_cursor.lnum != Insstart.lnum
|
||||
|| curwin->w_cursor.col >= Insstart.col)
|
||||
replace_do_bs();
|
||||
replace_do_bs(-1);
|
||||
}
|
||||
else
|
||||
(void)del_char(FALSE);
|
||||
@@ -8556,7 +8613,7 @@ ins_bs(c, mode, inserted_space_p)
|
||||
break;
|
||||
}
|
||||
if (State & REPLACE_FLAG)
|
||||
replace_do_bs();
|
||||
replace_do_bs(-1);
|
||||
else
|
||||
{
|
||||
#ifdef FEAT_MBYTE
|
||||
|
||||
+343
-88
@@ -32,6 +32,9 @@
|
||||
|
||||
#define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */
|
||||
|
||||
#define DO_NOT_FREE_CNT 99999 /* refcount for dict or list that should not
|
||||
be freed. */
|
||||
|
||||
/*
|
||||
* In a hashtab item "hi_key" points to "di_key" in a dictitem.
|
||||
* This avoids adding a pointer to the hashtab item.
|
||||
@@ -348,6 +351,7 @@ static struct vimvar
|
||||
{VV_NAME("mouse_col", VAR_NUMBER), 0},
|
||||
{VV_NAME("operator", VAR_STRING), VV_RO},
|
||||
{VV_NAME("searchforward", VAR_NUMBER), 0},
|
||||
{VV_NAME("oldfiles", VAR_LIST), 0},
|
||||
};
|
||||
|
||||
/* shorthand */
|
||||
@@ -355,6 +359,7 @@ static struct vimvar
|
||||
#define vv_nr vv_di.di_tv.vval.v_number
|
||||
#define vv_float vv_di.di_tv.vval.v_float
|
||||
#define vv_str vv_di.di_tv.vval.v_string
|
||||
#define vv_list vv_di.di_tv.vval.v_list
|
||||
#define vv_tv vv_di.di_tv
|
||||
|
||||
/*
|
||||
@@ -426,7 +431,6 @@ static long list_find_nr __ARGS((list_T *l, long idx, int *errorp));
|
||||
static long list_idx_of_item __ARGS((list_T *l, listitem_T *item));
|
||||
static void list_append __ARGS((list_T *l, listitem_T *item));
|
||||
static int list_append_tv __ARGS((list_T *l, typval_T *tv));
|
||||
static int list_append_string __ARGS((list_T *l, char_u *str, int len));
|
||||
static int list_append_number __ARGS((list_T *l, varnumber_T n));
|
||||
static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item));
|
||||
static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef));
|
||||
@@ -788,6 +792,8 @@ static void func_free __ARGS((ufunc_T *fp));
|
||||
static void func_unref __ARGS((char_u *name));
|
||||
static void func_ref __ARGS((char_u *name));
|
||||
static void call_user_func __ARGS((ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, linenr_T firstline, linenr_T lastline, dict_T *selfdict));
|
||||
static int can_free_funccal __ARGS((funccall_T *fc, int copyID)) ;
|
||||
static void free_funccal __ARGS((funccall_T *fc, int free_val));
|
||||
static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr));
|
||||
static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp));
|
||||
static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off));
|
||||
@@ -845,11 +851,17 @@ eval_clear()
|
||||
p = &vimvars[i];
|
||||
if (p->vv_di.di_tv.v_type == VAR_STRING)
|
||||
{
|
||||
vim_free(p->vv_di.di_tv.vval.v_string);
|
||||
p->vv_di.di_tv.vval.v_string = NULL;
|
||||
vim_free(p->vv_str);
|
||||
p->vv_str = NULL;
|
||||
}
|
||||
else if (p->vv_di.di_tv.v_type == VAR_LIST)
|
||||
{
|
||||
list_unref(p->vv_list);
|
||||
p->vv_list = NULL;
|
||||
}
|
||||
}
|
||||
hash_clear(&vimvarht);
|
||||
hash_init(&vimvarht); /* garbage_collect() will access it */
|
||||
hash_clear(&compat_hashtab);
|
||||
|
||||
/* script-local variables */
|
||||
@@ -916,6 +928,10 @@ func_level(cookie)
|
||||
/* pointer to funccal for currently active function */
|
||||
funccall_T *current_funccal = NULL;
|
||||
|
||||
/* pointer to list of previously used funccal, still around because some
|
||||
* item in it is still being used. */
|
||||
funccall_T *previous_funccal = NULL;
|
||||
|
||||
/*
|
||||
* Return TRUE when a function was ended by a ":return" command.
|
||||
*/
|
||||
@@ -1256,23 +1272,26 @@ skip_expr(pp)
|
||||
|
||||
/*
|
||||
* Top level evaluation function, returning a string.
|
||||
* When "convert" is TRUE convert a List into a sequence of lines and convert
|
||||
* a Float to a String.
|
||||
* Return pointer to allocated memory, or NULL for failure.
|
||||
*/
|
||||
char_u *
|
||||
eval_to_string(arg, nextcmd, dolist)
|
||||
eval_to_string(arg, nextcmd, convert)
|
||||
char_u *arg;
|
||||
char_u **nextcmd;
|
||||
int dolist; /* turn List into sequence of lines */
|
||||
int convert;
|
||||
{
|
||||
typval_T tv;
|
||||
char_u *retval;
|
||||
garray_T ga;
|
||||
char_u numbuf[NUMBUFLEN];
|
||||
|
||||
if (eval0(arg, &tv, nextcmd, TRUE) == FAIL)
|
||||
retval = NULL;
|
||||
else
|
||||
{
|
||||
if (dolist && tv.v_type == VAR_LIST)
|
||||
if (convert && tv.v_type == VAR_LIST)
|
||||
{
|
||||
ga_init2(&ga, (int)sizeof(char), 80);
|
||||
if (tv.vval.v_list != NULL)
|
||||
@@ -1280,6 +1299,13 @@ eval_to_string(arg, nextcmd, dolist)
|
||||
ga_append(&ga, NUL);
|
||||
retval = (char_u *)ga.ga_data;
|
||||
}
|
||||
#ifdef FEAT_FLOAT
|
||||
else if (convert && tv.v_type == VAR_FLOAT)
|
||||
{
|
||||
vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float);
|
||||
retval = vim_strsave(numbuf);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
retval = vim_strsave(get_tv_string(&tv));
|
||||
clear_tv(&tv);
|
||||
@@ -3277,7 +3303,7 @@ ex_call(eap)
|
||||
|
||||
if (*startarg != '(')
|
||||
{
|
||||
EMSG2(_("E107: Missing braces: %s"), eap->arg);
|
||||
EMSG2(_("E107: Missing parentheses: %s"), eap->arg);
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -3657,8 +3683,8 @@ item_lock(tv, deep, lock)
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if typeval "tv" is locked: Either tha value is locked itself or
|
||||
* it refers to a List or Dictionary that is locked.
|
||||
* Return TRUE if typeval "tv" is locked: Either that value is locked itself
|
||||
* or it refers to a List or Dictionary that is locked.
|
||||
*/
|
||||
static int
|
||||
tv_islocked(tv)
|
||||
@@ -3902,7 +3928,7 @@ eval0(arg, rettv, nextcmd, evaluate)
|
||||
|
||||
/*
|
||||
* Handle top level expression:
|
||||
* expr1 ? expr0 : expr0
|
||||
* expr2 ? expr1 : expr1
|
||||
*
|
||||
* "arg" must point to the first non-white of the expression.
|
||||
* "arg" is advanced to the next non-white after the recognized expression.
|
||||
@@ -6046,6 +6072,25 @@ list_find_nr(l, idx, errorp)
|
||||
return get_tv_number_chk(&li->li_tv, errorp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get list item "l[idx - 1]" as a string. Returns NULL for failure.
|
||||
*/
|
||||
char_u *
|
||||
list_find_str(l, idx)
|
||||
list_T *l;
|
||||
long idx;
|
||||
{
|
||||
listitem_T *li;
|
||||
|
||||
li = list_find(l, idx - 1);
|
||||
if (li == NULL)
|
||||
{
|
||||
EMSGN(_(e_listidx), idx);
|
||||
return NULL;
|
||||
}
|
||||
return get_tv_string(&li->li_tv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate "item" list "l" and return its index.
|
||||
* Returns -1 when "item" is not in the list.
|
||||
@@ -6137,7 +6182,7 @@ list_append_dict(list, dict)
|
||||
* When "len" >= 0 use "str[len]".
|
||||
* Returns FAIL when out of memory.
|
||||
*/
|
||||
static int
|
||||
int
|
||||
list_append_string(l, str, len)
|
||||
list_T *l;
|
||||
char_u *str;
|
||||
@@ -6454,7 +6499,7 @@ garbage_collect()
|
||||
buf_T *buf;
|
||||
win_T *wp;
|
||||
int i;
|
||||
funccall_T *fc;
|
||||
funccall_T *fc, **pfc;
|
||||
int did_free = FALSE;
|
||||
#ifdef FEAT_WINDOWS
|
||||
tabpage_T *tp;
|
||||
@@ -6497,6 +6542,9 @@ garbage_collect()
|
||||
set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID);
|
||||
}
|
||||
|
||||
/* v: vars */
|
||||
set_ref_in_ht(&vimvarht, copyID);
|
||||
|
||||
/*
|
||||
* 2. Go through the list of dicts and free items without the copyID.
|
||||
*/
|
||||
@@ -6535,6 +6583,20 @@ garbage_collect()
|
||||
else
|
||||
ll = ll->lv_used_next;
|
||||
|
||||
/* check if any funccal can be freed now */
|
||||
for (pfc = &previous_funccal; *pfc != NULL; )
|
||||
{
|
||||
if (can_free_funccal(*pfc, copyID))
|
||||
{
|
||||
fc = *pfc;
|
||||
*pfc = fc->caller;
|
||||
free_funccal(fc, TRUE);
|
||||
did_free = TRUE;
|
||||
}
|
||||
else
|
||||
pfc = &(*pfc)->caller;
|
||||
}
|
||||
|
||||
return did_free;
|
||||
}
|
||||
|
||||
@@ -6587,7 +6649,7 @@ set_ref_in_item(tv, copyID)
|
||||
{
|
||||
case VAR_DICT:
|
||||
dd = tv->vval.v_dict;
|
||||
if (dd->dv_copyID != copyID)
|
||||
if (dd != NULL && dd->dv_copyID != copyID)
|
||||
{
|
||||
/* Didn't see this dict yet. */
|
||||
dd->dv_copyID = copyID;
|
||||
@@ -6597,7 +6659,7 @@ set_ref_in_item(tv, copyID)
|
||||
|
||||
case VAR_LIST:
|
||||
ll = tv->vval.v_list;
|
||||
if (ll->lv_copyID != copyID)
|
||||
if (ll != NULL && ll->lv_copyID != copyID)
|
||||
{
|
||||
/* Didn't see this list yet. */
|
||||
ll->lv_copyID = copyID;
|
||||
@@ -7525,8 +7587,8 @@ static struct fst
|
||||
{"getwinposx", 0, 0, f_getwinposx},
|
||||
{"getwinposy", 0, 0, f_getwinposy},
|
||||
{"getwinvar", 2, 2, f_getwinvar},
|
||||
{"glob", 1, 1, f_glob},
|
||||
{"globpath", 2, 2, f_globpath},
|
||||
{"glob", 1, 2, f_glob},
|
||||
{"globpath", 2, 3, f_globpath},
|
||||
{"has", 1, 1, f_has},
|
||||
{"has_key", 2, 2, f_has_key},
|
||||
{"haslocaldir", 0, 0, f_haslocaldir},
|
||||
@@ -7856,9 +7918,9 @@ get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange,
|
||||
else if (!aborting())
|
||||
{
|
||||
if (argcount == MAX_FUNC_ARGS)
|
||||
emsg_funcname("E740: Too many arguments for function %s", name);
|
||||
emsg_funcname(N_("E740: Too many arguments for function %s"), name);
|
||||
else
|
||||
emsg_funcname("E116: Invalid arguments for function %s", name);
|
||||
emsg_funcname(N_("E116: Invalid arguments for function %s"), name);
|
||||
}
|
||||
|
||||
while (--argcount >= 0)
|
||||
@@ -8091,6 +8153,7 @@ call_func(name, len, rettv, argcount, argvars, firstline, lastline,
|
||||
|
||||
/*
|
||||
* Give an error message with a function name. Handle <SNR> things.
|
||||
* "ermsg" is to be passed without translation, use N_() instead of _().
|
||||
*/
|
||||
static void
|
||||
emsg_funcname(ermsg, name)
|
||||
@@ -9518,7 +9581,7 @@ f_expand(argvars, rettv)
|
||||
else
|
||||
{
|
||||
/* When the optional second argument is non-zero, don't remove matches
|
||||
* for 'suffixes' and 'wildignore' */
|
||||
* for 'wildignore' and don't put matches for 'suffixes' at the end. */
|
||||
if (argvars[1].v_type != VAR_UNKNOWN
|
||||
&& get_tv_number_chk(&argvars[1], &error))
|
||||
flags |= WILD_KEEP_ALL;
|
||||
@@ -10300,7 +10363,8 @@ f_function(argvars, rettv)
|
||||
s = get_tv_string(&argvars[0]);
|
||||
if (s == NULL || *s == NUL || VIM_ISDIGIT(*s))
|
||||
EMSG2(_(e_invarg2), s);
|
||||
else if (!function_exists(s))
|
||||
/* Don't check an autoload name for existence here. */
|
||||
else if (vim_strchr(s, AUTOLOAD_CHAR) == NULL && !function_exists(s))
|
||||
EMSG2(_("E700: Unknown function: %s"), s);
|
||||
else
|
||||
{
|
||||
@@ -10602,7 +10666,7 @@ f_getchar(argvars, rettv)
|
||||
# ifdef FEAT_WINDOWS
|
||||
win_T *wp;
|
||||
# endif
|
||||
int n = 1;
|
||||
int winnr = 1;
|
||||
|
||||
if (row >= 0 && col >= 0)
|
||||
{
|
||||
@@ -10612,9 +10676,9 @@ f_getchar(argvars, rettv)
|
||||
(void)mouse_comp_pos(win, &row, &col, &lnum);
|
||||
# ifdef FEAT_WINDOWS
|
||||
for (wp = firstwin; wp != win; wp = wp->w_next)
|
||||
++n;
|
||||
++winnr;
|
||||
# endif
|
||||
vimvars[VV_MOUSE_WIN].vv_nr = n;
|
||||
vimvars[VV_MOUSE_WIN].vv_nr = winnr;
|
||||
vimvars[VV_MOUSE_LNUM].vv_nr = lnum;
|
||||
vimvars[VV_MOUSE_COL].vv_nr = col + 1;
|
||||
}
|
||||
@@ -11284,13 +11348,25 @@ f_glob(argvars, rettv)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
{
|
||||
int flags = WILD_SILENT|WILD_USE_NL;
|
||||
expand_T xpc;
|
||||
int error = FALSE;
|
||||
|
||||
ExpandInit(&xpc);
|
||||
xpc.xp_context = EXPAND_FILES;
|
||||
/* When the optional second argument is non-zero, don't remove matches
|
||||
* for 'wildignore' and don't put matches for 'suffixes' at the end. */
|
||||
if (argvars[1].v_type != VAR_UNKNOWN
|
||||
&& get_tv_number_chk(&argvars[1], &error))
|
||||
flags |= WILD_KEEP_ALL;
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]),
|
||||
NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL);
|
||||
if (!error)
|
||||
{
|
||||
ExpandInit(&xpc);
|
||||
xpc.xp_context = EXPAND_FILES;
|
||||
rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]),
|
||||
NULL, flags, WILD_ALL);
|
||||
}
|
||||
else
|
||||
rettv->vval.v_string = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -11301,14 +11377,22 @@ f_globpath(argvars, rettv)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
{
|
||||
int flags = 0;
|
||||
char_u buf1[NUMBUFLEN];
|
||||
char_u *file = get_tv_string_buf_chk(&argvars[1], buf1);
|
||||
int error = FALSE;
|
||||
|
||||
/* When the optional second argument is non-zero, don't remove matches
|
||||
* for 'wildignore' and don't put matches for 'suffixes' at the end. */
|
||||
if (argvars[2].v_type != VAR_UNKNOWN
|
||||
&& get_tv_number_chk(&argvars[2], &error))
|
||||
flags |= WILD_KEEP_ALL;
|
||||
rettv->v_type = VAR_STRING;
|
||||
if (file == NULL)
|
||||
if (file == NULL || error)
|
||||
rettv->vval.v_string = NULL;
|
||||
else
|
||||
rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file);
|
||||
rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file,
|
||||
flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -11794,6 +11878,10 @@ f_has(argvars, rettv)
|
||||
n = has_patch(atoi((char *)name + 5));
|
||||
else if (STRICMP(name, "vim_starting") == 0)
|
||||
n = (starting != 0);
|
||||
#ifdef FEAT_MBYTE
|
||||
else if (STRICMP(name, "multi_byte_encoding") == 0)
|
||||
n = has_mbyte;
|
||||
#endif
|
||||
#if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32)
|
||||
else if (STRICMP(name, "balloon_multiline") == 0)
|
||||
n = multiline_balloon_available();
|
||||
@@ -15858,10 +15946,9 @@ item_compare2(s1, s2)
|
||||
if (res == FAIL)
|
||||
res = ITEM_COMPARE_FAIL;
|
||||
else
|
||||
/* return value has wrong type */
|
||||
res = get_tv_number_chk(&rettv, &item_compare_func_err);
|
||||
if (item_compare_func_err)
|
||||
res = ITEM_COMPARE_FAIL;
|
||||
res = ITEM_COMPARE_FAIL; /* return value has wrong type */
|
||||
clear_tv(&rettv);
|
||||
return res;
|
||||
}
|
||||
@@ -16610,8 +16697,11 @@ f_synIDattr(argvars, rettv)
|
||||
p = highlight_has_attr(id, HL_INVERSE, modec);
|
||||
break;
|
||||
|
||||
case 's': /* standout */
|
||||
p = highlight_has_attr(id, HL_STANDOUT, modec);
|
||||
case 's':
|
||||
if (TOLOWER_ASC(what[1]) == 'p') /* sp[#] */
|
||||
p = highlight_color(id, what, modec);
|
||||
else /* standout */
|
||||
p = highlight_has_attr(id, HL_STANDOUT, modec);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
@@ -16678,7 +16768,7 @@ f_synstack(argvars, rettv)
|
||||
col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */
|
||||
|
||||
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
|
||||
&& col >= 0 && col < (long)STRLEN(ml_get(lnum))
|
||||
&& col >= 0 && (col == 0 || col < (long)STRLEN(ml_get(lnum)))
|
||||
&& rettv_list_alloc(rettv) != FAIL)
|
||||
{
|
||||
(void)syn_get_id(curwin, lnum, (colnr_T)col, FALSE, NULL, TRUE);
|
||||
@@ -18117,14 +18207,28 @@ get_vim_var_str(idx)
|
||||
}
|
||||
|
||||
/*
|
||||
* Set v:count, v:count1 and v:prevcount.
|
||||
* Get List v: variable value. Caller must take care of reference count when
|
||||
* needed.
|
||||
*/
|
||||
list_T *
|
||||
get_vim_var_list(idx)
|
||||
int idx;
|
||||
{
|
||||
return vimvars[idx].vv_list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set v:count to "count" and v:count1 to "count1".
|
||||
* When "set_prevcount" is TRUE first set v:prevcount from v:count.
|
||||
*/
|
||||
void
|
||||
set_vcount(count, count1)
|
||||
set_vcount(count, count1, set_prevcount)
|
||||
long count;
|
||||
long count1;
|
||||
int set_prevcount;
|
||||
{
|
||||
vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr;
|
||||
if (set_prevcount)
|
||||
vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr;
|
||||
vimvars[VV_COUNT].vv_nr = count;
|
||||
vimvars[VV_COUNT1].vv_nr = count1;
|
||||
}
|
||||
@@ -18151,6 +18255,20 @@ set_vim_var_string(idx, val, len)
|
||||
vimvars[idx].vv_str = vim_strnsave(val, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set List v: variable to "val".
|
||||
*/
|
||||
void
|
||||
set_vim_var_list(idx, val)
|
||||
int idx;
|
||||
list_T *val;
|
||||
{
|
||||
list_unref(vimvars[idx].vv_list);
|
||||
vimvars[idx].vv_list = val;
|
||||
if (val != NULL)
|
||||
++val->lv_refcount;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set v:register if needed.
|
||||
*/
|
||||
@@ -18888,7 +19006,7 @@ init_var_dict(dict, dict_var)
|
||||
dictitem_T *dict_var;
|
||||
{
|
||||
hash_init(&dict->dv_hashtab);
|
||||
dict->dv_refcount = 99999;
|
||||
dict->dv_refcount = DO_NOT_FREE_CNT;
|
||||
dict_var->di_tv.vval.v_dict = dict;
|
||||
dict_var->di_tv.v_type = VAR_DICT;
|
||||
dict_var->di_tv.v_lock = VAR_FIXED;
|
||||
@@ -19225,6 +19343,8 @@ tv_check_lock(lock, name)
|
||||
* Copy the values from typval_T "from" to typval_T "to".
|
||||
* When needed allocates string or increases reference count.
|
||||
* Does not make a copy of a list or dict but copies the reference!
|
||||
* It is OK for "from" and "to" to point to the same item. This is used to
|
||||
* make a copy later.
|
||||
*/
|
||||
static void
|
||||
copy_tv(from, to)
|
||||
@@ -19768,7 +19888,7 @@ ex_function(eap)
|
||||
}
|
||||
}
|
||||
else
|
||||
emsg_funcname("E123: Undefined function: %s", name);
|
||||
emsg_funcname(N_("E123: Undefined function: %s"), name);
|
||||
}
|
||||
goto ret_free;
|
||||
}
|
||||
@@ -19812,7 +19932,7 @@ ex_function(eap)
|
||||
: eval_isnamec(arg[j])))
|
||||
++j;
|
||||
if (arg[j] != NUL)
|
||||
emsg_funcname(_(e_invarg2), arg);
|
||||
emsg_funcname((char *)e_invarg2, arg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20084,7 +20204,7 @@ ex_function(eap)
|
||||
v = find_var(name, &ht);
|
||||
if (v != NULL && v->di_tv.v_type == VAR_FUNC)
|
||||
{
|
||||
emsg_funcname("E707: Function name conflicts with variable: %s",
|
||||
emsg_funcname(N_("E707: Function name conflicts with variable: %s"),
|
||||
name);
|
||||
goto erret;
|
||||
}
|
||||
@@ -20099,7 +20219,7 @@ ex_function(eap)
|
||||
}
|
||||
if (fp->uf_calls > 0)
|
||||
{
|
||||
emsg_funcname("E127: Cannot redefine function %s: It is in use",
|
||||
emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"),
|
||||
name);
|
||||
goto erret;
|
||||
}
|
||||
@@ -20610,6 +20730,9 @@ func_dump_profile(fd)
|
||||
int st_len = 0;
|
||||
|
||||
todo = (int)func_hashtab.ht_used;
|
||||
if (todo == 0)
|
||||
return; /* nothing to dump */
|
||||
|
||||
sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo));
|
||||
|
||||
for (hi = func_hashtab.ht_array; todo > 0; ++hi)
|
||||
@@ -20658,6 +20781,8 @@ func_dump_profile(fd)
|
||||
prof_self_cmp);
|
||||
prof_sort_list(fd, sorttab, st_len, "SELF", TRUE);
|
||||
}
|
||||
|
||||
vim_free(sorttab);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -21032,7 +21157,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
|
||||
char_u *save_sourcing_name;
|
||||
linenr_T save_sourcing_lnum;
|
||||
scid_T save_current_SID;
|
||||
funccall_T fc;
|
||||
funccall_T *fc;
|
||||
int save_did_emsg;
|
||||
static int depth = 0;
|
||||
dictitem_T *v;
|
||||
@@ -21058,36 +21183,37 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
|
||||
|
||||
line_breakcheck(); /* check for CTRL-C hit */
|
||||
|
||||
fc.caller = current_funccal;
|
||||
current_funccal = &fc;
|
||||
fc.func = fp;
|
||||
fc.rettv = rettv;
|
||||
fc = (funccall_T *)alloc(sizeof(funccall_T));
|
||||
fc->caller = current_funccal;
|
||||
current_funccal = fc;
|
||||
fc->func = fp;
|
||||
fc->rettv = rettv;
|
||||
rettv->vval.v_number = 0;
|
||||
fc.linenr = 0;
|
||||
fc.returned = FALSE;
|
||||
fc.level = ex_nesting_level;
|
||||
fc->linenr = 0;
|
||||
fc->returned = FALSE;
|
||||
fc->level = ex_nesting_level;
|
||||
/* Check if this function has a breakpoint. */
|
||||
fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
|
||||
fc.dbg_tick = debug_tick;
|
||||
fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
|
||||
fc->dbg_tick = debug_tick;
|
||||
|
||||
/*
|
||||
* Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables
|
||||
* Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables
|
||||
* with names up to VAR_SHORT_LEN long. This avoids having to alloc/free
|
||||
* each argument variable and saves a lot of time.
|
||||
*/
|
||||
/*
|
||||
* Init l: variables.
|
||||
*/
|
||||
init_var_dict(&fc.l_vars, &fc.l_vars_var);
|
||||
init_var_dict(&fc->l_vars, &fc->l_vars_var);
|
||||
if (selfdict != NULL)
|
||||
{
|
||||
/* Set l:self to "selfdict". Use "name" to avoid a warning from
|
||||
* some compiler that checks the destination size. */
|
||||
v = &fc.fixvar[fixvar_idx++].var;
|
||||
v = &fc->fixvar[fixvar_idx++].var;
|
||||
name = v->di_key;
|
||||
STRCPY(name, "self");
|
||||
v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX;
|
||||
hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v));
|
||||
hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v));
|
||||
v->di_tv.v_type = VAR_DICT;
|
||||
v->di_tv.v_lock = 0;
|
||||
v->di_tv.vval.v_dict = selfdict;
|
||||
@@ -21099,28 +21225,31 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
|
||||
* Set a:0 to "argcount".
|
||||
* Set a:000 to a list with room for the "..." arguments.
|
||||
*/
|
||||
init_var_dict(&fc.l_avars, &fc.l_avars_var);
|
||||
add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0",
|
||||
init_var_dict(&fc->l_avars, &fc->l_avars_var);
|
||||
add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0",
|
||||
(varnumber_T)(argcount - fp->uf_args.ga_len));
|
||||
v = &fc.fixvar[fixvar_idx++].var;
|
||||
STRCPY(v->di_key, "000");
|
||||
/* Use "name" to avoid a warning from some compiler that checks the
|
||||
* destination size. */
|
||||
v = &fc->fixvar[fixvar_idx++].var;
|
||||
name = v->di_key;
|
||||
STRCPY(name, "000");
|
||||
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
|
||||
hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v));
|
||||
hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
|
||||
v->di_tv.v_type = VAR_LIST;
|
||||
v->di_tv.v_lock = VAR_FIXED;
|
||||
v->di_tv.vval.v_list = &fc.l_varlist;
|
||||
vim_memset(&fc.l_varlist, 0, sizeof(list_T));
|
||||
fc.l_varlist.lv_refcount = 99999;
|
||||
fc.l_varlist.lv_lock = VAR_FIXED;
|
||||
v->di_tv.vval.v_list = &fc->l_varlist;
|
||||
vim_memset(&fc->l_varlist, 0, sizeof(list_T));
|
||||
fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT;
|
||||
fc->l_varlist.lv_lock = VAR_FIXED;
|
||||
|
||||
/*
|
||||
* Set a:firstline to "firstline" and a:lastline to "lastline".
|
||||
* Set a:name to named arguments.
|
||||
* Set a:N to the "..." arguments.
|
||||
*/
|
||||
add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline",
|
||||
add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline",
|
||||
(varnumber_T)firstline);
|
||||
add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline",
|
||||
add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline",
|
||||
(varnumber_T)lastline);
|
||||
for (i = 0; i < argcount; ++i)
|
||||
{
|
||||
@@ -21136,7 +21265,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
|
||||
}
|
||||
if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN)
|
||||
{
|
||||
v = &fc.fixvar[fixvar_idx++].var;
|
||||
v = &fc->fixvar[fixvar_idx++].var;
|
||||
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
|
||||
}
|
||||
else
|
||||
@@ -21148,7 +21277,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
|
||||
v->di_flags = DI_FLAGS_RO;
|
||||
}
|
||||
STRCPY(v->di_key, name);
|
||||
hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v));
|
||||
hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
|
||||
|
||||
/* Note: the values are copied directly to avoid alloc/free.
|
||||
* "argvars" must have VAR_FIXED for v_lock. */
|
||||
@@ -21157,9 +21286,9 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
|
||||
|
||||
if (ai >= 0 && ai < MAX_FUNC_ARGS)
|
||||
{
|
||||
list_append(&fc.l_varlist, &fc.l_listitems[ai]);
|
||||
fc.l_listitems[ai].li_tv = argvars[i];
|
||||
fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED;
|
||||
list_append(&fc->l_varlist, &fc->l_listitems[ai]);
|
||||
fc->l_listitems[ai].li_tv = argvars[i];
|
||||
fc->l_listitems[ai].li_tv.v_lock = VAR_FIXED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21224,7 +21353,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
|
||||
if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL))
|
||||
func_do_profile(fp);
|
||||
if (fp->uf_profiling
|
||||
|| (fc.caller != NULL && &fc.caller->func->uf_profiling))
|
||||
|| (fc->caller != NULL && fc->caller->func->uf_profiling))
|
||||
{
|
||||
++fp->uf_tm_count;
|
||||
profile_start(&call_start);
|
||||
@@ -21240,7 +21369,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
|
||||
did_emsg = FALSE;
|
||||
|
||||
/* call do_cmdline() to execute the lines */
|
||||
do_cmdline(NULL, get_func_line, (void *)&fc,
|
||||
do_cmdline(NULL, get_func_line, (void *)fc,
|
||||
DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
|
||||
|
||||
--RedrawingDisabled;
|
||||
@@ -21255,16 +21384,16 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
|
||||
|
||||
#ifdef FEAT_PROFILE
|
||||
if (do_profiling == PROF_YES && (fp->uf_profiling
|
||||
|| (fc.caller != NULL && &fc.caller->func->uf_profiling)))
|
||||
|| (fc->caller != NULL && fc->caller->func->uf_profiling)))
|
||||
{
|
||||
profile_end(&call_start);
|
||||
profile_sub_wait(&wait_start, &call_start);
|
||||
profile_add(&fp->uf_tm_total, &call_start);
|
||||
profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children);
|
||||
if (fc.caller != NULL && &fc.caller->func->uf_profiling)
|
||||
if (fc->caller != NULL && fc->caller->func->uf_profiling)
|
||||
{
|
||||
profile_add(&fc.caller->func->uf_tm_children, &call_start);
|
||||
profile_add(&fc.caller->func->uf_tml_children, &call_start);
|
||||
profile_add(&fc->caller->func->uf_tm_children, &call_start);
|
||||
profile_add(&fc->caller->func->uf_tml_children, &call_start);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -21277,9 +21406,9 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
|
||||
|
||||
if (aborting())
|
||||
smsg((char_u *)_("%s aborted"), sourcing_name);
|
||||
else if (fc.rettv->v_type == VAR_NUMBER)
|
||||
else if (fc->rettv->v_type == VAR_NUMBER)
|
||||
smsg((char_u *)_("%s returning #%ld"), sourcing_name,
|
||||
(long)fc.rettv->vval.v_number);
|
||||
(long)fc->rettv->vval.v_number);
|
||||
else
|
||||
{
|
||||
char_u buf[MSG_BUF_LEN];
|
||||
@@ -21290,7 +21419,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
|
||||
/* The value may be very long. Skip the middle part, so that we
|
||||
* have some idea how it starts and ends. smsg() would always
|
||||
* truncate it at the end. */
|
||||
s = tv2string(fc.rettv, &tofree, numbuf2, 0);
|
||||
s = tv2string(fc->rettv, &tofree, numbuf2, 0);
|
||||
if (s != NULL)
|
||||
{
|
||||
trunc_string(s, buf, MSG_BUF_CLEN);
|
||||
@@ -21326,14 +21455,84 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
|
||||
}
|
||||
|
||||
did_emsg |= save_did_emsg;
|
||||
current_funccal = fc.caller;
|
||||
|
||||
/* The a: variables typevals were not allocated, only free the allocated
|
||||
* variables. */
|
||||
vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE);
|
||||
|
||||
vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */
|
||||
current_funccal = fc->caller;
|
||||
--depth;
|
||||
|
||||
/* if the a:000 list and the a: dict are not referenced we can free the
|
||||
* funccall_T and what's in it. */
|
||||
if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT
|
||||
&& fc->l_vars.dv_refcount == DO_NOT_FREE_CNT
|
||||
&& fc->l_avars.dv_refcount == DO_NOT_FREE_CNT)
|
||||
{
|
||||
free_funccal(fc, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
hashitem_T *hi;
|
||||
listitem_T *li;
|
||||
int todo;
|
||||
|
||||
/* "fc" is still in use. This can happen when returning "a:000" or
|
||||
* assigning "l:" to a global variable.
|
||||
* Link "fc" in the list for garbage collection later. */
|
||||
fc->caller = previous_funccal;
|
||||
previous_funccal = fc;
|
||||
|
||||
/* Make a copy of the a: variables, since we didn't do that above. */
|
||||
todo = (int)fc->l_avars.dv_hashtab.ht_used;
|
||||
for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi)
|
||||
{
|
||||
if (!HASHITEM_EMPTY(hi))
|
||||
{
|
||||
--todo;
|
||||
v = HI2DI(hi);
|
||||
copy_tv(&v->di_tv, &v->di_tv);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make a copy of the a:000 items, since we didn't do that above. */
|
||||
for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
|
||||
copy_tv(&li->li_tv, &li->li_tv);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if items in "fc" do not have "copyID". That means they are not
|
||||
* referenced from anywhere.
|
||||
*/
|
||||
static int
|
||||
can_free_funccal(fc, copyID)
|
||||
funccall_T *fc;
|
||||
int copyID;
|
||||
{
|
||||
return (fc->l_varlist.lv_copyID != copyID
|
||||
&& fc->l_vars.dv_copyID != copyID
|
||||
&& fc->l_avars.dv_copyID != copyID);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free "fc" and what it contains.
|
||||
*/
|
||||
static void
|
||||
free_funccal(fc, free_val)
|
||||
funccall_T *fc;
|
||||
int free_val; /* a: vars were allocated */
|
||||
{
|
||||
listitem_T *li;
|
||||
|
||||
/* The a: variables typevals may not have been allocated, only free the
|
||||
* allocated variables. */
|
||||
vars_clear_ext(&fc->l_avars.dv_hashtab, free_val);
|
||||
|
||||
/* free all l: variables */
|
||||
vars_clear(&fc->l_vars.dv_hashtab);
|
||||
|
||||
/* Free the a:000 variables if they were allocated. */
|
||||
if (free_val)
|
||||
for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
|
||||
clear_tv(&li->li_tv);
|
||||
|
||||
vim_free(fc);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -21906,6 +22105,62 @@ last_set_msg(scriptID)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* List v:oldfiles in a nice way.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ex_oldfiles(eap)
|
||||
exarg_T *eap;
|
||||
{
|
||||
list_T *l = vimvars[VV_OLDFILES].vv_list;
|
||||
listitem_T *li;
|
||||
int nr = 0;
|
||||
|
||||
if (l == NULL)
|
||||
msg((char_u *)_("No old files"));
|
||||
else
|
||||
{
|
||||
msg_start();
|
||||
msg_scroll = TRUE;
|
||||
for (li = l->lv_first; li != NULL && !got_int; li = li->li_next)
|
||||
{
|
||||
msg_outnum((long)++nr);
|
||||
MSG_PUTS(": ");
|
||||
msg_outtrans(get_tv_string(&li->li_tv));
|
||||
msg_putchar('\n');
|
||||
out_flush(); /* output one line at a time */
|
||||
ui_breakcheck();
|
||||
}
|
||||
/* Assume "got_int" was set to truncate the listing. */
|
||||
got_int = FALSE;
|
||||
|
||||
#ifdef FEAT_BROWSE_CMD
|
||||
if (cmdmod.browse)
|
||||
{
|
||||
quit_more = FALSE;
|
||||
nr = prompt_for_number(FALSE);
|
||||
msg_starthere();
|
||||
if (nr > 0)
|
||||
{
|
||||
char_u *p = list_find_str(get_vim_var_list(VV_OLDFILES),
|
||||
(long)nr);
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
p = expand_env_save(p);
|
||||
eap->arg = p;
|
||||
eap->cmdidx = CMD_edit;
|
||||
cmdmod.browse = FALSE;
|
||||
do_exedit(eap, NULL);
|
||||
vim_free(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FEAT_EVAL */
|
||||
|
||||
|
||||
|
||||
+50
-29
@@ -24,7 +24,7 @@ static int linelen __ARGS((int *has_tab));
|
||||
static void do_filter __ARGS((linenr_T line1, linenr_T line2, exarg_T *eap, char_u *cmd, int do_in, int do_out));
|
||||
#ifdef FEAT_VIMINFO
|
||||
static char_u *viminfo_filename __ARGS((char_u *));
|
||||
static void do_viminfo __ARGS((FILE *fp_in, FILE *fp_out, int want_info, int want_marks, int force_read));
|
||||
static void do_viminfo __ARGS((FILE *fp_in, FILE *fp_out, int flags));
|
||||
static int viminfo_encoding __ARGS((vir_T *virp));
|
||||
static int read_viminfo_up_to_marks __ARGS((vir_T *virp, int forceit, int writing));
|
||||
#endif
|
||||
@@ -49,6 +49,7 @@ do_ascii(eap)
|
||||
exarg_T *eap;
|
||||
{
|
||||
int c;
|
||||
int cval;
|
||||
char buf1[20];
|
||||
char buf2[20];
|
||||
char_u buf3[7];
|
||||
@@ -75,6 +76,10 @@ do_ascii(eap)
|
||||
{
|
||||
if (c == NL) /* NUL is stored as NL */
|
||||
c = NUL;
|
||||
if (c == CAR && get_fileformat(curbuf) == EOL_MAC)
|
||||
cval = NL; /* NL is stored as CR */
|
||||
else
|
||||
cval = c;
|
||||
if (vim_isprintc_strict(c) && (c < ' '
|
||||
#ifndef EBCDIC
|
||||
|| c > '~'
|
||||
@@ -94,7 +99,7 @@ do_ascii(eap)
|
||||
buf2[0] = NUL;
|
||||
vim_snprintf((char *)IObuff, IOSIZE,
|
||||
_("<%s>%s%s %d, Hex %02x, Octal %03o"),
|
||||
transchar(c), buf1, buf2, c, c, c);
|
||||
transchar(c), buf1, buf2, cval, cval, cval);
|
||||
#ifdef FEAT_MBYTE
|
||||
if (enc_utf8)
|
||||
c = cc[ci++];
|
||||
@@ -1676,14 +1681,12 @@ viminfo_error(errnum, message, line)
|
||||
|
||||
/*
|
||||
* read_viminfo() -- Read the viminfo file. Registers etc. which are already
|
||||
* set are not over-written unless force is TRUE. -- webb
|
||||
* set are not over-written unless "flags" includes VIF_FORCEIT. -- webb
|
||||
*/
|
||||
int
|
||||
read_viminfo(file, want_info, want_marks, forceit)
|
||||
char_u *file;
|
||||
int want_info;
|
||||
int want_marks;
|
||||
int forceit;
|
||||
read_viminfo(file, flags)
|
||||
char_u *file; /* file name or NULL to use default name */
|
||||
int flags; /* VIF_WANT_INFO et al. */
|
||||
{
|
||||
FILE *fp;
|
||||
char_u *fname;
|
||||
@@ -1691,7 +1694,7 @@ read_viminfo(file, want_info, want_marks, forceit)
|
||||
if (no_viminfo())
|
||||
return FAIL;
|
||||
|
||||
fname = viminfo_filename(file); /* may set to default if NULL */
|
||||
fname = viminfo_filename(file); /* get file name in allocated buffer */
|
||||
if (fname == NULL)
|
||||
return FAIL;
|
||||
fp = mch_fopen((char *)fname, READBIN);
|
||||
@@ -1701,8 +1704,9 @@ read_viminfo(file, want_info, want_marks, forceit)
|
||||
verbose_enter();
|
||||
smsg((char_u *)_("Reading viminfo file \"%s\"%s%s%s"),
|
||||
fname,
|
||||
want_info ? _(" info") : "",
|
||||
want_marks ? _(" marks") : "",
|
||||
(flags & VIF_WANT_INFO) ? _(" info") : "",
|
||||
(flags & VIF_WANT_MARKS) ? _(" marks") : "",
|
||||
(flags & VIF_GET_OLDFILES) ? _(" oldfiles") : "",
|
||||
fp == NULL ? _(" FAILED") : "");
|
||||
verbose_leave();
|
||||
}
|
||||
@@ -1712,10 +1716,9 @@ read_viminfo(file, want_info, want_marks, forceit)
|
||||
return FAIL;
|
||||
|
||||
viminfo_errcnt = 0;
|
||||
do_viminfo(fp, NULL, want_info, want_marks, forceit);
|
||||
do_viminfo(fp, NULL, flags);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1943,7 +1946,7 @@ write_viminfo(file, forceit)
|
||||
* root.
|
||||
*/
|
||||
if (fp_out != NULL)
|
||||
(void)fchown(fileno(fp_out), st_old.st_uid, st_old.st_gid);
|
||||
ignored = fchown(fileno(fp_out), st_old.st_uid, st_old.st_gid);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1968,7 +1971,7 @@ write_viminfo(file, forceit)
|
||||
}
|
||||
|
||||
viminfo_errcnt = 0;
|
||||
do_viminfo(fp_in, fp_out, !forceit, !forceit, FALSE);
|
||||
do_viminfo(fp_in, fp_out, forceit ? 0 : (VIF_WANT_INFO | VIF_WANT_MARKS));
|
||||
|
||||
fclose(fp_out); /* errors are ignored !? */
|
||||
if (fp_in != NULL)
|
||||
@@ -2041,12 +2044,10 @@ viminfo_filename(file)
|
||||
* do_viminfo() -- Should only be called from read_viminfo() & write_viminfo().
|
||||
*/
|
||||
static void
|
||||
do_viminfo(fp_in, fp_out, want_info, want_marks, force_read)
|
||||
do_viminfo(fp_in, fp_out, flags)
|
||||
FILE *fp_in;
|
||||
FILE *fp_out;
|
||||
int want_info;
|
||||
int want_marks;
|
||||
int force_read;
|
||||
int flags;
|
||||
{
|
||||
int count = 0;
|
||||
int eof = FALSE;
|
||||
@@ -2061,8 +2062,9 @@ do_viminfo(fp_in, fp_out, want_info, want_marks, force_read)
|
||||
|
||||
if (fp_in != NULL)
|
||||
{
|
||||
if (want_info)
|
||||
eof = read_viminfo_up_to_marks(&vir, force_read, fp_out != NULL);
|
||||
if (flags & VIF_WANT_INFO)
|
||||
eof = read_viminfo_up_to_marks(&vir,
|
||||
flags & VIF_FORCEIT, fp_out != NULL);
|
||||
else
|
||||
/* Skip info, find start of marks */
|
||||
while (!(eof = viminfo_readline(&vir))
|
||||
@@ -2092,8 +2094,9 @@ do_viminfo(fp_in, fp_out, want_info, want_marks, force_read)
|
||||
write_viminfo_bufferlist(fp_out);
|
||||
count = write_viminfo_marks(fp_out);
|
||||
}
|
||||
if (fp_in != NULL && want_marks)
|
||||
copy_viminfo_marks(&vir, fp_out, count, eof);
|
||||
if (fp_in != NULL
|
||||
&& (flags & (VIF_WANT_MARKS | VIF_GET_OLDFILES | VIF_FORCEIT)))
|
||||
copy_viminfo_marks(&vir, fp_out, count, eof, flags);
|
||||
|
||||
vim_free(vir.vir_line);
|
||||
#ifdef FEAT_MBYTE
|
||||
@@ -2414,8 +2417,8 @@ print_line(lnum, use_number, list)
|
||||
cursor_on(); /* msg_start() switches it off */
|
||||
out_flush();
|
||||
silent_mode = save_silent;
|
||||
info_message = FALSE;
|
||||
}
|
||||
info_message = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2704,7 +2707,12 @@ do_write(eap)
|
||||
if (eap->cmdidx == CMD_saveas)
|
||||
{
|
||||
if (retval == OK)
|
||||
{
|
||||
curbuf->b_p_ro = FALSE;
|
||||
#ifdef FEAT_WINDOWS
|
||||
redraw_tabline = TRUE;
|
||||
#endif
|
||||
}
|
||||
/* Change directories when the 'acd' option is set. */
|
||||
DO_AUTOCHDIR
|
||||
}
|
||||
@@ -3054,7 +3062,8 @@ getfile(fnum, ffname, sfname, setpm, lnum, forceit)
|
||||
retval = 0; /* it's in the same file */
|
||||
}
|
||||
else if (do_ecmd(fnum, ffname, sfname, NULL, lnum,
|
||||
(P_HID(curbuf) ? ECMD_HIDE : 0) + (forceit ? ECMD_FORCEIT : 0)) == OK)
|
||||
(P_HID(curbuf) ? ECMD_HIDE : 0) + (forceit ? ECMD_FORCEIT : 0),
|
||||
curwin) == OK)
|
||||
retval = -1; /* opened another file */
|
||||
else
|
||||
retval = 1; /* error encountered */
|
||||
@@ -3087,17 +3096,21 @@ theend:
|
||||
* ECMD_OLDBUF: use existing buffer if it exists
|
||||
* ECMD_FORCEIT: ! used for Ex command
|
||||
* ECMD_ADDBUF: don't edit, just add to buffer list
|
||||
* oldwin: Should be "curwin" when editing a new buffer in the current
|
||||
* window, NULL when splitting the window first. When not NULL info
|
||||
* of the previous buffer for "oldwin" is stored.
|
||||
*
|
||||
* return FAIL for failure, OK otherwise
|
||||
*/
|
||||
int
|
||||
do_ecmd(fnum, ffname, sfname, eap, newlnum, flags)
|
||||
do_ecmd(fnum, ffname, sfname, eap, newlnum, flags, oldwin)
|
||||
int fnum;
|
||||
char_u *ffname;
|
||||
char_u *sfname;
|
||||
exarg_T *eap; /* can be NULL! */
|
||||
linenr_T newlnum;
|
||||
int flags;
|
||||
win_T *oldwin;
|
||||
{
|
||||
int other_file; /* TRUE if editing another file */
|
||||
int oldbuf; /* TRUE if using existing buffer */
|
||||
@@ -3269,7 +3282,8 @@ do_ecmd(fnum, ffname, sfname, eap, newlnum, flags)
|
||||
{
|
||||
if (!cmdmod.keepalt)
|
||||
curwin->w_alt_fnum = curbuf->b_fnum;
|
||||
buflist_altfpos();
|
||||
if (oldwin != NULL)
|
||||
buflist_altfpos(oldwin);
|
||||
}
|
||||
|
||||
if (fnum)
|
||||
@@ -3373,7 +3387,7 @@ do_ecmd(fnum, ffname, sfname, eap, newlnum, flags)
|
||||
|
||||
/* close the link to the current buffer */
|
||||
u_sync(FALSE);
|
||||
close_buffer(curwin, curbuf,
|
||||
close_buffer(oldwin, curbuf,
|
||||
(flags & ECMD_HIDE) ? 0 : DOBUF_UNLOAD);
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
@@ -5059,6 +5073,7 @@ skip:
|
||||
|
||||
if (did_sub)
|
||||
++sub_nlines;
|
||||
vim_free(new_start); /* for when substitute was cancelled */
|
||||
vim_free(sub_firstline); /* free the copy of the original line */
|
||||
sub_firstline = NULL;
|
||||
}
|
||||
@@ -5610,7 +5625,13 @@ ex_help(eap)
|
||||
*/
|
||||
alt_fnum = curbuf->b_fnum;
|
||||
(void)do_ecmd(0, NULL, NULL, NULL, ECMD_LASTL,
|
||||
ECMD_HIDE + ECMD_SET_HELP);
|
||||
ECMD_HIDE + ECMD_SET_HELP,
|
||||
#ifdef FEAT_WINDOWS
|
||||
NULL /* buffer is still open, don't store info */
|
||||
#else
|
||||
curwin
|
||||
#endif
|
||||
);
|
||||
if (!cmdmod.keepalt)
|
||||
curwin->w_alt_fnum = alt_fnum;
|
||||
empty_fnum = curbuf->b_fnum;
|
||||
|
||||
+7
-3
@@ -278,7 +278,7 @@ EX(CMD_cquit, "cquit", ex_cquit,
|
||||
EX(CMD_crewind, "crewind", ex_cc,
|
||||
RANGE|NOTADR|COUNT|TRLBAR|BANG),
|
||||
EX(CMD_cscope, "cscope", do_cscope,
|
||||
EXTRA|NOTRLCOM|SBOXOK|XFILE),
|
||||
EXTRA|NOTRLCOM|XFILE),
|
||||
EX(CMD_cstag, "cstag", do_cstag,
|
||||
BANG|TRLBAR|WORD1),
|
||||
EX(CMD_cunmap, "cunmap", ex_unmap,
|
||||
@@ -506,7 +506,7 @@ EX(CMD_lchdir, "lchdir", ex_cd,
|
||||
EX(CMD_lclose, "lclose", ex_cclose,
|
||||
RANGE|NOTADR|COUNT|TRLBAR),
|
||||
EX(CMD_lcscope, "lcscope", do_cscope,
|
||||
EXTRA|NOTRLCOM|SBOXOK|XFILE),
|
||||
EXTRA|NOTRLCOM|XFILE),
|
||||
EX(CMD_left, "left", ex_align,
|
||||
TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
|
||||
EX(CMD_leftabove, "leftabove", ex_wrongmodifier,
|
||||
@@ -639,6 +639,8 @@ EX(CMD_nnoremenu, "nnoremenu", ex_menu,
|
||||
RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
|
||||
EX(CMD_noremap, "noremap", ex_map,
|
||||
BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
|
||||
EX(CMD_noautocmd, "noautocmd", ex_wrongmodifier,
|
||||
NEEDARG|EXTRA|NOTRLCOM),
|
||||
EX(CMD_nohlsearch, "nohlsearch", ex_nohlsearch,
|
||||
TRLBAR|SBOXOK|CMDWIN),
|
||||
EX(CMD_noreabbrev, "noreabbrev", ex_abbreviate,
|
||||
@@ -655,6 +657,8 @@ EX(CMD_nunmenu, "nunmenu", ex_menu,
|
||||
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
|
||||
EX(CMD_open, "open", ex_open,
|
||||
RANGE|EXTRA),
|
||||
EX(CMD_oldfiles, "oldfiles", ex_oldfiles,
|
||||
BANG|TRLBAR|SBOXOK|CMDWIN),
|
||||
EX(CMD_omap, "omap", ex_map,
|
||||
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
|
||||
EX(CMD_omapclear, "omapclear", ex_mapclear,
|
||||
@@ -806,7 +810,7 @@ EX(CMD_scriptnames, "scriptnames", ex_scriptnames,
|
||||
EX(CMD_scriptencoding, "scriptencoding", ex_scriptencoding,
|
||||
WORD1|TRLBAR|CMDWIN),
|
||||
EX(CMD_scscope, "scscope", do_scscope,
|
||||
EXTRA|NOTRLCOM|SBOXOK),
|
||||
EXTRA|NOTRLCOM),
|
||||
EX(CMD_set, "set", ex_set,
|
||||
TRLBAR|EXTRA|CMDWIN|SBOXOK),
|
||||
EX(CMD_setfiletype, "setfiletype", ex_setfiletype,
|
||||
|
||||
+101
-23
@@ -1417,6 +1417,63 @@ browse_save_fname(buf)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
/*
|
||||
* "Save changes" dialog that conforms to the Apple HIG.
|
||||
*/
|
||||
int
|
||||
vim_dialog_save_changes(buf)
|
||||
buf_T *buf;
|
||||
{
|
||||
char_u buff[IOSIZE];
|
||||
|
||||
dialog_msg(buff, _("Do you want to save the changes you made in the "
|
||||
"document \"%s\"?"), buf->b_fname);
|
||||
switch (do_dialog(VIM_QUESTION, buff,
|
||||
(char_u*) _("Your changes will be lost if you don't save "
|
||||
"them."),
|
||||
(buf->b_fname != NULL)
|
||||
? (char_u *)_("&Save\n&Cancel\n&Don't Save")
|
||||
: (char_u *)_("&Save...\n&Cancel\n&Don't Save"),
|
||||
1, NULL))
|
||||
{
|
||||
case 1: return VIM_YES;
|
||||
case 3: return VIM_NO;
|
||||
}
|
||||
|
||||
return VIM_CANCEL;
|
||||
}
|
||||
|
||||
/*
|
||||
* "Save all changes" dialog that tries to emulate the above "Save changes"
|
||||
* dialog for the case of several modified buffers.
|
||||
*/
|
||||
int
|
||||
vim_dialog_save_all_changes(buf)
|
||||
buf_T *buf;
|
||||
{
|
||||
char_u buff[IOSIZE];
|
||||
|
||||
dialog_msg(buff, _("There are several documents with unsaved changes. "
|
||||
"Do you want to save the changes you made in the "
|
||||
"document \"%s\"?"), buf->b_fname);
|
||||
switch (do_dialog(VIM_QUESTION, buff,
|
||||
(char_u*) _("Your changes will be lost if you don't save "
|
||||
"them."),
|
||||
(char_u *)_("&Save\n&Don't Save\nS&ave All\nD&iscard All\n"
|
||||
"&Cancel"),
|
||||
1, NULL))
|
||||
{
|
||||
case 1: return VIM_YES;
|
||||
case 2: return VIM_NO;
|
||||
case 3: return VIM_ALL;
|
||||
case 4: return VIM_DISCARDALL;
|
||||
}
|
||||
|
||||
return VIM_CANCEL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Ask the user what to do when abondoning a changed buffer.
|
||||
* Must check 'write' option first!
|
||||
@@ -1430,6 +1487,19 @@ dialog_changed(buf, checkall)
|
||||
int ret;
|
||||
buf_T *buf2;
|
||||
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
/* Save dialogs on Mac OS X are standardized so in case the GUI is enabled
|
||||
* and "c" isn't in 'guioptions' we use a OS X specific dialog. */
|
||||
if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL)
|
||||
{
|
||||
if (checkall)
|
||||
ret = vim_dialog_save_all_changes(buf);
|
||||
else
|
||||
ret = vim_dialog_save_changes(buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
dialog_msg(buff, _("Save changes to \"%s\"?"),
|
||||
(buf->b_fname != NULL) ?
|
||||
buf->b_fname : (char_u *)_("Untitled"));
|
||||
@@ -1437,6 +1507,9 @@ dialog_changed(buf, checkall)
|
||||
ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1);
|
||||
else
|
||||
ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1);
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret == VIM_YES)
|
||||
{
|
||||
@@ -2132,8 +2205,8 @@ do_argfile(eap, argn)
|
||||
* argument index. */
|
||||
if (do_ecmd(0, alist_name(&ARGLIST[curwin->w_arg_idx]), NULL,
|
||||
eap, ECMD_LAST,
|
||||
(P_HID(curwin->w_buffer) ? ECMD_HIDE : 0) +
|
||||
(eap->forceit ? ECMD_FORCEIT : 0)) == FAIL)
|
||||
(P_HID(curwin->w_buffer) ? ECMD_HIDE : 0)
|
||||
+ (eap->forceit ? ECMD_FORCEIT : 0), curwin) == FAIL)
|
||||
curwin->w_arg_idx = old_arg_idx;
|
||||
/* like Vi: set the mark where the cursor is in the file. */
|
||||
else if (eap->cmdidx != CMD_argdo)
|
||||
@@ -2842,6 +2915,7 @@ do_source(fname, check_other, is_vimrc)
|
||||
linenr_T save_sourcing_lnum;
|
||||
char_u *p;
|
||||
char_u *fname_exp;
|
||||
char_u *firstline = NULL;
|
||||
int retval = FAIL;
|
||||
#ifdef FEAT_EVAL
|
||||
scid_T save_current_SID;
|
||||
@@ -2992,23 +3066,6 @@ do_source(fname, check_other, is_vimrc)
|
||||
|
||||
cookie.level = ex_nesting_level;
|
||||
#endif
|
||||
#ifdef FEAT_MBYTE
|
||||
cookie.conv.vc_type = CONV_NONE; /* no conversion */
|
||||
|
||||
/* Try reading the first few bytes to check for a UTF-8 BOM. */
|
||||
{
|
||||
char_u buf[3];
|
||||
|
||||
if (fread((char *)buf, sizeof(char_u), (size_t)3, cookie.fp)
|
||||
== (size_t)3
|
||||
&& buf[0] == 0xef && buf[1] == 0xbb && buf[2] == 0xbf)
|
||||
/* Found BOM, setup conversion and skip over it. */
|
||||
convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc);
|
||||
else
|
||||
/* No BOM found, rewind. */
|
||||
fseek(cookie.fp, 0L, SEEK_SET);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Keep the sourcing name/lnum, for recursive calls.
|
||||
@@ -3018,6 +3075,27 @@ do_source(fname, check_other, is_vimrc)
|
||||
save_sourcing_lnum = sourcing_lnum;
|
||||
sourcing_lnum = 0;
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
cookie.conv.vc_type = CONV_NONE; /* no conversion */
|
||||
|
||||
/* Read the first line so we can check for a UTF-8 BOM. */
|
||||
firstline = getsourceline(0, (void *)&cookie, 0);
|
||||
if (firstline != NULL && STRLEN(firstline) >= 3 && firstline[0] == 0xef
|
||||
&& firstline[1] == 0xbb && firstline[2] == 0xbf)
|
||||
{
|
||||
/* Found BOM; setup conversion, skip over BOM and recode the line. */
|
||||
convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc);
|
||||
p = string_convert(&cookie.conv, firstline + 3, NULL);
|
||||
if (p == NULL)
|
||||
p = vim_strsave(firstline + 3);
|
||||
if (p != NULL)
|
||||
{
|
||||
vim_free(firstline);
|
||||
firstline = p;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef STARTUPTIME
|
||||
time_push(&tv_rel, &tv_start);
|
||||
#endif
|
||||
@@ -3111,9 +3189,8 @@ do_source(fname, check_other, is_vimrc)
|
||||
/*
|
||||
* Call do_cmdline, which will call getsourceline() to get the lines.
|
||||
*/
|
||||
do_cmdline(NULL, getsourceline, (void *)&cookie,
|
||||
do_cmdline(firstline, getsourceline, (void *)&cookie,
|
||||
DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT);
|
||||
|
||||
retval = OK;
|
||||
|
||||
#ifdef FEAT_PROFILE
|
||||
@@ -3145,8 +3222,8 @@ do_source(fname, check_other, is_vimrc)
|
||||
verbose_leave();
|
||||
}
|
||||
#ifdef STARTUPTIME
|
||||
vim_snprintf(IObuff, IOSIZE, "sourcing %s", fname);
|
||||
time_msg(IObuff, &tv_start);
|
||||
vim_snprintf((char *)IObuff, IOSIZE, "sourcing %s", fname);
|
||||
time_msg((char *)IObuff, &tv_start);
|
||||
time_pop(&tv_rel);
|
||||
#endif
|
||||
|
||||
@@ -3171,6 +3248,7 @@ almosttheend:
|
||||
#endif
|
||||
fclose(cookie.fp);
|
||||
vim_free(cookie.nextline);
|
||||
vim_free(firstline);
|
||||
#ifdef FEAT_MBYTE
|
||||
convert_setup(&cookie.conv, NULL, NULL);
|
||||
#endif
|
||||
|
||||
+111
-23
@@ -220,7 +220,8 @@ static void ex_popup __ARGS((exarg_T *eap));
|
||||
#ifndef FEAT_GUI_MSWIN
|
||||
# define ex_simalt ex_ni
|
||||
#endif
|
||||
#if !defined(FEAT_GUI_MSWIN) && !defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_MOTIF)
|
||||
#if !(defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_GTK) || \
|
||||
defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_MACVIM))
|
||||
# define gui_mch_find_dialog ex_ni
|
||||
# define gui_mch_replace_dialog ex_ni
|
||||
#endif
|
||||
@@ -365,6 +366,7 @@ static void ex_tag_cmd __ARGS((exarg_T *eap, char_u *name));
|
||||
# define ex_function ex_ni
|
||||
# define ex_delfunction ex_ni
|
||||
# define ex_return ex_ni
|
||||
# define ex_oldfiles ex_ni
|
||||
#endif
|
||||
static char_u *arg_all __ARGS((void));
|
||||
#ifdef FEAT_SESSION
|
||||
@@ -1776,7 +1778,7 @@ do_one_cmd(cmdlinep, sourcing,
|
||||
}
|
||||
if (checkforcmd(&ea.cmd, "browse", 3))
|
||||
{
|
||||
#ifdef FEAT_BROWSE
|
||||
#ifdef FEAT_BROWSE_CMD
|
||||
cmdmod.browse = TRUE;
|
||||
#endif
|
||||
continue;
|
||||
@@ -2984,6 +2986,7 @@ static struct cmdmod
|
||||
{"keepmarks", 3, FALSE},
|
||||
{"leftabove", 5, FALSE},
|
||||
{"lockmarks", 3, FALSE},
|
||||
{"noautocmd", 3, FALSE},
|
||||
{"rightbelow", 6, FALSE},
|
||||
{"sandbox", 3, FALSE},
|
||||
{"silent", 3, FALSE},
|
||||
@@ -3614,6 +3617,7 @@ set_one_cmd_context(xp, buff)
|
||||
return set_context_in_autocmd(xp, arg, FALSE);
|
||||
|
||||
case CMD_doautocmd:
|
||||
case CMD_doautoall:
|
||||
return set_context_in_autocmd(xp, arg, TRUE);
|
||||
#endif
|
||||
case CMD_set:
|
||||
@@ -5496,6 +5500,9 @@ invalid_count:
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* ":command ..."
|
||||
*/
|
||||
static void
|
||||
ex_command(eap)
|
||||
exarg_T *eap;
|
||||
@@ -5928,6 +5935,7 @@ do_ucmd(eap)
|
||||
|
||||
char_u *start;
|
||||
char_u *end;
|
||||
char_u *ksp;
|
||||
size_t len, totlen;
|
||||
|
||||
size_t split_len = 0;
|
||||
@@ -5944,16 +5952,51 @@ do_ucmd(eap)
|
||||
|
||||
/*
|
||||
* Replace <> in the command by the arguments.
|
||||
* First round: "buf" is NULL, compute length, allocate "buf".
|
||||
* Second round: copy result into "buf".
|
||||
*/
|
||||
buf = NULL;
|
||||
for (;;)
|
||||
{
|
||||
p = cmd->uc_rep;
|
||||
q = buf;
|
||||
p = cmd->uc_rep; /* source */
|
||||
q = buf; /* destinateion */
|
||||
totlen = 0;
|
||||
while ((start = vim_strchr(p, '<')) != NULL
|
||||
&& (end = vim_strchr(start + 1, '>')) != NULL)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
start = vim_strchr(p, '<');
|
||||
if (start != NULL)
|
||||
end = vim_strchr(start + 1, '>');
|
||||
if (buf != NULL)
|
||||
{
|
||||
ksp = vim_strchr(p, K_SPECIAL);
|
||||
if (ksp != NULL && (start == NULL || ksp < start || end == NULL)
|
||||
&& ((ksp[1] == KS_SPECIAL && ksp[2] == KE_FILLER)
|
||||
# ifdef FEAT_GUI
|
||||
|| (ksp[1] == KS_EXTRA && ksp[2] == (int)KE_CSI)
|
||||
# endif
|
||||
))
|
||||
{
|
||||
/* K_SPECIAL han been put in the buffer as K_SPECIAL
|
||||
* KS_SPECIAL KE_FILLER, like for mappings, but
|
||||
* do_cmdline() doesn't handle that, so convert it back.
|
||||
* Also change K_SPECIAL KS_EXTRA KE_CSI into CSI. */
|
||||
len = ksp - p;
|
||||
if (len > 0)
|
||||
{
|
||||
mch_memmove(q, p, len);
|
||||
q += len;
|
||||
}
|
||||
*q++ = ksp[1] == KS_SPECIAL ? K_SPECIAL : CSI;
|
||||
p = ksp + 3;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* break if there no <item> is found */
|
||||
if (start == NULL || end == NULL)
|
||||
break;
|
||||
|
||||
/* Include the '>' */
|
||||
++end;
|
||||
|
||||
@@ -7503,7 +7546,8 @@ do_exedit(eap, old_curwin)
|
||||
/* ":new" or ":tabnew" without argument: edit an new empty buffer */
|
||||
setpcmark();
|
||||
(void)do_ecmd(0, NULL, NULL, eap, ECMD_ONE,
|
||||
ECMD_HIDE + (eap->forceit ? ECMD_FORCEIT : 0));
|
||||
ECMD_HIDE + (eap->forceit ? ECMD_FORCEIT : 0),
|
||||
old_curwin == NULL ? curwin : NULL);
|
||||
}
|
||||
else if ((eap->cmdidx != CMD_split
|
||||
#ifdef FEAT_VERTSPLIT
|
||||
@@ -7540,7 +7584,7 @@ do_exedit(eap, old_curwin)
|
||||
#ifdef FEAT_LISTCMDS
|
||||
+ (eap->cmdidx == CMD_badd ? ECMD_ADDBUF : 0 )
|
||||
#endif
|
||||
) == FAIL)
|
||||
, old_curwin == NULL ? curwin : NULL) == FAIL)
|
||||
{
|
||||
/* Editing the file failed. If the window was split, close it. */
|
||||
#ifdef FEAT_WINDOWS
|
||||
@@ -8768,8 +8812,8 @@ ex_mkrc(eap)
|
||||
else if (*dirnow != NUL
|
||||
&& (ssop_flags & SSOP_CURDIR) && globaldir != NULL)
|
||||
{
|
||||
(void)mch_chdir((char *)globaldir);
|
||||
shorten_fnames(TRUE);
|
||||
if (mch_chdir((char *)globaldir) == OK)
|
||||
shorten_fnames(TRUE);
|
||||
}
|
||||
|
||||
failed |= (makeopens(fd, dirnow) == FAIL);
|
||||
@@ -9525,24 +9569,50 @@ eval_vars(src, srcstart, usedlen, lnump, errormsg, escaped)
|
||||
break;
|
||||
}
|
||||
s = src + 1;
|
||||
if (*s == '<') /* "#<99" uses v:oldfiles */
|
||||
++s;
|
||||
i = (int)getdigits(&s);
|
||||
*usedlen = (int)(s - src); /* length of what we expand */
|
||||
|
||||
buf = buflist_findnr(i);
|
||||
if (buf == NULL)
|
||||
if (src[1] == '<')
|
||||
{
|
||||
*errormsg = (char_u *)_("E194: No alternate file name to substitute for '#'");
|
||||
if (*usedlen < 2)
|
||||
{
|
||||
/* Should we give an error message for #<text? */
|
||||
*usedlen = 1;
|
||||
return NULL;
|
||||
}
|
||||
#ifdef FEAT_EVAL
|
||||
result = list_find_str(get_vim_var_list(VV_OLDFILES),
|
||||
(long)i);
|
||||
if (result == NULL)
|
||||
{
|
||||
*errormsg = (char_u *)"";
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
*errormsg = (char_u *)_("E809: #< is not available without the +eval feature");
|
||||
return NULL;
|
||||
}
|
||||
if (lnump != NULL)
|
||||
*lnump = ECMD_LAST;
|
||||
if (buf->b_fname == NULL)
|
||||
{
|
||||
result = (char_u *)"";
|
||||
valid = 0; /* Must have ":p:h" to be valid */
|
||||
#endif
|
||||
}
|
||||
else
|
||||
result = buf->b_fname;
|
||||
{
|
||||
buf = buflist_findnr(i);
|
||||
if (buf == NULL)
|
||||
{
|
||||
*errormsg = (char_u *)_("E194: No alternate file name to substitute for '#'");
|
||||
return NULL;
|
||||
}
|
||||
if (lnump != NULL)
|
||||
*lnump = ECMD_LAST;
|
||||
if (buf->b_fname == NULL)
|
||||
{
|
||||
result = (char_u *)"";
|
||||
valid = 0; /* Must have ":p:h" to be valid */
|
||||
}
|
||||
else
|
||||
result = buf->b_fname;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef FEAT_SEARCHPATH
|
||||
@@ -9560,6 +9630,15 @@ eval_vars(src, srcstart, usedlen, lnump, errormsg, escaped)
|
||||
#ifdef FEAT_AUTOCMD
|
||||
case SPEC_AFILE: /* file name for autocommand */
|
||||
result = autocmd_fname;
|
||||
if (result != NULL && !autocmd_fname_full)
|
||||
{
|
||||
/* Still need to turn the fname into a full path. It is
|
||||
* postponed to avoid a delay when <afile> is not used. */
|
||||
autocmd_fname_full = TRUE;
|
||||
result = FullName_save(autocmd_fname, FALSE);
|
||||
vim_free(autocmd_fname);
|
||||
autocmd_fname = result;
|
||||
}
|
||||
if (result == NULL)
|
||||
{
|
||||
*errormsg = (char_u *)_("E495: no autocommand file name to substitute for \"<afile>\"");
|
||||
@@ -9897,6 +9976,14 @@ makeopens(fd, dirnow)
|
||||
if (fprintf(fd, "set lines=%ld columns=%ld" , Rows, Columns) < 0
|
||||
|| put_eol(fd) == FAIL)
|
||||
return FAIL;
|
||||
#ifdef FEAT_FULLSCREEN
|
||||
/* fullscreen needs to be set after lines and columns */
|
||||
if (p_fullscreen)
|
||||
{
|
||||
if (fprintf(fd, "set fullscreen") < 0 || put_eol(fd) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FEAT_GUI
|
||||
@@ -10086,7 +10173,7 @@ makeopens(fd, dirnow)
|
||||
*/
|
||||
if (put_line(fd, "let s:sx = expand(\"<sfile>:p:r\").\"x.vim\"") == FAIL
|
||||
|| put_line(fd, "if file_readable(s:sx)") == FAIL
|
||||
|| put_line(fd, " exe \"source \" . s:sx") == FAIL
|
||||
|| put_line(fd, " exe \"source \" . fnameescape(s:sx)") == FAIL
|
||||
|| put_line(fd, "endif") == FAIL)
|
||||
return FAIL;
|
||||
|
||||
@@ -10708,7 +10795,8 @@ ex_viminfo(eap)
|
||||
p_viminfo = (char_u *)"'100";
|
||||
if (eap->cmdidx == CMD_rviminfo)
|
||||
{
|
||||
if (read_viminfo(eap->arg, TRUE, TRUE, eap->forceit) == FAIL)
|
||||
if (read_viminfo(eap->arg, VIF_WANT_INFO | VIF_WANT_MARKS
|
||||
| (eap->forceit ? VIF_FORCEIT : 0)) == FAIL)
|
||||
EMSG(_("E195: Cannot open viminfo file for reading"));
|
||||
}
|
||||
else
|
||||
|
||||
+36
-9
@@ -31,6 +31,8 @@ struct cmdline_info
|
||||
int cmdattr; /* attributes for prompt */
|
||||
int overstrike; /* Typing mode on the command line. Shared by
|
||||
getcmdline() and put_on_cmdline(). */
|
||||
expand_T *xpc; /* struct being used for expansion, xp_pattern
|
||||
may point into cmdbuff */
|
||||
int xp_context; /* type of expansion */
|
||||
# ifdef FEAT_EVAL
|
||||
char_u *xp_arg; /* user-defined expansion arg */
|
||||
@@ -38,7 +40,11 @@ struct cmdline_info
|
||||
# endif
|
||||
};
|
||||
|
||||
static struct cmdline_info ccline; /* current cmdline_info */
|
||||
/* The current cmdline_info. It is initialized in getcmdline() and after that
|
||||
* used by other functions. When invoking getcmdline() recursively it needs
|
||||
* to be saved with save_cmdline() and restored with restore_cmdline().
|
||||
* TODO: make it local to getcmdline() and pass it around. */
|
||||
static struct cmdline_info ccline;
|
||||
|
||||
static int cmd_showtail; /* Only show path tail in lists ? */
|
||||
|
||||
@@ -238,6 +244,7 @@ getcmdline(firstc, count, indent)
|
||||
}
|
||||
|
||||
ExpandInit(&xpc);
|
||||
ccline.xpc = &xpc;
|
||||
|
||||
#ifdef FEAT_RIGHTLEFT
|
||||
if (curwin->w_p_rl && *curwin->w_p_rlc == 's'
|
||||
@@ -408,9 +415,10 @@ getcmdline(firstc, count, indent)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* <S-Tab> works like CTRL-P (unless 'wc' is <S-Tab>).
|
||||
* When there are matching completions to select <S-Tab> works like
|
||||
* CTRL-P (unless 'wc' is <S-Tab>).
|
||||
*/
|
||||
if (c != p_wc && c == K_S_TAB && xpc.xp_numfiles != -1)
|
||||
if (c != p_wc && c == K_S_TAB && xpc.xp_numfiles > 0)
|
||||
c = Ctrl_P;
|
||||
|
||||
#ifdef FEAT_WILDMENU
|
||||
@@ -1513,6 +1521,7 @@ getcmdline(firstc, count, indent)
|
||||
int old_firstc;
|
||||
|
||||
vim_free(ccline.cmdbuff);
|
||||
xpc.xp_context = EXPAND_NOTHING;
|
||||
if (hiscnt == hislen)
|
||||
p = lookfor; /* back to the old one */
|
||||
else
|
||||
@@ -1839,6 +1848,7 @@ returncmd:
|
||||
#endif
|
||||
|
||||
ExpandCleanup(&xpc);
|
||||
ccline.xpc = NULL;
|
||||
|
||||
#ifdef FEAT_SEARCH_EXTRA
|
||||
if (did_incsearch)
|
||||
@@ -2508,6 +2518,20 @@ realloc_cmdbuff(len)
|
||||
}
|
||||
mch_memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen + 1);
|
||||
vim_free(p);
|
||||
|
||||
if (ccline.xpc != NULL
|
||||
&& ccline.xpc->xp_pattern != NULL
|
||||
&& ccline.xpc->xp_context != EXPAND_NOTHING
|
||||
&& ccline.xpc->xp_context != EXPAND_UNSUCCESSFUL)
|
||||
{
|
||||
int i = (int)(ccline.xpc->xp_pattern - p);
|
||||
|
||||
/* If xp_pattern points inside the old cmdbuff it needs to be adjusted
|
||||
* to point into the newly allocated memory. */
|
||||
if (i >= 0 && i <= ccline.cmdlen)
|
||||
ccline.xpc->xp_pattern = ccline.cmdbuff + i;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -2875,6 +2899,7 @@ save_cmdline(ccp)
|
||||
prev_ccline = ccline;
|
||||
ccline.cmdbuff = NULL;
|
||||
ccline.cmdprompt = NULL;
|
||||
ccline.xpc = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3582,6 +3607,7 @@ ExpandOne(xp, str, orig, options, mode)
|
||||
ExpandInit(xp)
|
||||
expand_T *xp;
|
||||
{
|
||||
xp->xp_pattern = NULL;
|
||||
xp->xp_backslash = XP_BS_NONE;
|
||||
#ifndef BACKSLASH_IN_FILENAME
|
||||
xp->xp_shell = FALSE;
|
||||
@@ -4874,7 +4900,7 @@ ExpandRTDir(pat, num_file, file, dirname)
|
||||
if (s == NULL)
|
||||
return FAIL;
|
||||
sprintf((char *)s, "%s/%s*.vim", dirname, pat);
|
||||
all = globpath(p_rtp, s);
|
||||
all = globpath(p_rtp, s, 0);
|
||||
vim_free(s);
|
||||
if (all == NULL)
|
||||
return FAIL;
|
||||
@@ -4915,9 +4941,10 @@ ExpandRTDir(pat, num_file, file, dirname)
|
||||
* newlines. Returns NULL for an error or no matches.
|
||||
*/
|
||||
char_u *
|
||||
globpath(path, file)
|
||||
globpath(path, file, expand_options)
|
||||
char_u *path;
|
||||
char_u *file;
|
||||
int expand_options;
|
||||
{
|
||||
expand_T xpc;
|
||||
char_u *buf;
|
||||
@@ -4946,10 +4973,10 @@ globpath(path, file)
|
||||
{
|
||||
add_pathsep(buf);
|
||||
STRCAT(buf, file);
|
||||
if (ExpandFromContext(&xpc, buf, &num_p, &p, WILD_SILENT) != FAIL
|
||||
&& num_p > 0)
|
||||
if (ExpandFromContext(&xpc, buf, &num_p, &p,
|
||||
WILD_SILENT|expand_options) != FAIL && num_p > 0)
|
||||
{
|
||||
ExpandEscape(&xpc, buf, num_p, p, WILD_SILENT);
|
||||
ExpandEscape(&xpc, buf, num_p, p, WILD_SILENT|expand_options);
|
||||
for (len = 0, i = 0; i < num_p; ++i)
|
||||
len += (int)STRLEN(p[i]) + 1;
|
||||
|
||||
@@ -6028,7 +6055,7 @@ ex_window()
|
||||
cmdwin_type = '-';
|
||||
|
||||
/* Create the command-line buffer empty. */
|
||||
(void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE);
|
||||
(void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
|
||||
(void)setfname(curbuf, (char_u *)"[Command Line]", NULL, TRUE);
|
||||
set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
|
||||
set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
|
||||
|
||||
+7
-3
@@ -770,9 +770,13 @@
|
||||
|
||||
/*
|
||||
* +browse ":browse" command.
|
||||
* or just the ":browse" command modifier
|
||||
*/
|
||||
#if defined(FEAT_NORMAL) && (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) || defined(FEAT_GUI_MACVIM))
|
||||
# define FEAT_BROWSE
|
||||
#if defined(FEAT_NORMAL)
|
||||
# define FEAT_BROWSE_CMD
|
||||
# if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) || defined(FEAT_GUI_MACVIM)
|
||||
# define FEAT_BROWSE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -1099,7 +1103,7 @@
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MOTIF) \
|
||||
|| defined(MSWIN_FIND_REPLACE)
|
||||
|| defined(MSWIN_FIND_REPLACE) || defined(FEAT_GUI_MACVIM)
|
||||
# define FIND_REPLACE_DIALOG 1
|
||||
#endif
|
||||
|
||||
|
||||
+116
-19
@@ -932,7 +932,10 @@ retry:
|
||||
else
|
||||
{
|
||||
if (eap != NULL && eap->force_ff != 0)
|
||||
{
|
||||
fileformat = get_fileformat_force(curbuf, eap);
|
||||
try_unix = try_dos = try_mac = FALSE;
|
||||
}
|
||||
else if (curbuf->b_p_bin)
|
||||
fileformat = EOL_UNIX; /* binary: use Unix format */
|
||||
else if (*p_ffs == NUL)
|
||||
@@ -2211,7 +2214,7 @@ failed:
|
||||
{
|
||||
/* Use stderr for stdin, makes shell commands work. */
|
||||
close(0);
|
||||
dup(2);
|
||||
ignored = dup(2);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2341,11 +2344,6 @@ failed:
|
||||
STRCAT(IObuff, _("[CR missing]"));
|
||||
c = TRUE;
|
||||
}
|
||||
if (ff_error == EOL_MAC)
|
||||
{
|
||||
STRCAT(IObuff, _("[NL found]"));
|
||||
c = TRUE;
|
||||
}
|
||||
if (split)
|
||||
{
|
||||
STRCAT(IObuff, _("[long lines split]"));
|
||||
@@ -2711,7 +2709,7 @@ check_marks_read()
|
||||
{
|
||||
if (!curbuf->b_marks_read && get_viminfo_parameter('\'') > 0
|
||||
&& curbuf->b_ffname != NULL)
|
||||
read_viminfo(NULL, FALSE, TRUE, FALSE);
|
||||
read_viminfo(NULL, VIF_WANT_MARKS);
|
||||
|
||||
/* Always set b_marks_read; needed when 'viminfo' is changed to include
|
||||
* the ' parameter after opening a buffer. */
|
||||
@@ -3451,7 +3449,7 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit,
|
||||
{
|
||||
# ifdef UNIX
|
||||
# ifdef HAVE_FCHOWN
|
||||
fchown(fd, st_old.st_uid, st_old.st_gid);
|
||||
ignored = fchown(fd, st_old.st_uid, st_old.st_gid);
|
||||
# endif
|
||||
if (mch_stat((char *)IObuff, &st) < 0
|
||||
|| st.st_uid != st_old.st_uid
|
||||
@@ -4367,7 +4365,7 @@ restore_backup:
|
||||
|| st.st_uid != st_old.st_uid
|
||||
|| st.st_gid != st_old.st_gid)
|
||||
{
|
||||
fchown(fd, st_old.st_uid, st_old.st_gid);
|
||||
ignored = fchown(fd, st_old.st_uid, st_old.st_gid);
|
||||
if (perm >= 0) /* set permission again, may have changed */
|
||||
(void)mch_setperm(wfname, perm);
|
||||
}
|
||||
@@ -5554,9 +5552,10 @@ check_for_bom(p, size, lenp, flags)
|
||||
name = "ucs-4le"; /* FF FE 00 00 */
|
||||
len = 4;
|
||||
}
|
||||
else if (flags == FIO_ALL || flags == (FIO_UCS2 | FIO_ENDIAN_L))
|
||||
else if (flags == (FIO_UCS2 | FIO_ENDIAN_L))
|
||||
name = "ucs-2le"; /* FF FE */
|
||||
else if (flags == (FIO_UTF16 | FIO_ENDIAN_L))
|
||||
else if (flags == FIO_ALL || flags == (FIO_UTF16 | FIO_ENDIAN_L))
|
||||
/* utf-16le is preferred, it also works for ucs-2le text */
|
||||
name = "utf-16le"; /* FF FE */
|
||||
}
|
||||
else if (p[0] == 0xfe && p[1] == 0xff
|
||||
@@ -6036,9 +6035,9 @@ vim_fgets(buf, size, fp)
|
||||
{
|
||||
tbuf[FGETS_SIZE - 2] = NUL;
|
||||
#ifdef USE_CR
|
||||
fgets_cr((char *)tbuf, FGETS_SIZE, fp);
|
||||
ignoredp = fgets_cr((char *)tbuf, FGETS_SIZE, fp);
|
||||
#else
|
||||
fgets((char *)tbuf, FGETS_SIZE, fp);
|
||||
ignoredp = fgets((char *)tbuf, FGETS_SIZE, fp);
|
||||
#endif
|
||||
} while (tbuf[FGETS_SIZE - 2] != NUL && tbuf[FGETS_SIZE - 2] != '\n');
|
||||
}
|
||||
@@ -6112,12 +6111,24 @@ vim_rename(from, to)
|
||||
#ifdef HAVE_ACL
|
||||
vim_acl_T acl; /* ACL from original file */
|
||||
#endif
|
||||
#if defined(UNIX) || defined(CASE_INSENSITIVE_FILENAME)
|
||||
int use_tmp_file = FALSE;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When the names are identical, there is nothing to do.
|
||||
* When the names are identical, there is nothing to do. When they refer
|
||||
* to the same file (ignoring case and slash/backslash differences) but
|
||||
* the file name differs we need to go through a temp file.
|
||||
*/
|
||||
if (fnamecmp(from, to) == 0)
|
||||
return 0;
|
||||
{
|
||||
#ifdef CASE_INSENSITIVE_FILENAME
|
||||
if (STRCMP(gettail(from), gettail(to)) != 0)
|
||||
use_tmp_file = TRUE;
|
||||
else
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fail if the "from" file doesn't exist. Avoids that "to" is deleted.
|
||||
@@ -6125,6 +6136,55 @@ vim_rename(from, to)
|
||||
if (mch_stat((char *)from, &st) < 0)
|
||||
return -1;
|
||||
|
||||
#ifdef UNIX
|
||||
{
|
||||
struct stat st_to;
|
||||
|
||||
/* It's possible for the source and destination to be the same file.
|
||||
* This happens when "from" and "to" differ in case and are on a FAT32
|
||||
* filesystem. In that case go through a temp file name. */
|
||||
if (mch_stat((char *)to, &st_to) >= 0
|
||||
&& st.st_dev == st_to.st_dev
|
||||
&& st.st_ino == st_to.st_ino)
|
||||
use_tmp_file = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(UNIX) || defined(CASE_INSENSITIVE_FILENAME)
|
||||
if (use_tmp_file)
|
||||
{
|
||||
char tempname[MAXPATHL + 1];
|
||||
|
||||
/*
|
||||
* Find a name that doesn't exist and is in the same directory.
|
||||
* Rename "from" to "tempname" and then rename "tempname" to "to".
|
||||
*/
|
||||
if (STRLEN(from) >= MAXPATHL - 5)
|
||||
return -1;
|
||||
STRCPY(tempname, from);
|
||||
for (n = 123; n < 99999; ++n)
|
||||
{
|
||||
sprintf((char *)gettail((char_u *)tempname), "%d", n);
|
||||
if (mch_stat(tempname, &st) < 0)
|
||||
{
|
||||
if (mch_rename((char *)from, tempname) == 0)
|
||||
{
|
||||
if (mch_rename(tempname, (char *)to) == 0)
|
||||
return 0;
|
||||
/* Strange, the second step failed. Try moving the
|
||||
* file back and return failure. */
|
||||
mch_rename(tempname, (char *)from);
|
||||
return -1;
|
||||
}
|
||||
/* If it fails for one temp name it will most likely fail
|
||||
* for any temp name, give up. */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Delete the "to" file, this is required on some systems to make the
|
||||
* mch_rename() work, on other systems it makes sure that we don't have
|
||||
@@ -6232,6 +6292,9 @@ vim_rename(from, to)
|
||||
}
|
||||
|
||||
static int already_warned = FALSE;
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
static int default_reload_choice = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check if any not hidden buffer has been changed.
|
||||
@@ -6274,6 +6337,9 @@ check_timestamps(focus)
|
||||
++no_wait_return;
|
||||
did_check_timestamps = TRUE;
|
||||
already_warned = FALSE;
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
default_reload_choice = 0;
|
||||
#endif
|
||||
for (buf = firstbuf; buf != NULL; )
|
||||
{
|
||||
/* Only check buffers in a window. */
|
||||
@@ -6292,6 +6358,9 @@ check_timestamps(focus)
|
||||
}
|
||||
buf = buf->b_next;
|
||||
}
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
default_reload_choice = 0;
|
||||
#endif
|
||||
--no_wait_return;
|
||||
need_check_timestamps = FALSE;
|
||||
if (need_wait_return && didit == 2)
|
||||
@@ -6551,9 +6620,33 @@ buf_check_timestamp(buf, focus)
|
||||
STRCAT(tbuf, "\n");
|
||||
STRCAT(tbuf, mesg2);
|
||||
}
|
||||
# ifdef FEAT_GUI_MACVIM
|
||||
if (default_reload_choice > 0)
|
||||
{
|
||||
if (default_reload_choice == 2)
|
||||
reload = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (do_dialog(VIM_WARNING, (char_u *)_("Warning"), tbuf,
|
||||
(char_u *)_("&OK\n&Load File\nLoad &All\n&Ignore All"),
|
||||
1, NULL))
|
||||
{
|
||||
case 3:
|
||||
default_reload_choice = 2;
|
||||
case 2:
|
||||
reload = TRUE;
|
||||
break;
|
||||
case 4:
|
||||
default_reload_choice = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
# else
|
||||
if (do_dialog(VIM_WARNING, (char_u *)_("Warning"), tbuf,
|
||||
(char_u *)_("&OK\n&Load File"), 1, NULL) == 2)
|
||||
reload = TRUE;
|
||||
# endif
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -8528,6 +8621,7 @@ apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
|
||||
char_u *save_sourcing_name;
|
||||
linenr_T save_sourcing_lnum;
|
||||
char_u *save_autocmd_fname;
|
||||
int save_autocmd_fname_full;
|
||||
int save_autocmd_bufnr;
|
||||
char_u *save_autocmd_match;
|
||||
int save_autocmd_busy;
|
||||
@@ -8606,6 +8700,7 @@ apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
|
||||
* Save the autocmd_* variables and info about the current buffer.
|
||||
*/
|
||||
save_autocmd_fname = autocmd_fname;
|
||||
save_autocmd_fname_full = autocmd_fname_full;
|
||||
save_autocmd_bufnr = autocmd_bufnr;
|
||||
save_autocmd_match = autocmd_match;
|
||||
save_autocmd_busy = autocmd_busy;
|
||||
@@ -8623,14 +8718,15 @@ apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
|
||||
if (fname != NULL && *fname != NUL)
|
||||
autocmd_fname = fname;
|
||||
else if (buf != NULL)
|
||||
autocmd_fname = buf->b_fname;
|
||||
autocmd_fname = buf->b_ffname;
|
||||
else
|
||||
autocmd_fname = NULL;
|
||||
}
|
||||
else
|
||||
autocmd_fname = fname_io;
|
||||
if (autocmd_fname != NULL)
|
||||
autocmd_fname = FullName_save(autocmd_fname, FALSE);
|
||||
autocmd_fname = vim_strsave(autocmd_fname);
|
||||
autocmd_fname_full = FALSE; /* call FullName_save() later */
|
||||
|
||||
/*
|
||||
* Set the buffer number to be used for <abuf>.
|
||||
@@ -8815,6 +8911,7 @@ apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
|
||||
sourcing_lnum = save_sourcing_lnum;
|
||||
vim_free(autocmd_fname);
|
||||
autocmd_fname = save_autocmd_fname;
|
||||
autocmd_fname_full = save_autocmd_fname_full;
|
||||
autocmd_bufnr = save_autocmd_bufnr;
|
||||
autocmd_match = save_autocmd_match;
|
||||
#ifdef FEAT_EVAL
|
||||
@@ -8923,7 +9020,7 @@ auto_next_pat(apc, stop_at_last)
|
||||
{
|
||||
apc->curpat = NULL;
|
||||
|
||||
/* only use a pattern when it has not been removed, has commands and
|
||||
/* Only use a pattern when it has not been removed, has commands and
|
||||
* the group matches. For buffer-local autocommands only check the
|
||||
* buffer number. */
|
||||
if (ap->pat != NULL && ap->cmds != NULL
|
||||
@@ -9109,7 +9206,7 @@ static int include_groups = FALSE;
|
||||
set_context_in_autocmd(xp, arg, doautocmd)
|
||||
expand_T *xp;
|
||||
char_u *arg;
|
||||
int doautocmd; /* TRUE for :doautocmd, FALSE for :autocmd */
|
||||
int doautocmd; /* TRUE for :doauto*, FALSE for :autocmd */
|
||||
{
|
||||
char_u *p;
|
||||
int group;
|
||||
|
||||
+16
-10
@@ -48,7 +48,7 @@ static int checkCloseRec __ARGS((garray_T *gap, linenr_T lnum, int level));
|
||||
static int foldFind __ARGS((garray_T *gap, linenr_T lnum, fold_T **fpp));
|
||||
static int foldLevelWin __ARGS((win_T *wp, linenr_T lnum));
|
||||
static void checkupdate __ARGS((win_T *wp));
|
||||
static void setFoldRepeat __ARGS((linenr_T lnum, long count, int open));
|
||||
static void setFoldRepeat __ARGS((linenr_T lnum, long count, int do_open));
|
||||
static linenr_T setManualFold __ARGS((linenr_T lnum, int opening, int recurse, int *donep));
|
||||
static linenr_T setManualFoldWin __ARGS((win_T *wp, linenr_T lnum, int opening, int recurse, int *donep));
|
||||
static void foldOpenNested __ARGS((fold_T *fpr));
|
||||
@@ -740,7 +740,7 @@ deleteFold(start, end, recursive, had_visual)
|
||||
garray_T *found_ga;
|
||||
fold_T *found_fp = NULL;
|
||||
linenr_T found_off = 0;
|
||||
int use_level = FALSE;
|
||||
int use_level;
|
||||
int maybe_small = FALSE;
|
||||
int level = 0;
|
||||
linenr_T lnum = start;
|
||||
@@ -757,6 +757,7 @@ deleteFold(start, end, recursive, had_visual)
|
||||
gap = &curwin->w_folds;
|
||||
found_ga = NULL;
|
||||
lnum_off = 0;
|
||||
use_level = FALSE;
|
||||
for (;;)
|
||||
{
|
||||
if (!foldFind(gap, lnum - lnum_off, &fp))
|
||||
@@ -783,20 +784,21 @@ deleteFold(start, end, recursive, had_visual)
|
||||
else
|
||||
{
|
||||
lnum = found_fp->fd_top + found_fp->fd_len + found_off;
|
||||
did_one = TRUE;
|
||||
|
||||
if (foldmethodIsManual(curwin))
|
||||
deleteFoldEntry(found_ga,
|
||||
(int)(found_fp - (fold_T *)found_ga->ga_data), recursive);
|
||||
else
|
||||
{
|
||||
if (found_fp->fd_top + found_off < first_lnum)
|
||||
first_lnum = found_fp->fd_top;
|
||||
if (lnum > last_lnum)
|
||||
if (first_lnum > found_fp->fd_top + found_off)
|
||||
first_lnum = found_fp->fd_top + found_off;
|
||||
if (last_lnum < lnum)
|
||||
last_lnum = lnum;
|
||||
parseMarker(curwin);
|
||||
if (!did_one)
|
||||
parseMarker(curwin);
|
||||
deleteFoldMarkers(found_fp, recursive, found_off);
|
||||
}
|
||||
did_one = TRUE;
|
||||
|
||||
/* redraw window */
|
||||
changed_window_setting();
|
||||
@@ -811,6 +813,10 @@ deleteFold(start, end, recursive, had_visual)
|
||||
redraw_curbuf_later(INVERTED);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
/* Deleting markers may make cursor column invalid. */
|
||||
check_cursor_col();
|
||||
|
||||
if (last_lnum > 0)
|
||||
changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L);
|
||||
}
|
||||
@@ -1241,10 +1247,10 @@ checkupdate(wp)
|
||||
* Repeat "count" times.
|
||||
*/
|
||||
static void
|
||||
setFoldRepeat(lnum, count, open)
|
||||
setFoldRepeat(lnum, count, do_open)
|
||||
linenr_T lnum;
|
||||
long count;
|
||||
int open;
|
||||
int do_open;
|
||||
{
|
||||
int done;
|
||||
long n;
|
||||
@@ -1252,7 +1258,7 @@ setFoldRepeat(lnum, count, open)
|
||||
for (n = 0; n < count; ++n)
|
||||
{
|
||||
done = DONE_NOTHING;
|
||||
(void)setManualFold(lnum, open, FALSE, &done);
|
||||
(void)setManualFold(lnum, do_open, FALSE, &done);
|
||||
if (!(done & DONE_ACTION))
|
||||
{
|
||||
/* Only give an error message when no fold could be opened. */
|
||||
|
||||
+2
-2
@@ -4702,7 +4702,7 @@ makemap(fd, buf)
|
||||
return FAIL;
|
||||
if (mp->m_noremap != REMAP_YES && fprintf(fd, "nore") < 0)
|
||||
return FAIL;
|
||||
if (fprintf(fd, cmd) < 0)
|
||||
if (fputs(cmd, fd) < 0)
|
||||
return FAIL;
|
||||
if (buf != NULL && fputs(" <buffer>", fd) < 0)
|
||||
return FAIL;
|
||||
@@ -4801,7 +4801,7 @@ put_escstr(fd, strstart, what)
|
||||
}
|
||||
if (IS_SPECIAL(c) || modifiers) /* special key */
|
||||
{
|
||||
if (fprintf(fd, (char *)get_special_key_name(c, modifiers)) < 0)
|
||||
if (fputs((char *)get_special_key_name(c, modifiers), fd) < 0)
|
||||
return FAIL;
|
||||
continue;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user