The default Cocoa key bindings map these key presses to two commands
which led them to be triggered twice. Avoid this by passing
Alt+Function key presses straight to Vim instead of to
interpretKeyEvents:.
The 'plus' button on the tabline got first responder status when leaving
full-screen, which (among other things) looks bad when full keyboard
access is enabled.
Also some code cleanup.
Window and view code was refactored to better accomodate the transition
to the ATSUI text rendering code. View specific code has been
completely moved into MMVimView and window code is now all in
MMWindowController; the window controller is also 'full-screen aware'.
Finally, the text storage is no longer referenced outside MMTextView --
the idea is that the text view is the public class for handling the
work that MMTextStorage used to be the public interface for.
This refactoring also brings some improvements:
- window resizing is more responsive
- full-screen window memory leak fixed
- proper fix for erroneous 'buffer modified' warning
- full-screen no longer tried to set 'nil-title' (this caused backend
connection problems)
- changing lines/columns in full-screen works properly
- open dialog now works in full-screen on Tiger
The font was not retained when setting gui.norm_font leading to a pointer into
freed memory. The font instance is now retained before its pointer value is
stored in gui.norm_font.
When ~/Library/Preferences/org.vim.MacVim.plist does not exist the window will
be placed according to the frame passed when initializing the NSWindow, so set
some sane default values.
If vim is started via '-g', it forks and exec()s a new (!) vim instance in the
child process. But if the gui is started via `:gui`, no forking is done.
In MacVim, pass the '-f' flag when starting a new Vim process (should not fork
in this instance).
Programs that support ODB asks MacVim to open files. When a file is written or
closed, MacVim notifies the program of these events. (At the moment the 'Burl'
parameter is parsed but ignored. The 'RdEV' parameter is ignored.)
Always send SetTextDimensionsMsgID to Vim at the end of live resize to ensure
that resizeWindowToFit gets called. Otherwise the window can be too big and
will then automatically resize when a dialog sheet is presented or when the
window is moved, which feels strange.
Before terminating gracefully, send a TerminateNowMsgID to every Vim process so
that they can determine whether MacVim quit or crashed. If MacVim quits, call
getout() to exit Vim (this removes swap files), otherwise call
getout_preserve_modified() (this preserves swap files).
When the default system keyboard script is non-roman the input manager is
automatically switched to a roman keyboard script when going to normal mode.
See 'imd', 'imc', 'imi' for some relevant options. MacVim uses an
over-the-spot style of IM support.
New Vim processes are by default launched via a login shell so that the user's
environment gets profiled. This behavior can be disabled by setting the user
default "MMLoginShell" to 0.
When dropping multiple files, make sure none of the files are already open. If
all files were already open, then select the window and tab of the first file
that was open. If at least one file was not already open, then simply ignore
the open files and open the unopened ones.
Also don't check if files exists inside application:openFiles: since files that
are passed here are assumed to already exists. The existence check has been
moved to the system services message openFile:userData:error:.
Characters and columns are no longer assumed to be in one-to-one
correspondence. Thus when modifying the text storage a (row,column) pair must
be searched for. This is managed using
[NSString rangeOfComposedCharacterSequenceAtIndex:]
and by marking wide characters with an attribute (called "MMWideChar"). We
also provide an optimized code path for when characters and columns are in
one-to-one correspondence (no wide chars, only chars that can be represented by
one utf16 character).
A new typesetter is also used. Instead of overriding
layoutGlyphsInLayoutManager:::: we override willSetLineFragmentRect::::. This
typesetter can handle composing characters, whereas the old typesetter couldn't
(it can still be used by setting the user default "MMTypesetter" to
"MMTypesetter2".)
Note that text rendering still has flaws, the Cocoa Text System and Vim has
different opinions on how much space certain characters take up and this
results in display bugs. (E.g. nonspacing marks such as U+064C are
problematic.) Also, sometimes the layout manager hides glyphs but Vim assumes
that each character is displayed (resulting in yet more display bugs).
Added support for 'guifontwide'. This can be set to anything (different font
size); it is quite possible to set it so that the display becomes completely
messed up.
When a file is dropped, each Vim process is checked to see if the file is
already open. If so, raise the corresponding window and select the tab that
holds the opened file. Only works when one file is dropped.
Now possible to evaluate expressions in a Vim process from MacVim [MMBackend
evaluateExpression:], and to send arbitrary input to Vim [MMVimController
addVimInput:]. Expression evaluation is used to query Vim state from within
MacVim.
When opening a file use these methods to check if it is already loaded, if so
raise the corresponding window (doesn't work for multiple files).
On applicationShoulTerminate: check the 'documentEdited' flag of each window to
decide whether any buffers were modified instead of making a DO call to each
Vim process.
The user environment is not always sourced when MacVim starts. To solve this
each Vim process is launched via a login shell like this:
$SHELL -l -c "exec /path/to/Vim -g <args>"
Also make sure that if an argument contains a space then enclose it in quotes.
This fixes the ':set lines=1000000' problem in fu mode. Furthermore, this
fixes a regression that the tab sizes weren't adjusted when changing the window
size.
When matchparen is used gui_mch_update() gets called a lot. This function
checks the run loop for new input which takes a long time. To speed things up
make sure that the run loop is only checked every 100 ms or so (controlled by
MMUpdateTimeoutInterval in gui_macvim.m).
This flag is supposed to indicate that the background should be "transparent".
However, not setting the background color leads to a rendering artifact where
the character after the cursor sometimes is not drawn. Simply ignoring the
DRAW_TRANSP flag takes care of this bug.
It seems that NSWindows get notfied of each step of the live-resize, but
NSViews get notified of the start and end events. So, we make MMTextView
forward these notifications to the window controller, and let the window
controller figure out when to change the title.
Signed-off-by: Tim Allen <screwtape@froup.com>
Mouse and keyboard input is handled immediately, all other input is put on a
queue which is processed whenever gui_mch_update() is called. This avoids DO
calls to be sent from the backend during processing of another DO call. (See
comments in MMBackend processInput:data: and processInputQueue.) One problem
this caused was that connectionDidDie notification was not received when
processInput:data: got called recursively (and thus processes could "leak").
Also did some code cleanup to MMBackend.