Skip to content

Commit

Permalink
Allow pinning the cmdline to be aligned to the bottom of window
Browse files Browse the repository at this point in the history
Add a setting that could pin the command-line portion of Vim to the
bottom of the MacVim window. This is useful when smooth resizing is set,
guioption+=k, or in full screen. In those situations, the MacVim window
size is usually not direct multiples of the Vim text sizes. Previously
the command-line would be drawn like other texts, and hence not aligned
to the bottom and hence looking aesthetically a little off.

When this setting is set, the command-line portion would be aligned to
the bottom of the window. This essentially moves the gap (due to the
extra height of the window) from the bottom to be between cmdline and
the rest of Vim. When cmdheight is changed, or other situations (e.g.
typing too much cmdline height to be increased), the gap will be
adjusted as well.

Implementation-wise, this was done by passing the `commandline_row` var
from Vim to MacVim, which serves as a good estimate of where the
command-line is. This works better than just using the `cmdheight`
option as it is closer to the current state of the cmdline. One issue is
that in hit-enter prompts, the row is set to the 2nd to last row to
anticipate more messages, and we just add a big hack by incrementing the
row by 1 in hit-enter state so only the "Press Enter..." part is aligned
to bottom. We also have to do something similar to when it's showing
"--more--" for similar reasons.

- An alternative would have been to modify Vim to provide us the
  information we want (the number of rows below the status line) but
  it's pretty tricky to do as cmdline_row is used in lots of places.
  It's easier / simpler to do a simple hack like this to localize the
  damage.

Close #833
  • Loading branch information
ychin committed Sep 11, 2022
1 parent 6b26957 commit a7279d8
Show file tree
Hide file tree
Showing 13 changed files with 193 additions and 26 deletions.
5 changes: 3 additions & 2 deletions runtime/doc/gui_mac.txt
Original file line number Diff line number Diff line change
Expand Up @@ -256,20 +256,21 @@ Here is a list of relevant dictionary entries:

