Skip to content

Commit 347d8c7

Browse files
authored
Merge pull request #1554 from ychin/getcellpixels-support
Implement getcellpixels() for MacVim
2 parents e2f0b24 + dd1a253 commit 347d8c7

File tree

10 files changed

+89
-1
lines changed

10 files changed

+89
-1
lines changed

src/MacVim/MMBackend.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757
#endif
5858
}
5959

60+
@property (nonatomic, readonly) NSSize cellSize;
61+
6062
+ (MMBackend *)sharedInstance;
6163

6264
- (void)setBackgroundColor:(int)color;

src/MacVim/MMBackend.m

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ - (void)focusChange:(BOOL)on;
171171
- (void)handleToggleToolbar;
172172
- (void)handleScrollbarEvent:(NSData *)data;
173173
- (void)handleSetFont:(NSData *)data;
174+
- (void)handleCellSize:(NSData *)data;
174175
- (void)handleDropFiles:(NSData *)data;
175176
- (void)handleDropString:(NSData *)data;
176177
- (void)startOdbEditWithArguments:(NSDictionary *)args;
@@ -1328,6 +1329,9 @@ - (oneway void)processInput:(int)msgid data:(in bycopy NSData *)data
13281329
// modified files when we get here.
13291330
isTerminating = YES;
13301331
getout(0);
1332+
} else if (UpdateCellSizeMsgID == msgid) {
1333+
// Immediately handle simple state updates to they can be reflected in Vim.
1334+
[self handleCellSize:data];
13311335
} else {
13321336
// First remove previous instances of this message from the input
13331337
// queue, else the input queue may fill up as a result of Vim not being
@@ -2705,6 +2709,18 @@ - (void)handleSetFont:(NSData *)data
27052709
CONVERT_FROM_UTF8_FREE(s);
27062710
}
27072711

2712+
- (void)handleCellSize:(NSData *)data
2713+
{
2714+
if (!data) return;
2715+
2716+
const void *bytes = [data bytes];
2717+
2718+
// Don't use gui.char_width/height because for simplicity we set those to
2719+
// 1. We store the cell size separately (it's only used for
2720+
// getcellpixels()).
2721+
memcpy(&_cellSize, bytes, sizeof(NSSize));
2722+
}
2723+
27082724
- (void)handleDropFiles:(NSData *)data
27092725
{
27102726
// TODO: Get rid of this method; instead use Vim script directly. At the

src/MacVim/MMVimController.m

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,14 @@ - (void)handleMessage:(int)msgid data:(NSData *)data
10121012
}
10131013

10141014
[windowController setFont:font];
1015+
1016+
// Notify Vim of updated cell size for getcellpixels(). Note that
1017+
// this is asynchronous, which means getcellpixels() will not be
1018+
// immediately reflected after setting guifont.
1019+
NSSize cellsize = windowController.vimView.textView.cellSize;
1020+
[self sendMessage:UpdateCellSizeMsgID
1021+
data:[NSData dataWithBytes:&cellsize length:sizeof(cellsize)]];
1022+
10151023
[name release];
10161024
}
10171025
break;

src/MacVim/MacVim.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ extern const char * const MMVimMsgIDStrings[];
300300
MSG(ScrollbarEventMsgID) \
301301
MSG(SetFontMsgID) \
302302
MSG(SetWideFontMsgID) \
303+
MSG(UpdateCellSizeMsgID) \
303304
MSG(VimShouldCloseMsgID) \
304305
MSG(SetDefaultColorsMsgID) \
305306
MSG(SetTablineColorsMsgID) \

src/MacVim/gui_macvim.m

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,9 @@
247247
// correspondence (assuming all characters have the same dimensions).
248248
gui.scrollbar_width = gui.scrollbar_height = 0;
249249

250+
// For simplicity we just set char width/height to 1 as the GUI is
251+
// decoupled from Vim anyway so Vim doesn't need to know the accurate
252+
// pixel sizes.
250253
gui.char_height = 1;
251254
gui.char_width = 1;
252255
gui.char_ascent = 0;
@@ -1664,6 +1667,14 @@
16641667
return OK;
16651668
}
16661669

1670+
void
1671+
gui_mch_calc_cell_size(struct cellsize *cs_out)
1672+
{
1673+
NSSize cellsize = [MMBackend sharedInstance].cellSize;
1674+
cs_out->cs_xpixel = round(cellsize.width);
1675+
cs_out->cs_ypixel = round(cellsize.height);
1676+
}
1677+
16671678

16681679
void
16691680
gui_mch_beep(void)

