Skip to content

Commit bd3cbd1

Browse files
committed
monospace font for floatings windows
to avoid breaking plugins such as fzf-lua, and before having a better solution, floating windows are now rendered with monospace font. in the future, we may want to have per-grid/window/buffer option. to chose the monospace font, set this in ginit.vim: call rpcnotify(1, 'Gui', 'FontMono', 'Fira Code 16')
1 parent 19a3052 commit bd3cbd1

10 files changed

Lines changed: 154 additions & 86 deletions

File tree

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,13 @@ the project could thus have been named *gtkleguinvim*. but it's too long.
2323
![](./screenshots/completion.png)
2424

2525
![](./screenshots/fzf-and-split.png)
26+
27+
![](./screenshots/fzf-lua-monospace.png)
28+
29+
to configure __leguinvim__, you may:
30+
31+
```vim
32+
" ~/.config/nvim/ginit.vim
33+
call rpcnotify(1, 'Gui', 'Font', 'Liberation Sans 20') " main font
34+
call rpcnotify(1, 'Gui', 'FontMono', 'Fira Code 16') " monospace font (floating windows)
35+
```

screenshots/fzf-lua-monospace.png

315 KB
Loading

src/grid.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,14 @@ pub struct Grid {
122122
pub start_row: i64,
123123
pub start_col: i64,
124124

125-
// Floating windows
126-
pub is_float: bool,
125+
pub floating: bool,
127126
pub zindex: u64,
128127
pub compindex: u64,
129128
pub anchor: String,
130129
pub anchor_grid_id: u64,
131-
pub anchor_pos: (i64, i64), // for pmenu
130+
pub anchor_pos: (i64, i64),
132131
pub border_removed: bool,
132+
pub monospace: bool,
133133

134134
pub border: [bool; 4],
135135
}
@@ -142,21 +142,22 @@ impl Grid {
142142
start_row: 0, // split window
143143
start_col: 0, // split window
144144
hidden: false, // e.g. tabs
145-
is_float: false,
145+
floating: false,
146146
anchor: String::from(""),
147147
anchor_grid_id: 0,
148148
zindex: 0,
149149
compindex: 0,
150150
border_removed: false,
151151
border: [false, false, false, false], // top, right, bottom, left
152152
anchor_pos: (-1, -1),
153+
monospace: false,
153154
}
154155
}
155156

