Compare commits

...

137 Commits

Author SHA1 Message Date
Bjorn Winckler 95f42c734a Snapshot 44 2009-03-29 17:34:18 +02:00
Bjorn Winckler e1ece272fa Exit full-screen if the window moves
The window is not supposed to move in full-screen mode so if this
happens then exit full-screen.  This situation can occur e.g. if the
window is on a screen that gets unplugged.
2009-03-29 16:40:59 +02:00
Bjorn Winckler 73b5d1837c Validate screen before constraining window
If a window is on a screen that gets unplugged it may happen that
[NSWindow screen] returns nil.  Guard against this when constraining
the window frame to the screen frame.

This fixes a bug where a window could "disappear" if it was on a screen
that got unplugged.
2009-03-29 16:35:47 +02:00
Bjorn Winckler 790f685006 Merge upstream
Conflicts:
	src/vim.h
2009-03-18 20:10:00 +02:00
vimboss a680267d49 updated for version 7.2-148 2009-03-18 18:09:03 +00:00
vimboss 5f1547b288 updated for version 7.2-147 2009-03-18 15:28:08 +00:00
vimboss 9d9a5983f5 updated for version 7.2-146 2009-03-18 14:42:00 +00:00
vimboss 16e57e6189 updated for version 7.2-145 2009-03-18 13:32:24 +00:00
vimboss 5d45d4a4d2 updated for version 7.2-144 2009-03-18 13:21:18 +00:00
vimboss 0546647038 updated for version 7.2-143 2009-03-18 11:52:53 +00:00
vimboss c9ad0b6d4d updated for version 7.2-142 2009-03-18 11:22:25 +00:00
Bjorn Winckler 25306ee0c5 Fix full-screen zooming with Dock visible
This fixes a bug where 'set fu=maxvert' would not cover the screen
vertically if the Dock was visible.
2009-03-16 17:36:05 +01:00
Bjorn Winckler 2e024248fa Use /usr/bin/python in icons/Makefile 2009-03-16 17:05:17 +01:00
Bjorn Winckler 85879328b0 Fix "set go+=rT" bug
The number of columns now matches the width of the window after calling
"set go+=rT".
2009-03-15 14:12:48 +01:00
Bjorn Winckler 9c530a8030 Revert temp patch, fixed properly in 7.2.121
This patch ensures that Ctrl-C works during lengthy :grep operations in
GUI mode.
2009-03-15 15:58:46 +01:00
Bjorn Winckler 9105eb1fd0 Tab labels only shows file name tail 2009-03-15 15:15:23 +01:00
Bjorn Winckler c49868a11f Fix <C-Tab> regression
This fixes a regression introduced with commmit
c79be7f927aff8b2b52a6d8d917b899154ab0ff9 where Ctrl+Unprintable key
presses could no longer be mapped to.
2009-03-13 22:35:12 +01:00
vimboss 795860de7c updated for version 7.2-141 2009-03-11 16:58:40 +00:00
vimboss 90a729a8e4 updated for version 7.2-140 2009-03-11 16:47:21 +00:00
vimboss 1a328483b7 updated for version 7.2-139 2009-03-11 16:29:20 +00:00
vimboss 5e09d64d77 updated for version 7.2-138 2009-03-11 15:37:53 +00:00
vimboss 4591403b7e updated for version 7.2-137 2009-03-11 15:28:26 +00:00
vimboss e90f76c1aa updated for version 7.2-136 2009-03-11 14:37:32 +00:00
vimboss 8745e4380e updated for version 7.2-135 2009-03-11 14:10:38 +00:00
vimboss cd7a1f6539 updated for version 7.2-134 2009-03-11 12:11:02 +00:00
vimboss bb21f9f120 updated for version 7.2-133 2009-03-11 11:47:18 +00:00
vimboss 38c7ababf6 updated for version 7.2-132 2009-03-05 02:15:53 +00:00
vimboss 5aea857883 updated for version 7.2-131 2009-03-04 03:13:35 +00:00
vimboss 322b4eec7e updated for version 7.2-130 2009-03-02 01:47:02 +00:00
vimboss 886d3d7aed updated for version 7.2-129 2009-03-02 01:12:48 +00:00
vimboss b2f7a2f021 updated for version 7.2-128 2009-03-01 01:45:35 +00:00
Zvezdan Petkovic 4374e9787e Colors.plist autogenerated from "showrgb" command
The Colors.plist dictionary is now generated from "showrgb" to properly
match rgb.txt.  Also add three colors which were missing from the output
of "showrgb" (darkyellow, lightmagenta, lightred).
2009-02-25 20:09:30 +01:00
vimboss 080a7c2c6c updated for version 7.2-127 2009-02-24 03:38:04 +00:00
vimboss ffef064005 updated for version 7.2-126 2009-02-24 03:30:14 +00:00
vimboss d23a68d047 updated for version 7.2-125 2009-02-24 03:12:40 +00:00
vimboss c973e12d3e updated for version 7.2-124 2009-02-22 23:54:59 +00:00
vimboss 5e0543116b updated for version 7.2-123 2009-02-22 22:43:27 +00:00
vimboss d9f633dbb3 updated for version 7.2-122 2009-02-22 20:13:39 +00:00
vimboss 32cb07dd61 updated for version 7.2-121 2009-02-22 01:52:59 +00:00
vimboss 40ae005819 updated for version 7.2-120 2009-02-22 01:37:59 +00:00
vimboss c4e8fcc338 updated for version 7.2-119 2009-02-22 00:14:58 +00:00
vimboss 9dbb79f942 updated for version 7.2-118 2009-02-21 23:59:19 +00:00
vimboss 031479c46b updated for version 7.2-117 2009-02-21 23:03:09 +00:00
vimboss 843a3a41bf updated for version 7.2-116 2009-02-21 21:58:24 +00:00
vimboss 01973d329c updated for version 7.2-115 2009-02-21 21:30:39 +00:00
vimboss bcfeb7c895 updated for version 7.2-114 2009-02-21 21:14:00 +00:00
vimboss 46b250b75f updated for version 7.2-113 2009-02-21 21:04:20 +00:00
vimboss 9b06b0a4b2 updated for version 7.2-112 2009-02-21 20:23:59 +00:00
vimboss 80b36e7995 updated for version 7.2-111 2009-02-21 20:11:41 +00:00
vimboss d29599b7ea updated for version 7.2-110 2009-02-21 19:37:46 +00:00
vimboss a63fc2427e updated for version 7.2-109 2009-02-21 19:28:48 +00:00
Bjorn Winckler 393e47945b Snapshot 43 2009-02-20 14:43:08 +01:00
Bjorn Winckler 5100db4427 Set correct protocol for frontend proxy 2009-02-18 23:21:46 +01:00
Bjorn Winckler 19ee857237 Merge upstream
Conflicts:
	src/buffer.c
2009-02-11 22:49:00 +01:00
vimboss 781ac5b687 updated for version 7.2-108 2009-02-11 21:48:40 +00:00
vimboss 9b52c915d9 updated for version 7.2-107 2009-02-11 17:47:54 +00:00
vimboss 7a68824771 updated for version 7.2-106 2009-02-11 16:58:49 +00:00
vimboss c2aed127ca updated for version 7.2-105 2009-02-11 15:47:05 +00:00
vimboss 12b3ecfdcd updated for version 7.2-104 2009-02-11 15:03:45 +00:00
vimboss 4143f69655 updated for version 7.2-103 2009-02-11 10:35:36 +00:00
Bjorn Winckler 7a720947c8 Mention that 'go' does not support "f" in help 2009-02-10 22:11:43 +01:00
Bjorn Winckler 9393a4151c Revert "Don't init backend if Vim is about to fork"
This reverts commit ef03c36272e9a45f71659df7cecfce7aa15c2cbf.

Conflicts:

	src/MacVim/gui_macvim.m
