Add an option :opt:disable_ligatures_under_cursor to disable multi-character ligatures under the cursor to make editing easier
Fixes #461
This commit is contained in:
@@ -20,6 +20,10 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
- macOS: Allow opening new kitty tabs/top-level windows from Finder
|
||||
(:pull:`1350`)
|
||||
|
||||
- Add an option :opt:`disable_ligatures_under_cursor` to disable
|
||||
multi-character ligatures under the cursor to make editing easier
|
||||
(:iss:`461`)
|
||||
|
||||
- Allow specifying a value of ``none`` for the :opt:`selection_foreground`
|
||||
which will cause kitty to not change text color in selections (:iss:`1358`)
|
||||
|
||||
|
||||
@@ -257,8 +257,8 @@ Syntax is::
|
||||
'''))
|
||||
|
||||
o('disable_ligatures_under_cursor', False, long_text=_('''
|
||||
Render the characters of a ligature under the cursor individually
|
||||
to make editing more intuitive.
|
||||
Render the characters of a multi-character ligature under the cursor
|
||||
individually to make editing more intuitive.
|
||||
'''))
|
||||
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ typedef struct {
|
||||
|
||||
|
||||
static hb_buffer_t *harfbuzz_buffer = NULL;
|
||||
static hb_feature_t no_liga_feature;
|
||||
static hb_feature_t no_calt_feature = {0};
|
||||
static char_type shape_buffer[4096] = {0};
|
||||
static size_t max_texture_size = 1024, max_array_len = 1024;
|
||||
|
||||
@@ -743,10 +743,10 @@ shape(CPUCell *first_cpu_cell, GPUCell *first_gpu_cell, index_type num_cells, hb
|
||||
group_state.last_gpu_cell = first_gpu_cell + (num_cells ? num_cells - 1 : 0);
|
||||
load_hb_buffer(first_cpu_cell, first_gpu_cell, num_cells);
|
||||
|
||||
if (!disable_ligature) {
|
||||
hb_shape(font, harfbuzz_buffer, NULL, 0);
|
||||
if (disable_ligature) {
|
||||
hb_shape(font, harfbuzz_buffer, &no_calt_feature, 1);
|
||||
} else {
|
||||
hb_shape(font, harfbuzz_buffer, &no_liga_feature, 1);
|
||||
hb_shape(font, harfbuzz_buffer, NULL, 0);
|
||||
}
|
||||
|
||||
unsigned int info_length, positions_length;
|
||||
@@ -1023,14 +1023,13 @@ render_line(FONTS_DATA_HANDLE fg_, Line *line, index_type lnum, Cursor *cursor)
|
||||
bool center_glyph = false;
|
||||
bool disable_ligature = false;
|
||||
bool disable_ligature_in_line = false;
|
||||
index_type first_cell_in_run, i, cursor_x;
|
||||
index_type first_cell_in_run, i;
|
||||
attrs_type prev_width = 0;
|
||||
if (cursor != NULL && OPT(disable_ligatures_under_cursor)) {
|
||||
cursor_x = cursor->x;
|
||||
if (lnum == cursor->y) disable_ligature_in_line = true;
|
||||
}
|
||||
for (i=0, first_cell_in_run=0; i < line->xnum; i++) {
|
||||
disable_ligature = disable_ligature_in_line && (first_cell_in_run <= cursor_x && cursor_x <= i);
|
||||
disable_ligature = disable_ligature_in_line && (first_cell_in_run <= cursor->x && cursor->x <= i);
|
||||
if (prev_width == 2) { prev_width = 0; continue; }
|
||||
CPUCell *cpu_cell = line->cpu_cells + i;
|
||||
GPUCell *gpu_cell = line->gpu_cells + i;
|
||||
@@ -1381,8 +1380,12 @@ init_fonts(PyObject *module) {
|
||||
harfbuzz_buffer = hb_buffer_create();
|
||||
if (harfbuzz_buffer == NULL || !hb_buffer_allocation_successful(harfbuzz_buffer) || !hb_buffer_pre_allocate(harfbuzz_buffer, 2048)) { PyErr_NoMemory(); return false; }
|
||||
hb_buffer_set_cluster_level(harfbuzz_buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
|
||||
const char* feature_str = "-calt";
|
||||
if (!hb_feature_from_string(feature_str, strlen(feature_str), &no_liga_feature)) fatal("hb_feature_from_string() failed");
|
||||
#define feature_str "-calt"
|
||||
if (!hb_feature_from_string(feature_str, sizeof(feature_str) - 1, &no_calt_feature)) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Failed to create -calt harfbuzz feature");
|
||||
return false;
|
||||
}
|
||||
#undef feature_str
|
||||
if (PyModule_AddFunctions(module, module_methods) != 0) return false;
|
||||
current_send_sprite_to_gpu = send_sprite_to_gpu;
|
||||
return true;
|
||||
|
||||
@@ -1468,7 +1468,7 @@ screen_reset_dirty(Screen *self) {
|
||||
}
|
||||
|
||||
void
|
||||
screen_update_cell_data(Screen *self, void *address, FONTS_DATA_HANDLE fonts_data, bool update_cursor_pos) {
|
||||
screen_update_cell_data(Screen *self, void *address, FONTS_DATA_HANDLE fonts_data, bool cursor_has_moved) {
|
||||
unsigned int history_line_added_count = self->history_line_added_count;
|
||||
index_type lnum;
|
||||
bool was_dirty = self->is_dirty;
|
||||
@@ -1478,8 +1478,7 @@ screen_update_cell_data(Screen *self, void *address, FONTS_DATA_HANDLE fonts_dat
|
||||
for (index_type y = 0; y < MIN(self->lines, self->scrolled_by); y++) {
|
||||
lnum = self->scrolled_by - 1 - y;
|
||||
historybuf_init_line(self->historybuf, lnum, self->historybuf->line);
|
||||
if (self->historybuf->line->has_dirty_text ||
|
||||
(update_cursor_pos && (self->cursor->y == lnum || self->last_rendered_cursor_y == lnum))) {
|
||||
if (self->historybuf->line->has_dirty_text) {
|
||||
render_line(fonts_data, self->historybuf->line, lnum, self->cursor);
|
||||
historybuf_mark_line_clean(self->historybuf, lnum);
|
||||
}
|
||||
@@ -1489,7 +1488,7 @@ screen_update_cell_data(Screen *self, void *address, FONTS_DATA_HANDLE fonts_dat
|
||||
lnum = y - self->scrolled_by;
|
||||
linebuf_init_line(self->linebuf, lnum);
|
||||
if (self->linebuf->line->has_dirty_text ||
|
||||
(update_cursor_pos && (self->cursor->y == lnum || self->last_rendered_cursor_y == lnum))) {
|
||||
(cursor_has_moved && (self->cursor->y == lnum || self->last_rendered_cursor_y == lnum))) {
|
||||
render_line(fonts_data, self->linebuf->line, lnum, self->cursor);
|
||||
linebuf_mark_line_clean(self->linebuf, lnum);
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ void screen_apply_selection(Screen *self, void *address, size_t size);
|
||||
bool screen_is_selection_dirty(Screen *self);
|
||||
bool screen_has_selection(Screen*);
|
||||
bool screen_invert_colors(Screen *self);
|
||||
void screen_update_cell_data(Screen *self, void *address, FONTS_DATA_HANDLE, bool update_cursor_pos);
|
||||
void screen_update_cell_data(Screen *self, void *address, FONTS_DATA_HANDLE, bool cursor_has_moved);
|
||||
bool screen_is_cursor_visible(Screen *self);
|
||||
bool screen_selection_range_for_line(Screen *self, index_type y, index_type *start, index_type *end);
|
||||
bool screen_selection_range_for_word(Screen *self, index_type x, index_type *, index_type *, index_type *start, index_type *end);
|
||||
|
||||
Reference in New Issue
Block a user