156157
pub fn new_pmenu() -> Self {
157158
Grid {
158159
hidden: true,
159-
is_float: true,
160+
floating: true,
160161
zindex: 1000,
161162
border_removed: true,
162163
border: [true, true, true, true],
@@ -177,9 +178,10 @@ impl Grid {
177178
self.start_row = row;
178179
self.start_col = col;
179180
self.zindex = zindex;
180-
self.is_float = true;
181+
self.floating = true;
181182
self.border.fill(true);
182183
self.anchor_grid_id = anchor_grid;
184+
self.monospace = true;
183185
}
184186

185187
pub fn get_cursor(&self) -> (usize, usize) {
@@ -230,19 +232,27 @@ impl Grid {
230232
}
231233

232234
pub fn start_x(&self, cell_metrics: &CellMetrics) -> f64 {
233-
self.start_col as f64 * cell_metrics.char_width / GRID_WIDTH_RATIO
235+
if self.monospace {
236+
self.start_col as f64 * cell_metrics.char_width
237+
} else {
238+
self.start_col as f64 * cell_metrics.char_width / GRID_WIDTH_RATIO
239+
}
234240
}
235241

236242
pub fn start_y(&self, cell_metrics: &CellMetrics) -> f64 {
237243
self.start_row as f64 * cell_metrics.line_height
238244
}
239245

240246
pub fn width(&self, cell_metrics: &CellMetrics) -> f64 {
241-
self.columns() as f64 * cell_metrics.char_width / GRID_WIDTH_RATIO
247+
if self.monospace {
248+
self.model.columns as f64 * cell_metrics.char_width
249+
} else {
250+
self.model.columns as f64 * cell_metrics.char_width / GRID_WIDTH_RATIO
251+
}
242252
}
243253

244254
pub fn height(&self, cell_metrics: &CellMetrics) -> f64 {
245-
self.rows() as f64 * cell_metrics.line_height
255+
self.model.rows as f64 * cell_metrics.line_height
246256
}
247257

248258
pub fn sign_column_len(&self) -> usize {

src/nvim/redraw_handler.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ pub fn call_gui_event(
226226
args: Vec<Value>,
227227
) -> result::Result<(), String> {
228228
match method {
229+
"FontMono" => call!(ui->set_font_mono(args: str)),
229230
"Font" => call!(ui->set_font(args: str)),
230231
"FontFeatures" => call!(ui->set_font_features(args: str)),
231232
"Linespace" => call!(ui->set_line_space(args: str)),

src/nvim_viewport.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,16 @@ impl WidgetImpl for NvimViewportObject {
156156
// Render scenes get pretty huge here, so we cache them as often as possible
157157
let font_ctx = &render_state.font_ctx;
158158
let cell_metrics = font_ctx.cell_metrics();
159+
let mono_ctx = &render_state.mono_ctx;
160+
let mono_metrics = mono_ctx.cell_metrics();
159161
if inner.snapshot_cache.is_none() {
160-
inner.snapshot_cache =
161-
snapshot_all_grids(cell_metrics, &state.grids, &state.pix_grids, hl);
162+
inner.snapshot_cache = snapshot_all_grids(
163+
cell_metrics,
164+
mono_metrics,
165+
&state.grids,
166+
&state.pix_grids,
167+
hl,
168+
);
162169
}
163170
if let Some(ref cached_snapshot) = inner.snapshot_cache {
164171
let push_opacity = transparency.filled_alpha < 0.99999;
@@ -175,7 +182,8 @@ impl WidgetImpl for NvimViewportObject {
175182

176183
if let Some(cursor) = state.cursor() {
177184
if let Some(grid) = state.grids.get(state.cursor_grid) {
178-
snapshot_cursor(snapshot_in, cursor, font_ctx, grid, hl, transparency);
185+
// let pix_grid = &state.pix_grids.get(&state.cursor_grid).unwrap();
186+
snapshot_cursor(snapshot_in, cursor, font_ctx, mono_ctx, grid, hl, transparency);
179187
}
180188
}
181189
} else {

src/pix_grid.rs

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,12 @@ fn new_pix_model(columns: usize, rows: usize, space_width: i32) -> PixModel {
2525
}
2626

2727
impl PixGrid {
28-
pub fn new(grid: &Grid, cell_metrics: &CellMetrics, start_x: f64) -> PixGrid {
28+
pub fn new(grid: &Grid, cell_metrics: &CellMetrics, start_x: f64, start_y: f64) -> PixGrid {
2929
let model = grid.model.model();
3030

3131
/* get infos about grid position and size */
3232
let (rows, columns) = (grid.model.rows, grid.model.columns);
3333
let space_width = cell_metrics.char_width as i32;
34-
let start_x = start_x + grid.start_x(cell_metrics);
35-
let start_y = grid.start_y(cell_metrics);
3634
let width = grid.width(cell_metrics);
3735
let height = grid.height(cell_metrics);
3836

@@ -151,36 +149,34 @@ impl PixGridMap {
151149
pub fn get_mut(&mut self, id: &u64) -> Option<&mut PixGrid> {
152150
self.grids.get_mut(id)
153151
}
154-
pub fn get_or_create(
155-
&mut self,
156-
id: &u64,
157-
grid: &Grid,
158-
cell_metrics: &CellMetrics,
159-
) -> &mut PixGrid {
160-
if self.grids.contains_key(&id) {
161-
return self.grids.get_mut(&id).unwrap();
162-
}
163-
self.insert(grid, cell_metrics);
164-
self.get_mut(id).unwrap()
165-
}
166152
pub fn new() -> Self {
167153
PixGridMap {
168154
grids: FnvHashMap::default(),
169155
pmenu: PixGrid::empty(),
170156
}
171157
}
172-
pub fn insert(&mut self, grid: &Grid, cell_metrics: &CellMetrics) {
158+
pub fn insert(&mut self, grid: &Grid, cell_metrics: &CellMetrics, start_x: f64, start_y: f64) {
173159
self.grids
174-
.insert(grid.id, PixGrid::new(grid, cell_metrics, 0.0));
160+
.insert(grid.id, PixGrid::new(grid, cell_metrics, start_x, start_y));
175161
}
176-
pub fn fit_gridmap(&mut self, gridmap: &GridMap, cell_metrics: &CellMetrics) {
162+
pub fn fit_gridmap(
163+
&mut self,
164+
gridmap: &GridMap,
165+
cell_metrics: &CellMetrics,
166+
mono_metrics: &CellMetrics,
167+
) {
177168
for (id, grid) in gridmap.grids.iter() {
178169
if let Some(pg) = self.get_mut(id) {
179170
if pg.fit(grid) {
180171
continue;
181172
}
182173
}
183-
self.insert(grid, cell_metrics);
174+
let cm = if grid.monospace {
175+
mono_metrics
176+
} else {
177+
cell_metrics
178+
};
179+
self.insert(grid, cm, grid.start_x(cm), grid.start_y(cm));
184180
}
185181
}
186182
}

src/render/context.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ pub struct CellMetrics {
167167
pub strikethrough_thickness: f64,
168168
pub pango_ascent: i32,
169169
pub pango_descent: i32,
170-
pub pango_char_width: i32,
171170
}
172171

173172
impl CellMetrics {
@@ -195,7 +194,6 @@ impl CellMetrics {
195194
CellMetrics {
196195
pango_ascent: font_metrics.ascent(),
197196
pango_descent: font_metrics.descent(),
198-
pango_char_width: font_metrics.approximate_char_width(),
199197
ascent,
200198
descent,
201199
line_height: ascent + descent + f64::from(line_space),
@@ -212,7 +210,6 @@ impl CellMetrics {
212210
CellMetrics {
213211
pango_ascent: 0,
214212
pango_descent: 0,
215-
pango_char_width: 0,
216213
ascent: 0.0,
217214
descent: 0.0,
218215
line_height,

src/render/mod.rs

Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -87,33 +87,23 @@ enum RenderStepKind {
8787

8888
pub fn snapshot_all_grids(
8989
cell_metrics: &CellMetrics,
90+
mono_metrics: &CellMetrics,
9091
gridmap: &GridMap,
9192
pix_gridmap: &PixGridMap,
9293
hl: &HighlightMap,
9394
) -> Option<gsk::RenderNode> {
9495
let mut snapshot = gtk::Snapshot::new();
9596
let grids = gridmap.sorted_visible();
96-
9797
for (id, grid) in grids.iter() {
98-
if let Some(pix_grid) = pix_gridmap.get(*id) {
99-
if pix_grid.columns != grid.model.columns {
100-
snapshot_grid(
101-
&mut snapshot,
102-
cell_metrics,
103-
&grid,
104-
&PixGrid::new(grid, cell_metrics, 0.0),
105-
hl,
106-
);
107-
} else {
108-
snapshot_grid(&mut snapshot, cell_metrics, &grid, pix_grid, hl);
109-
}
98+
let pix_grid = pix_gridmap.get(*id).unwrap();
99+
let cm = if grid.monospace {
100+
mono_metrics
110101
} else {
111-
eprintln!("missing PixGrid {id}");
112-
}
102+
cell_metrics
103+
};
104+
snapshot_grid(&mut snapshot, cm, &grid, pix_grid, hl);
113105
}
114-
115106
snapshot_pmenu(&mut snapshot, gridmap, pix_gridmap, cell_metrics, hl);
116-
117107
snapshot.to_node()
118108
}
119109

@@ -252,20 +242,38 @@ fn snapshot_text(
252242
hl: &HighlightMap,
253243
) {
254244
let line_height = cell_metrics.line_height as f32;
255-
let mut y = (line_height * grid.start_row as f32) + cell_metrics.ascent as f32;
256-
for (row, line) in model.iter().enumerate() {
257-
let pix_row = &pix_grid.matrix[row];
258-
for (col, cell) in line.line.iter().enumerate() {
259-
snapshot_cell(
260-
&snapshot,
261-
&line.item_line[col],
262-
hl,
263-
cell,
264-
pix_row[col] as f32,
265-
y,
266-
);
245+
let mut y = (pix_grid.start_y + cell_metrics.ascent) as f32;
246+
if !grid.monospace {
247+
for (row, line) in model.iter().enumerate() {
248+
let pix_row = &pix_grid.matrix[row];
249+
for (col, cell) in line.line.iter().enumerate() {
250+
snapshot_cell(
251+
&snapshot,
252+
&line.item_line[col],
253+
hl,
254+
cell,
255+
pix_row[col] as f32,
256+
y,
257+
);
258+
}
259+
y += line_height;
260+
}
261+
} else {
262+
let char_width = cell_metrics.char_width as f32;
263+
let mut y = (pix_grid.start_y + cell_metrics.ascent) as f32;
264+
for line in model {
265+
for (col, cell) in line.line.iter().enumerate() {
266+
snapshot_cell(
267+
&snapshot,
268+
&line.item_line[col],
269+
hl,
270+
cell,
271+
pix_grid.start_x as f32 + (col as f32 * char_width),
272+
y,
273+
);
274+
}
275+
y += line_height;
267276
}
268-
y += line_height;
269277
}
270278
}
271279

@@ -293,7 +301,8 @@ fn snapshot_pmenu(
293301
}
294302
let model = pmenu.model.model();
295303
let start_x = anchor_pix.matrix[row as usize][col as usize] as f64;
296-
let pmenu_pix_grid = PixGrid::new(pmenu, cell_metrics, start_x);
304+
let start_y = pmenu.start_y(cell_metrics);
305+
let pmenu_pix_grid = PixGrid::new(pmenu, cell_metrics, start_x, start_y);
297306
grid_bg(snapshot, &pmenu_pix_grid, hl.bg());
298307
snapshot_text(snapshot, cell_metrics, model, pmenu, &pmenu_pix_grid, hl);
299308
grid_border(snapshot, pmenu, &pmenu_pix_grid, hl);
@@ -303,6 +312,7 @@ pub fn snapshot_cursor<T: CursorRedrawCb + 'static>(
303312
snapshot: &gtk::Snapshot,
304313
cursor: &Cursor<T>,
305314
font_ctx: &Context,
315+
mono_ctx: &Context,
306316
grid: &Grid,
307317
hl: &HighlightMap,
308318
transparency: TransparencySettings,
@@ -313,7 +323,15 @@ pub fn snapshot_cursor<T: CursorRedrawCb + 'static>(
313323

314324
let ui_model = &grid.model;
315325

316-
let cell_metrics = font_ctx.cell_metrics();
326+
// TODO monospace: i use this A LOT. it may be a macro?
327+
let ctx = if grid.monospace {
328+
mono_ctx
329+
} else {
330+
font_ctx
331+
};
332+
333+
let cell_metrics = ctx.cell_metrics();
334+
317335
let CellMetrics { ascent, .. } = *cell_metrics;
318336
let (cursor_row, cursor_col) = ui_model.get_flushed_cursor();
319337

@@ -325,6 +343,7 @@ pub fn snapshot_cursor<T: CursorRedrawCb + 'static>(
325343
};
326344

327345
let space_size: i32 = cell_metrics.char_width as i32;
346+
328347
let (pixel_width, x, until_x) =
329348
cursor_x(cursor_line, cursor_col, space_size, grid.sign_column_len());
330349
let x = (x as f64 + grid.start_x(cell_metrics)) as i32;
@@ -352,7 +371,7 @@ pub fn snapshot_cursor<T: CursorRedrawCb + 'static>(
352371

353372
cursor.snapshot(
354373
snapshot,
355-
font_ctx,
374+
ctx,
356375
(x, y),
357376
cell,
358377
hl,

src/settings.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl State {
4545
return;
4646
}
4747

48-
shell.set_font_desc(&self.gnome_interface_settings.string("monospace-font-name"));
48+
shell.set_font_desc(&self.gnome_interface_settings.string("monospace-font-name"), false); // TODO monospace?
4949
self.font_source = FontSource::Gnome;
5050
}
5151
}

0 commit comments

Comments
 (0)