2009-02-10 22:06:18 +01:00
Bjorn Winckler 95a678d204 Don't update 'fuoptions' before GUI has started
This avoids allocating the MMBackend object before forking.
2009-02-10 22:03:36 +01:00
Bjorn Winckler 68cec2f91b Fork directly after command line scan
This fixes a bug with relative paths as arguments when 'autochdir' was
enabled and also cuts down on startup times.  However, it also has the
negative side-effect that 'f' is no longer supported in 'guioptions'.
2009-02-10 22:00:40 +01:00
Bjorn Winckler 5ed292ebfb Revert old forking code 2009-02-10 21:19:37 +01:00
Bjorn Winckler 6d70e1a179 Fix untitled window on reopen with quickstart
This reverts commit 662aa32b399c1149daa1cd3a2b5bccc8e75f589a and
clarifies the comment regarding how 'pidArguments' is used.
2009-02-08 22:29:58 +01:00
Bjorn Winckler 355d2ec231 Fix untitled window on reopen bug
When MacVim is started from Terminal "-MMNoWindow yes" is passed as an
argument.  This argument will no longer stop new windows from opening on
"reactivate" events -- it only affects "activate" events.
2009-02-08 22:08:34 +01:00
Bjorn Winckler c6ceb6c969 Decrease delay in gui_macvim_flush() 2009-02-07 15:56:17 +01:00
Nicolas Weber 60c1c58967 Fix icon generation Makefile 2009-02-06 22:43:54 +01:00
Bjorn Winckler ba43ddb524 Add more files in MacVim/icons to .gitignore 2009-02-06 18:21:59 +01:00
Nicolas Weber 2a032c05b7 Make icon module compilation more portable 2009-02-05 17:11:45 -08:00
vimboss 8d8aecf662 updated for version 7.2-102 2009-02-05 19:48:25 +00:00
Bjorn Winckler 380d7b2cbf Update credits 2009-02-04 22:04:32 +01:00
Bjorn Winckler 30a12fc740 Ignore temporary files in src/MacVim/icons folder 2009-02-04 21:28:15 +01:00
vimboss 43050b40f8 updated for version 7.2-101 2009-02-04 17:35:52 +00:00
vimboss d5dfed9cfc updated for version 7.2-100 2009-02-04 16:50:47 +00:00
vimboss 0e2e98e570 updated for version 7.2-099 2009-02-04 16:29:07 +00:00
vimboss d0a875e3af updated for version 7.2-098 2009-02-04 15:27:06 +00:00
vimboss b770256474 updated for version 7.2-097 2009-02-04 13:19:42 +00:00
vimboss e14b8cd599 updated for version 7.2-096 2009-02-04 12:14:51 +00:00
vimboss 938149499b updated for version 7.2-095 2009-02-04 10:46:25 +00:00
vimboss 9245af7148 updated for version 7.2-094 2009-02-04 10:20:58 +00:00
Nicolas Weber a874eae869 Update credits 2009-02-01 10:37:58 -08:00
Nicolas Weber cca95bae41 Use text-based 16x16 icons 2009-02-01 10:20:32 -08:00
Bjorn Winckler 243fcce65c Ensure viminfo is written on Cmd-q 2009-02-01 10:15:40 +01:00
Bjorn Winckler b8c8a68a5c Fix <C-]> on German keyboard layout
Instead of checking for Ctrl-character, check when Cocoa translates a
keypress to an unprintable character (in particular, this happens on
Ctrl-character).  This ensures keys like <C-]> work on (some) keyboards
where ] requires the use of Alt.
2009-01-30 20:34:41 +01:00
Bjorn Winckler 8502d5f2b2 Avoid exception in key handling routine 2009-01-30 18:30:21 +01:00
vimboss da857362b0 updated for version 7.2-093 2009-01-28 20:23:17 +00:00
vimboss 4c50d72cdf updated for version 7.2-092 2009-01-28 18:09:38 +00:00
vimboss 9af39a7cb2 updated for version 7.2-091 2009-01-28 15:04:42 +00:00
vimboss d4038f59f4 updated for version 7.2-090 2009-01-28 14:42:59 +00:00
vimboss 9150d82be1 updated for version 7.2-089 2009-01-28 13:18:26 +00:00
Bjorn Winckler 87694dc1bf Tell Git to ignore .pyc files in icons folder 2009-01-23 23:36:12 +01:00
Bjorn Winckler 22704e2bb4 Remove .pyc files from icons folder on clean 2009-01-23 23:33:02 +01:00
Nico Weber 95676cfcd4 Doc icon generation cleanup 2009-01-23 23:28:07 +01:00
Bjorn Winckler 1e901456a5 Fix two minor memory leaks
The MMTextViewHelper class failed to release two objects on dealloc.
2009-01-23 23:23:10 +01:00
vimboss 899f9a6260 updated for version 7.2-088 2009-01-22 20:50:10 +00:00
vimboss 6b989afdb1 updated for version 7.2-087 2009-01-22 20:32:12 +00:00
vimboss 4f48c32bc3 updated for version 7.2-086 2009-01-22 19:48:55 +00:00
vimboss c2ea4b240d updated for version 7.2-085 2009-01-22 17:33:49 +00:00
Bjorn Winckler f81158c840 Always respect MMLayoutVerticalSplit
This flag used to be ignored when dropping a file onto a window.
2009-01-17 20:34:51 +01:00
Bjorn Winckler 3950b3a6b1 Respect layout pref when raising an open file
For example, with layout set to "arglist" and with 'hidden' enabled,
double-clicking an already open (but hidden) file will no longer cause
it to open in a new tab.  Instead it opens as if the ":buf" command had
been used.
2009-01-17 20:25:48 +01:00
vimboss ae65cb89b3 updated for version 7.2-084 2009-01-13 17:11:05 +00:00
vimboss f90e3c31ab updated for version 7.2-083 2009-01-13 16:28:21 +00:00
vimboss 014700ca55 updated for version 7.2-082 2009-01-13 15:58:01 +00:00
vimboss f86423097b updated for version 7.2-081 2009-01-13 15:38:37 +00:00
vimboss a4cdb9b1c4 updated for version 7.2-080 2009-01-13 11:29:48 +00:00
Jonathon Mah 03a1a0ea74 Opening with search text does inclusive search 2009-01-13 06:27:01 +10:30
Jonathon Mah 4e1a1cad93 Fix typo in debug message string 2009-01-13 06:25:24 +10:30
Bjorn Winckler e4abcd6741 Snapshot 42 2009-01-12 16:35:09 +01:00
Bjorn Winckler b0f34cac04 Update appcast 2009-01-10 21:09:43 +01:00
Bjorn Winckler dd243c8ab1 Snapshot 41 2009-01-10 20:57:33 +01:00
Bjorn Winckler 02592cfe41 Prune draw queue before sending to frontend
If the draw queue fills up with lots (i.e. twice the number of max rows)
of insert/delete line commands we can remove draw commands from the
beginning of the draw queue.  This reduces the possibility of the draw
queue overflowing.
2009-01-10 17:39:29 +01:00
Bjorn Winckler e706fca4d6 Cmd-. sends SIGINT
Ctrl-C does not always work to interrupt a stuck Vim process. By making
Cmd-. send SIGINT it is more likely to succeed where Ctrl-C has failed.
(E.g. Ctrl-C may fail if a DO message is dropped, or if the Vim process
is stuck in a loop and isn't checking for new input.)
2009-01-10 17:38:11 +01:00
Bjorn Winckler 8d00a30b0a Show output from external commands as it happens
Previously, all output was sent to the frontend at once so only the last
few rows were visible.  This was a bit disconcerting when a command took
a bit of time because there was no feedback that anything was happening.
The downside to this patch is that it takes a bit longer for a command
to finish since the frontend has to do more drawing.
2009-01-10 17:37:49 +01:00
Bjorn Winckler 76200b7c03 Allow interrupt during external commands 2009-01-08 21:25:37 +01:00
Bjorn Winckler e648d3b011 Don't ignore SIGCHLD (fix automatic updating)
Ignoring SIGCHLD caused problems with automatic updating (Sparkle) since
it uses popen() (and hence implicitly uses wait4()) to unpack archives.
Now that SIGCHLD is no longer ignored we have to reap child processes
after exiting a Vim process as well as when MacVim is about to
terminate.
2009-01-08 16:11:30 +01:00
Bjorn Winckler 1db4b7903b Make no DO calls during app termination 2009-01-07 21:01:47 +01:00
Bjorn Winckler e5e129b933 Prune unnecessary code, clarify comment 2009-01-07 20:19:44 +01:00
Bjorn Winckler 354968a9b9 Add comment 2009-01-07 20:16:01 +01:00
Bjorn Winckler 87e4ef758b Clean up process termination code
Exiting immediately on TerminateNowMsgID simplifies the code a bit and
also minimizes the probability of a process not terminating before
MacVim.
2009-01-07 20:14:03 +01:00
Bjorn Winckler 2b721c9e9c New user default MMLoadDefaultFont
When enabled the default font is loaded from within the app bundle each
time MacVim is started (the default setting).  Startup times are shorter
if this is disabled.  Note that if the default font has already been
installed on the system then this may as well be disabled.
2009-01-07 14:19:27 +01:00
Bjorn Winckler c50143db47 Fix deprecated API compiler warning 2009-01-06 22:05:50 +01:00
Bjorn Winckler 2153ab22d7 Don't load default font in Vim (faster startup)
Loading and unloading a font can take a substantial amount of time so
this cuts down on the startup time.
2009-01-06 21:41:47 +01:00
Bjorn Winckler aefc975f1b Fix compiler issues on Tiger 2009-01-06 22:58:38 +01:00
Bjorn Winckler 79851d47b1 Build Debug and Release using default SDK
The Universal target still builds using the 10.4u SDK.
2009-01-06 17:51:36 +01:00
Bjorn Winckler 2c9f69f2bf Fix double free memory problem
This bug was introduced in commit:
    e162109d6f022942edb7281736f587ee79e20bfe
2009-01-06 18:31:38 +01:00
vimboss 9dc3e9172c updated for version 7.2-079 2009-01-06 15:14:30 +00:00
vimboss 2e69b16f67 updated for version 7.2-078 2009-01-06 14:02:45 +00:00
Bjorn Winckler 462fb78a85 Deprecate "redr|f" in addInput: calls
The previous commit ensures these are no longer neeeded (they used to be
there to avoid the "Press ENTER..." prompt).
2009-01-04 22:13:48 +01:00
Bjorn Winckler d2dbd62e7b Avoid "Press ENTER..." prompt
When adding input programmatically the 'silent' flag is automatically
set.  Hopefully this will mean the end of the annoying "Press ENTER..."
prompt.  This also means that it should no longer be necessary to
manually try to make commands silent (e.g. ":redr|f" should not be
needed).
2009-01-04 21:44:27 +01:00
Bjorn Winckler e1c4adc8c9 Add user default to toggle the "add tab" button
The user default MMShowAddTabButton controls whether the "add tab"
button is displayed on the tab bar or not.
2009-01-04 17:58:57 +01:00
Bjorn Winckler 2ffc552c25 Avoid switching Spaces when using 'mvim' 2009-01-04 17:46:48 +01:00
Nico Weber 7845992803 Toggle menu bar on focus change in full-screen 2009-01-02 13:55:11 -08:00
vimboss 3142e74a3a updated for version 7.2-077 2008-12-31 15:21:32 +00:00
Nico Weber 1eb73428b0 Icon generation works on Tiger again 2008-12-30 23:36:50 -08:00
vimboss c5b2d1b5b4 updated for version 7.2-076 2008-12-30 15:15:57 +00:00
103 changed files with 3903 additions and 1939 deletions
+8
View File
@@ -3,6 +3,14 @@
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
+13 -4
View File
@@ -1,4 +1,4 @@
*gui_mac.txt* For Vim version 7.2. Last change: 2008 Oct 25
*gui_mac.txt* For Vim version 7.2. Last change: 2009 Mar 15
VIM REFERENCE MANUAL by Bjorn Winckler
@@ -117,6 +117,11 @@ really bad once you start using tabs. For example, dropping two files, then
dropping two more, and switching back to the first tab would cause weird
strings like "((3) of 2)" to appear in the window title.
*macvim-tablabel*
Tab labels only show the tail of the file name to make the tabs more readable
when editing files in deeply nested folders. Add the line "set guitablabel="
to your .gvimrc file to revert back to the default Vim tab label.
*macvim-options*
These are the non-standard options that MacVim supports:
'antialias' 'fullscreen' 'fuoptions'
@@ -260,9 +265,11 @@ Here is a list of relevant dictionary entries:
KEY VALUE ~
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]
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]
@@ -561,9 +568,11 @@ 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. This is synonymous with CTRL-C and can
hence be used instead of Esc to exit insert mode (in
case you find Esc a bit hard to reach).
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
+2 -1
View File
@@ -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*
+14 -3
View File
@@ -1,4 +1,4 @@
*if_cscop.txt* For Vim version 7.2. Last change: 2005 Mar 29
*if_cscop.txt* For Vim version 7.2. Last change: 2009 Mar 18
VIM REFERENCE MANUAL by Andy Kahn
@@ -131,11 +131,22 @@ The available subcommands are:
7 or f: Find this file
8 or i: Find files #including this file
For all types, except 4 and 6, leading white space for {name} is
removed. For 4 and 6 there is exactly one space between {querytype}
and {name}. Further white space is included in {name}.
EXAMPLES >
:cscope find c vim_free
:cscope find 3 vim_free
:cscope find 3 vim_free
<
These two examples perform the same query. >
These two examples perform the same query: functions calling
"vim_free". >
:cscope find t initOnce
:cscope find t initOnce
<
The first one searches for the text "initOnce", the second one for
" initOnce". >
:cscope find 0 DEFAULT_TERM
<
+5 -3
View File
@@ -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
+2 -3
View File
@@ -3490,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
@@ -4273,9 +4275,6 @@ A jump table for the options with a short description can be found at |Q_op|.
be able to execute Normal mode commands.
This is the opposite of the 'keymap' option, where characters are
mapped in Insert mode.
This only works for 8-bit characters. The value of 'langmap' may be
specified with multi-byte characters (e.g., UTF-8), but only the lower
8 bits of each character will be used.
Example (for Greek, in UTF-8): *greek* >
:set langmap=ΑA,ΒB,ΨC,ΔD,ΕE,ΦF,ΓG,ΗH,ΙI,ΞJ,ΚK,ΛL,ΜM,ΝN,ΟO,ΠP,QQ,ΡR,ΣS,ΤT,ΘU,ΩV,WW,ΧX,ΥY,ΖZ,αa,βb,ψc,δd,εe,φf,γg,ηh,ιi,ξj,κk,λl,μm,νn,οo,πp,qq,ρr,σs,τt,θu,ωv,ςw,χx,υy,ζz
+464 -461
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -1,4 +1,4 @@
{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf350
{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf430
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\vieww9000\viewh8400\viewkind0
@@ -40,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}}.\
@@ -52,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).}
+1 -1
View File
@@ -1153,7 +1153,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>40</string>
<string>44</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
+1
View File
@@ -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;
+212 -82
View File
@@ -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,8 +82,6 @@ typedef struct
#pragma options align=reset
static int executeInLoginShell(NSString *path, NSArray *args);
@interface MMAppController (MMServices)
- (void)openSelection:(NSPasteboard *)pboard userData:(NSString *)userData
@@ -128,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;
@@ -154,14 +151,12 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
+ (void)initialize
{
// Avoid zombies (we fork Vim processes which we don't want to wait for).
signal(SIGCHLD, SIG_IGN);
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], MMNoWindowKey,
[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,
@@ -188,6 +183,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
[NSNumber numberWithBool:NO], MMVerticalSplitKey,
[NSNumber numberWithInt:0], MMPreloadCacheSizeKey,
[NSNumber numberWithInt:0], MMLastWindowClosedBehaviorKey,
[NSNumber numberWithBool:YES], MMLoadDefaultFontKey,
nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
@@ -206,7 +202,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
{
if (!(self = [super init])) return nil;
fontContainerRef = loadFonts();
[self loadDefaultFont];
vimControllers = [NSMutableArray new];
cachedVimControllers = [NSMutableArray new];
@@ -345,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];
@@ -365,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
@@ -457,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];
@@ -515,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;
@@ -549,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
@@ -607,6 +639,14 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
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
@@ -636,21 +676,26 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
[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 screen]) {
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 ([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];
}
} else {
NSLog(@"[%s] WINDOW NOT ON SCREEN, don't constrain position", _cmd);
}
}
@@ -797,6 +842,17 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
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
@@ -804,10 +860,18 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
// 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\"|"
"tab sb %@|let &swb=oldswb|unl oldswb|"
"cal foreground()|redr|f<CR>", firstFile];
"%@ %@|let &swb=oldswb|unl oldswb|"
"cal foreground()<CR>", bufCmd, firstFile];
[firstController addVimInput:input];
@@ -824,23 +888,13 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
//
// b) 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"];
MMVimController *vc;
if (openInCurrentWindow && (vc = [self topmostVimController])) {
// Open files in an already open window.
[[[vc windowController] window] makeKeyAndOrderFront:self];
@@ -935,7 +989,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];
@@ -1077,7 +1131,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];
@@ -1272,7 +1326,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
@@ -1282,9 +1336,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]];
@@ -1523,7 +1586,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;
}
@@ -1738,6 +1801,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
@@ -1877,13 +1948,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
@@ -1955,10 +2066,6 @@ executeInLoginShell(NSString *path, NSArray *args)
} else if (pid == 0) {
// Child process
// We need to undo our zombie avoidance as Vim waits for and needs
// the exit statuses of processes it spawns.
signal(SIGCHLD, SIG_DFL);
if (close(ds[1]) == -1) exit(255);
if (dup2(ds[0], 0) == -1) exit(255);
@@ -1982,7 +2089,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
View File
@@ -892,10 +892,19 @@ defaultLineHeightForFont(NSFont *font)
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
{
+4 -4
View File
@@ -41,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;
@@ -95,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;
+151 -105
View File
@@ -51,13 +51,6 @@ static int eventModifierFlagsToVimModMask(int modifierFlags);
static int eventModifierFlagsToVimMouseModMask(int modifierFlags);
static int eventButtonNumberToVimMouseButton(int buttonNumber);
// Before exiting process, sleep for this many microseconds. This is to allow
// any distributed object messages in transit to be received by MacVim before
// the process dies (otherwise an error message is logged by Cocoa). Note that
// this delay is only necessary if an NSConnection to MacVim has been
// established.
static useconds_t MMExitProcessDelay = 300000;
// In gui_macvim.m
vimmenu_T *menu_for_descriptor(NSArray *desc);
@@ -77,6 +70,9 @@ static NSString *MMSymlinkWarningString =
"\ta symlink, then your MacVim.app bundle is incomplete.\n\n";
extern GuiFont gui_mch_retain_font(GuiFont font);
@interface NSString (MMServerNameCompare)
- (NSComparisonResult)serverNameCompare:(NSString *)string;
@@ -86,6 +82,8 @@ static NSString *MMSymlinkWarningString =
@interface MMBackend (Private)
- (void)clearDrawData;
- (void)didChangeWholeLine;
- (void)waitForDialogReturn;
- (void)insertVimStateMessage;
- (void)processInputQueue;
@@ -138,8 +136,6 @@ static NSString *MMSymlinkWarningString =
self = [super init];
if (!self) return nil;
fontContainerRef = loadFonts();
outputQueue = [[NSMutableArray alloc] init];
inputQueue = [[NSMutableArray alloc] init];
drawData = [[NSMutableData alloc] initWithCapacity:1024];
@@ -173,7 +169,7 @@ static NSString *MMSymlinkWarningString =
//NSLog(@"%@ %s", [self className], _cmd);
[[NSNotificationCenter defaultCenter] removeObserver:self];
[oldWideFont release]; oldWideFont = nil;
gui_mch_free_font(oldWideFont); oldWideFont = NOFONT;
[blinkTimer release]; blinkTimer = nil;
[alternateServerName release]; alternateServerName = nil;
[serverReplyDict release]; serverReplyDict = nil;
@@ -346,7 +342,7 @@ static NSString *MMSymlinkWarningString =
frontendProxy = [proxy connectBackend:self pid:pid];
if (frontendProxy) {
[frontendProxy retain];
[frontendProxy setProtocolForProxy:@protocol(MMAppProtocol)];
[frontendProxy setProtocolForProxy:@protocol(MMFrontendProtocol)];
ok = YES;
}
}
@@ -370,7 +366,7 @@ static NSString *MMSymlinkWarningString =
// Any draw commands in queue are effectively obsolete since this clearAll
// will negate any effect they have, therefore we may as well clear the
// draw queue.
[drawData setLength:0];
[self clearDrawData];
[drawData appendBytes:&type length:sizeof(int)];
}
@@ -402,6 +398,9 @@ static NSString *MMSymlinkWarningString =
[drawData appendBytes:&bottom length:sizeof(int)];
[drawData appendBytes:&left length:sizeof(int)];
[drawData appendBytes:&right length:sizeof(int)];
if (left == 0 && right == gui.num_cols-1)
[self didChangeWholeLine];
}
- (void)drawString:(char*)s length:(int)len row:(int)row column:(int)col
@@ -437,6 +436,9 @@ static NSString *MMSymlinkWarningString =
[drawData appendBytes:&bottom length:sizeof(int)];
[drawData appendBytes:&left length:sizeof(int)];
[drawData appendBytes:&right length:sizeof(int)];
if (left == 0 && right == gui.num_cols-1)
[self didChangeWholeLine];
}
- (void)drawCursorAtRow:(int)row column:(int)col shape:(int)shape
@@ -472,7 +474,7 @@ static NSString *MMSymlinkWarningString =
// Keep running the run-loop until there is no more input to process.
while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true)
== kCFRunLoopRunHandledSource)
;
; // do nothing
}
- (void)flushQueue:(BOOL)force
@@ -485,10 +487,10 @@ static NSString *MMSymlinkWarningString =
if ([drawData length] > 0) {
// HACK! Detect changes to 'guifontwide'.
if (gui.wide_font != (GuiFont)oldWideFont) {
[oldWideFont release];
oldWideFont = [(NSFont*)gui.wide_font retain];
[self setWideFont:oldWideFont];
if (gui.wide_font != oldWideFont) {
gui_mch_free_font(oldWideFont);
oldWideFont = gui_mch_retain_font(gui.wide_font);
[self setFont:oldWideFont wide:YES];
}
int type = SetCursorPosDrawType;
@@ -497,7 +499,7 @@ static NSString *MMSymlinkWarningString =
[drawData appendBytes:&gui.col length:sizeof(gui.col)];
[self queueMessage:BatchDrawMsgID data:[drawData copy]];
[drawData setLength:0];
[self clearDrawData];
}
if ([outputQueue count] > 0) {
@@ -512,8 +514,7 @@ static NSString *MMSymlinkWarningString =
outputQueue);
if (![connection isValid]) {
NSLog(@"WARNING! Connection is invalid, exit now!");
NSLog(@"waitForAck=%d got_int=%d isTerminating=%d",
waitForAck, got_int, isTerminating);
NSLog(@"waitForAck=%d got_int=%d", waitForAck, got_int);
mch_exit(-1);
}
}
@@ -559,21 +560,17 @@ static NSString *MMSymlinkWarningString =
{
// NOTE: This is called if mch_exit() is called. Since we assume here that
// the process has started properly, be sure to use exit() instead of
// mch_exit() to prematurely terminate a process.
// To notify MacVim that this Vim process is exiting we could simply
// invalidate the connection and it would automatically receive a
// connectionDidDie: notification. However, this notification seems to
// take up to 300 ms to arrive which is quite a noticeable delay. Instead
// we immediately send a message to MacVim asking it to close the window
// belonging to this process, and then we invalidate the connection (in
// case the message got lost).
// mch_exit() to prematurely terminate a process (or set 'isTerminating'
// first).
// Make sure no connectionDidDie: notification is received now that we are
// already exiting.
[[NSNotificationCenter defaultCenter] removeObserver:self];
if ([connection isValid]) {
// The 'isTerminating' flag indicates that the frontend is also exiting so
// there is no need to flush any more output since the frontend won't look
// at it anyway.
if (!isTerminating && [connection isValid]) {
@try {
// Flush the entire queue in case a VimLeave autocommand added
// something to the queue.
@@ -584,7 +581,15 @@ static NSString *MMSymlinkWarningString =
NSLog(@"Exception caught when sending CloseWindowMsgID: \"%@\"", e);
}
[connection invalidate];
// NOTE: If Cmd-w was pressed to close the window the menu is briefly
// highlighted and during this pause the frontend won't receive any DO
// messages. If the Vim process exits before this highlighting has
// finished Cocoa will emit the following error message:
// *** -[NSMachPort handlePortMessage:]: dropping incoming DO message
// because the connection or ports are invalid
// To avoid this warning we delay here. If the warning still appears
// this delay may need to be increased.
usleep(150000);
}
#ifdef MAC_CLIENTSERVER
@@ -592,13 +597,6 @@ static NSString *MMSymlinkWarningString =
[[NSConnection defaultConnection] setRootObject:nil];
[[NSConnection defaultConnection] invalidate];
#endif
if (fontContainerRef) {
ATSFontDeactivate(fontContainerRef, NULL, kATSOptionFlagsDefault);
fontContainerRef = 0;
}
usleep(MMExitProcessDelay);
}
- (void)selectTab:(int)index
@@ -834,35 +832,27 @@ static NSString *MMSymlinkWarningString =
[self queueMessage:SetScrollbarThumbMsgID data:data];
}
- (void)setFont:(NSFont *)font
- (void)setFont:(GuiFont)font wide:(BOOL)wide
{
NSString *fontName = [font displayName];
float size = [font pointSize];
int len = [fontName lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
if (len > 0) {
NSMutableData *data = [NSMutableData data];
[data appendBytes:&size length:sizeof(float)];
[data appendBytes:&len length:sizeof(int)];
[data appendBytes:[fontName UTF8String] length:len];
[self queueMessage:SetFontMsgID data:data];
NSString *fontName = (NSString *)font;
float size = 0;
NSArray *components = [fontName componentsSeparatedByString:@":"];
if ([components count] == 2) {
size = [[components lastObject] floatValue];
fontName = [components objectAtIndex:0];
}
}
- (void)setWideFont:(NSFont *)font
{
NSString *fontName = [font displayName];
float size = [font pointSize];
int len = [fontName lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSMutableData *data = [NSMutableData data];
[data appendBytes:&size length:sizeof(float)];
[data appendBytes:&len length:sizeof(int)];
if (len > 0)
[data appendBytes:[fontName UTF8String] length:len];
else if (!wide)
return; // Only the wide font can be set to nothing
[self queueMessage:SetWideFontMsgID data:data];
[self queueMessage:(wide ? SetWideFontMsgID : SetFontMsgID) data:data];
}
- (void)executeActionWithName:(NSString *)name
@@ -1055,11 +1045,7 @@ static NSString *MMSymlinkWarningString =
// which waits on the run loop will fail to detect this message (e.g. in
// waitForConnectionAcknowledgement).
BOOL shouldClearQueue = NO;
if (InterruptMsgID == msgid) {
shouldClearQueue = YES;
got_int = TRUE;
} else if (InsertTextMsgID == msgid && data != nil) {
if (InsertTextMsgID == msgid && data != nil) {
const void *bytes = [data bytes];
bytes += sizeof(int);
int len = *((int*)bytes); bytes += sizeof(int);
@@ -1067,17 +1053,18 @@ static NSString *MMSymlinkWarningString =
char_u *str = (char_u*)bytes;
if ((str[0] == Ctrl_C && ctrl_c_interrupts) ||
(str[0] == intr_char && intr_char != Ctrl_C)) {
shouldClearQueue = YES;
got_int = TRUE;
[inputQueue removeAllObjects];
return;
}
}
} else if (TerminateNowMsgID == msgid) {
shouldClearQueue = YES;
// Terminate immediately (the frontend is about to quit or this process
// was aborted). Don't preserve modified files since the user would
// already have been presented with a dialog warning if there were any
// modified files when we get here.
isTerminating = YES;
}
if (shouldClearQueue) {
[inputQueue removeAllObjects];
getout(0);
return;
}
@@ -1236,11 +1223,18 @@ static NSString *MMSymlinkWarningString =
}
- (void)addInput:(in bycopy NSString *)input
client:(in byref id <MMVimClientProtocol>)client
client:(in byref id <MMVimClientProtocol>)client
{
//NSLog(@"addInput:%@ client:%@", input, (id)client);
[self addInput:input];
// NOTE: We don't call addInput: here because it differs from
// server_to_input_buf() in that it always sets the 'silent' flag and we
// don't want the MacVim client/server code to behave differently from
// other platforms.
char_u *s = [input vimStringSave];
server_to_input_buf(s);
vim_free(s);
[self addClient:(id)client];
}
@@ -1449,11 +1443,11 @@ static NSString *MMSymlinkWarningString =
{
if (!waitForAck) return;
while (waitForAck && !got_int && [connection isValid] && !isTerminating) {
while (waitForAck && !got_int && [connection isValid]) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]];
//NSLog(@" waitForAck=%d got_int=%d isTerminating=%d isValid=%d",
// waitForAck, got_int, isTerminating, [connection isValid]);
//NSLog(@" waitForAck=%d got_int=%d isValid=%d",
// waitForAck, got_int, [connection isValid]);
}
if (waitForAck) {
@@ -1464,7 +1458,6 @@ static NSString *MMSymlinkWarningString =
// NOTE: We intentionally do not call mch_exit() since this in turn
// will lead to -[MMBackend exit] getting called which we want to
// avoid.
usleep(MMExitProcessDelay);
exit(0);
}
@@ -1483,6 +1476,40 @@ static NSString *MMSymlinkWarningString =
@implementation MMBackend (Private)
- (void)clearDrawData
{
[drawData setLength:0];
numWholeLineChanges = offsetForDrawDataPrune = 0;
}
- (void)didChangeWholeLine
{
// It may happen that draw queue is filled up with lots of changes that
// affect a whole row. If the number of such changes equals twice the
// number of visible rows then we can prune some commands off the queue.
//
// NOTE: If we don't perform this pruning the draw queue may grow
// indefinitely if Vim were to repeatedly send draw commands without ever
// waiting for new input (that's when the draw queue is flushed). The one
// instance I know where this can happen is when a command is executed in
// the shell (think ":grep" with thousands of matches).
++numWholeLineChanges;
if (numWholeLineChanges == gui.num_rows) {
// Remember the offset to prune up to.
offsetForDrawDataPrune = [drawData length];
} else if (numWholeLineChanges == 2*gui.num_rows) {
// Delete all the unnecessary draw commands.
NSMutableData *d = [[NSMutableData alloc]
initWithBytes:[drawData bytes] + offsetForDrawDataPrune
length:[drawData length] - offsetForDrawDataPrune];
offsetForDrawDataPrune = [d length];
numWholeLineChanges -= gui.num_rows;
[drawData release];
drawData = d;
}
}
- (void)waitForDialogReturn
{
// Keep processing the run loop until a dialog returns. To avoid getting
@@ -1493,8 +1520,7 @@ static NSString *MMSymlinkWarningString =
// items while a sheet is being displayed, so we can't just wait for the
// first message to arrive and assume that is the setDialogReturn: call.
while (nil == dialogReturn && !got_int && [connection isValid]
&& !isTerminating)
while (nil == dialogReturn && !got_int && [connection isValid])
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]];
@@ -1536,12 +1562,16 @@ static NSString *MMSymlinkWarningString =
// to make synchronous calls from MacVim to Vim in order to get state.
BOOL mmta = curbuf ? curbuf->b_p_mmta : NO;
int numTabs = tabpage_index(NULL) - 1;
if (numTabs < 0)
numTabs = 0;
NSDictionary *vimState = [NSDictionary dictionaryWithObjectsAndKeys:
[[NSFileManager defaultManager] currentDirectoryPath], @"pwd",
[NSNumber numberWithInt:p_mh], @"p_mh",
[NSNumber numberWithBool:[self unusedEditor]], @"unusedEditor",
[NSNumber numberWithBool:mmta], @"p_mmta",
[NSNumber numberWithInt:numTabs], @"numTabs",
nil];
// Put the state before all other messages.
@@ -1982,19 +2012,15 @@ static NSString *MMSymlinkWarningString =
- (void)connectionDidDie:(NSNotification *)notification
{
// If the main connection to MacVim is lost this means that MacVim was
// either quit (by the user chosing Quit on the MacVim menu), or it has
// crashed. In the former case the flag 'isTerminating' is set and we then
// quit cleanly; in the latter case we make sure the swap files are left
// for recovery.
// If the main connection to MacVim is lost this means that either MacVim
// has crashed or this process did not receive its termination message
// properly (e.g. if the TerminateNowMsgID was dropped).
//
// NOTE: This is not called if a Vim controller invalidates its connection.
//NSLog(@"%s isTerminating=%d", _cmd, isTerminating);
if (isTerminating)
getout(0);
else
getout_preserve_modified(1);
NSLog(@"WARNING[%s]: Main connection was lost before process had a chance "
"to terminate; preserving swap files.", _cmd);
getout_preserve_modified(1);
}
- (void)blinkTimerFired:(NSTimer *)timer
@@ -2132,7 +2158,7 @@ static NSString *MMSymlinkWarningString =
bytes += sizeof(unsigned); // len not used
NSMutableString *name = [NSMutableString stringWithUTF8String:bytes];
[name appendString:[NSString stringWithFormat:@":h%.2f", pointSize]];
[name appendString:[NSString stringWithFormat:@":h%d", (int)pointSize]];
char_u *s = (char_u*)[name UTF8String];
#ifdef FEAT_MBYTE
@@ -2413,10 +2439,7 @@ static NSString *MMSymlinkWarningString =
[self addInput:@"|vert sall"];
// Restore the old value of 'suffixes'.
[self addInput:@"|let &su=mvim_oldsu|unlet mvim_oldsu"];
// Adding "|redr|f" ensures a "Hit ENTER" prompt is not shown.
[self addInput:@"|redr|f<CR>"];
[self addInput:@"|let &su=mvim_oldsu|unlet mvim_oldsu<CR>"];
} else {
// When opening one file we try to reuse the current window,
// but not if its buffer is modified or has a filename.
@@ -2447,9 +2470,7 @@ static NSString *MMSymlinkWarningString =
}
[self addInput:cmd];
// Adding "|redr|f" ensures a "Hit ENTER" prompt is not shown.
[self addInput:@"|redr|f<CR>"];
[self addInput:@"<CR>"];
}
// Force screen redraw (does it have to be this complicated?).
@@ -2503,9 +2524,7 @@ static NSString *MMSymlinkWarningString =
NSString *searchText = [args objectForKey:@"searchText"];
if (searchText) {
// TODO: Searching is an exclusive motion, so if the pattern would
// match on row 0 column 0 then this pattern will miss that match.
[self addInput:[NSString stringWithFormat:@"<C-\\><C-N>gg/\\c%@<CR>",
[self addInput:[NSString stringWithFormat:@"<C-\\><C-N>gg/\\c%@/e<CR>",
searchText]];
}
}
@@ -2524,17 +2543,44 @@ static NSString *MMSymlinkWarningString =
- (void)addInput:(NSString *)input
{
char_u *s = (char_u*)[input UTF8String];
// NOTE: This code is essentially identical to server_to_input_buf(),
// except the 'silent' flag is TRUE in the call to ins_typebuf() below.
char_u *string = [input vimStringSave];
if (!string) return;
#ifdef FEAT_MBYTE
s = CONVERT_FROM_UTF8(s);
#endif
/* Set 'cpoptions' the way we want it.
* B set - backslashes are *not* treated specially
* k set - keycodes are *not* reverse-engineered
* < unset - <Key> sequences *are* interpreted
* The last but one parameter of replace_termcodes() is TRUE so that the
* <lt> sequence is recognised - needed for a real backslash.
*/
char_u *ptr = NULL;
char_u *cpo_save = p_cpo;
p_cpo = (char_u *)"Bk";
char_u *str = replace_termcodes((char_u *)string, &ptr, FALSE, TRUE, FALSE);
p_cpo = cpo_save;
server_to_input_buf(s);
if (*ptr != NUL) /* trailing CTRL-V results in nothing */
{
/*
* Add the string to the input stream.
* Can't use add_to_input_buf() here, we now have K_SPECIAL bytes.
*
* First clear typed characters from the typeahead buffer, there could
* be half a mapping there. Then append to the existing string, so
* that multiple commands from a client are concatenated.
*/
if (typebuf.tb_maplen < typebuf.tb_len)
del_typebuf(typebuf.tb_len - typebuf.tb_maplen, typebuf.tb_maplen);
(void)ins_typebuf(str, REMAP_NONE, typebuf.tb_len, TRUE, TRUE);
#ifdef FEAT_MBYTE
CONVERT_FROM_UTF8_FREE(s);
#endif
/* Let input_available() know we inserted text in the typeahead
* buffer. */
typebuf_was_filled = TRUE;
}
vim_free(ptr);
vim_free(string);
}
- (BOOL)unusedEditor
+28 -27
View File
@@ -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;
@@ -139,8 +149,10 @@ static int numFullscreenWindows = 0;
int fuRows = currRows, fuColumns = currColumns;
// NOTE: Do not use [NSScreen visibleFrame] when determining the screen
// size since it compensates for menu and dock.
int maxRows, maxColumns;
NSSize size = [[self screen] visibleFrame].size;
NSSize size = [[self screen] frame].size;
[view constrainRows:&maxRows columns:&maxColumns toSize:size];
// Store current pre-fu vim size
@@ -277,8 +289,6 @@ static int numFullscreenWindows = 0;
CGReleaseDisplayFadeReservation(token);
}
[self revealDockIfAppropriate];
[self autorelease]; // Balance the above retain
}
@@ -347,38 +357,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);
}
}
+6 -3
View File
@@ -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 =
+21 -10
View File
@@ -52,7 +52,9 @@ static float MMDragAreaSize = 73.0f;
- (void)dealloc
{
[insertionPointColor release]; insertionPointColor = nil;
[markedText release]; markedText = nil;
[markedTextAttributes release]; markedTextAttributes = nil;
[super dealloc];
}
@@ -100,14 +102,19 @@ static float MMDragAreaSize = 73.0f;
int flags = [event modifierFlags];
if ((flags & NSControlKeyMask) ||
((flags & NSAlternateKeyMask) && (flags & NSFunctionKeyMask))) {
BOOL unmodIsPrintable = YES;
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]];
if (unmod && [unmod length] > 0 && [unmod characterAtIndex:0] < 0x20)
unmodIsPrintable = NO;
NSString *chars = [event characters];
if ([chars length] == 1 && [chars characterAtIndex:0] < 0x20
&& unmodIsPrintable) {
// HACK! Send unprintable characters (such as C-@, C-[, C-\, C-],
// C-^, C-_) as normal text to be added to the Vim input buffer.
// This must be done in order for the backend to be able to
// separate e.g. Ctrl-i and Ctrl-tab.
[self insertText:chars];
} else {
[self dispatchKeyEvent:event];
}
@@ -264,10 +271,14 @@ static float MMDragAreaSize = 73.0f;
if ([unmodchars isEqual:@"?"])
return NO;
// Cmd-. is hard-wired to send an interrupt (like Ctrl-C).
// 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:@"."]) {
[[self vimController] sendMessage:InterruptMsgID data:nil];
kill([[self vimController] pid], SIGINT);
return YES;
}
@@ -741,7 +752,7 @@ static float MMDragAreaSize = 73.0f;
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];
+1
View File
@@ -49,6 +49,7 @@
- (NSString *)serverName;
- (MMWindowController *)windowController;
- (NSDictionary *)vimState;
- (id)objectForVimStateKey:(NSString *)key;
- (NSMenu *)mainMenu;
- (BOOL)isPreloading;
- (void)setIsPreloading:(BOOL)yn;
+16 -3
View File
@@ -200,6 +200,11 @@ static BOOL isUnsafeMessage(int msgid);
return vimState;
}
- (id)objectForVimStateKey:(NSString *)key
{
return [vimState objectForKey:key];
}
- (NSMenu *)mainMenu
{
return mainMenu;
@@ -247,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",
@@ -859,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];
+3 -3
View File
@@ -88,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
@@ -100,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)];
@@ -129,7 +129,7 @@ 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];
+11 -1
View File
@@ -142,8 +142,18 @@
- (IBAction)zoom:(id)sender
{
NSScreen *screen = [self screen];
if (!screen) {
NSLog(@"[%s] WINDOW NOT ON SCREEN, zoom to main screen", _cmd);
screen = [NSScreen mainScreen];
if (!screen) {
NSLog(@"[%s] NO MAIN SCREEN, abort zoom", _cmd);
return;
}
}
NSRect frame = [self frame];
NSRect defaultFrame = [[self screen] visibleFrame];
NSRect defaultFrame = [screen visibleFrame];
defaultFrame = [[self delegate] windowWillUseStandardFrame:self
defaultFrame:defaultFrame];
+1
View File
@@ -22,6 +22,7 @@
MMVimView *vimView;
BOOL setupDone;
BOOL shouldResizeVimView;
int shouldUpdateToolbar;
BOOL keepOnScreen;
BOOL fullscreenEnabled;
NSString *windowAutosaveKey;
+86 -30
View File
@@ -81,6 +81,7 @@
- (BOOL)askBackendForStarRegister:(NSPasteboard *)pb;
- (void)hideTablineSeparator:(BOOL)hide;
- (void)doFindNext:(BOOL)next;
- (void)updateToolbar;
@end
@@ -428,6 +429,9 @@
// If we were to immediately resize then the vim view size would jitter
// (e.g. hiding/showing scrollbars often happens several time in one
// update).
// Also delay toggling the toolbar until after scrollbars otherwise
// problems arise when showing toolbar and scrollbar at the same time, i.e.
// on "set go+=rT".
if (shouldResizeVimView) {
shouldResizeVimView = NO;
@@ -448,6 +452,11 @@
keepOnScreen = NO;
}
if (shouldUpdateToolbar != 0) {
[self updateToolbar];
shouldUpdateToolbar = 0;
}
}
- (void)showTabBar:(BOOL)on
@@ -481,20 +490,16 @@
[toolbar setSizeMode:size];
[toolbar setDisplayMode:mode];
[toolbar setVisible:on];
if (([decoratedWindow styleMask] & NSTexturedBackgroundWindowMask) == 0) {
if (!on) {
[self hideTablineSeparator:YES];
} else {
[self hideTablineSeparator:![[vimView tabBarControl] isHidden]];
}
// NOTE: If the window is not visible we must toggle the toolbar
// immediately, otherwise "set go-=T" in .gvimrc will lead to the toolbar
// showing its hide animation every time a new window is opened. (See
// processCommandQueueDidFinish for the reason why we need to delay
// toggling the toolbar when the window is visible.)
if ([decoratedWindow isVisible]) {
shouldUpdateToolbar = on ? 1 : -1;
} else {
// Textured windows don't have a line below there title bar, so we
// need the separator in this case as well. In fact, the only case
// where we don't need the separator is when the tab bar control
// is visible (because it brings its own separator).
[self hideTablineSeparator:![[vimView tabBarControl] isHidden]];
[self updateToolbar];
}
}
@@ -757,7 +762,19 @@
- (void)windowDidMove:(NSNotification *)notification
{
if (setupDone && windowAutosaveKey) {
if (!setupDone)
return;
if (fullscreenEnabled) {
// HACK! The full-screen is not supposed to be able to be moved. If we
// do get here while in full-screen something unexpected happened (e.g.
// the full-screen window was on an external display that got
// unplugged) and we handle this situation by leaving full-screen.
[self leaveFullscreen];
return;
}
if (windowAutosaveKey) {
NSRect frame = [decoratedWindow frame];
NSPoint topLeft = { frame.origin.x, NSMaxY(frame) };
NSString *topLeftString = NSStringFromPoint(topLeft);
@@ -774,7 +791,11 @@
// 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, ...).
if (![win screen])
return proposedFrameSize;
// NOTE: Not called in full-screen mode so use "visibleFrame" instead of
// "frame".
NSRect maxFrame = [self constrainFrame:[[win screen] visibleFrame]];
if (proposedFrameSize.width > maxFrame.size.width)
@@ -891,24 +912,28 @@
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 ([decoratedWindow screen]) {
// Ensure that the window fits inside the visible part of the screen.
// NOTE: Not called in full-screen mode so use "visibleFrame' instead
// of "frame".
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)
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 (NSMaxX(newFrame) > NSMaxX(maxFrame))
newFrame.origin.x = NSMaxX(maxFrame) - newFrame.size.width;
}
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];
@@ -917,7 +942,15 @@
- (NSSize)constrainContentSizeToScreenSize:(NSSize)contentSize
{
NSWindow *win = [self window];
NSRect rect = [win contentRectForFrameRect:[[win screen] visibleFrame]];
if (![win screen])
return contentSize;
// NOTE: This may be called in both windowed and full-screen mode. The
// "visibleFrame" method does not overlap menu and dock so should not be
// used in full-screen.
NSRect screenRect = fullscreenEnabled ? [[win screen] frame]
: [[win screen] visibleFrame];
NSRect rect = [win contentRectForFrameRect:screenRect];
if (contentSize.height > rect.size.height)
contentSize.height = rect.size.height;
@@ -1025,4 +1058,27 @@
[vimController addVimInput:input];
}
- (void)updateToolbar
{
NSToolbar *toolbar = [decoratedWindow toolbar];
if (!toolbar) return;
BOOL on = shouldUpdateToolbar > 0 ? YES : NO;
[toolbar setVisible:on];
if (([decoratedWindow styleMask] & NSTexturedBackgroundWindowMask) == 0) {
if (!on) {
[self hideTablineSeparator:YES];
} else {
[self hideTablineSeparator:![[vimView tabBarControl] isHidden]];
}
} else {
// Textured windows don't have a line below there title bar, so we
// need the separator in this case as well. In fact, the only case
// where we don't need the separator is when the tab bar control
// is visible (because it brings its own separator).
[self hideTablineSeparator:![[vimView tabBarControl] isHidden]];
}
}
@end // MMWindowController (Private)
-6
View File
@@ -174,7 +174,6 @@ enum {
SetDocumentFilenameMsgID,
OpenWithArgumentsMsgID,
CloseWindowMsgID,
InterruptMsgID,
SetFullscreenColorMsgID,
ShowFindReplaceDialogMsgID,
FindReplaceMsgID,
@@ -225,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;
+1 -35
View File
@@ -29,7 +29,7 @@ char *MessageStrings[] =
"ShowTabBarMsgID",
"HideTabBarMsgID",
"SetTextRowsMsgID",
"SetTextColumsMsgID",
"SetTextColumnsMsgID",
"SetTextDimensionsMsgID",
"LiveResizeMsgID",
"SetTextDimensionsReplyMsgID",
@@ -81,7 +81,6 @@ char *MessageStrings[] =
"SetDocumentFilenameMsgID",
"OpenWithArgumentsMsgID",
"CloseWindowMsgID",
"InterruptMsgID",
"SetFullscreenColorMsgID",
"ShowFindReplaceDialogMsgID",
"FindReplaceMsgID",
@@ -100,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
+5 -5
View File
@@ -737,7 +737,7 @@
i386,
);
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 40;
CURRENT_PROJECT_VERSION = 44;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
@@ -778,7 +778,7 @@
buildSettings = {
ARCHS = "$(NATIVE_ARCH)";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 40;
CURRENT_PROJECT_VERSION = 44;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
@@ -797,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;
@@ -810,7 +810,7 @@
buildSettings = {
ARCHS = "$(NATIVE_ARCH)";
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 40;
CURRENT_PROJECT_VERSION = 44;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
@@ -829,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;
+2
View File
@@ -26,6 +26,7 @@
extern NSString *MMTabMinWidthKey;
extern NSString *MMTabMaxWidthKey;
extern NSString *MMTabOptimumWidthKey;
extern NSString *MMShowAddTabButtonKey;
extern NSString *MMTextInsetLeftKey;
extern NSString *MMTextInsetRightKey;
extern NSString *MMTextInsetTopKey;
@@ -53,6 +54,7 @@ extern NSString *MMOpenLayoutKey;
extern NSString *MMVerticalSplitKey;
extern NSString *MMPreloadCacheSizeKey;
extern NSString *MMLastWindowClosedBehaviorKey;
extern NSString *MMLoadDefaultFontKey;
// Enum for MMUntitledWindowKey
+2
View File
@@ -17,6 +17,7 @@
NSString *MMTabMinWidthKey = @"MMTabMinWidth";
NSString *MMTabMaxWidthKey = @"MMTabMaxWidth";
NSString *MMTabOptimumWidthKey = @"MMTabOptimumWidth";
NSString *MMShowAddTabButtonKey = @"MMShowAddTabButton";
NSString *MMTextInsetLeftKey = @"MMTextInsetLeft";
NSString *MMTextInsetRightKey = @"MMTextInsetRight";
NSString *MMTextInsetTopKey = @"MMTextInsetTop";
@@ -44,6 +45,7 @@ NSString *MMOpenLayoutKey = @"MMOpenLayout";
NSString *MMVerticalSplitKey = @"MMVerticalSplit";
NSString *MMPreloadCacheSizeKey = @"MMPreloadCacheSize";
NSString *MMLastWindowClosedBehaviorKey = @"MMLastWindowClosedBehavior";
NSString *MMLoadDefaultFontKey = @"MMLoadDefaultFont";
+115 -87
View File
@@ -22,13 +22,12 @@
// 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 BOOL gui_mch_init_has_finished = NO;
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);
@@ -99,15 +98,6 @@ gui_mch_init(void)
{
//NSLog(@"gui_mch_init()");
// NOTE! Because OS X has to exec after fork we effectively end up doing
// the initialization twice (because this function is called before the
// fork). To avoid all this extra work we check if Vim is about to fork,
// and if so do nothing for now.
//
// TODO: Is this check 100% foolproof?
if (gui.dofork && (vim_strchr(p_go, GO_FORG) == NULL))
return OK;
if (![[MMBackend sharedInstance] checkin]) {
// TODO: Kill the process if there is no terminal to fall back on,
// otherwise the process will run outputting to the console.
@@ -140,8 +130,6 @@ gui_mch_init(void)
// in [g]vimrc.
gui_mch_adjust_charheight();
gui_mch_init_has_finished = YES;
return OK;
}
@@ -162,12 +150,6 @@ gui_mch_exit(int rc)
int
gui_mch_open(void)
{
//NSLog(@"gui_mch_open()");
// This check is to avoid doing extra work when we're about to fork.
if (!gui_mch_init_has_finished)
return OK;
return [[MMBackend sharedInstance] openGUIWindow];
}
@@ -189,7 +171,8 @@ gui_mch_update(void)
// 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.
// second. Note that Cmd-. sends SIGINT so it has higher success rate at
// interrupting Vim.
static CFAbsoluteTime lastTime = 0;
CFAbsoluteTime nowTime = CFAbsoluteTimeGetCurrent();
@@ -210,6 +193,48 @@ gui_mch_flush(void)
}
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. */
void
@@ -897,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.
*/
@@ -911,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);
@@ -925,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
@@ -952,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;
}
@@ -983,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 ------------------------------------------------------------
@@ -1675,6 +1700,9 @@ 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);
+4 -1
View File
@@ -1,7 +1,7 @@
" System gvimrc file for MacVim
"
" Maintainer: Bjorn Winckler <bjorn.winckler@gmail.com>
" Last Change: Sun Oct 04 2008
" Last Change: Sun Mar 15 2009
"
" This is a work in progress. If you feel so inclined, please help me improve
" this file.
@@ -26,6 +26,9 @@ if !exists("colors_name")
colorscheme macvim
endif
" To make tabs more readable, the label only contains the tail of the file
" name and the buffer modified flag.
set guitablabel=%M%t
" Send print jobs to Preview.app. This does not delete the temporary ps file
+17 -2
View File
@@ -2,10 +2,25 @@
OUTDIR ?= .
$(OUTDIR)/MacVim-generic.icns: make_icons.py vim-noshadow-512.png
$(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
/usr/bin/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
rm -f $(OUTDIR)/MacVim-*.icns loadfont.so *.pyc \
EnvyCodeR.zip *.ttf *.reg *.txt
rm -rf *.egginfo build # Created by setup.py
+605
View File
@@ -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()
+65
View File
@@ -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()
+56
View File
@@ -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);
}
+98 -437
View File
@@ -1,30 +1,51 @@
# Creates a document icon from an app icon and an optional text.
# The font is not quite right, use this script to create a document icon
# for 'PDF' and compare the D with the D in Preview's pdf.icns
# Creates all of MacVim document icons.
# http://www.macresearch.org/cocoa-scientists-part-xx-python-scriptersmeet-cocoa
try:
from Foundation import *
# 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 math
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+)
# path to makeicns binary
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
# XXX: 32x32 variants only support 3-4 letters of text
GENERIC_ICON_NAME = 'MacVim-generic'
vimIcons = {
GENERIC_ICON_NAME: [u'', LARGE],
@@ -35,19 +56,19 @@ vimIcons = {
'MacVim-c': [u'C', SMALL],
'MacVim-m': [u'M', SMALL],
'MacVim-mm': [u'MM', SMALL],
'MacVim-cpp': [u'C\uff0b\uff0b', SMALL], # fullwidth plusses
'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', SMALL],
'MacVim-py': [u'PYTHON', SMALL],
'MacVim-perl': [u'PERL,PL', SMALL],
'MacVim-py': [u'PYTHON,PY', SMALL],
'MacVim-php': [u'PHP', SMALL],
'MacVim-rb': [u'RUBY', SMALL],
'MacVim-rb': [u'RUBY,RB', SMALL],
'MacVim-bash': [u'SH', SMALL],
'MacVim-patch': [u'DIFF', SMALL],
'MacVim-applescript': [u'\uf8ffSCPT', SMALL], # apple sign
'MacVim-applescript': [u'\uf8ffSCPT,\uf8ffS', SMALL], # apple sign
'MacVim-as': [u'FLASH', LINK],
'MacVim-asp': [u'ASP', LINK],
'MacVim-bib': [u'BIB', LINK],
@@ -60,8 +81,8 @@ vimIcons = {
'MacVim-css': [u'CSS', SMALL],
'MacVim-dtd': [u'DTD', LINK],
'MacVim-dylan': [u'DYLAN', LINK],
'MacVim-erl': [u'ERLANG', SMALL],
'MacVim-fscript': [u'FSCPT', SMALL],
'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],
@@ -70,386 +91,21 @@ vimIcons = {
'MacVim-bsh': [u'BSH', LINK],
'MacVim-properties': [u'PROP', LINK],
'MacVim-jsp': [u'JSP', SMALL],
'MacVim-lisp': [u'LISP', 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', 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', SMALL],
'MacVim-vb': [u'VBASIC', LINK],
'MacVim-yaml': [u'YAML', SMALL],
'MacVim-vcf': [u'VCARD,VCF', SMALL],
'MacVim-vb': [u'VBASIC,VB', LINK],
'MacVim-yaml': [u'YAML,YAML,YML', SMALL],
'MacVim-gtd': [u'GTD', LINK],
}
shorttext = {
u'MacVim-py': u'PY',
u'MacVim-rb': u'RB',
u'MacVim-perl': u'PL',
u'MacVim-applescript': u'\uf8ffS',
u'MacVim-erl': u'ERL',
u'MacVim-fscript': u'FSCR',
u'MacVim-sch': u'SCM',
u'MacVim-vcf': u'VCF',
u'MacVim-vb': u'VB',
}
# Resources
BACKGROUND = '/System/Library/CoreServices/CoreTypes.bundle/' + \
'Contents/Resources/GenericDocumentIcon.icns' # might require leopard?
APPICON = 'vim-noshadow-512.png'
#APPICON = 'vim-noshadow-no-v-512.png'
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(filename))
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():
if map(int, rep.size()) == [w, h]:
r = rep
break
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)
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):
self.bgRenderer = bg
self.icon = icon
self.cache = {}
def drawIcon(self, s):
if not self.icon:
return
# found by flow program, better than anything i came up with manually before
# (except for the 16x16 variant :-( )
transforms = {
512: [ 0.7049, 0.5653, -4.2432, 0.5656],
256: [ 0.5690, 0.5658, -1.9331, 0.5656],
128: [ 1.1461, 0.5684, -0.8482, 0.5681],
32: [-0.2682, 0.5895, -2.2130, 0.5701], # intensity
#32: [-0.2731, 0.5898, -2.2262, 0.5729], # rgb (no rmse difference)
#16: [-0.3033, 0.4909, -1.3235, 0.4790], # program, intensity
#16: [-0.3087, 0.4920, -1.2990, 0.4750], # program, rgb mode
16: [ 0.0000, 0.5000, -1.0000, 0.5000], # manually, better
}
assert s in [16, 32, 128, 256, 512]
a = transforms[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):
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(outname, s, bg, textRenderer, text, shorttext=None):
# Fill in background
output = bg.backgroundAtSize(s).copy()
# Draw text on top of shadow
context = Context(output)
if s in [16, 32] and shorttext:
text = shorttext
textRenderer.drawTextAtSize(text, s)
context.done()
# Save
output.save(outname)
def createLinks(icons, target):
assert len(icons) > 0
@@ -460,65 +116,75 @@ def createLinks(icons, target):
os.symlink(target, icnsName)
TMPFILE = 'make_icons_tmp_%d.png'
sizes = [512, 128, 32, 16]
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)
if dont_create:
print "PyObjC not found, only using a stock icon for document icons."
import shutil
shutil.copyfile(BACKGROUND, '%s.icns' % GENERIC_ICON_NAME)
createLinks([name for name in vimIcons if name != GENERIC_ICON_NAME],
'%s.icns' % GENERIC_ICON_NAME)
return
# Make us not crash
# http://www.cocoabuilder.com/archive/message/cocoa/2008/8/6/214964
NSApplicationLoad()
textRenderer = TextRenderer()
#textRenderer = OfficeTextRenderer()
# Prepare input images
bgIcon = Image(BACKGROUND)
#bg = SplittableBackground(bgIcon, shouldSplit=False)
bg = SplittableBackground(bgIcon, shouldSplit=True)
icon = Image(appIcon)
bgRenderer = BackgroundRenderer(bg, icon)
if not os.access(makeIcns, os.X_OK):
print 'Cannot find makeicns at %s', makeIcns
return
# create LARGE and SMALL icons first...
for name, t in vimIcons.iteritems():
text, size = t
if size == LINK: continue
print name
icnsName = '%s.icns' % name
if size == SMALL:
currSizes = [128, 32, 16]
args = '-128 %s -32 %s -16 %s' % (
TMPFILE % 128, TMPFILE % 32, TMPFILE % 16)
elif size == LARGE:
currSizes = [512, 128, 32, 16]
args = '-512 %s -128 %s -32 %s -16 %s' % (
TMPFILE % 512, TMPFILE % 128, TMPFILE % 32, TMPFILE % 16)
st = shorttext.get(name)
for s in currSizes:
createIcon(TMPFILE % s, s, bgRenderer, textRenderer, text, shorttext=st)
os.system('%s %s -out %s' % (makeIcns, args, icnsName))
del text, size, name, t
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],
@@ -526,9 +192,4 @@ def main():
if __name__ == '__main__':
try:
main()
finally:
for s in sizes:
if os.access(TMPFILE % s, os.F_OK):
os.remove(TMPFILE % s)
+3 -2
View File
@@ -54,9 +54,10 @@ void usage() {
NSBitmapImageRep* getBitmapImageRepOfSize(NSImage* img, int size) {
// Don't resample if it's not necessary
// XXX: Seems as if this creates problems in some situations, disable this
// for now.
#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])) {
+5
View File
@@ -0,0 +1,5 @@
from distutils.core import setup, Extension
setup(name="loadfont", version="1.0",
ext_modules = [Extension("loadfont", ["loadfont.c"])])
+92
View File
@@ -40,6 +40,98 @@
Sparkle supports updates in zip, tar, tbz, tgz, or dmg format.
-->
<item>
<title>Snapshot 44 released</title>
<description><![CDATA[
<h1>MacVim snapshot 44 released</h1>
<p> Changes since snapshot 43:
<ul>
<li> The color table had many erroneous entries which have been corrected (Zvezdan Petkovic) </li>
<li> Ctrl+tab works again </li>
<li> Tab labels only show file tail by default to make them more legible (reset to default by adding "set guitablabel&" to .gvimrc) </li>
<li> The number of columns does not change on ":set go+=rT" </li>
<li> Fixed problems with view not maximizing when entering full-screen and the Dock was visible </li>
<li> Fix various problems related to having windows on a screen that got unplugged (fixes Issue 162) </li>
<li> Latest source code version and runtime files (e.g. the Python syntax file is fixed, fixes Issue 160) </li>
</ul>
</p>
]]></description>
<pubDate>Sun, 29 Mar 2009 16:56 CET</pubDate>
<enclosure type="application/octet-stream"
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-44.tbz"
length="8139075"
sparkle:version="44"
sparkle:shortVersionString="7.2"
/>
</item>
<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[
+3
View File
@@ -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.
+61
View File
@@ -11565,6 +11565,67 @@ _ACEOF
fi
{ $as_echo "$as_me:$LINENO: checking for working volatile" >&5
$as_echo_n "checking for working volatile... " >&6; }
if test "${ac_cv_c_volatile+set}" = set; then
$as_echo_n "(cached) " >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
int
main ()
{
volatile int x;
int * volatile y = (int *) 0;
return !x && !y;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
$as_echo "$ac_try_echo") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
ac_cv_c_volatile=yes
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_c_volatile=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_volatile" >&5
$as_echo "$ac_cv_c_volatile" >&6; }
if test $ac_cv_c_volatile = no; then
cat >>confdefs.h <<\_ACEOF
#define volatile /**/
_ACEOF
fi
{ $as_echo "$as_me:$LINENO: checking for mode_t" >&5
$as_echo_n "checking for mode_t... " >&6; }
if test "${ac_cv_type_mode_t+set}" = set; then
+6 -11
View File
@@ -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 */
@@ -819,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);
@@ -916,9 +913,6 @@ do_bufdel(command, arg, addr_count, start_bnr, end_bnr, forceit)
}
}
#ifdef FEAT_NETBEANS_INTG
netbeansCloseFile = 0;
#endif
return errormsg;
}
@@ -5114,7 +5108,8 @@ buf_spname(buf)
*/
FOR_ALL_TAB_WINDOWS(tp, win)
if (win->w_buffer == buf)
break;
goto win_found;
win_found:
if (win != NULL && win->w_llist_ref != NULL)
return _("[Location List]");
else
+3
View File
@@ -50,6 +50,9 @@
/* Define to empty if the keyword does not work. */
#undef const
/* Define to empty if the keyword does not work. */
#undef volatile
/* Define to `int' if <sys/types.h> doesn't define. */
#undef mode_t
+1
View File
@@ -2184,6 +2184,7 @@ fi
dnl Checks for typedefs, structures, and compiler characteristics.
AC_PROG_GCC_TRADITIONAL
AC_C_CONST
AC_C_VOLATILE
AC_TYPE_MODE_T
AC_TYPE_OFF_T
AC_TYPE_PID_T
+6 -4
View File
@@ -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"
@@ -116,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.
*/
@@ -929,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
@@ -1153,7 +1153,7 @@ ex_diffoff(eap)
for (wp = firstwin; wp != NULL; wp = wp->w_next)
{
if (wp == curwin || eap->forceit)
if (wp == curwin || (eap->forceit && wp->w_p_diff))
{
/* Set 'diff', 'scrollbind' off and 'wrap' on. */
wp->w_p_diff = FALSE;
@@ -2129,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 -24
View File
@@ -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
@@ -7646,9 +7703,7 @@ ins_reg()
*/
++no_mapping;
regname = plain_vgetc();
#ifdef FEAT_LANGMAP
LANGMAP_ADJUST(regname, TRUE);
#endif
if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P)
{
/* Get a third key for literal register insertion */
@@ -7657,9 +7712,7 @@ ins_reg()
add_to_showcmd_c(literally);
#endif
regname = plain_vgetc();
#ifdef FEAT_LANGMAP
LANGMAP_ADJUST(regname, TRUE);
#endif
}
--no_mapping;
@@ -8150,7 +8203,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 +8292,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 +8609,7 @@ ins_bs(c, mode, inserted_space_p)
break;
}
if (State & REPLACE_FLAG)
replace_do_bs();
replace_do_bs(-1);
else
{
#ifdef FEAT_MBYTE
+9 -8
View File
@@ -3928,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.
@@ -7918,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)
@@ -8153,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)
@@ -19887,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;
}
@@ -19931,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);
}
}
@@ -20203,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;
}
@@ -20218,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;
}
@@ -21497,7 +21498,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
/*
* Return TRUE if items in "fc" do not have "copyID". That means they are not
* referenced from anywyere.
* referenced from anywhere.
*/
static int
can_free_funccal(fc, copyID)
+51 -19
View File
@@ -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++];
@@ -2412,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;
}
/*
@@ -2702,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
}
@@ -6531,6 +6541,7 @@ static sign_T *first_sign = NULL;
static int last_sign_typenr = MAX_TYPENR; /* is decremented */
static void sign_list_defined __ARGS((sign_T *sp));
static void sign_undefine __ARGS((sign_T *sp, sign_T *sp_prev));
/*
* ":sign" command
@@ -6739,24 +6750,8 @@ ex_sign(eap)
/* ":sign list {name}" */
sign_list_defined(sp);
else
{
/* ":sign undefine {name}" */
vim_free(sp->sn_name);
vim_free(sp->sn_icon);
#ifdef FEAT_SIGN_ICONS
if (sp->sn_image != NULL)
{
out_flush();
gui_mch_destroy_sign(sp->sn_image);
}
#endif
vim_free(sp->sn_text);
if (sp_prev == NULL)
first_sign = sp->sn_next;
else
sp_prev->sn_next = sp->sn_next;
vim_free(sp);
}
sign_undefine(sp, sp_prev);
}
}
else
@@ -7004,6 +6999,31 @@ sign_list_defined(sp)
}
}
/*
* Undefine a sign and free its memory.
*/
static void
sign_undefine(sp, sp_prev)
sign_T *sp;
sign_T *sp_prev;
{
vim_free(sp->sn_name);
vim_free(sp->sn_icon);
#ifdef FEAT_SIGN_ICONS
if (sp->sn_image != NULL)
{
out_flush();
gui_mch_destroy_sign(sp->sn_image);
}
#endif
vim_free(sp->sn_text);
if (sp_prev == NULL)
first_sign = sp->sn_next;
else
sp_prev->sn_next = sp->sn_next;
vim_free(sp);
}
/*
* Get highlighting attribute for sign "typenr".
* If "line" is TRUE: line highl, if FALSE: text highl.
@@ -7078,6 +7098,18 @@ sign_typenr2name(typenr)
return (char_u *)_("[Deleted]");
}
#if defined(EXITFREE) || defined(PROTO)
/*
* Undefine/free all signs.
*/
void
free_signs()
{
while (first_sign != NULL)
sign_undefine(first_sign, NULL);
}
#endif
#endif
#if defined(FEAT_GUI) || defined(FEAT_CLIENTSERVER) || defined(PROTO)
+24 -19
View File
@@ -2915,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;
@@ -3065,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.
@@ -3091,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
@@ -3184,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
@@ -3244,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
+65 -7
View File
@@ -3690,6 +3690,11 @@ set_one_cmd_context(xp, buff)
case CMD_highlight:
set_context_in_highlight_cmd(xp, arg);
break;
#ifdef FEAT_CSCOPE
case CMD_cscope:
set_context_in_cscope_cmd(xp, arg);
break;
#endif
#ifdef FEAT_LISTCMDS
case CMD_bdelete:
case CMD_bwipeout:
@@ -5142,7 +5147,11 @@ uc_add_command(name, name_len, rep, argt, def, flags, compl, compl_arg, force)
}
vim_free(cmd->uc_rep);
cmd->uc_rep = 0;
cmd->uc_rep = NULL;
#if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
vim_free(cmd->uc_compl_arg);
cmd->uc_compl_arg = NULL;
#endif
break;
}
@@ -5201,6 +5210,9 @@ static struct
{EXPAND_AUGROUP, "augroup"},
{EXPAND_BUFFERS, "buffer"},
{EXPAND_COMMANDS, "command"},
#if defined(FEAT_CSCOPE)
{EXPAND_CSCOPE, "cscope"},
#endif
#if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
{EXPAND_USER_DEFINED, "custom"},
{EXPAND_USER_LIST, "customlist"},
@@ -5500,6 +5512,9 @@ invalid_count:
return OK;
}
/*
* ":command ..."
*/
static void
ex_command(eap)
exarg_T *eap;
@@ -5931,7 +5946,8 @@ do_ucmd(eap)
char_u *q;
char_u *start;
char_u *end;
char_u *end = NULL;
char_u *ksp;
size_t len, totlen;
size_t split_len = 0;
@@ -5948,16 +5964,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; /* destination */
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;
@@ -7827,6 +7878,9 @@ free_cd_dir()
{
vim_free(prev_dir);
prev_dir = NULL;
vim_free(globaldir);
globaldir = NULL;
}
#endif
@@ -7849,6 +7903,10 @@ ex_cd(eap)
else
#endif
{
#ifdef FEAT_AUTOCMD
if (allbuf_locked())
return;
#endif
if (vim_strchr(p_cpo, CPO_CHDIR) != NULL && curbufIsChanged()
&& !eap->forceit)
{
@@ -8773,7 +8831,7 @@ ex_mkrc(eap)
else if (*dirnow != NUL
&& (ssop_flags & SSOP_CURDIR) && globaldir != NULL)
{
if (mch_chdir((char *)globaldir) == OK)
if (mch_chdir((char *)globaldir) == 0)
shorten_fnames(TRUE);
}
+22 -6
View File
@@ -2000,8 +2000,8 @@ text_locked_msg()
#if defined(FEAT_AUTOCMD) || defined(PROTO)
/*
* Check if "curbuf_lock" is set and return TRUE when it is and give an error
* message.
* Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is
* and give an error message.
*/
int
curbuf_locked()
@@ -2011,6 +2011,21 @@ curbuf_locked()
EMSG(_("E788: Not allowed to edit another buffer now"));
return TRUE;
}
return allbuf_locked();
}
/*
* Check if "allbuf_lock" is set and return TRUE when it is and give an error
* message.
*/
int
allbuf_locked()
{
if (allbuf_lock > 0)
{
EMSG(_("E811: Not allowed to change buffer information now"));
return TRUE;
}
return FALSE;
}
#endif
@@ -4503,6 +4518,9 @@ ExpandFromContext(xp, pat, num_file, file, options)
{EXPAND_EVENTS, get_event_name, TRUE},
{EXPAND_AUGROUP, get_augroup_name, TRUE},
#endif
#ifdef FEAT_CSCOPE
{EXPAND_CSCOPE, get_cscope_name, TRUE},
#endif
#if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
{EXPAND_LANGUAGE, get_lang_arg, TRUE},
@@ -6050,9 +6068,7 @@ ex_window()
# endif
return K_IGNORE;
}
cmdwin_type = ccline.cmdfirstc;
if (cmdwin_type == NUL)
cmdwin_type = '-';
cmdwin_type = get_cmdline_type();
/* Create the command-line buffer empty. */
(void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
@@ -6076,7 +6092,7 @@ ex_window()
/* Showing the prompt may have set need_wait_return, reset it. */
need_wait_return = FALSE;
histtype = hist_char2type(ccline.cmdfirstc);
histtype = hist_char2type(cmdwin_type);
if (histtype == HIST_CMD || histtype == HIST_DEBUG)
{
if (p_wc == TAB)
+124 -9
View File
@@ -69,7 +69,7 @@ static int apply_autocmds_exarg __ARGS((event_T event, char_u *fname, char_u *fn
static int au_find_group __ARGS((char_u *name));
# define AUGROUP_DEFAULT -1 /* default autocmd group */
# define AUGROUP_ERROR -2 /* errornouse autocmd group */
# define AUGROUP_ERROR -2 /* erroneous autocmd group */
# define AUGROUP_ALL -3 /* all autocmd groups */
#endif
@@ -144,7 +144,9 @@ static int get_mac_fio_flags __ARGS((char_u *ptr));
# endif
#endif
static int move_lines __ARGS((buf_T *frombuf, buf_T *tobuf));
#ifdef FEAT_AUTOCMD
static char *e_auchangedbuf = N_("E812: Autocommands changed buffer or buffer name");
#endif
void
filemess(buf, name, s, attr)
@@ -295,6 +297,19 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
int conv_restlen = 0; /* nr of bytes in conv_rest[] */
#endif
#ifdef FEAT_AUTOCMD
/* Remember the initial values of curbuf, curbuf->b_ffname and
* curbuf->b_fname to detect whether they are altered as a result of
* executing nasty autocommands. Also check if "fname" and "sfname"
* point to one of these values. */
buf_T *old_curbuf = curbuf;
char_u *old_b_ffname = curbuf->b_ffname;
char_u *old_b_fname = curbuf->b_fname;
int using_b_ffname = (fname == curbuf->b_ffname)
|| (sfname == curbuf->b_ffname);
int using_b_fname = (fname == curbuf->b_fname)
|| (sfname == curbuf->b_fname);
#endif
write_no_eol_lnum = 0; /* in case it was set by the previous read */
/*
@@ -589,7 +604,21 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
#ifdef FEAT_QUICKFIX
if (!bt_dontwrite(curbuf))
#endif
{
check_need_swap(newfile);
#ifdef FEAT_AUTOCMD
/* SwapExists autocommand may mess things up */
if (curbuf != old_curbuf
|| (using_b_ffname
&& (old_b_ffname != curbuf->b_ffname))
|| (using_b_fname
&& (old_b_fname != curbuf->b_fname)))
{
EMSG(_(e_auchangedbuf));
return FAIL;
}
#endif
}
if (dir_of_file_exists(fname))
filemess(curbuf, sfname, (char_u *)_("[New File]"), 0);
else
@@ -668,6 +697,17 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
#endif
{
check_need_swap(newfile);
#ifdef FEAT_AUTOCMD
if (!read_stdin && (curbuf != old_curbuf
|| (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
|| (using_b_fname && (old_b_fname != curbuf->b_fname))))
{
EMSG(_(e_auchangedbuf));
if (!read_buffer)
close(fd);
return FAIL;
}
#endif
#ifdef UNIX
/* Set swap file protection bits after creating it. */
if (swap_mode > 0 && curbuf->b_ml.ml_mfp->mf_fname != NULL)
@@ -698,7 +738,6 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
{
int m = msg_scroll;
int n = msg_scrolled;
buf_T *old_curbuf = curbuf;
/*
* The file must be closed again, the autocommands may want to change
@@ -740,8 +779,13 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
/*
* Don't allow the autocommands to change the current buffer.
* Try to re-open the file.
*
* Don't allow the autocommands to change the buffer name either
* (cd for example) if it invalidates fname or sfname.
*/
if (!read_stdin && (curbuf != old_curbuf
|| (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
|| (using_b_fname && (old_b_fname != curbuf->b_fname))
|| (fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) < 0))
{
--no_wait_return;
@@ -5248,13 +5292,16 @@ buf_write_bytes(ip)
/* Convert with iconv(). */
if (ip->bw_restlen > 0)
{
char *fp;
/* Need to concatenate the remainder of the previous call and
* the bytes of the current call. Use the end of the
* conversion buffer for this. */
fromlen = len + ip->bw_restlen;
from = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
mch_memmove((void *)from, ip->bw_rest, (size_t)ip->bw_restlen);
mch_memmove((void *)(from + ip->bw_restlen), buf, (size_t)len);
fp = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
mch_memmove(fp, ip->bw_rest, (size_t)ip->bw_restlen);
mch_memmove(fp + ip->bw_restlen, buf, (size_t)len);
from = fp;
tolen = ip->bw_conv_buflen - fromlen;
}
else
@@ -6111,12 +6158,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.
@@ -6124,6 +6183,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
@@ -6267,7 +6375,7 @@ check_timestamps(focus)
if (!stuff_empty() || global_busy || !typebuf_typed()
#ifdef FEAT_AUTOCMD
|| autocmd_busy || curbuf_lock > 0
|| autocmd_busy || curbuf_lock > 0 || allbuf_lock > 0
#endif
)
need_check_timestamps = TRUE; /* check later */
@@ -6475,8 +6583,10 @@ buf_check_timestamp(buf, focus)
set_vim_var_string(VV_FCS_REASON, (char_u *)reason, -1);
set_vim_var_string(VV_FCS_CHOICE, (char_u *)"", -1);
# endif
++allbuf_lock;
n = apply_autocmds(EVENT_FILECHANGEDSHELL,
buf->b_fname, buf->b_fname, FALSE, buf);
--allbuf_lock;
busy = FALSE;
if (n)
{
@@ -6551,6 +6661,11 @@ buf_check_timestamp(buf, focus)
tbuf = alloc((unsigned)(STRLEN(path) + STRLEN(mesg)
+ STRLEN(mesg2) + 2));
sprintf((char *)tbuf, mesg, path);
#ifdef FEAT_EVAL
/* Set warningmsg here, before the unimportant and output-specific
* mesg2 has been appended. */
set_vim_var_string(VV_WARNINGMSG, tbuf, -1);
#endif
#if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
if (can_reload)
{
+12 -6
View File
@@ -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);
}
+4
View File
@@ -3816,7 +3816,11 @@ showmap(mp, local)
int len = 1;
if (msg_didout || msg_silent != 0)
{
msg_putchar('\n');
if (got_int) /* 'q' typed at MORE prompt */
return;
}
if ((mp->m_mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
msg_putchar('!'); /* :map! */
else if (mp->m_mode & INSERT)
+17 -7
View File
@@ -482,8 +482,10 @@ EXTERN char *foreground_argument INIT(= NULL);
/*
* While executing external commands or in Ex mode, should not insert GUI
* events in the input buffer: Set hold_gui_events to non-zero.
*
* volatile because it is used in signal handler sig_sysmouse().
*/
EXTERN int hold_gui_events INIT(= 0);
EXTERN volatile int hold_gui_events INIT(= 0);
/*
* When resizing the shell is postponed, remember the new size, and call
@@ -597,7 +599,8 @@ EXTERN int exiting INIT(= FALSE);
EXTERN int really_exiting INIT(= FALSE);
/* TRUE when we are sure to exit, e.g., after
* a deadly signal */
EXTERN int full_screen INIT(= FALSE);
/* volatile because it is used in signal handler deathtrap(). */
EXTERN volatile int full_screen INIT(= FALSE);
/* TRUE when doing full-screen output
* otherwise only writing some messages */
@@ -616,6 +619,11 @@ EXTERN int textlock INIT(= 0);
EXTERN int curbuf_lock INIT(= 0);
/* non-zero when the current buffer can't be
* changed. Used for FileChangedRO. */
EXTERN int allbuf_lock INIT(= 0);
/* non-zero when no buffer name can be
* changed, no buffer can be deleted and
* current directory can't be changed.
* Used for SwapExists et al. */
#endif
#ifdef FEAT_EVAL
# define HAVE_SANDBOX
@@ -739,10 +747,12 @@ EXTERN JMP_BUF x_jump_env;
*/
EXTERN JMP_BUF lc_jump_env; /* argument to SETJMP() */
# ifdef SIGHASARG
EXTERN int lc_signal; /* catched signal number, 0 when no was signal
catched; used for mch_libcall() */
/* volatile because it is used in signal handlers. */
EXTERN volatile int lc_signal; /* caught signal number, 0 when no was signal
caught; used for mch_libcall() */
# endif
EXTERN int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */
/* volatile because it is used in signal handler deathtrap(). */
EXTERN volatile int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */
#endif
#if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT)
@@ -986,7 +996,8 @@ EXTERN int curscript INIT(= 0); /* index in scriptin[] */
EXTERN FILE *scriptout INIT(= NULL); /* stream to write script to */
EXTERN int read_cmd_fd INIT(= 0); /* fd to read commands from */
EXTERN int got_int INIT(= FALSE); /* set to TRUE when interrupt
/* volatile because it is used in signal handler catch_sigint(). */
EXTERN volatile int got_int INIT(= FALSE); /* set to TRUE when interrupt
signal occurred */
#ifdef USE_TERM_CONSOLE
EXTERN int term_console INIT(= FALSE); /* set to TRUE when console used */
@@ -1342,7 +1353,6 @@ EXTERN garray_T error_ga
#ifdef FEAT_NETBEANS_INTG
EXTERN char *netbeansArg INIT(= NULL); /* the -nb[:host:port:passwd] arg */
EXTERN int netbeansCloseFile INIT(= 0); /* send killed if != 0 */
EXTERN int netbeansFireChanges INIT(= 1); /* send buffer changes if != 0 */
EXTERN int netbeansForcedQuit INIT(= 0);/* don't write modified files */
EXTERN int netbeansReadFile INIT(= 1); /* OK to read from disk if != 0 */
+13 -89
View File
@@ -58,7 +58,11 @@ static int can_update_cursor = TRUE; /* can display the cursor */
gui_start()
{
char_u *old_term;
#if defined(UNIX) && !defined(__BEOS__)
#if defined(UNIX) && !defined(__BEOS__) && !defined(MACOS_X)
/* By the time we get here Mac OS X will already have forked (it does so
* right after scanning the command line) so don't do anything here. This
* means that "f" in 'guioptions' cannot be supported.
*/
# define MAY_FORK
int dofork = TRUE;
#endif
@@ -117,82 +121,10 @@ gui_start()
*/
if (gui.in_use && dofork)
{
pid_t pid = -1;
# if defined MACOS_X
int i;
/* on os x, you have to exec after a fork, otherwise calls to
* frameworks will assert (and without corefoundation, you can't start
* the gui. what fun.). See CAVEATS at
http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/fork.2.html
*
* Since we have to go through this anyways, we might as well use vfork.
* But: then we can't detach from our starting shell, so stick with
* fork.
*
* Kinda sucks to restart vim when doing :gui, so don't fork in that
* case (make sure gui.dofork is only set when interpreting argv, not
* when doing :gui. Currently, gui.dofork is set to false in ex_gui().
*
* Also doesn't work well if vim starts cscope (or some other
* subprocess I guess), because it's not transferred to the newly
* exec'd process, leaving an orphaned process (not a zombie process)
* behind. The Right Thing is to kill all our child processes before
* calling exec.
*/
/* stolen from http://paste.lisp.org/display/50906 */
extern int *_NSGetArgc(void);
extern char ***_NSGetArgv(void);
int argc = *_NSGetArgc();
char ** argv = *_NSGetArgv();
char * newargv[argc+2];
newargv[0] = argv[0];
/*
* make sure "-f" is in front of potential "--remote" flags, else
* they would consume it.
*/
newargv[1] = "-f";
for (i = 1; i < argc; i++) {
newargv[i + 1] = argv[i];
}
newargv[argc+1] = NULL;
/* shut down all the stuff we just started, just to start
* it again from the exec :-\ */
prepare_getout();
pid = fork();
switch(pid) {
case -1:
# ifndef NDEBUG
fprintf(stderr, "vim: Mac OS X workaround fork() failed!");
# endif
_exit(255);
case 0:
/* Child. */
/* make sure we survive our shell */
setsid();
/* Restarts the vim process, will not return. */
execvp(argv[0], newargv);
/* if we come here, exec has failed. bail. */
_exit(255);
default:
/* Parent */
_exit(0);
}
# else
int pipefd[2]; /* pipe between parent and child */
int pipe_error;
char dummy;
pid_t pid = -1;
/* Setup a pipe between the child and the parent, so that the parent
* knows when the child has done the setsid() call and is allowed to
@@ -227,30 +159,27 @@ http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/fork.2.h
_exit(0);
}
# if defined(HAVE_SETSID) || defined(HAVE_SETPGID)
# if defined(HAVE_SETSID) || defined(HAVE_SETPGID)
/*
* Change our process group. On some systems/shells a CTRL-C in the
* shell where Vim was started would otherwise kill gvim!
*/
if (pid == 0) /* child */
# if defined(HAVE_SETSID)
# if defined(HAVE_SETSID)
(void)setsid();
# else
# else
(void)setpgid(0, 0);
# endif
# endif
# endif
if (!pipe_error)
{
close(pipefd[0]);
close(pipefd[1]);
}
# if defined(FEAT_GUI_GNOME) && defined(FEAT_SESSION)
# if defined(FEAT_GUI_GNOME) && defined(FEAT_SESSION)
/* Tell the session manager our new PID */
gui_mch_forked();
# endif
# endif
}
#else
@@ -4820,6 +4749,8 @@ ex_gui(eap)
* Check for "-f" argument: foreground, don't fork.
* Also don't fork when started with "gvim -f".
* Do fork when using "gui -b".
* Note that Mac OS X will never fork on :gui since it can only fork on
* startup right after scanning the command line.
*/
if (arg[0] == '-'
&& (arg[1] == 'f' || arg[1] == 'b')
@@ -4832,13 +4763,6 @@ ex_gui(eap)
{
/* Clear the command. Needed for when forking+exiting, to avoid part
* of the argument ending up after the shell prompt. */
#ifdef MACOS_X
/* os x doesn't really support fork(), so we can't fork of a gui
* in an already running vim. see gui_start() for more details.
*/
gui.dofork = FALSE;
#endif
msg_clr_eos_force();
gui_start();
}
+6 -1
View File
@@ -235,7 +235,12 @@ typedef long guicolor_T; /* handle for a GUI color; for X11 this should
displays there is a tiny chance this is an
actual color */
#ifdef FEAT_GUI_GTK
#if defined(FEAT_GUI_MACVIM)
typedef void *GuiFont;
typedef void *GuiFontset;
# define NOFONT (GuiFont)NULL
# define NOFONTSET (GuiFontset)NULL
#elif defined(FEAT_GUI_GTK)
# ifdef HAVE_GTK2
typedef PangoFontDescription *GuiFont; /* handle for a GUI font */
typedef PangoFontDescription *GuiFontset; /* handle for a GUI fontset */
+17
View File
@@ -1291,6 +1291,23 @@ drawBalloon(beval)
XtNy, ty,
NULL);
#endif
/* Set tooltip colors */
{
Arg args[2];
#ifdef FEAT_GUI_MOTIF
args[0].name = XmNbackground;
args[0].value = gui.tooltip_bg_pixel;
args[1].name = XmNforeground;
args[1].value = gui.tooltip_fg_pixel;
#else /* Athena */
args[0].name = XtNbackground;
args[0].value = gui.tooltip_bg_pixel;
args[1].name = XtNforeground;
args[1].value = gui.tooltip_fg_pixel;
#endif
XtSetValues(beval->balloonLabel, &args[0], XtNumber(args));
}
XtPopup(beval->balloonShell, XtGrabNone);
+31 -1
View File
@@ -1582,6 +1582,17 @@ gui_mch_init(void)
s_findrep_struct.lpstrReplaceWith[0] = NUL;
s_findrep_struct.wFindWhatLen = MSWIN_FR_BUFSIZE;
s_findrep_struct.wReplaceWithLen = MSWIN_FR_BUFSIZE;
# if defined(FEAT_MBYTE) && defined(WIN3264)
s_findrep_struct_w.lStructSize = sizeof(s_findrep_struct_w);
s_findrep_struct_w.lpstrFindWhat =
(LPWSTR)alloc(MSWIN_FR_BUFSIZE * sizeof(WCHAR));
s_findrep_struct_w.lpstrFindWhat[0] = NUL;
s_findrep_struct_w.lpstrReplaceWith =
(LPWSTR)alloc(MSWIN_FR_BUFSIZE * sizeof(WCHAR));
s_findrep_struct_w.lpstrReplaceWith[0] = NUL;
s_findrep_struct_w.wFindWhatLen = MSWIN_FR_BUFSIZE;
s_findrep_struct_w.wReplaceWithLen = MSWIN_FR_BUFSIZE;
# endif
#endif
theend:
@@ -2938,8 +2949,27 @@ dialog_callback(
/* If the edit box exists, copy the string. */
if (s_textfield != NULL)
GetDlgItemText(hwnd, DLG_NONBUTTON_CONTROL + 2,
{
# if defined(FEAT_MBYTE) && defined(WIN3264)
/* If the OS is Windows NT, and 'encoding' differs from active
* codepage: use wide function and convert text. */
if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT
&& enc_codepage >= 0 && (int)GetACP() != enc_codepage)
{
WCHAR *wp = (WCHAR *)alloc(IOSIZE * sizeof(WCHAR));
char_u *p;
GetDlgItemTextW(hwnd, DLG_NONBUTTON_CONTROL + 2, wp, IOSIZE);
p = utf16_to_enc(wp, NULL);
vim_strncpy(s_textfield, p, IOSIZE);
vim_free(p);
vim_free(wp);
}
else
# endif
GetDlgItemText(hwnd, DLG_NONBUTTON_CONTROL + 2,
s_textfield, IOSIZE);
}
/*
* Need to check for IDOK because if the user just hits Return to
+88 -4
View File
@@ -153,6 +153,9 @@ static int destroying = FALSE; /* call DestroyWindow() ourselves */
#ifdef MSWIN_FIND_REPLACE
static UINT s_findrep_msg = 0; /* set in gui_w[16/32].c */
static FINDREPLACE s_findrep_struct;
# if defined(FEAT_MBYTE) && defined(WIN3264)
static FINDREPLACEW s_findrep_struct_w;
# endif
static HWND s_findrep_hwnd = NULL;
static int s_findrep_is_find; /* TRUE for find dialog, FALSE
for find/replace dialog */
@@ -884,6 +887,45 @@ _OnMenu(
#endif
#ifdef MSWIN_FIND_REPLACE
# if defined(FEAT_MBYTE) && defined(WIN3264)
/*
* copy useful data from structure LPFINDREPLACE to structure LPFINDREPLACEW
*/
static void
findrep_atow(LPFINDREPLACEW lpfrw, LPFINDREPLACE lpfr)
{
WCHAR *wp;
lpfrw->hwndOwner = lpfr->hwndOwner;
lpfrw->Flags = lpfr->Flags;
wp = enc_to_utf16(lpfr->lpstrFindWhat, NULL);
wcsncpy(lpfrw->lpstrFindWhat, wp, lpfrw->wFindWhatLen - 1);
vim_free(wp);
/* the field "lpstrReplaceWith" doesn't need to be copied */
}
/*
* copy useful data from structure LPFINDREPLACEW to structure LPFINDREPLACE
*/
static void
findrep_wtoa(LPFINDREPLACE lpfr, LPFINDREPLACEW lpfrw)
{
char_u *p;
lpfr->Flags = lpfrw->Flags;
p = utf16_to_enc(lpfrw->lpstrFindWhat, NULL);
vim_strncpy(lpfr->lpstrFindWhat, p, lpfr->wFindWhatLen - 1);
vim_free(p);
p = utf16_to_enc(lpfrw->lpstrReplaceWith, NULL);
vim_strncpy(lpfr->lpstrReplaceWith, p, lpfr->wReplaceWithLen - 1);
vim_free(p);
}
# endif
/*
* Handle a Find/Replace window message.
*/
@@ -893,6 +935,16 @@ _OnFindRepl(void)
int flags = 0;
int down;
# if defined(FEAT_MBYTE) && defined(WIN3264)
/* If the OS is Windows NT, and 'encoding' differs from active codepage:
* convert text from wide string. */
if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT
&& enc_codepage >= 0 && (int)GetACP() != enc_codepage)
{
findrep_wtoa(&s_findrep_struct, &s_findrep_struct_w);
}
# endif
if (s_findrep_struct.Flags & FR_DIALOGTERM)
/* Give main window the focus back. */
(void)SetFocus(s_hwnd);
@@ -1663,8 +1715,17 @@ process_message(void)
if (msg.message == WM_OLE)
{
char_u *str = (char_u *)msg.lParam;
add_to_input_buf(str, (int)STRLEN(str));
vim_free(str);
if (str == NULL || *str == NUL)
{
/* Message can't be ours, forward it. Fixes problem with Ultramon
* 3.0.4 */
DispatchMessage(&msg);
}
else
{
add_to_input_buf(str, (int)STRLEN(str));
vim_free(str); /* was allocated in CVim::SendKeys() */
}
return;
}
#endif
@@ -2553,7 +2614,19 @@ gui_mch_find_dialog(exarg_T *eap)
if (!IsWindow(s_findrep_hwnd))
{
initialise_findrep(eap->arg);
s_findrep_hwnd = FindText((LPFINDREPLACE) &s_findrep_struct);
# if defined(FEAT_MBYTE) && defined(WIN3264)
/* If the OS is Windows NT, and 'encoding' differs from active
* codepage: convert text and use wide function. */
if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT
&& enc_codepage >= 0 && (int)GetACP() != enc_codepage)
{
findrep_atow(&s_findrep_struct_w, &s_findrep_struct);
s_findrep_hwnd = FindTextW(
(LPFINDREPLACEW) &s_findrep_struct_w);
}
else
# endif
s_findrep_hwnd = FindText((LPFINDREPLACE) &s_findrep_struct);
}
set_window_title(s_findrep_hwnd,
@@ -2578,7 +2651,18 @@ gui_mch_replace_dialog(exarg_T *eap)
if (!IsWindow(s_findrep_hwnd))
{
initialise_findrep(eap->arg);
s_findrep_hwnd = ReplaceText((LPFINDREPLACE) &s_findrep_struct);
# if defined(FEAT_MBYTE) && defined(WIN3264)
if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT
&& enc_codepage >= 0 && (int)GetACP() != enc_codepage)
{
findrep_atow(&s_findrep_struct_w, &s_findrep_struct);
s_findrep_hwnd = ReplaceTextW(
(LPFINDREPLACEW) &s_findrep_struct_w);
}
else
# endif
s_findrep_hwnd = ReplaceText(
(LPFINDREPLACE) &s_findrep_struct);
}
set_window_title(s_findrep_hwnd,
+26 -33
View File
@@ -1587,6 +1587,8 @@ gui_mch_uninit()
XtCloseDisplay(gui.dpy);
gui.dpy = NULL;
vimShell = (Widget)0;
vim_free(gui_argv);
gui_argv = NULL;
}
/*
@@ -1761,6 +1763,8 @@ gui_mch_exit(rc)
* says that this isn't needed when exiting, so just skip it. */
XtCloseDisplay(gui.dpy);
#endif
vim_free(gui_argv);
gui_argv = NULL;
}
/*
@@ -3439,47 +3443,37 @@ gui_mch_register_sign(signfile)
char_u *signfile;
{
XpmAttributes attrs;
XImage *sign;
XImage *sign = NULL;
int status;
/*
* Setup the color substitution table.
*/
sign = NULL;
if (signfile[0] != NUL && signfile[0] != '-')
{
sign = (XImage *)alloc(sizeof(XImage));
if (sign != NULL)
XpmColorSymbol color[5] =
{
XpmColorSymbol color[5] =
{
{"none", NULL, 0},
{"iconColor1", NULL, 0},
{"bottomShadowColor", NULL, 0},
{"topShadowColor", NULL, 0},
{"selectColor", NULL, 0}
};
attrs.valuemask = XpmColorSymbols;
attrs.numsymbols = 2;
attrs.colorsymbols = color;
attrs.colorsymbols[0].pixel = gui.back_pixel;
attrs.colorsymbols[1].pixel = gui.norm_pixel;
status = XpmReadFileToImage(gui.dpy, (char *)signfile,
{"none", NULL, 0},
{"iconColor1", NULL, 0},
{"bottomShadowColor", NULL, 0},
{"topShadowColor", NULL, 0},
{"selectColor", NULL, 0}
};
attrs.valuemask = XpmColorSymbols;
attrs.numsymbols = 2;
attrs.colorsymbols = color;
attrs.colorsymbols[0].pixel = gui.back_pixel;
attrs.colorsymbols[1].pixel = gui.norm_pixel;
status = XpmReadFileToImage(gui.dpy, (char *)signfile,
&sign, NULL, &attrs);
if (status == 0)
{
/* Sign width is fixed at two columns now.
if (sign->width > gui.sign_width)
gui.sign_width = sign->width + 8; */
}
else
{
vim_free(sign);
sign = NULL;
EMSG(_(e_signdata));
}
if (status == 0)
{
/* Sign width is fixed at two columns now.
if (sign->width > gui.sign_width)
gui.sign_width = sign->width + 8; */
}
else
EMSG(_(e_signdata));
}
return (void *)sign;
@@ -3489,8 +3483,7 @@ gui_mch_register_sign(signfile)
gui_mch_destroy_sign(sign)
void *sign;
{
XFree(((XImage *)sign)->data);
vim_free(sign);
XDestroyImage((XImage*)sign);
}
#endif
+128 -7
View File
@@ -93,12 +93,117 @@ cs_usage_msg(x)
(void)EMSG2(_("E560: Usage: cs[cope] %s"), cs_cmds[(int)x].usage);
}
#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
static enum
{
EXP_CSCOPE_SUBCMD, /* expand ":cscope" sub-commands */
EXP_CSCOPE_FIND, /* expand ":cscope find" arguments */
EXP_CSCOPE_KILL /* expand ":cscope kill" arguments */
} expand_what;
/*
* Function given to ExpandGeneric() to obtain the cscope command
* expansion.
*/
/*ARGSUSED*/
char_u *
get_cscope_name(xp, idx)
expand_T *xp;
int idx;
{
switch (expand_what)
{
case EXP_CSCOPE_SUBCMD:
/* Complete with sub-commands of ":cscope":
* add, find, help, kill, reset, show */
return (char_u *)cs_cmds[idx].name;
case EXP_CSCOPE_FIND:
{
const char *query_type[] =
{
"c", "d", "e", "f", "g", "i", "s", "t", NULL
};
/* Complete with query type of ":cscope find {query_type}".
* {query_type} can be letters (c, d, ... t) or numbers (0, 1,
* ..., 8) but only complete with letters, since numbers are
* redundant. */
return (char_u *)query_type[idx];
}
case EXP_CSCOPE_KILL:
{
int i;
int current_idx = 0;
static char_u connection[2];
/* ":cscope kill" accepts connection numbers or partial names of
* the pathname of the cscope database as argument. Only complete
* with connection numbers. -1 can also be used to kill all
* connections. */
for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
{
if (csinfo[i].fname == NULL)
continue;
if (current_idx++ == idx)
{
/* Connection number fits in one character since
* CSCOPE_MAX_CONNECTIONS is < 10 */
connection[0] = i + '0';
connection[1] = NUL;
return connection;
}
}
return (current_idx == idx && idx > 0) ? (char_u *)"-1" : NULL;
}
default:
return NULL;
}
}
/*
* Handle command line completion for :cscope command.
*/
void
set_context_in_cscope_cmd(xp, arg)
expand_T *xp;
char_u *arg;
{
char_u *p;
/* Default: expand subcommands */
xp->xp_context = EXPAND_CSCOPE;
expand_what = EXP_CSCOPE_SUBCMD;
xp->xp_pattern = arg;
/* (part of) subcommand already typed */
if (*arg != NUL)
{
p = skiptowhite(arg);
if (*p != NUL) /* past first word */
{
xp->xp_pattern = skipwhite(p);
if (*skiptowhite(xp->xp_pattern) != NUL)
xp->xp_context = EXPAND_NOTHING;
else if (STRNICMP(arg, "add", p - arg) == 0)
xp->xp_context = EXPAND_FILES;
else if (STRNICMP(arg, "kill", p - arg) == 0)
expand_what = EXP_CSCOPE_KILL;
else if (STRNICMP(arg, "find", p - arg) == 0)
expand_what = EXP_CSCOPE_FIND;
else
xp->xp_context = EXPAND_NOTHING;
}
}
}
#endif /* FEAT_CMDL_COMPL */
/*
* PRIVATE: do_cscope_general
*
* find the command, print help if invalid, and the then call the
* corresponding command function,
* called from do_cscope and do_scscope
* Find the command, print help if invalid, and then call the corresponding
* command function.
*/
static void
do_cscope_general(eap, make_split)
@@ -659,6 +764,7 @@ cs_create_cmd(csoption, pattern)
{
char *cmd;
short search;
char *pat;
switch (csoption[0])
{
@@ -692,10 +798,17 @@ cs_create_cmd(csoption, pattern)
return NULL;
}
if ((cmd = (char *)alloc((unsigned)(strlen(pattern) + 2))) == NULL)
/* Skip white space before the patter, except for text and pattern search,
* they may want to use the leading white space. */
pat = pattern;
if (search != 4 && search != 6)
while vim_iswhite(*pat)
++pat;
if ((cmd = (char *)alloc((unsigned)(strlen(pat) + 2))) == NULL)
return NULL;
(void)sprintf(cmd, "%d%s", search, pattern);
(void)sprintf(cmd, "%d%s", search, pat);
return cmd;
} /* cs_create_cmd */
@@ -1177,8 +1290,16 @@ cs_help(eap)
(void)MSG_PUTS(_("cscope commands:\n"));
while (cmdp->name != NULL)
{
(void)smsg((char_u *)_("%-5s: %-30s (Usage: %s)"),
cmdp->name, _(cmdp->help), cmdp->usage);
char *help = _(cmdp->help);
int space_cnt = 30 - vim_strsize((char_u *)help);
/* Use %*s rather than %30s to ensure proper alignment in utf-8 */
if (space_cnt < 0)
space_cnt = 0;
(void)smsg((char_u *)_("%-5s: %s%*s (Usage: %s)"),
cmdp->name,
help, space_cnt, " ",
cmdp->usage);
if (strcmp(cmdp->name, "find") == 0)
MSG_PUTS(_("\n"
" c: Find functions calling this function\n"
+6 -2
View File
@@ -353,9 +353,13 @@ CVim::SendKeys(BSTR keys)
}
/* Pass the string to the main input loop. The memory will be freed when
* the message is processed.
* the message is processed. Except for an empty message, we don't need
* to post it then.
*/
PostMessage(NULL, WM_OLE, 0, (LPARAM)str);
if (*str == NUL)
vim_free(str);
else
PostMessage(NULL, WM_OLE, 0, (LPARAM)str);
return S_OK;
}
+19 -10
View File
@@ -1151,14 +1151,23 @@ VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
/* Check if we run into a recursive loop. The item must be in lookupDict
* then and we can use it again. */
sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U, (long_u)our_tv);
result = PyDict_GetItemString(lookupDict, ptrBuf);
if (result != NULL)
Py_INCREF(result);
else if (our_tv->v_type == VAR_STRING)
if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
|| (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
{
sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U,
our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list
: (long_u)our_tv->vval.v_dict);
result = PyDict_GetItemString(lookupDict, ptrBuf);
if (result != NULL)
{
Py_INCREF(result);
return result;
}
}
if (our_tv->v_type == VAR_STRING)
{
result = Py_BuildValue("s", our_tv->vval.v_string);
PyDict_SetItemString(lookupDict, ptrBuf, result);
}
else if (our_tv->v_type == VAR_NUMBER)
{
@@ -1167,7 +1176,6 @@ VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
/* For backwards compatibility numbers are stored as strings. */
sprintf(buf, "%ld", (long)our_tv->vval.v_number);
result = Py_BuildValue("s", buf);
PyDict_SetItemString(lookupDict, ptrBuf, result);
}
# ifdef FEAT_FLOAT
else if (our_tv->v_type == VAR_FLOAT)
@@ -1176,7 +1184,6 @@ VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
sprintf(buf, "%f", our_tv->vval.v_float);
result = Py_BuildValue("s", buf);
PyDict_SetItemString(lookupDict, ptrBuf, result);
}
# endif
else if (our_tv->v_type == VAR_LIST)
@@ -1185,10 +1192,11 @@ VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
listitem_T *curr;
result = PyList_New(0);
PyDict_SetItemString(lookupDict, ptrBuf, result);
if (list != NULL)
{
PyDict_SetItemString(lookupDict, ptrBuf, result);
for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
{
newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
@@ -1200,7 +1208,6 @@ VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
else if (our_tv->v_type == VAR_DICT)
{
result = PyDict_New();
PyDict_SetItemString(lookupDict, ptrBuf, result);
if (our_tv->vval.v_dict != NULL)
{
@@ -1209,6 +1216,8 @@ VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
hashitem_T *hi;
dictitem_T *di;
PyDict_SetItemString(lookupDict, ptrBuf, result);
for (hi = ht->ht_array; todo > 0; ++hi)
{
if (!HASHITEM_EMPTY(hi))
+21 -5
View File
@@ -127,15 +127,31 @@
#ifdef FEAT_LANGMAP
/*
* Adjust chars in a language according to 'langmap' option.
* NOTE that there is NO overhead if 'langmap' is not set; but even
* when set we only have to do 2 ifs and an array lookup.
* NOTE that there is no noticeable overhead if 'langmap' is not set.
* When set the overhead for characters < 256 is small.
* Don't apply 'langmap' if the character comes from the Stuff buffer.
* The do-while is just to ignore a ';' after the macro.
*/
# define LANGMAP_ADJUST(c, condition) do { \
if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \
c = langmap_mapchar[c]; \
# ifdef FEAT_MBYTE
# define LANGMAP_ADJUST(c, condition) \
do { \
if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0) \
{ \
if ((c) < 256) \
c = langmap_mapchar[c]; \
else \
c = langmap_adjust_mb(c); \
} \
} while (0)
# else
# define LANGMAP_ADJUST(c, condition) \
do { \
if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \
c = langmap_mapchar[c]; \
} while (0)
# endif
#else
# define LANGMAP_ADJUST(c, condition) /* nop */
#endif
/*
+14 -15
View File
@@ -360,6 +360,11 @@ main
command_line_scan(&params);
TIME_MSG("parsing arguments");
#ifdef MACOS_X
if (gui.starting && gui.dofork)
macosx_fork(); /* Never returns */
#endif
/*
* On some systems, when we compile with the GUI, we always use it. On Mac
* there is no terminal version, and on Windows we can't fork one off with
@@ -1282,9 +1287,10 @@ getout_preserve_modified(exitval)
#endif
/* Prepare proper exit*/
/* Exit properly */
void
prepare_getout()
getout(exitval)
int exitval;
{
#ifdef FEAT_AUTOCMD
buf_T *buf;
@@ -1294,6 +1300,12 @@ prepare_getout()
exiting = TRUE;
/* When running in Ex mode an error causes us to exit with a non-zero exit
* code. POSIX requires this, although it's not 100% clear from the
* standard. */
if (exmode_active)
exitval += ex_exitval;
/* Position the cursor on the last screen line, below all the text */
#ifdef FEAT_GUI
if (!gui.in_use)
@@ -1410,20 +1422,7 @@ prepare_getout()
if (garbage_collect_at_exit)
garbage_collect();
#endif
}
/* Exit properly */
void
getout(exitval)
int exitval;
{
/* When running in Ex mode an error causes us to exit with a non-zero exit
* code. POSIX requires this, although it's not 100% clear from the
* standard. */
if (exmode_active)
exitval += ex_exitval;
prepare_getout();
mch_exit(exitval);
}
+17 -5
View File
@@ -976,7 +976,7 @@ wait_return(redraw)
}
}
else if (msg_scrolled > Rows - 2
&& (c == 'j' || c == K_DOWN || c == 'd'))
&& (c == 'j' || c == K_DOWN || c == 'd' || c == 'f'))
c = K_IGNORE;
}
} while ((had_got_int && c == Ctrl_C)
@@ -2504,7 +2504,6 @@ do_more_prompt(typed_char)
break;
case 'u': /* Up half a page */
case K_PAGEUP:
scroll = -(Rows / 2);
break;
@@ -2513,10 +2512,12 @@ do_more_prompt(typed_char)
break;
case 'b': /* one page back */
case K_PAGEUP:
scroll = -(Rows - 1);
break;
case ' ': /* one extra page */
case 'f':
case K_PAGEDOWN:
case K_LEFTMOUSE:
scroll = Rows - 1;
@@ -2552,7 +2553,6 @@ do_more_prompt(typed_char)
{
/* Jump to the choices of the dialog. */
retval = TRUE;
lines_left = Rows - 1;
}
else
#endif
@@ -2560,6 +2560,9 @@ do_more_prompt(typed_char)
got_int = TRUE;
quit_more = TRUE;
}
/* When there is some more output (wrapping line) display that
* without another prompt. */
lines_left = Rows - 1;
break;
#ifdef FEAT_CLIPBOARD
@@ -3309,7 +3312,10 @@ do_dialog(type, title, message, buttons, dfltbutton, textfield)
{
c = gui_mch_dialog(type, title, message, buttons, dfltbutton,
textfield);
msg_end_prompt();
/* avoid a hit-enter prompt without clearing the cmdline */
need_wait_return = FALSE;
emsg_on_display = FALSE;
cmdline_row = msg_row;
/* Flush output to avoid that further messages and redrawing is done
* in the wrong order. */
@@ -4556,7 +4562,13 @@ vim_snprintf(str, str_m, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
remove_trailing_zeroes = TRUE;
}
if (fmt_spec == 'f' && abs_f > 1.0e307)
if (fmt_spec == 'f' &&
#ifdef VAX
abs_f > 1.0e38
#else
abs_f > 1.0e307
#endif
)
{
/* Avoid a buffer overflow */
strcpy(tmp, "inf");
+6 -2
View File
@@ -2955,6 +2955,8 @@ change_warning(col)
int col; /* column for message; non-zero when in insert
mode and 'showmode' is on */
{
static char *w_readonly = N_("W10: Warning: Changing a readonly file");
if (curbuf->b_did_warn == FALSE
&& curbufIsChanged() == 0
#ifdef FEAT_AUTOCMD
@@ -2977,8 +2979,10 @@ change_warning(col)
if (msg_row == Rows - 1)
msg_col = col;
msg_source(hl_attr(HLF_W));
MSG_PUTS_ATTR(_("W10: Warning: Changing a readonly file"),
hl_attr(HLF_W) | MSG_HIST);
MSG_PUTS_ATTR(_(w_readonly), hl_attr(HLF_W) | MSG_HIST);
#ifdef FEAT_EVAL
set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_readonly), -1);
#endif
msg_clr_eos();
(void)msg_end();
if (msg_silent == 0 && !silent_mode)
+17 -3
View File
@@ -496,7 +496,8 @@ check_cursor_col()
{
colnr_T len;
#ifdef FEAT_VIRTUALEDIT
colnr_T oldcol = curwin->w_cursor.col + curwin->w_cursor.coladd;
colnr_T oldcol = curwin->w_cursor.col;
colnr_T oldcoladd = curwin->w_cursor.col + curwin->w_cursor.coladd;
#endif
len = (colnr_T)STRLEN(ml_get_curline());
@@ -535,7 +536,13 @@ check_cursor_col()
if (oldcol == MAXCOL)
curwin->w_cursor.coladd = 0;
else if (ve_flags == VE_ALL)
curwin->w_cursor.coladd = oldcol - curwin->w_cursor.col;
{
if (oldcoladd > curwin->w_cursor.col)
curwin->w_cursor.coladd = oldcoladd - curwin->w_cursor.col;
else
/* avoid weird number when there is a miscalculation or overflow */
curwin->w_cursor.coladd = 0;
}
#endif
}
@@ -1010,6 +1017,9 @@ free_all_mem()
# if defined(FEAT_PROFILE)
do_cmdline_cmd((char_u *)"profdel *");
# endif
# if defined(FEAT_KEYMAP)
do_cmdline_cmd((char_u *)"set keymap=");
#endif
# ifdef FEAT_TITLE
free_titles();
@@ -1034,6 +1044,9 @@ free_all_mem()
free_regexp_stuff();
free_tag_stuff();
free_cd_dir();
# ifdef FEAT_SIGNS
free_signs();
# endif
# ifdef FEAT_EVAL
set_expr_line(NULL);
# endif
@@ -4696,7 +4709,8 @@ vim_findfile(search_ctx_arg)
stackp->ffs_filearray_cur = i + 1;
ff_push(search_ctx, stackp);
simplify_filename(file_path);
if (!path_with_url(file_path))
simplify_filename(file_path);
if (mch_dirname(ff_expand_buffer, MAXPATHL)
== OK)
{
-37
View File
@@ -33,7 +33,6 @@ FILE *nb_debug = NULL;
u_int nb_dlevel = 0; /* nb_debug verbosity level */
void nbdb(char *, ...);
void nbtrace(char *, ...);
static int lookup(char *);
#ifdef USE_NB_ERRORHANDLER
@@ -100,25 +99,6 @@ nbdebug_log_init(
} /* end nbdebug_log_init */
void
nbtrace(
char *fmt,
...)
{
va_list ap;
if (nb_debug!= NULL && (nb_dlevel & (NB_TRACE | NB_TRACE_VERBOSE))) {
va_start(ap, fmt);
vfprintf(nb_debug, fmt, ap);
va_end(ap);
fflush(nb_debug);
}
} /* end nbtrace */
void
nbdbg(
char *fmt,
@@ -136,23 +116,6 @@ nbdbg(
} /* end nbdbg */
void
nbprt(
char *fmt,
...)
{
va_list ap;
if (nb_debug != NULL && nb_dlevel & NB_PRINT) {
va_start(ap, fmt);
vfprintf(nb_debug, fmt, ap);
va_end(ap);
fflush(nb_debug);
}
} /* end nbprt */
static int
lookup(
char *file)
-16
View File
@@ -43,8 +43,6 @@ typedef enum {
void nbdbg(char *, ...);
void nbprt(char *, ...);
void nbtrace(char *, ...);
void nbdebug_wait __ARGS((u_int wait_flags, char *wait_var, u_int wait_secs));
void nbdebug_log_init __ARGS((char *log_var, char *level_var));
@@ -70,19 +68,5 @@ nbdbg(
{
}
void
nbprt(
char *fmt,
...)
{
}
void
nbtrace(
char *fmt,
...)
{
}
#endif /* NBDEBUG */
#endif /* NBDEBUG_H */
+9 -27
View File
@@ -1924,7 +1924,7 @@ nb_do_cmd(
vim_free(path);
if (bufp == NULL)
{
nbdebug((" File %s not found in setBufferNumber\n", args));
nbdebug((" File %s not found in setBufferNumber\n", args));
EMSG2("E642: File %s not found in setBufferNumber", args);
return FAIL;
}
@@ -2318,7 +2318,7 @@ nb_do_cmd(
}
if (pos)
{
coloncmd(":sign place %d line=%d name=%d buffer=%d",
coloncmd(":sign place %d line=%ld name=%d buffer=%d",
serNum, pos->lnum, typeNum, buf->bufp->b_fnum);
if (typeNum == curPCtype)
coloncmd(":sign jump %d buffer=%d", serNum,
@@ -2422,7 +2422,7 @@ nb_do_cmd(
GUARDED) == 0)
{
coloncmd(
":sign place %d line=%d name=%d buffer=%d",
":sign place %d line=%ld name=%d buffer=%d",
guardId++, lnum, GUARDED,
buf->bufp->b_fnum);
}
@@ -2921,44 +2921,26 @@ netbeans_file_opened(buf_T *bufp)
}
/*
* Tell netbeans a file was closed.
* Tell netbeans that a file was deleted or wiped out.
*/
void
netbeans_file_closed(buf_T *bufp)
netbeans_file_killed(buf_T *bufp)
{
int bufno = nb_getbufno(bufp);
nbbuf_T *nbbuf = nb_get_buf(bufno);
char buffer[2*MAXPATHL];
if (!haveConnection || bufno < 0)
if (!haveConnection || bufno == -1)
return;
if (!netbeansCloseFile)
{
nbdebug(("Ignoring file_closed for %s. File was closed from IDE\n",
bufp->b_ffname));
return;
}
nbdebug(("netbeans_file_closed:\n"));
nbdebug((" Closing bufno: %d", bufno));
if (curbuf != NULL && curbuf != bufp)
{
nbdebug((" Curbuf bufno: %d\n", nb_getbufno(curbuf)));
}
else if (curbuf == bufp)
{
nbdebug((" curbuf == bufp\n"));
}
if (bufno <= 0)
return;
nbdebug(("netbeans_file_killed:\n"));
nbdebug((" Killing bufno: %d", bufno));
sprintf(buffer, "%d:killed=%d\n", bufno, r_cmdno);
nbdebug(("EVT: %s", buffer));
nb_send(buffer, "netbeans_file_closed");
nb_send(buffer, "netbeans_file_killed");
if (nbbuf != NULL)
nbbuf->bufp = NULL;
+3 -16
View File
@@ -651,10 +651,7 @@ normal_cmd(oap, toplevel)
* Get the command character from the user.
*/
c = safe_vgetc();
#ifdef FEAT_LANGMAP
LANGMAP_ADJUST(c, TRUE);
#endif
#ifdef FEAT_VISUAL
/*
@@ -744,9 +741,7 @@ getcount:
}
++no_zero_mapping; /* don't map zero here */
c = plain_vgetc();
#ifdef FEAT_LANGMAP
LANGMAP_ADJUST(c, TRUE);
#endif
--no_zero_mapping;
if (ctrl_w)
{
@@ -769,9 +764,7 @@ getcount:
++no_mapping;
++allow_keys; /* no mapping for nchar, but keys */
c = plain_vgetc(); /* get next character */
#ifdef FEAT_LANGMAP
LANGMAP_ADJUST(c, TRUE);
#endif
--no_mapping;
--allow_keys;
#ifdef FEAT_CMDL_INFO
@@ -959,9 +952,7 @@ getcount:
* "gr", "g'" and "g`".
*/
ca.nchar = plain_vgetc();
#ifdef FEAT_LANGMAP
LANGMAP_ADJUST(ca.nchar, TRUE);
#endif
#ifdef FEAT_CMDL_INFO
need_flushbuf |= add_to_showcmd(ca.nchar);
#endif
@@ -1062,10 +1053,8 @@ getcount:
}
#endif
#ifdef FEAT_LANGMAP
/* adjust chars > 127, except after "tTfFr" commands */
LANGMAP_ADJUST(*cp, !lang);
#endif
#ifdef FEAT_RIGHTLEFT
/* adjust Hebrew mapped char */
if (p_hkmap && lang && KeyTyped)
@@ -4649,9 +4638,7 @@ nv_zet(cap)
++no_mapping;
++allow_keys; /* no mapping for nchar, but allow key codes */
nchar = plain_vgetc();
#ifdef FEAT_LANGMAP
LANGMAP_ADJUST(nchar, TRUE);
#endif
--no_mapping;
--allow_keys;
#ifdef FEAT_CMDL_INFO
@@ -5007,9 +4994,7 @@ dozet:
++no_mapping;
++allow_keys; /* no mapping for nchar, but allow key codes */
nchar = plain_vgetc();
#ifdef FEAT_LANGMAP
LANGMAP_ADJUST(nchar, TRUE);
#endif
--no_mapping;
--allow_keys;
#ifdef FEAT_CMDL_INFO
@@ -6811,6 +6796,8 @@ nv_replace(cap)
/* Visual mode "r" */
if (VIsual_active)
{
if (got_int)
reset_VIsual();
nv_operator(cap);
return;
}
@@ -7867,7 +7854,7 @@ nv_g_cmd(cap)
else
i = curwin->w_leftcol;
/* Go to the middle of the screen line. When 'number' is on and lines
* are wrapping the middle can be more to the left.*/
* are wrapping the middle can be more to the left. */
if (cap->nchar == 'm')
i += (W_WIDTH(curwin) - curwin_col_off()
+ ((curwin->w_p_wrap && i > 0)
+86 -64
View File
@@ -72,11 +72,11 @@ static struct yankreg *y_previous = NULL; /* ptr to last written yankreg */
*/
struct block_def
{
int startspaces; /* 'extra' cols of first char */
int endspaces; /* 'extra' cols of first char */
int startspaces; /* 'extra' cols before first char */
int endspaces; /* 'extra' cols after last char */
int textlen; /* chars in block */
char_u *textstart; /* pointer to 1st char in block */
colnr_T textcol; /* cols of chars (at least part.) in block */
char_u *textstart; /* pointer to 1st char (partially) in block */
colnr_T textcol; /* index of chars (partially) in block */
colnr_T start_vcol; /* start col of 1st char wholly inside block */
colnr_T end_vcol; /* start col of 1st char wholly after block */
#ifdef FEAT_VISUALEXTRA
@@ -382,15 +382,14 @@ shift_block(oap, amount)
{
int left = (oap->op_type == OP_LSHIFT);
int oldstate = State;
int total, split;
char_u *newp, *oldp, *midp, *ptr;
int total;
char_u *newp, *oldp;
int oldcol = curwin->w_cursor.col;
int p_sw = (int)curbuf->b_p_sw;
int p_ts = (int)curbuf->b_p_ts;
struct block_def bd;
int internal = 0;
int incr;
colnr_T vcol, col = 0, ws_vcol;
colnr_T ws_vcol;
int i = 0, j = 0;
int len;
@@ -456,67 +455,89 @@ shift_block(oap, amount)
}
else /* left */
{
vcol = oap->start_vcol;
/* walk vcol past ws to be removed */
for (midp = oldp + bd.textcol;
vcol < (oap->start_vcol + total) && vim_iswhite(*midp); )
{
incr = lbr_chartabsize_adv(&midp, (colnr_T)vcol);
vcol += incr;
}
/* internal is the block-internal ws replacing a split TAB */
if (vcol > (oap->start_vcol + total))
{
/* we have to split the TAB *(midp-1) */
internal = vcol - (oap->start_vcol + total);
}
/* if 'expandtab' is not set, use TABs */
colnr_T destination_col; /* column to which text in block will
be shifted */
char_u *verbatim_copy_end; /* end of the part of the line which is
copied verbatim */
colnr_T verbatim_copy_width;/* the (displayed) width of this part
of line */
unsigned fill; /* nr of spaces that replace a TAB */
unsigned new_line_len; /* the length of the line after the
block shift */
size_t block_space_width;
size_t shift_amount;
char_u *non_white = bd.textstart;
colnr_T non_white_col;
split = bd.startspaces + internal;
if (split > 0)
{
if (!curbuf->b_p_et)
{
for (ptr = oldp, col = 0; ptr < oldp+bd.textcol; )
col += lbr_chartabsize_adv(&ptr, (colnr_T)col);
/*
* Firstly, let's find the first non-whitespace character that is
* displayed after the block's start column and the character's column
* number. Also, let's calculate the width of all the whitespace
* characters that are displayed in the block and precede the searched
* non-whitespace character.
*/
/* col+1 now equals the start col of the first char of the
* block (may be < oap.start_vcol if we're splitting a TAB) */
i = ((col % p_ts) + split) / p_ts; /* number of tabs */
}
if (i)
j = ((col % p_ts) + split) % p_ts; /* number of spp */
else
j = split;
/* If "bd.startspaces" is set, "bd.textstart" points to the character,
* the part of which is displayed at the block's beginning. Let's start
* searching from the next character. */
if (bd.startspaces)
mb_ptr_adv(non_white);
/* The character's column is in "bd.start_vcol". */
non_white_col = bd.start_vcol;
while (vim_iswhite(*non_white))
{
incr = lbr_chartabsize_adv(&non_white, non_white_col);
non_white_col += incr;
}
newp = alloc_check(bd.textcol + i + j + (unsigned)STRLEN(midp) + 1);
block_space_width = non_white_col - oap->start_vcol;
/* We will shift by "total" or "block_space_width", whichever is less.
*/
shift_amount = (block_space_width < total? block_space_width: total);
/* The column to which we will shift the text. */
destination_col = non_white_col - shift_amount;
/* Now let's find out how much of the beginning of the line we can
* reuse without modification. */
verbatim_copy_end = bd.textstart;
verbatim_copy_width = bd.start_vcol;
/* If "bd.startspaces" is set, "bd.textstart" points to the character
* preceding the block. We have to subtract its width to obtain its
* column number. */
if (bd.startspaces)
verbatim_copy_width -= bd.start_char_vcols;
while (verbatim_copy_width < destination_col)
{
incr = lbr_chartabsize(verbatim_copy_end, verbatim_copy_width);
if (verbatim_copy_width + incr > destination_col)
break;
verbatim_copy_width += incr;
mb_ptr_adv(verbatim_copy_end);
}
/* If "destination_col" is different from the width of the initial
* part of the line that will be copied, it means we encountered a tab
* character, which we will have to partly replace with spaces. */
fill = destination_col - verbatim_copy_width;
/* The replacement line will consist of:
* - the beginning of the original line up to "verbatim_copy_end",
* - "fill" number of spaces,
* - the rest of the line, pointed to by non_white. */
new_line_len = (unsigned)(verbatim_copy_end - oldp)
+ fill
+ (unsigned)STRLEN(non_white) + 1;
newp = alloc_check(new_line_len);
if (newp == NULL)
return;
vim_memset(newp, NUL, (size_t)(bd.textcol + i + j + STRLEN(midp) + 1));
/* copy first part we want to keep */
mch_memmove(newp, oldp, (size_t)bd.textcol);
/* Now copy any TABS and spp to ensure correct alignment! */
while (vim_iswhite(*midp))
{
if (*midp == TAB)
i++;
else /*space */
j++;
midp++;
}
/* We might have an extra TAB worth of spp now! */
if (j / p_ts && !curbuf->b_p_et)
{
i++;
j -= p_ts;
}
copy_chars(newp + bd.textcol, (size_t)i, TAB);
copy_spaces(newp + bd.textcol + i, (size_t)j);
/* the end */
STRMOVE(newp + STRLEN(newp), midp);
mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp));
copy_spaces(newp + (verbatim_copy_end - oldp), (size_t)fill);
STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white);
}
/* replace the line */
ml_replace(curwin->w_cursor.lnum, newp, FALSE);
@@ -4851,7 +4872,8 @@ paragraph_start(lnum)
* - textlen includes the first/last char to be (partly) deleted
* - start/endspaces is the number of columns that are taken by the
* first/last deleted char minus the number of columns that have to be
* deleted. for yank and tilde:
* deleted.
* for yank and tilde:
* - textlen includes the first/last char to be wholly yanked
* - start/endspaces is the number of columns of the first/last yanked char
* that are to be yanked.
+220 -45
View File
@@ -4178,11 +4178,23 @@ do_set(arg, opt_flags)
&& options[opt_idx].var == VAR_WIN)
goto skip;
/* Disallow changing some options from modelines */
if ((opt_flags & OPT_MODELINE) && (flags & P_SECURE))
/* Disallow changing some options from modelines. */
if (opt_flags & OPT_MODELINE)
{
errmsg = (char_u *)_("E520: Not allowed in a modeline");
goto skip;
if (flags & P_SECURE)
{
errmsg = (char_u *)_("E520: Not allowed in a modeline");
goto skip;
}
#ifdef FEAT_DIFF
/* In diff mode some options are overruled. This avoids that
* 'foldmethod' becomes "marker" instead of "diff" and that
* "wrap" gets set. */
if (curwin->w_p_diff
&& (options[opt_idx].indir == PV_FDM
|| options[opt_idx].indir == PV_WRAP))
goto skip;
#endif
}
#ifdef HAVE_SANDBOX
@@ -5332,6 +5344,21 @@ insecure_flag(opt_idx, opt_flags)
}
#endif
#ifdef FEAT_TITLE
static void redraw_titles __ARGS((void));
/*
* Redraw the window title and/or tab page text later.
*/
static void redraw_titles()
{
need_maketitle = TRUE;
# ifdef FEAT_WINDOWS
redraw_tabline = TRUE;
# endif
}
#endif
/*
* Set a string option to a new value (without checking the effect).
* The string is copied into allocated memory.
@@ -5471,6 +5498,10 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
int did_chartab = FALSE;
char_u **gvarp;
long_u free_oldval = (options[opt_idx].flags & P_ALLOCED);
#ifdef FEAT_GUI
/* set when changing an option that only requires a redraw in the GUI */
int redraw_gui_only = FALSE;
#endif
/* Get the global option to compare with, otherwise we would have to check
* two values for all local options. */
@@ -5732,7 +5763,7 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
{
# ifdef FEAT_TITLE
/* May show a "+" in the title now. */
need_maketitle = TRUE;
redraw_titles();
# endif
/* Add 'fileencoding' to the swap file. */
ml_setflags(curbuf);
@@ -5751,7 +5782,7 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
{
errmsg = mb_init();
# ifdef FEAT_TITLE
need_maketitle = TRUE;
redraw_titles();
# endif
}
}
@@ -5834,14 +5865,28 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
/* load or unload key mapping tables */
errmsg = keymap_init();
/* When successfully installed a new keymap switch on using it. */
if (*curbuf->b_p_keymap != NUL && errmsg == NULL)
if (errmsg == NULL)
{
curbuf->b_p_iminsert = B_IMODE_LMAP;
if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT)
curbuf->b_p_imsearch = B_IMODE_LMAP;
set_iminsert_global();
set_imsearch_global();
if (*curbuf->b_p_keymap != NUL)
{
/* Installed a new keymap, switch on using it. */
curbuf->b_p_iminsert = B_IMODE_LMAP;
if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT)
curbuf->b_p_imsearch = B_IMODE_LMAP;
}
else
{
/* Cleared the keymap, may reset 'iminsert' and 'imsearch'. */
if (curbuf->b_p_iminsert == B_IMODE_LMAP)
curbuf->b_p_iminsert = B_IMODE_NONE;
if (curbuf->b_p_imsearch == B_IMODE_LMAP)
curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
}
if ((opt_flags & OPT_LOCAL) == 0)
{
set_iminsert_global();
set_imsearch_global();
}
# ifdef FEAT_WINDOWS
status_redraw_curbuf();
# endif
@@ -5864,7 +5909,7 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
else
curbuf->b_p_tx = FALSE;
#ifdef FEAT_TITLE
need_maketitle = TRUE;
redraw_titles();
#endif
/* update flag in swap file */
ml_setflags(curbuf);
@@ -6045,15 +6090,23 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
/* ":set t_Co=0" and ":set t_Co=1" do ":set t_Co=" */
if (varp == &T_CCO)
{
t_colors = atoi((char *)T_CCO);
if (t_colors <= 1)
int colors = atoi((char *)T_CCO);
/* Only reinitialize colors if t_Co value has really changed to
* avoid expensive reload of colorscheme if t_Co is set to the
* same value multiple times. */
if (colors != t_colors)
{
if (new_value_alloced)
vim_free(T_CCO);
T_CCO = empty_option;
t_colors = colors;
if (t_colors <= 1)
{
if (new_value_alloced)
vim_free(T_CCO);
T_CCO = empty_option;
}
/* We now have a different color setup, initialize it again. */
init_highlight(TRUE, FALSE);
}
/* We now have a different color setup, initialize it again. */
init_highlight(TRUE, FALSE);
}
ttest(FALSE);
if (varp == &T_ME)
@@ -6124,6 +6177,7 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
errmsg = (char_u *)N_("E596: Invalid font(s)");
}
}
redraw_gui_only = TRUE;
}
# ifdef FEAT_XFONTSET
else if (varp == &p_guifontset)
@@ -6132,6 +6186,7 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
errmsg = (char_u *)N_("E597: can't select fontset");
else if (gui.in_use && gui_init_font(p_guifontset, TRUE) != OK)
errmsg = (char_u *)N_("E598: Invalid fontset");
redraw_gui_only = TRUE;
}
# endif
# ifdef FEAT_MBYTE
@@ -6141,6 +6196,7 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
errmsg = (char_u *)N_("E533: can't select wide font");
else if (gui_get_wide_font() == FAIL)
errmsg = (char_u *)N_("E534: Invalid wide font");
redraw_gui_only = TRUE;
}
# endif
#endif
@@ -6202,13 +6258,24 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
#ifdef FEAT_GUI
/* 'guioptions' */
else if (varp == &p_go)
{
gui_init_which_components(oldval);
redraw_gui_only = TRUE;
}
#endif
#if defined(FEAT_GUI_TABLINE)
/* 'guitablabel' */
else if (varp == &p_gtl)
{
redraw_tabline = TRUE;
redraw_gui_only = TRUE;
}
/* 'guitabtooltip' */
else if (varp == &p_gtt)
{
redraw_gui_only = TRUE;
}
#endif
#if defined(FEAT_MOUSE_TTY) && (defined(UNIX) || defined(VMS))
@@ -6797,7 +6864,11 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
if (curwin->w_curswant != MAXCOL)
curwin->w_set_curswant = TRUE; /* in case 'showbreak' changed */
check_redraw(options[opt_idx].flags);
#ifdef FEAT_GUI
/* check redraw when it's not a GUI option or the GUI is active. */
if (!redraw_gui_only || gui.in_use)
#endif
check_redraw(options[opt_idx].flags);
return errmsg;
}
@@ -7185,22 +7256,28 @@ set_bool_option(opt_idx, varp, value, opt_flags)
curbuf->b_did_warn = FALSE;
#ifdef FEAT_TITLE
need_maketitle = TRUE;
redraw_titles();
#endif
}
#ifdef FEAT_TITLE
/* when 'modifiable' is changed, redraw the window title */
else if ((int *)varp == &curbuf->b_p_ma)
need_maketitle = TRUE;
{
redraw_titles();
}
/* when 'endofline' is changed, redraw the window title */
else if ((int *)varp == &curbuf->b_p_eol)
need_maketitle = TRUE;
#ifdef FEAT_MBYTE
/* when 'bomb' is changed, redraw the window title */
{
redraw_titles();
}
# ifdef FEAT_MBYTE
/* when 'bomb' is changed, redraw the window title and tab page text */
else if ((int *)varp == &curbuf->b_p_bomb)
need_maketitle = TRUE;
#endif
{
redraw_titles();
}
# endif
#endif
/* when 'bin' is set also set some other options */
@@ -7208,7 +7285,7 @@ set_bool_option(opt_idx, varp, value, opt_flags)
{
set_options_bin(old_value, curbuf->b_p_bin, opt_flags);
#ifdef FEAT_TITLE
need_maketitle = TRUE;
redraw_titles();
#endif
}
@@ -7393,7 +7470,7 @@ set_bool_option(opt_idx, varp, value, opt_flags)
if (!value)
save_file_ff(curbuf); /* Buffer is unchanged */
#ifdef FEAT_TITLE
need_maketitle = TRUE;
redraw_titles();
#endif
#ifdef FEAT_AUTOCMD
modified_was_set = value;
@@ -7600,9 +7677,13 @@ set_bool_option(opt_idx, varp, value, opt_flags)
* set. */
if (STRCMP(p_enc, "utf-8") != 0)
{
static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
msg_source(hl_attr(HLF_W));
MSG_ATTR(_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'"),
hl_attr(HLF_W));
MSG_ATTR(_(w_arabic), hl_attr(HLF_W));
#ifdef FEAT_EVAL
set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1);
#endif
}
# ifdef FEAT_MBYTE
@@ -7828,7 +7909,7 @@ set_num_option(opt_idx, varp, value, errbuf, errbuflen, opt_flags)
newFoldLevel();
}
/* 'foldminlevel' */
/* 'foldminlines' */
else if (pp == &curwin->w_p_fml)
{
foldUpdateAll(curwin);
@@ -10232,25 +10313,110 @@ wc_use_keyname(varp, wcp)
#ifdef FEAT_LANGMAP
/*
* Any character has an equivalent character. This is used for keyboards that
* have a special language mode that sends characters above 128 (although
* other characters can be translated too).
* Any character has an equivalent 'langmap' character. This is used for
* keyboards that have a special language mode that sends characters above
* 128 (although other characters can be translated too). The "to" field is a
* Vim command character. This avoids having to switch the keyboard back to
* ASCII mode when leaving Insert mode.
*
* langmap_mapchar[] maps any of 256 chars to an ASCII char used for Vim
* commands.
* When FEAT_MBYTE is defined langmap_mapga.ga_data is a sorted table of
* langmap_entry_T. This does the same as langmap_mapchar[] for characters >=
* 256.
*/
# ifdef FEAT_MBYTE
/*
* With multi-byte support use growarray for 'langmap' chars >= 256
*/
typedef struct
{
int from;
int to;
} langmap_entry_T;
static garray_T langmap_mapga;
static void langmap_set_entry __ARGS((int from, int to));
/*
* char_u langmap_mapchar[256];
* Normally maps each of the 128 upper chars to an <128 ascii char; used to
* "translate" native lang chars in normal mode or some cases of
* insert mode without having to tediously switch lang mode back&forth.
* Search for an entry in "langmap_mapga" for "from". If found set the "to"
* field. If not found insert a new entry at the appropriate location.
*/
static void
langmap_set_entry(from, to)
int from;
int to;
{
langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
int a = 0;
int b = langmap_mapga.ga_len;
/* Do a binary search for an existing entry. */
while (a != b)
{
int i = (a + b) / 2;
int d = entries[i].from - from;
if (d == 0)
{
entries[i].to = to;
return;
}
if (d < 0)
a = i + 1;
else
b = i;
}
if (ga_grow(&langmap_mapga, 1) != OK)
return; /* out of memory */
/* insert new entry at position "a" */
entries = (langmap_entry_T *)(langmap_mapga.ga_data) + a;
mch_memmove(entries + 1, entries,
(langmap_mapga.ga_len - a) * sizeof(langmap_entry_T));
++langmap_mapga.ga_len;
entries[0].from = from;
entries[0].to = to;
}
/*
* Apply 'langmap' to multi-byte character "c" and return the result.
*/
int
langmap_adjust_mb(c)
int c;
{
langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
int a = 0;
int b = langmap_mapga.ga_len;
while (a != b)
{
int i = (a + b) / 2;
int d = entries[i].from - c;
if (d == 0)
return entries[i].to; /* found matching entry */
if (d < 0)
a = i + 1;
else
b = i;
}
return c; /* no entry found, return "c" unmodified */
}
# endif
static void
langmap_init()
{
int i;
for (i = 0; i < 256; i++) /* we init with a-one-to one map */
langmap_mapchar[i] = i;
for (i = 0; i < 256; i++)
langmap_mapchar[i] = i; /* we init with a one-to-one map */
# ifdef FEAT_MBYTE
ga_init2(&langmap_mapga, sizeof(langmap_entry_T), 8);
# endif
}
/*
@@ -10264,7 +10430,10 @@ langmap_set()
char_u *p2;
int from, to;
langmap_init(); /* back to one-to-one map first */
#ifdef FEAT_MBYTE
ga_clear(&langmap_mapga); /* clear the previous map first */
#endif
langmap_init(); /* back to one-to-one map */
for (p = p_langmap; p[0] != NUL; )
{
@@ -10314,7 +10483,13 @@ langmap_set()
transchar(from));
return;
}
langmap_mapchar[from & 255] = to;
#ifdef FEAT_MBYTE
if (from >= 256)
langmap_set_entry(from, to);
else
#endif
langmap_mapchar[from & 255] = to;
/* Advance to next pair */
mb_ptr_adv(p);
+64
View File
@@ -609,3 +609,67 @@ mch_textdomain(const char *domain)
return (char*)domain;
}
#endif
void macosx_fork()
{
pid_t pid;
int i;
/*
* On OS X, you have to exec after a fork, otherwise calls to frameworks
* will assert (and without Core Foundation, you can't start the gui. What
* fun.). See CAVEATS at:
*
* http://developer.apple.com/documentation/Darwin/Reference/ManPages/
* man2/fork.2.html
*
* Since we have to go through this anyways, we might as well use vfork.
* But: then we can't detach from our starting shell, so stick with fork.
*/
/* Stolen from http://paste.lisp.org/display/50906 */
extern int *_NSGetArgc(void);
extern char ***_NSGetArgv(void);
int argc = *_NSGetArgc();
char ** argv = *_NSGetArgv();
char * newargv[argc+2];
newargv[0] = argv[0];
/*
* Make sure "-f" is in front of potential "--remote" flags, else
* they would consume it.
*/
newargv[1] = "-f";
for (i = 1; i < argc; i++) {
newargv[i + 1] = argv[i];
}
newargv[argc+1] = NULL;
pid = fork();
switch(pid) {
case -1:
# ifndef NDEBUG
fprintf(stderr, "vim: Mac OS X workaround fork() failed!");
# endif
_exit(255);
case 0:
/* Child. */
/* Make sure we survive our shell */
setsid();
/* Restarts the vim process, will not return. */
execvp(argv[0], newargv);
/* If we come here, exec has failed. bail. */
_exit(255);
default:
/* Parent */
_exit(0);
}
}
+21 -2
View File
@@ -1223,6 +1223,25 @@ utf16_to_enc(short_u *str, int *lenp)
}
#endif /* FEAT_MBYTE */
/*
* Wait for another process to Close the Clipboard.
* Returns TRUE for success.
*/
int
vim_open_clipboard()
{
int delay = 10;
while (!OpenClipboard(NULL))
{
if (delay > 500)
return FALSE; /* waited too long, give up */
Sleep(delay);
delay *= 2; /* wait for 10, 20, 40, 80, etc. msec */
}
return TRUE;
}
/*
* Get the current selection and put it in the clipboard register.
*
@@ -1254,7 +1273,7 @@ clip_mch_request_selection(VimClipboard *cbd)
* Don't pass GetActiveWindow() as an argument to OpenClipboard() because
* then we can't paste back into the same window for some reason - webb.
*/
if (!OpenClipboard(NULL))
if (!vim_open_clipboard())
return;
/* Check for vim's own clipboard format first. This only gets the type of
@@ -1562,7 +1581,7 @@ clip_mch_set_selection(VimClipboard *cbd)
* because then we can't paste back into the same window for some
* reason - webb.
*/
if (OpenClipboard(NULL))
if (vim_open_clipboard())
{
if (EmptyClipboard())
{
+96 -25
View File
@@ -181,7 +181,8 @@ static RETSIGTYPE catch_sigpwr __ARGS(SIGPROTOARG);
&& defined(FEAT_TITLE) && !defined(FEAT_GUI_GTK)
# define SET_SIG_ALARM
static RETSIGTYPE sig_alarm __ARGS(SIGPROTOARG);
static int sig_alarm_called;
/* volatile because it is used in signal handler sig_alarm(). */
static volatile int sig_alarm_called;
#endif
static RETSIGTYPE deathtrap __ARGS(SIGPROTOARG);
@@ -201,13 +202,16 @@ static int save_patterns __ARGS((int num_pat, char_u **pat, int *num_file, char_
# define SIG_ERR ((RETSIGTYPE (*)())-1)
#endif
static int do_resize = FALSE;
/* volatile because it is used in signal handler sig_winch(). */
static volatile int do_resize = FALSE;
#ifndef __EMX__
static char_u *extra_shell_arg = NULL;
static int show_shell_mess = TRUE;
#endif
static int deadly_signal = 0; /* The signal we caught */
static int in_mch_delay = FALSE; /* sleeping in mch_delay() */
/* volatile because it is used in signal handler deathtrap(). */
static volatile int deadly_signal = 0; /* The signal we caught */
/* volatile because it is used in signal handler deathtrap(). */
static volatile int in_mch_delay = FALSE; /* sleeping in mch_delay() */
static int curr_tmode = TMODE_COOK; /* contains current terminal mode */
@@ -802,7 +806,7 @@ init_signal_stack()
#endif
/*
* We need correct potatotypes for a signal function, otherwise mean compilers
* We need correct prototypes for a signal function, otherwise mean compilers
* will barf when the second argument to signal() is ``wrong''.
* Let me try it with a few tricky defines from my own osdef.h (jw).
*/
@@ -1068,13 +1072,18 @@ deathtrap SIGDEFARG(sigarg)
SIGRETURN;
}
#ifdef _REENTRANT
#if defined(_REENTRANT) && defined(SIGCONT)
/*
* On Solaris with multi-threading, suspending might not work immediately.
* Catch the SIGCONT signal, which will be used as an indication whether the
* suspending has been done or not.
*
* On Linux, signal is not always handled immediately either.
* See https://bugs.launchpad.net/bugs/291373
*
* volatile because it is used in in signal handler sigcont_handler().
*/
static int sigcont_received;
static volatile int sigcont_received;
static RETSIGTYPE sigcont_handler __ARGS(SIGPROTOARG);
/*
@@ -1118,15 +1127,28 @@ mch_suspend()
}
# endif
# ifdef _REENTRANT
# if defined(_REENTRANT) && defined(SIGCONT)
sigcont_received = FALSE;
# endif
kill(0, SIGTSTP); /* send ourselves a STOP signal */
# ifdef _REENTRANT
/* When we didn't suspend immediately in the kill(), do it now. Happens
* on multi-threaded Solaris. */
if (!sigcont_received)
pause();
# if defined(_REENTRANT) && defined(SIGCONT)
/*
* Wait for the SIGCONT signal to be handled. It generally happens
* immediately, but somehow not all the time. Do not call pause()
* because there would be race condition which would hang Vim if
* signal happened in between the test of sigcont_received and the
* call to pause(). If signal is not yet received, call sleep(0)
* to just yield CPU. Signal should then be received. If somehow
* it's still not received, sleep 1, 2, 3 ms. Don't bother waiting
* further if signal is not received after 1+2+3+4 ms (not expected
* to happen).
*/
{
long wait;
for (wait = 0; !sigcont_received && wait <= 3L; wait++)
/* Loop is not entered most of the time */
mch_delay(wait, FALSE);
}
# endif
# ifdef FEAT_TITLE
@@ -1175,7 +1197,7 @@ set_signals()
#ifdef SIGTSTP
signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL);
#endif
#ifdef _REENTRANT
#if defined(_REENTRANT) && defined(SIGCONT)
signal(SIGCONT, sigcont_handler);
#endif
@@ -1234,7 +1256,7 @@ catch_int_signal()
reset_signals()
{
catch_signals(SIG_DFL, SIG_DFL);
#ifdef _REENTRANT
#if defined(_REENTRANT) && defined(SIGCONT)
/* SIGCONT isn't in the list, because its default action is ignore */
signal(SIGCONT, SIG_DFL);
#endif
@@ -3952,7 +3974,17 @@ mch_call_shell(cmd, options)
* children can be kill()ed. Don't do this when using pipes,
* because stdin is not a tty, we would lose /dev/tty. */
if (p_stmp)
{
(void)setsid();
# if defined(SIGHUP)
/* When doing "!xterm&" and 'shell' is bash: the shell
* will exit and send SIGHUP to all processes in its
* group, killing the just started process. Ignore SIGHUP
* to avoid that. (suggested by Simon Schubert)
*/
signal(SIGHUP, SIG_IGN);
# endif
}
# endif
# ifdef FEAT_GUI
if (pty_slave_fd >= 0)
@@ -4084,6 +4116,9 @@ mch_call_shell(cmd, options)
int fromshell_fd;
garray_T ga;
int noread_cnt;
# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
struct timeval start_tv;
# endif
# ifdef FEAT_GUI
if (pty_master_fd >= 0)
@@ -4193,7 +4228,9 @@ mch_call_shell(cmd, options)
ga_init2(&ga, 1, BUFLEN);
noread_cnt = 0;
# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
gettimeofday(&start_tv, NULL);
# endif
for (;;)
{
/*
@@ -4206,25 +4243,34 @@ mch_call_shell(cmd, options)
* that a typed password is echoed for ssh or gpg command.
* Don't get characters when the child has already
* finished (wait_pid == 0).
* Don't get extra characters when we already have one.
* Don't read characters unless we didn't get output for a
* while, avoids that ":r !ls" eats typeahead.
* while (noread_cnt > 4), avoids that ":r !ls" eats
* typeahead.
*/
len = 0;
if (!(options & SHELL_EXPAND)
&& ((options &
(SHELL_READ|SHELL_WRITE|SHELL_COOKED))
!= (SHELL_READ|SHELL_WRITE|SHELL_COOKED)
#ifdef FEAT_GUI
# ifdef FEAT_GUI
|| gui.in_use
#endif
# endif
)
&& wait_pid == 0
&& (ta_len > 0
|| (noread_cnt > 4
&& (len = ui_inchar(ta_buf,
BUFLEN, 10L, 0)) > 0)))
&& (ta_len > 0 || noread_cnt > 4))
{
if (ta_len == 0)
{
/* Get extra characters when we don't have any.
* Reset the counter and timer. */
noread_cnt = 0;
# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
gettimeofday(&start_tv, NULL);
# endif
len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
}
if (ta_len > 0 || len > 0)
{
/*
* For pipes:
* Check for CTRL-C: send interrupt signal to child.
@@ -4326,9 +4372,9 @@ mch_call_shell(cmd, options)
{
ta_len -= len;
mch_memmove(ta_buf, ta_buf + len, ta_len);
noread_cnt = 0;
}
}
}
}
if (got_int)
@@ -4434,8 +4480,31 @@ mch_call_shell(cmd, options)
windgoto(msg_row, msg_col);
cursor_on();
out_flush();
# if FEAT_GUI_MACVIM
if (gui.in_use)
gui_macvim_flush();
# endif
if (got_int)
break;
# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
{
struct timeval now_tv;
long msec;
/* Avoid that we keep looping here without
* checking for a CTRL-C for a long time. Don't
* break out too often to avoid losing typeahead. */
gettimeofday(&now_tv, NULL);
msec = (now_tv.tv_sec - start_tv.tv_sec) * 1000L
+ (now_tv.tv_usec - start_tv.tv_usec) / 1000L;
if (msec > 2000)
{
noread_cnt = 5;
break;
}
}
# endif
}
/* If we already detected the child has finished break the
@@ -5858,7 +5927,9 @@ gpm_open()
* we are going to suspend or starting an external process
* so we shouldn't have problem with this
*/
# ifdef SIGTSTP
signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL);
# endif
return 1; /* succeed */
}
if (gpm_fd == -2)
+3
View File
@@ -263,6 +263,9 @@ extern char *vim_SelFile __ARGS((Widget toplevel, char *prompt, char *init_path,
#ifdef MACOS_CONVERT
# include "os_mac_conv.pro"
#endif
#ifdef MACOS_X
# include "os_macosx.pro"
#endif
#ifdef __BORLANDC__
# define _PROTO_H
+1
View File
@@ -40,6 +40,7 @@ void global_exe __ARGS((char_u *cmd));
int read_viminfo_sub_string __ARGS((vir_T *virp, int force));
void write_viminfo_sub_string __ARGS((FILE *fp));
void free_old_sub __ARGS((void));
void free_signs __ARGS((void));
int prepare_tagpreview __ARGS((int undo_sync));
void ex_help __ARGS((exarg_T *eap));
char_u *check_help_lang __ARGS((char_u *arg));
+1
View File
@@ -4,6 +4,7 @@ char_u *getcmdline_prompt __ARGS((int firstc, char_u *prompt, int attr, int xp_c
int text_locked __ARGS((void));
void text_locked_msg __ARGS((void));
int curbuf_locked __ARGS((void));
int allbuf_locked __ARGS((void));
char_u *getexline __ARGS((int c, void *dummy, int indent));
char_u *getexmodeline __ARGS((int promptc, void *dummy, int indent));
int cmdline_overstrike __ARGS((void));
+2
View File
@@ -14,6 +14,8 @@ gui_mch_update(void);
void
gui_mch_flush(void);
void
gui_macvim_flush(void);
void
gui_macvim_force_flush(void);
int
gui_mch_wait_for_chars(int wtime);
+2
View File
@@ -1,4 +1,6 @@
/* if_cscope.c */
char_u *get_cscope_name __ARGS((expand_T *xp, int idx));
void set_context_in_cscope_cmd __ARGS((expand_T *xp, char_u *arg));
void do_cscope __ARGS((exarg_T *eap));
void do_scscope __ARGS((exarg_T *eap));
void do_cstag __ARGS((exarg_T *eap));
-1
View File
@@ -1,6 +1,5 @@
/* main.c */
void main_loop __ARGS((int cmdwin, int noexmode));
void prepare_getout __ARGS(());
void getout_preserve_modified __ARGS((int exitval));
void getout __ARGS((int exitval));
int process_env __ARGS((char_u *env, int is_viminit));
+1 -1
View File
@@ -11,7 +11,7 @@ void netbeans_send_disconnect __ARGS((void));
void netbeans_frame_moved __ARGS((int new_x, int new_y));
void netbeans_file_activated __ARGS((buf_T *bufp));
void netbeans_file_opened __ARGS((buf_T *bufp));
void netbeans_file_closed __ARGS((buf_T *bufp));
void netbeans_file_killed __ARGS((buf_T *bufp));
void netbeans_inserted __ARGS((buf_T *bufp, linenr_T linenr, colnr_T col, char_u *txt, int newlen));
void netbeans_removed __ARGS((buf_T *bufp, linenr_T linenr, colnr_T col, long len));
void netbeans_unmodified __ARGS((buf_T *bufp));
+1
View File
@@ -44,6 +44,7 @@ void set_imsearch_global __ARGS((void));
void set_context_in_set_cmd __ARGS((expand_T *xp, char_u *arg, int opt_flags));
int ExpandSettings __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file));
int ExpandOldSetting __ARGS((int *num_file, char_u ***file));
int langmap_adjust_mb __ARGS((int c));
int has_format_option __ARGS((int x));
int shortmess __ARGS((int x));
void vimrc_found __ARGS((char_u *fname, char_u *envname));
+3
View File
@@ -0,0 +1,3 @@
/* os_macosx.pro */
void macosx_fork __ARGS((void));
/* vim: set ft=c : */
+14 -12
View File
@@ -1419,6 +1419,7 @@ qf_jump(qi, dir, errornr, forceit)
int opened_window = FALSE;
win_T *win;
win_T *altwin;
int flags;
#endif
win_T *oldwin = curwin;
int print_message = TRUE;
@@ -1531,7 +1532,6 @@ qf_jump(qi, dir, errornr, forceit)
if (qf_ptr->qf_type == 1 && (!curwin->w_buffer->b_help || cmdmod.tab != 0))
{
win_T *wp;
int n;
if (cmdmod.tab != 0)
wp = NULL;
@@ -1547,13 +1547,16 @@ qf_jump(qi, dir, errornr, forceit)
* Split off help window; put it at far top if no position
* specified, the current window is vertically split and narrow.
*/
n = WSP_HELP;
flags = WSP_HELP;
# ifdef FEAT_VERTSPLIT
if (cmdmod.split == 0 && curwin->w_width != Columns
&& curwin->w_width < 80)
n |= WSP_TOP;
flags |= WSP_TOP;
# endif
if (win_split(0, n) == FAIL)
if (qi != &ql_info)
flags |= WSP_NEWLOC; /* don't copy the location list */
if (win_split(0, flags) == FAIL)
goto theend;
opened_window = TRUE; /* close it when fail */
@@ -1563,7 +1566,6 @@ qf_jump(qi, dir, errornr, forceit)
if (qi != &ql_info) /* not a quickfix list */
{
/* The new window should use the supplied location list */
qf_free_all(curwin);
curwin->w_llist = qi;
qi->qf_refcount++;
}
@@ -1610,10 +1612,11 @@ qf_jump(qi, dir, errornr, forceit)
{
goto_tabpage_win(tp, wp);
usable_win = 1;
break;
goto win_found;
}
}
}
win_found:
/*
* If there is only one window and it is the quickfix window, create a
@@ -1623,7 +1626,10 @@ qf_jump(qi, dir, errornr, forceit)
{
ll_ref = curwin->w_llist_ref;
if (win_split(0, WSP_ABOVE) == FAIL)
flags = WSP_ABOVE;
if (ll_ref != NULL)
flags |= WSP_NEWLOC;
if (win_split(0, flags) == FAIL)
goto failed; /* not enough room for window */
opened_window = TRUE; /* close it when fail */
p_swb = empty_option; /* don't split again */
@@ -1635,7 +1641,6 @@ qf_jump(qi, dir, errornr, forceit)
{
/* The new window should use the location list from the
* location list window */
qf_free_all(curwin);
curwin->w_llist = ll_ref;
ll_ref->qf_refcount++;
}
@@ -2310,15 +2315,12 @@ ex_copen(eap)
if (eap->cmdidx == CMD_copen || eap->cmdidx == CMD_cwindow)
/* Create the new window at the very bottom. */
win_goto(lastwin);
if (win_split(height, WSP_BELOW) == FAIL)
if (win_split(height, WSP_BELOW | WSP_NEWLOC) == FAIL)
return; /* not enough room for window */
#ifdef FEAT_SCROLLBIND
curwin->w_p_scb = FALSE;
#endif
/* Remove the location list for the quickfix window */
qf_free_all(curwin);
if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow)
{
/*
+4 -6
View File
@@ -4532,7 +4532,7 @@ regmatch(scan)
cleanup_subexpr();
if (!REG_MULTI) /* Single-line regexp */
{
if (reg_endp[no] == NULL)
if (reg_startp[no] == NULL || reg_endp[no] == NULL)
{
/* Backref was not set: Match an empty string. */
len = 0;
@@ -4548,7 +4548,7 @@ regmatch(scan)
}
else /* Multi-line regexp */
{
if (reg_endpos[no].lnum < 0)
if (reg_startpos[no].lnum < 0 || reg_endpos[no].lnum < 0)
{
/* Backref was not set: Match an empty string. */
len = 0;
@@ -7279,13 +7279,11 @@ reg_submatch(no)
}
else
{
if (submatch_match->endp[no] == NULL)
s = submatch_match->startp[no];
if (s == NULL || submatch_match->endp[no] == NULL)
retval = NULL;
else
{
s = submatch_match->startp[no];
retval = vim_strnsave(s, (int)(submatch_match->endp[no] - s));
}
}
return retval;
+98 -41
View File
@@ -2596,6 +2596,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
int noinvcur = FALSE; /* don't invert the cursor */
#ifdef FEAT_VISUAL
pos_T *top, *bot;
int lnum_in_visual_area = FALSE;
#endif
pos_T pos;
long v;
@@ -2792,9 +2793,10 @@ win_line(wp, lnum, startrow, endrow, nochange)
top = &VIsual;
bot = &curwin->w_cursor;
}
lnum_in_visual_area = (lnum >= top->lnum && lnum <= bot->lnum);
if (VIsual_mode == Ctrl_V) /* block mode */
{
if (lnum >= top->lnum && lnum <= bot->lnum)
if (lnum_in_visual_area)
{
fromcol = wp->w_old_cursor_fcol;
tocol = wp->w_old_cursor_lcol;
@@ -2887,8 +2889,9 @@ win_line(wp, lnum, startrow, endrow, nochange)
}
else
tocol = MAXCOL;
if (fromcol == tocol) /* do at least one character */
tocol = fromcol + 1; /* happens when past end of line */
/* do at least one character; happens when past end of line */
if (fromcol == tocol)
tocol = fromcol + 1;
area_highlighting = TRUE;
attr = hl_attr(HLF_I);
}
@@ -3420,6 +3423,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
&& (*mb_ptr2cells)(ptr) > 1)
#endif
|| ((int)vcol_prev == fromcol_prev
&& vcol_prev < vcol /* not at margin */
&& vcol < tocol))
area_attr = attr; /* start highlighting */
else if (area_attr != 0
@@ -3552,7 +3556,8 @@ win_line(wp, lnum, startrow, endrow, nochange)
/* Use line_attr when not in the Visual or 'incsearch' area
* (area_attr may be 0 when "noinvcur" is set). */
else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL)
|| (vcol < fromcol || vcol >= tocol)))
|| vcol < fromcol || vcol_prev < fromcol_prev
|| vcol >= tocol))
char_attr = line_attr;
#endif
else
@@ -4114,6 +4119,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
# endif
(col < W_WIDTH(wp)))
&& !(noinvcur
&& lnum == wp->w_cursor.lnum
&& (colnr_T)vcol == wp->w_virtcol)))
&& lcs_eol_one >= 0)
{
@@ -4255,7 +4261,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
* preedit_changed and commit. Thus Vim can't set "im_is_active", use
* im_is_preediting() here. */
if (xic != NULL
&& lnum == curwin->w_cursor.lnum
&& lnum == wp->w_cursor.lnum
&& (State & INSERT)
&& !p_imdisable
&& im_is_preediting()
@@ -4264,7 +4270,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
colnr_T tcol;
if (preedit_end_col == MAXCOL)
getvcol(curwin, &(curwin->w_cursor), &tcol, NULL, NULL);
getvcol(curwin, &(wp->w_cursor), &tcol, NULL, NULL);
else
tcol = preedit_end_col;
if ((long)preedit_start_col <= vcol && vcol < (long)tcol)
@@ -4361,7 +4367,13 @@ win_line(wp, lnum, startrow, endrow, nochange)
}
#endif
if (lcs_eol == lcs_eol_one
&& ((area_attr != 0 && vcol == fromcol && c == NUL)
&& ((area_attr != 0 && vcol == fromcol
#ifdef FEAT_VISUAL
&& (VIsual_mode != Ctrl_V
|| lnum == VIsual.lnum
|| lnum == curwin->w_cursor.lnum)
#endif
&& c == NUL)
#ifdef FEAT_SEARCH_EXTRA
/* highlight 'hlsearch' match at end of line */
|| (prevcol_hl_flag == TRUE
@@ -4455,7 +4467,8 @@ win_line(wp, lnum, startrow, endrow, nochange)
if (c == NUL)
{
#ifdef FEAT_SYN_HL
if (eol_hl_off > 0 && vcol - eol_hl_off == (long)wp->w_virtcol)
if (eol_hl_off > 0 && vcol - eol_hl_off == (long)wp->w_virtcol
&& lnum == wp->w_cursor.lnum)
{
/* highlight last char after line */
--col;
@@ -4557,7 +4570,8 @@ win_line(wp, lnum, startrow, endrow, nochange)
* highlight the cursor position itself. */
if (wp->w_p_cuc && vcol == (long)wp->w_virtcol
&& lnum != wp->w_cursor.lnum
&& draw_state == WL_LINE)
&& draw_state == WL_LINE
&& !lnum_in_visual_area)
{
vcol_save_attr = char_attr;
char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUC));
@@ -4660,7 +4674,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
--n_skip;
/* Only advance the "vcol" when after the 'number' column. */
if (draw_state >= WL_SBR
if (draw_state > WL_NR
#ifdef FEAT_DIFF
&& filler_todo <= 0
#endif
@@ -5127,8 +5141,8 @@ screen_line(row, coloff, endcol, clear_width
#endif
#if defined(FEAT_GUI) || defined(UNIX)
/* The bold trick makes a single row of pixels appear in the next
* character. When a bold character is removed, the next
/* The bold trick makes a single column of pixels appear in the
* next character. When a bold character is removed, the next
* character should be redrawn too. This happens for our own GUI
* and for some xterms. */
if (
@@ -6271,9 +6285,15 @@ screen_puts_len(text, len, row, col, attr)
int pcc[MAX_MCO];
# endif
#endif
#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX)
int force_redraw_this;
int force_redraw_next = FALSE;
#endif
int need_redraw;
if (ScreenLines == NULL || row >= screen_Rows) /* safety check */
return;
off = LineOffset[row] + col;
#ifdef FEAT_MBYTE
/* When drawing over the right halve of a double-wide char clear out the
@@ -6283,10 +6303,21 @@ screen_puts_len(text, len, row, col, attr)
&& !gui.in_use
# endif
&& mb_fix_col(col, row) != col)
screen_puts_len((char_u *)" ", 1, row, col - 1, 0);
{
ScreenLines[off - 1] = ' ';
ScreenAttrs[off - 1] = 0;
if (enc_utf8)
{
ScreenLinesUC[off - 1] = 0;
ScreenLinesC[0][off - 1] = 0;
}
/* redraw the previous cell, make it empty */
screen_char(off - 1, row, col - 1);
/* force the cell at "col" to be redrawn */
force_redraw_next = TRUE;
}
#endif
off = LineOffset[row] + col;
#ifdef FEAT_MBYTE
max_off = LineOffset[row] + screen_Columns;
#endif
@@ -6350,7 +6381,12 @@ screen_puts_len(text, len, row, col, attr)
}
#endif
if (ScreenLines[off] != c
#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX)
force_redraw_this = force_redraw_next;
force_redraw_next = FALSE;
#endif
need_redraw = ScreenLines[off] != c
#ifdef FEAT_MBYTE
|| (mbyte_cells == 2
&& ScreenLines[off + 1] != (enc_dbcs ? ptr[1] : 0))
@@ -6358,24 +6394,24 @@ screen_puts_len(text, len, row, col, attr)
&& c == 0x8e
&& ScreenLines2[off] != ptr[1])
|| (enc_utf8
&& (ScreenLinesUC[off] != (u8char_T)u8c
&& (ScreenLinesUC[off] != (u8char_T)(c >= 0x80 ? u8c : 0)
|| screen_comp_differs(off, u8cc)))
#endif
|| ScreenAttrs[off] != attr
|| exmode_active
|| exmode_active;
if (need_redraw
#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX)
|| force_redraw_this
#endif
)
{
#if defined(FEAT_GUI) || defined(UNIX)
/* The bold trick makes a single row of pixels appear in the next
* character. When a bold character is removed, the next
* character should be redrawn too. This happens for our own GUI
* and for some xterms.
* Force the redraw by setting the attribute to a different value
* than "attr", the contents of ScreenLines[] may be needed by
* mb_off2cells() further on.
* Don't do this for the last drawn character, because the next
* character may not be redrawn. */
if (
* and for some xterms. */
if (need_redraw && ScreenLines[off] != ' ' && (
# ifdef FEAT_GUI
gui.in_use
# endif
@@ -6385,23 +6421,14 @@ screen_puts_len(text, len, row, col, attr)
# ifdef UNIX
term_is_xterm
# endif
)
))
{
int n;
int n = ScreenAttrs[off];
n = ScreenAttrs[off];
# ifdef FEAT_MBYTE
if (col + mbyte_cells < screen_Columns
&& (n > HL_ALL || (n & HL_BOLD))
&& (len < 0 ? ptr[mbyte_blen] != NUL
: ptr + mbyte_blen < text + len))
ScreenAttrs[off + mbyte_cells] = attr + 1;
# else
if (col + 1 < screen_Columns
&& (n > HL_ALL || (n & HL_BOLD))
&& (len < 0 ? ptr[1] != NUL : ptr + 1 < text + len))
ScreenLines[off + 1] = 0;
# endif
if (n > HL_ALL)
n = syn_attr2attr(n);
if (n & HL_BOLD)
force_redraw_next = TRUE;
}
#endif
#ifdef FEAT_MBYTE
@@ -6488,6 +6515,20 @@ screen_puts_len(text, len, row, col, attr)
++ptr;
}
}
#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX)
/* If we detected the next character needs to be redrawn, but the text
* doesn't extend up to there, update the character here. */
if (force_redraw_next && col < screen_Columns)
{
# ifdef FEAT_MBYTE
if (enc_dbcs != 0 && dbcs_off2cells(off, max_off) > 1)
screen_char_2(off, row, col);
else
# endif
screen_char(off, row, col);
}
#endif
}
#ifdef FEAT_SEARCH_EXTRA
@@ -7364,7 +7405,11 @@ screenalloc(clear)
#endif
static int entered = FALSE; /* avoid recursiveness */
static int done_outofmem_msg = FALSE; /* did outofmem message */
#ifdef FEAT_AUTOCMD
int retry_count = 0;
retry:
#endif
/*
* Allocation of the screen buffers is done only when the size changes and
* when Rows and Columns have been set and we have started doing full
@@ -7448,10 +7493,13 @@ screenalloc(clear)
{
outofmem = TRUE;
#ifdef FEAT_WINDOWS
break;
goto give_up;
#endif
}
}
#ifdef FEAT_WINDOWS
give_up:
#endif
#ifdef FEAT_MBYTE
for (i = 0; i < p_mco; ++i)
@@ -7636,8 +7684,17 @@ screenalloc(clear)
--RedrawingDisabled;
#ifdef FEAT_AUTOCMD
if (starting == 0)
/*
* Do not apply autocommands more than 3 times to avoid an endless loop
* in case applying autocommands always changes Rows or Columns.
*/
if (starting == 0 && ++retry_count <= 3)
{
apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, FALSE, curbuf);
/* In rare cases, autocommands may have altered Rows or Columns,
* jump back to check if we need to allocate the screen again. */
goto retry;
}
#endif
}
+6 -3
View File
@@ -2376,7 +2376,7 @@ spell_move_to(wp, dir, allwords, curline, attrp)
/* If we are back at the starting line and there is no match then
* give up. */
if (lnum == wp->w_cursor.lnum && !found_one)
if (lnum == wp->w_cursor.lnum && (!found_one || wrapped))
break;
/* Skip the characters at the start of the next line that were
@@ -4956,13 +4956,16 @@ typedef struct compitem_S
* Structure that is used to store the items in the word tree. This avoids
* the need to keep track of each allocated thing, everything is freed all at
* once after ":mkspell" is done.
* Note: "sb_next" must be just before "sb_data" to make sure the alignment of
* "sb_data" is correct for systems where pointers must be aligned on
* pointer-size boundaries and sizeof(pointer) > sizeof(int) (e.g., Sparc).
*/
#define SBLOCKSIZE 16000 /* size of sb_data */
typedef struct sblock_S sblock_T;
struct sblock_S
{
sblock_T *sb_next; /* next block in list */
int sb_used; /* nr of bytes already in use */
sblock_T *sb_next; /* next block in list */
char_u sb_data[1]; /* data, actually longer */
};
@@ -15011,7 +15014,7 @@ soundalike_score(goodstart, badstart)
case 0:
/*
* Lenghts are equal, thus changes must result in same length: An
* Lengths are equal, thus changes must result in same length: An
* insert is only possible in combination with a delete.
* 1: check if for identical strings
*/
+21 -7
View File
@@ -515,7 +515,7 @@ do_tag(tag, type, count, forceit, verbose)
* If a count is supplied to the ":tag <name>" command, then
* jump to count'th matching tag.
*/
if (type == DT_TAG && count > 0)
if (type == DT_TAG && *tag != NUL && count > 0)
cur_match = count - 1;
if (type == DT_SELECT || type == DT_JUMP
@@ -618,7 +618,7 @@ do_tag(tag, type, count, forceit, verbose)
taglen_advance(taglen);
MSG_PUTS_ATTR(_("file\n"), hl_attr(HLF_T));
for (i = 0; i < num_matches; ++i)
for (i = 0; i < num_matches && !got_int; ++i)
{
parse_match(matches[i], &tagp);
if (!new_tag && (
@@ -655,6 +655,8 @@ do_tag(tag, type, count, forceit, verbose)
}
if (msg_col > 0)
msg_putchar('\n');
if (got_int)
break;
msg_advance(15);
/* print any extra fields */
@@ -689,6 +691,8 @@ do_tag(tag, type, count, forceit, verbose)
if (msg_col + ptr2cells(p) >= Columns)
{
msg_putchar('\n');
if (got_int)
break;
msg_advance(15);
}
p = msg_outtrans_one(p, attr);
@@ -704,6 +708,8 @@ do_tag(tag, type, count, forceit, verbose)
if (msg_col > 15)
{
msg_putchar('\n');
if (got_int)
break;
msg_advance(15);
}
}
@@ -734,6 +740,8 @@ do_tag(tag, type, count, forceit, verbose)
{
if (msg_col + (*p == TAB ? 1 : ptr2cells(p)) > Columns)
msg_putchar('\n');
if (got_int)
break;
msg_advance(15);
/* skip backslash used for escaping command char */
@@ -760,12 +768,9 @@ do_tag(tag, type, count, forceit, verbose)
if (msg_col)
msg_putchar('\n');
ui_breakcheck();
if (got_int)
{
got_int = FALSE; /* only stop the listing */
break;
}
}
if (got_int)
got_int = FALSE; /* only stop the listing */
ask_for_selection = TRUE;
}
#if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL)
@@ -2542,6 +2547,15 @@ free_tag_stuff()
{
ga_clear_strings(&tag_fnames);
do_tag(NULL, DT_FREE, 0, 0, 0);
tag_freematch();
# if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
if (ptag_entry.tagname)
{
vim_free(ptag_entry.tagname);
ptag_entry.tagname = NULL;
}
# endif
}
#endif
+9 -1
View File
@@ -4920,7 +4920,15 @@ check_termcode(max_offset, buf, buflen)
key_name[0] = KEY2TERMCAP0(key);
key_name[1] = KEY2TERMCAP1(key);
if (key_name[0] == KS_KEY)
string[new_slen++] = key_name[1]; /* from ":set <M-b>=xx" */
{
/* from ":set <M-b>=xx" */
#ifdef FEAT_MBYTE
if (has_mbyte)
new_slen += (*mb_char2bytes)(key_name[1], string + new_slen);
else
#endif
string[new_slen++] = key_name[1];
}
else
{
string[new_slen++] = K_SPECIAL;
+3 -1
View File
@@ -25,7 +25,8 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \
test43.out test44.out test45.out test46.out test47.out \
test48.out test51.out test53.out test54.out test55.out \
test56.out test57.out test58.out test59.out test60.out \
test61.out test62.out test63.out test64.out test65.out
test61.out test62.out test63.out test64.out test65.out \
test66.out
.SUFFIXES: .in .out
@@ -110,3 +111,4 @@ test62.out: test62.in
test63.out: test63.in
test64.out: test64.in
test65.out: test65.in
test66.out: test66.in
+1 -1
View File
@@ -26,7 +26,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \
test15.out test17.out test18.out test21.out test26.out \
test30.out test31.out test32.out test33.out test34.out \
test37.out test38.out test39.out test40.out test41.out \
test42.out test52.out test65.out
test42.out test52.out test65.out test66.out
SCRIPTS32 = test50.out
+1 -1
View File
@@ -45,7 +45,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \
test15.out test17.out test18.out test21.out test26.out \
test30.out test31.out test32.out test33.out test34.out \
test37.out test38.out test39.out test40.out test41.out \
test42.out test52.out test65.out
test42.out test52.out test65.out test66.out
SCRIPTS32 = test50.out
+2 -1
View File
@@ -25,7 +25,8 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \
test43.out test44.out test45.out test46.out test47.out \
test48.out test51.out test53.out test54.out test55.out \
test56.out test57.out test58.out test59.out test60.out \
test61.out test62.out test63.out test64.out test65.out
test61.out test62.out test63.out test64.out test65.out \
test66.out
.SUFFIXES: .in .out
+3 -2
View File
@@ -4,7 +4,7 @@
# Authors: Zoltan Arpadffy, <arpadffy@polarhome.com>
# Sandor Kopanyi, <sandor.kopanyi@mailbox.hu>
#
# Last change: 2008 Aug 19
# Last change: 2009 Mar 05
#
# This has been tested on VMS 6.2 to 8.3 on DEC Alpha, VAX and IA64.
# Edit the lines in the Configuration section below to select.
@@ -68,7 +68,8 @@ SCRIPT = test1.out test2.out test3.out test4.out test5.out \
test43.out test44.out test45.out test46.out \
test48.out test51.out test53.out test54.out test55.out \
test56.out test57.out test60.out \
test61.out test62.out test63.out test64.out test65.out
test61.out test62.out test63.out test64.out test65.out \
test66.out
.IFDEF WANT_GUI
SCRIPT_GUI = test16.out
+1 -1
View File
@@ -20,7 +20,7 @@ SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \
test48.out test49.out test51.out test52.out test53.out \
test54.out test55.out test56.out test57.out test58.out \
test59.out test60.out test61.out test62.out test63.out \
test64.out test65.out
test64.out test65.out test66.out
SCRIPTS_GUI = test16.out
+25
View File
@@ -0,0 +1,25 @@
Test for visual block shift and tab characters.
STARTTEST
:so small.vim
/^abcdefgh
4jI j<<11|D
7|a 
7|a 
7|a 4k13|4j<
:$-4,$w! test.out
:$-4,$s/\s\+//g
4kI j<<
7|a 
7|a 
7|a 4k13|4j3<
:$-4,$w >> test.out
:qa!
ENDTEST
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
+10
View File
@@ -0,0 +1,10 @@
abcdefghijklmnopqrstuvwxyz
abcdefghij
abc defghijklmnopqrstuvwxyz
abc defghijklmnopqrstuvwxyz
abc defghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghij
abc defghijklmnopqrstuvwxyz
abc defghijklmnopqrstuvwxyz
abc defghijklmnopqrstuvwxyz

Some files were not shown because too many files have changed in this diff Show More