src/evalfunc.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5425,8 +5425,15 @@ f_getcellpixels(typval_T *argvars UNUSED, typval_T *rettv)
54255425
if (gui.in_use)
54265426
{
54275427
// success pixel size and no gui.
5428+
#ifdef FEAT_GUI_MACVIM
5429+
struct cellsize cs;
5430+
gui_mch_calc_cell_size(&cs);
5431+
list_append_number(rettv->vval.v_list, (varnumber_T)cs.cs_xpixel);
5432+
list_append_number(rettv->vval.v_list, (varnumber_T)cs.cs_ypixel);
5433+
#else
54285434
list_append_number(rettv->vval.v_list, (varnumber_T)gui.char_width);
54295435
list_append_number(rettv->vval.v_list, (varnumber_T)gui.char_height);
5436+
#endif
54305437
}
54315438
else
54325439
#endif

src/os_unix.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4442,7 +4442,16 @@ mch_report_winsize(int fd, int rows, int cols)
44424442

44434443
// calcurate and set tty pixel size
44444444
struct cellsize cs;
4445-
mch_calc_cell_size(&cs);
4445+
#if defined(FEAT_GUI) && defined(FEAT_GUI_MACVIM)
4446+
if (gui.in_use)
4447+
{
4448+
gui_mch_calc_cell_size(&cs);
4449+
}
4450+
else
4451+
#endif
4452+
{
4453+
mch_calc_cell_size(&cs);
4454+
}
44464455

44474456
if (cs.cs_xpixel == -1)
44484457
{

src/proto/gui_macvim.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ void gui_mch_set_font(GuiFont font);
4343
void gui_mch_expand_font(optexpand_T *args, void *param, int (*add_match)(char_u *val));
4444
int gui_mch_adjust_charheight(void);
4545
int gui_mch_adjust_charwidth(void);
46+
void gui_mch_calc_cell_size(struct cellsize *cs_out);
4647
void gui_mch_beep(void);
4748
char_u *gui_mch_browse(int saving, char_u *title, char_u *dflt, char_u *ext, char_u *initdir, char_u *filter);
4849
char_u *gui_mch_browsedir(char_u *title, char_u *initdir);

src/terminal.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4831,8 +4831,15 @@ parse_csi(
48314831
#ifdef FEAT_GUI
48324832
if (gui.in_use)
48334833
{
4834+
#ifdef FEAT_GUI_MACVIM
4835+
struct cellsize cs;
4836+
gui_mch_calc_cell_size(&cs);
4837+
x += wp->w_wincol * cs.cs_xpixel;
4838+
y += W_WINROW(wp) * cs.cs_ypixel;
4839+
#else
48344840
x += wp->w_wincol * gui.char_width;
48354841
y += W_WINROW(wp) * gui.char_height;
4842+
#endif
48364843
}
48374844
else
48384845
#endif

src/testdir/test_functions.vim

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4338,6 +4338,32 @@ func Test_getcellpixels_gui()
43384338
endif
43394339
endfunc
43404340

4341+
" Test for getcellpixels() for MacVim
4342+
func Test_getcellpixels_macvim()
4343+
CheckGui
4344+
CheckRunVimInTerminal
4345+
if has("gui_running") && has('gui_macvim')
4346+
" MacVim works asynchronously and getcellpixels() does not immediately
4347+
" work either at launch or after guifont has been changed. It's a
4348+
" deliberate design decision. Right now the caller has to wait for MacVim
4349+
" to update the state before getcellpixels() will reflect the correct
4350+
" value, hence the need for multiple wait's here.
4351+
call WaitForAssert({-> assert_notequal(0, getcellpixels()[0], 'Uninitialized getcellpixels')})
4352+
call assert_equal([7, 13], getcellpixels()) " Default font is Menlo:h11
4353+
set guifont=Menlo:h13
4354+
call WaitForAssert({-> assert_equal([8, 15], getcellpixels())})
4355+
4356+
" Also test hosting a terminal and have that be updated
4357+
let buf = RunVimInTerminal('', #{})
4358+
call term_sendkeys(buf, ":redi @\"\<CR>")
4359+
call term_sendkeys(buf, ":echo getcellpixels()\<CR>")
4360+
call term_sendkeys(buf, ":redi END\<CR>")
4361+
call term_sendkeys(buf, "P")
4362+
call WaitForAssert({-> assert_equal(string(getcellpixels()), term_getline(buf, 3))}, 1000)
4363+
call StopVimInTerminal(buf)
4364+
endif
4365+
endfunc
4366+
43414367
func Str2Blob(s)
43424368
return list2blob(str2list(a:s))
43434369
endfunc

0 commit comments

Comments
 (0)