KEY VALUE ~
*MMCellWidthMultiplier* width of a normal glyph in em units [float]
*MMCmdLineAlignBottom* Pin command-line to bottom of MacVim [bool]
*MMDialogsTrackPwd* open/save dialogs track the Vim pwd [bool]
*MMDisableLaunchAnimation* disable launch animation when opening a new
MacVim window [bool]
*MMFullScreenFadeTime* fade delay for non-native fullscreen [float]
*MMFontPreserveLineSpacing* use the line-spacing as specified by font [bool]
*MMLoginShellArgument* login shell parameter [string]
*MMLoginShellCommand* which shell to use to launch Vim [string]
*MMFullScreenFadeTime* fade delay for non-native fullscreen [float]
*MMNativeFullScreen* use native full screen mode [bool]
*MMNonNativeFullScreenShowMenu* show menus when in non-native full screen [bool]
*MMNonNativeFullScreenSafeAreaBehavior*
behavior for non-native full sreen regarding
the safe area (aka the "notch") [int]
*MMNoFontSubstitution* disable automatic font substitution [bool]
(Deprecated: Non-CoreText renderer only)
*MMFontPreserveLineSpacing* use the line-spacing as specified by font [bool]
*MMNoTitleBarWindow* hide title bar [bool]
*MMTitlebarAppearsTransparent* enable a transparent titlebar [bool]
*MMAppearanceModeSelection* dark mode selection (|macvim-dark-mode|)[bool]
Expand Down
1 change: 1 addition & 0 deletions runtime/doc/tags
Original file line number Diff line number Diff line change
Expand Up @@ -5405,6 +5405,7 @@ M motion.txt /*M*
MDI starting.txt /*MDI*
MMAppearanceModeSelection gui_mac.txt /*MMAppearanceModeSelection*
MMCellWidthMultiplier gui_mac.txt /*MMCellWidthMultiplier*
MMCmdLineAlignBottom gui_mac.txt /*MMCmdLineAlignBottom*
MMDialogsTrackPwd gui_mac.txt /*MMDialogsTrackPwd*
MMDisableLaunchAnimation gui_mac.txt /*MMDisableLaunchAnimation*
MMFontPreserveLineSpacing gui_mac.txt /*MMFontPreserveLineSpacing*
Expand Down
42 changes: 35 additions & 7 deletions src/MacVim/Base.lproj/Preferences.xib
Original file line number Diff line number Diff line change
Expand Up @@ -257,11 +257,11 @@
<point key="canvasLocation" x="137.5" y="21.5"/>
</customView>
<customView id="hr4-G4-3ZG" userLabel="Appearance">
<rect key="frame" x="0.0" y="0.0" width="483" height="315"/>
<rect key="frame" x="0.0" y="0.0" width="483" height="341"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<customView id="fw0-VK-Nbz" userLabel="Dark mode selection">
<rect key="frame" x="19" y="137" width="433" height="156"/>
<rect key="frame" x="19" y="163" width="433" height="156"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" id="T40-Os-PUf" userLabel="Dark mode selection">
Expand Down Expand Up @@ -322,7 +322,7 @@
</subviews>
</customView>
<customView id="7af-iK-4r7" userLabel="Titlebar appearance">
<rect key="frame" x="19" y="91" width="433" height="38"/>
<rect key="frame" x="19" y="117" width="433" height="38"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button id="7ie-0J-0Zr">
Expand Down Expand Up @@ -361,7 +361,7 @@
</subviews>
</customView>
<customView id="BpJ-rH-ona" userLabel="Full Screen">
<rect key="frame" x="19" y="45" width="433" height="38"/>
<rect key="frame" x="19" y="71" width="433" height="38"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button toolTip="Use macOS's native full screen mode, which integrates with Mission Control and creates a new Space for the window." id="YKV-u2-Egc" userLabel="Use native full screen">
Expand Down Expand Up @@ -405,7 +405,7 @@
</subviews>
</customView>
<customView id="a3v-cB-TFa" userLabel="Font">
<rect key="frame" x="19" y="20" width="433" height="18"/>
<rect key="frame" x="19" y="46" width="433" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button id="A48-s0-kdR" userLabel="Preserve Line Spacing">
Expand All @@ -432,8 +432,36 @@
</textField>
</subviews>
</customView>
<customView id="Dey-Wx-2gx" userLabel="Cmdline">
<rect key="frame" x="20" y="20" width="433" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button id="qMh-iV-0iD">
<rect key="frame" x="189" y="-1" width="244" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
<string key="toolTip">When using smooth resizing, guioption+=k, or full screen; MacVim's window size can sometimes be slightly larger than Vim's content size, causing the command-line to not be aligned to the bottom. This option will make sure the command-line is always pinned to the bottom.</string>
<buttonCell key="cell" type="check" title="Pin to the bottom of the window" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="uZL-IX-Dv8">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="cmdlineAlignBottomChanged:" target="-2" id="LgN-MI-0Nt"/>
<binding destination="58" name="value" keyPath="values.MMCmdLineAlignBottom" id="pIr-52-5vV"/>
</connections>
</button>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" id="Lzq-i0-zWi" userLabel="Cmdline">
<rect key="frame" x="-2" y="0.0" width="187" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="right" title="Command-line:" id="2Lp-vX-AcA">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</customView>
</subviews>
<point key="canvasLocation" x="137.5" y="412.5"/>
<point key="canvasLocation" x="137.5" y="425.5"/>
</customView>
<customView id="620" userLabel="Advanced">
<rect key="frame" x="0.0" y="0.0" width="483" height="264"/>
Expand Down Expand Up @@ -504,7 +532,7 @@
</connections>
</button>
</subviews>
<point key="canvasLocation" x="137.5" y="743"/>
<point key="canvasLocation" x="144" y="911"/>
</customView>
</objects>
</document>
1 change: 1 addition & 0 deletions src/MacVim/MMAppController.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
- (void)refreshAllAppearances;
- (void)refreshAllFonts;
- (void)refreshAllResizeConstraints;
- (void)refreshAllTextViews;

- (IBAction)newWindow:(id)sender;
- (IBAction)newWindowAndActivate:(id)sender;
Expand Down
12 changes: 12 additions & 0 deletions src/MacVim/MMAppController.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#import "MMAppController.h"
#import "MMPreferenceController.h"
#import "MMVimController.h"
#import "MMVimView.h"
#import "MMWindowController.h"
#import "MMTextView.h"
#import "Miscellaneous.h"
Expand Down Expand Up @@ -253,6 +254,7 @@ + (void)initialize
[NSNumber numberWithInt:0], MMNonNativeFullScreenSafeAreaBehaviorKey,
[NSNumber numberWithBool:YES], MMShareFindPboardKey,
[NSNumber numberWithBool:NO], MMSmoothResizeKey,
[NSNumber numberWithBool:NO], MMCmdLineAlignBottomKey,
nil];

[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
Expand Down Expand Up @@ -1142,6 +1144,16 @@ - (void)refreshAllResizeConstraints
}
}

- (void)refreshAllTextViews
{
unsigned count = [vimControllers count];
for (unsigned i = 0; i < count; ++i) {
MMVimController *vc = [vimControllers objectAtIndex:i];
[vc.windowController.vimView.textView updateCmdlineRow];
vc.windowController.vimView.textView.needsDisplay = YES;
}
}

- (IBAction)newWindow:(id)sender
{
ASLogDebug(@"Open new window");
Expand Down
20 changes: 20 additions & 0 deletions src/MacVim/MMBackend.m
Original file line number Diff line number Diff line change
Expand Up @@ -1816,13 +1816,33 @@ - (void)insertVimStateMessage
if (numTabs < 0)
numTabs = 0;

// Custom hacks to deal with cmdline_row not being perfect for our use cases.
int cmdline_row_adjusted = cmdline_row;
if (State == MODE_HITRETURN) {
// When we are in hit-return mode, Vim does a weird thing and sets
// cmdline_row to be the 2nd-to-last row, which would make pinning
// cmdline to bottom look weird. This is done in msg_start() and
// wait_return().
// Instead of modifying Vim, we just hack around this by manually
// increasing the row by one. This would make the pin happen right at
// the "Hit Enter..." prompt.
cmdline_row_adjusted++;
} else if (State == MODE_ASKMORE) {
// In "more" mode, Vim sometimes set cmdline_row, sometimes it doesn't.
// Silver lining is that it always only takes one row and doesn't wrap
// like hit-enter, so we know we can always just pin it to the last row
// and be done with the hack.
cmdline_row_adjusted = Rows - 1;
}

NSDictionary *vimState = [NSDictionary dictionaryWithObjectsAndKeys:
[[NSFileManager defaultManager] currentDirectoryPath], @"pwd",
[NSNumber numberWithInt:p_mh], @"p_mh",
[NSNumber numberWithBool:mmta], @"p_mmta",
[NSNumber numberWithInt:numTabs], @"numTabs",
[NSNumber numberWithInt:fuoptions_flags], @"fullScreenOptions",
[NSNumber numberWithLong:p_mouset], @"p_mouset",
[NSNumber numberWithInt:cmdline_row_adjusted], @"cmdline_row", // Used for pinning cmdline to bottom of window
nil];

// Put the state before all other messages.
Expand Down
1 change: 1 addition & 0 deletions src/MacVim/MMCoreTextView.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
- (BOOL)convertPoint:(NSPoint)point toRow:(int *)row column:(int *)column;
- (NSRect)rectForRow:(int)row column:(int)column numRows:(int)nr
numColumns:(int)nc;
- (void)updateCmdlineRow;

//
// NSTextView methods
Expand Down
Loading

0 comments on commit a7279d8

Please sign in to comment.