mirror of
https://github.com/neovim/neovim.git
synced 2025-09-07 11:58:17 +00:00

committed by
Justin M. Keyes

parent
16babc6687
commit
dd4a5fcbb6
@@ -12,6 +12,7 @@
|
|||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/api/private/defs.h"
|
||||||
#include "nvim/api/private/helpers.h"
|
#include "nvim/api/private/helpers.h"
|
||||||
#include "nvim/popupmnu.h"
|
#include "nvim/popupmnu.h"
|
||||||
|
#include "nvim/cursor_shape.h"
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "api/ui.c.generated.h"
|
# include "api/ui.c.generated.h"
|
||||||
@@ -69,6 +70,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
|
|||||||
ui->clear = remote_ui_clear;
|
ui->clear = remote_ui_clear;
|
||||||
ui->eol_clear = remote_ui_eol_clear;
|
ui->eol_clear = remote_ui_eol_clear;
|
||||||
ui->cursor_goto = remote_ui_cursor_goto;
|
ui->cursor_goto = remote_ui_cursor_goto;
|
||||||
|
ui->cursor_style_set = remote_ui_cursor_style_set;
|
||||||
ui->update_menu = remote_ui_update_menu;
|
ui->update_menu = remote_ui_update_menu;
|
||||||
ui->busy_start = remote_ui_busy_start;
|
ui->busy_start = remote_ui_busy_start;
|
||||||
ui->busy_stop = remote_ui_busy_stop;
|
ui->busy_stop = remote_ui_busy_stop;
|
||||||
@@ -298,6 +300,14 @@ static void remote_ui_scroll(UI *ui, int count)
|
|||||||
push_call(ui, "scroll", args);
|
push_call(ui, "scroll", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void remote_ui_cursor_style_set(UI *ui, Dictionary styles)
|
||||||
|
{
|
||||||
|
Array args = ARRAY_DICT_INIT;
|
||||||
|
Object copy = copy_object(DICTIONARY_OBJ(styles));
|
||||||
|
ADD(args, copy);
|
||||||
|
push_call(ui, "cursor_style_set", args);
|
||||||
|
}
|
||||||
|
|
||||||
static void remote_ui_highlight_set(UI *ui, HlAttrs attrs)
|
static void remote_ui_highlight_set(UI *ui, HlAttrs attrs)
|
||||||
{
|
{
|
||||||
Array args = ARRAY_DICT_INIT;
|
Array args = ARRAY_DICT_INIT;
|
||||||
|
@@ -7,40 +7,84 @@
|
|||||||
#include "nvim/charset.h"
|
#include "nvim/charset.h"
|
||||||
#include "nvim/strings.h"
|
#include "nvim/strings.h"
|
||||||
#include "nvim/syntax.h"
|
#include "nvim/syntax.h"
|
||||||
|
#include "nvim/api/private/helpers.h"
|
||||||
|
#include "nvim/ui.h"
|
||||||
|
|
||||||
/*
|
/// Handling of cursor and mouse pointer shapes in various modes.
|
||||||
* Handling of cursor and mouse pointer shapes in various modes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static cursorentry_T shape_table[SHAPE_IDX_COUNT] =
|
static cursorentry_T shape_table[SHAPE_IDX_COUNT] =
|
||||||
{
|
{
|
||||||
/* The values will be filled in from the 'guicursor' and 'mouseshape'
|
// The values will be filled in from the 'guicursor' and 'mouseshape'
|
||||||
* defaults when Vim starts.
|
// defaults when Vim starts.
|
||||||
* Adjust the SHAPE_IDX_ defines when making changes! */
|
// Adjust the SHAPE_IDX_ defines when making changes!
|
||||||
{0, 0, 0, 700L, 400L, 250L, 0, 0, "n", SHAPE_CURSOR+SHAPE_MOUSE},
|
{ "normal",
|
||||||
{0, 0, 0, 700L, 400L, 250L, 0, 0, "v", SHAPE_CURSOR+SHAPE_MOUSE},
|
0, 0, 0, 700L, 400L, 250L, 0, 0, "n", SHAPE_CURSOR+SHAPE_MOUSE },
|
||||||
{0, 0, 0, 700L, 400L, 250L, 0, 0, "i", SHAPE_CURSOR+SHAPE_MOUSE},
|
{ "visual",
|
||||||
{0, 0, 0, 700L, 400L, 250L, 0, 0, "r", SHAPE_CURSOR+SHAPE_MOUSE},
|
0, 0, 0, 700L, 400L, 250L, 0, 0, "v", SHAPE_CURSOR+SHAPE_MOUSE },
|
||||||
{0, 0, 0, 700L, 400L, 250L, 0, 0, "c", SHAPE_CURSOR+SHAPE_MOUSE},
|
{ "insert",
|
||||||
{0, 0, 0, 700L, 400L, 250L, 0, 0, "ci", SHAPE_CURSOR+SHAPE_MOUSE},
|
0, 0, 0, 700L, 400L, 250L, 0, 0, "i", SHAPE_CURSOR+SHAPE_MOUSE },
|
||||||
{0, 0, 0, 700L, 400L, 250L, 0, 0, "cr", SHAPE_CURSOR+SHAPE_MOUSE},
|
{ "replace",
|
||||||
{0, 0, 0, 700L, 400L, 250L, 0, 0, "o", SHAPE_CURSOR+SHAPE_MOUSE},
|
0, 0, 0, 700L, 400L, 250L, 0, 0, "r", SHAPE_CURSOR+SHAPE_MOUSE },
|
||||||
{0, 0, 0, 700L, 400L, 250L, 0, 0, "ve", SHAPE_CURSOR+SHAPE_MOUSE},
|
{ "cmd_normal",
|
||||||
{0, 0, 0, 0L, 0L, 0L, 0, 0, "e", SHAPE_MOUSE},
|
0, 0, 0, 700L, 400L, 250L, 0, 0, "c", SHAPE_CURSOR+SHAPE_MOUSE },
|
||||||
{0, 0, 0, 0L, 0L, 0L, 0, 0, "s", SHAPE_MOUSE},
|
{ "cmd_insert", 0,
|
||||||
{0, 0, 0, 0L, 0L, 0L, 0, 0, "sd", SHAPE_MOUSE},
|
0, 0, 700L, 400L, 250L, 0, 0, "ci", SHAPE_CURSOR+SHAPE_MOUSE },
|
||||||
{0, 0, 0, 0L, 0L, 0L, 0, 0, "vs", SHAPE_MOUSE},
|
{ "cmd_replace",
|
||||||
{0, 0, 0, 0L, 0L, 0L, 0, 0, "vd", SHAPE_MOUSE},
|
0, 0, 0, 700L, 400L, 250L, 0, 0, "cr", SHAPE_CURSOR+SHAPE_MOUSE },
|
||||||
{0, 0, 0, 0L, 0L, 0L, 0, 0, "m", SHAPE_MOUSE},
|
{ "pending",
|
||||||
{0, 0, 0, 0L, 0L, 0L, 0, 0, "ml", SHAPE_MOUSE},
|
0, 0, 0, 700L, 400L, 250L, 0, 0, "o", SHAPE_CURSOR+SHAPE_MOUSE },
|
||||||
{0, 0, 0, 100L, 100L, 100L, 0, 0, "sm", SHAPE_CURSOR},
|
{ "visual_select",
|
||||||
|
0, 0, 0, 700L, 400L, 250L, 0, 0, "ve", SHAPE_CURSOR+SHAPE_MOUSE },
|
||||||
|
{ "cmd_line", 0, 0, 0, 0L, 0L, 0L, 0, 0, "e", SHAPE_MOUSE },
|
||||||
|
{ "statusline", 0, 0, 0, 0L, 0L, 0L, 0, 0, "s", SHAPE_MOUSE },
|
||||||
|
{ "drag_statusline", 0, 0, 0, 0L, 0L, 0L, 0, 0, "sd", SHAPE_MOUSE },
|
||||||
|
{ "vsep", 0, 0, 0, 0L, 0L, 0L, 0, 0, "vs", SHAPE_MOUSE },
|
||||||
|
{ "vdrag", 0, 0, 0, 0L, 0L, 0L, 0, 0, "vd", SHAPE_MOUSE },
|
||||||
|
{ "more", 0, 0, 0, 0L, 0L, 0L, 0, 0, "m", SHAPE_MOUSE },
|
||||||
|
{ "more_lastline", 0, 0, 0, 0L, 0L, 0L, 0, 0, "ml", SHAPE_MOUSE },
|
||||||
|
{ "match_paren", 0, 0, 0, 100L, 100L, 100L, 0, 0, "sm", SHAPE_CURSOR },
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/// Converts cursor_shapes into a Dictionary of dictionaries
|
||||||
* Parse the 'guicursor' option ("what" is SHAPE_CURSOR) or 'mouseshape'
|
/// @return a dictionary of the form {"normal" : { "cursor_shape": ... }, ...}
|
||||||
* ("what" is SHAPE_MOUSE).
|
Dictionary cursor_shape_dict(void)
|
||||||
* Returns error message for an illegal option, NULL otherwise.
|
{
|
||||||
*/
|
Dictionary all = ARRAY_DICT_INIT;
|
||||||
|
|
||||||
|
for (int i = 0; i < SHAPE_IDX_COUNT; i++) {
|
||||||
|
Dictionary dic = ARRAY_DICT_INIT;
|
||||||
|
cursorentry_T *cur = &shape_table[i];
|
||||||
|
if (cur->used_for & SHAPE_MOUSE) {
|
||||||
|
PUT(dic, "mouse_shape", INTEGER_OBJ(cur->mshape));
|
||||||
|
}
|
||||||
|
if (cur->used_for & SHAPE_CURSOR) {
|
||||||
|
String shape_str;
|
||||||
|
switch (cur->shape) {
|
||||||
|
case SHAPE_BLOCK: shape_str = cstr_to_string("block"); break;
|
||||||
|
case SHAPE_VER: shape_str = cstr_to_string("vertical"); break;
|
||||||
|
case SHAPE_HOR: shape_str = cstr_to_string("horizontal"); break;
|
||||||
|
default: shape_str = cstr_to_string("unknown");
|
||||||
|
}
|
||||||
|
PUT(dic, "cursor_shape", STRING_OBJ(shape_str));
|
||||||
|
PUT(dic, "cell_percentage", INTEGER_OBJ(cur->percentage));
|
||||||
|
PUT(dic, "blinkwait", INTEGER_OBJ(cur->blinkwait));
|
||||||
|
PUT(dic, "blinkon", INTEGER_OBJ(cur->blinkon));
|
||||||
|
PUT(dic, "blinkoff", INTEGER_OBJ(cur->blinkoff));
|
||||||
|
PUT(dic, "hl_id", INTEGER_OBJ(cur->id));
|
||||||
|
PUT(dic, "id_lm", INTEGER_OBJ(cur->id_lm));
|
||||||
|
}
|
||||||
|
PUT(dic, "short_name", STRING_OBJ(cstr_to_string(cur->name)));
|
||||||
|
|
||||||
|
PUT(all, cur->full_name, DICTIONARY_OBJ(dic));
|
||||||
|
}
|
||||||
|
|
||||||
|
return all;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse the 'guicursor' option
|
||||||
|
///
|
||||||
|
/// @param what either SHAPE_CURSOR or SHAPE_MOUSE ('mouseshape')
|
||||||
|
///
|
||||||
|
/// @returns error message for an illegal option, NULL otherwise.
|
||||||
char_u *parse_shape_opt(int what)
|
char_u *parse_shape_opt(int what)
|
||||||
{
|
{
|
||||||
char_u *modep;
|
char_u *modep;
|
||||||
@@ -71,19 +115,18 @@ char_u *parse_shape_opt(int what)
|
|||||||
return (char_u *)N_("E546: Illegal mode");
|
return (char_u *)N_("E546: Illegal mode");
|
||||||
commap = vim_strchr(modep, ',');
|
commap = vim_strchr(modep, ',');
|
||||||
|
|
||||||
/*
|
// Repeat for all mode's before the colon.
|
||||||
* Repeat for all mode's before the colon.
|
// For the 'a' mode, we loop to handle all the modes.
|
||||||
* For the 'a' mode, we loop to handle all the modes.
|
|
||||||
*/
|
|
||||||
all_idx = -1;
|
all_idx = -1;
|
||||||
assert(modep < colonp);
|
assert(modep < colonp);
|
||||||
while (modep < colonp || all_idx >= 0) {
|
while (modep < colonp || all_idx >= 0) {
|
||||||
if (all_idx < 0) {
|
if (all_idx < 0) {
|
||||||
/* Find the mode. */
|
// Find the mode
|
||||||
if (modep[1] == '-' || modep[1] == ':')
|
if (modep[1] == '-' || modep[1] == ':') {
|
||||||
len = 1;
|
len = 1;
|
||||||
else
|
} else {
|
||||||
len = 2;
|
len = 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (len == 1 && TOLOWER_ASC(modep[0]) == 'a') {
|
if (len == 1 && TOLOWER_ASC(modep[0]) == 'a') {
|
||||||
all_idx = SHAPE_IDX_COUNT - 1;
|
all_idx = SHAPE_IDX_COUNT - 1;
|
||||||
@@ -100,11 +143,11 @@ char_u *parse_shape_opt(int what)
|
|||||||
modep += len + 1;
|
modep += len + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (all_idx >= 0)
|
if (all_idx >= 0) {
|
||||||
idx = all_idx--;
|
idx = all_idx--;
|
||||||
else if (round == 2) {
|
} else if (round == 2) {
|
||||||
{
|
{
|
||||||
/* Set the defaults, for the missing parts */
|
// Set the defaults, for the missing parts
|
||||||
shape_table[idx].shape = SHAPE_BLOCK;
|
shape_table[idx].shape = SHAPE_BLOCK;
|
||||||
shape_table[idx].blinkwait = 700L;
|
shape_table[idx].blinkwait = 700L;
|
||||||
shape_table[idx].blinkon = 400L;
|
shape_table[idx].blinkon = 400L;
|
||||||
@@ -208,6 +251,23 @@ char_u *parse_shape_opt(int what)
|
|||||||
shape_table[SHAPE_IDX_VE].id_lm = shape_table[SHAPE_IDX_V].id_lm;
|
shape_table[SHAPE_IDX_VE].id_lm = shape_table[SHAPE_IDX_V].id_lm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ui_cursor_style_set();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Map cursor mode from string to integer
|
||||||
|
///
|
||||||
|
/// @param mode Fullname of the mode whose id we are looking for
|
||||||
|
/// @return -1 in case of failure, else the matching SHAPE_ID* integer
|
||||||
|
int cursor_mode_str2int(const char *mode)
|
||||||
|
{
|
||||||
|
for (int current_mode = 0; current_mode < SHAPE_IDX_COUNT; current_mode++) {
|
||||||
|
if (strcmp(shape_table[current_mode].full_name, mode) == 0) {
|
||||||
|
return current_mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ELOG("Unknown mode %s", mode);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1,32 +1,34 @@
|
|||||||
#ifndef NVIM_CURSOR_SHAPE_H
|
#ifndef NVIM_CURSOR_SHAPE_H
|
||||||
#define NVIM_CURSOR_SHAPE_H
|
#define NVIM_CURSOR_SHAPE_H
|
||||||
|
|
||||||
/*
|
/// struct to store values from 'guicursor' and 'mouseshape'
|
||||||
* struct to store values from 'guicursor' and 'mouseshape'
|
/// Indexes in shape_table[]
|
||||||
*/
|
typedef enum {
|
||||||
/* Indexes in shape_table[] */
|
SHAPE_IDX_N = 0, ///< Normal mode
|
||||||
#define SHAPE_IDX_N 0 /* Normal mode */
|
SHAPE_IDX_V = 1, ///< Visual mode
|
||||||
#define SHAPE_IDX_V 1 /* Visual mode */
|
SHAPE_IDX_I = 2, ///< Insert mode
|
||||||
#define SHAPE_IDX_I 2 /* Insert mode */
|
SHAPE_IDX_R = 3, ///< Replace mode
|
||||||
#define SHAPE_IDX_R 3 /* Replace mode */
|
SHAPE_IDX_C = 4, ///< Command line Normal mode
|
||||||
#define SHAPE_IDX_C 4 /* Command line Normal mode */
|
SHAPE_IDX_CI = 5, ///< Command line Insert mode
|
||||||
#define SHAPE_IDX_CI 5 /* Command line Insert mode */
|
SHAPE_IDX_CR = 6, ///< Command line Replace mode
|
||||||
#define SHAPE_IDX_CR 6 /* Command line Replace mode */
|
SHAPE_IDX_O = 7, ///< Operator-pending mode
|
||||||
#define SHAPE_IDX_O 7 /* Operator-pending mode */
|
SHAPE_IDX_VE = 8, ///< Visual mode with 'selection' exclusive
|
||||||
#define SHAPE_IDX_VE 8 /* Visual mode with 'selection' exclusive */
|
SHAPE_IDX_CLINE = 9, ///< On command line
|
||||||
#define SHAPE_IDX_CLINE 9 /* On command line */
|
SHAPE_IDX_STATUS = 10, ///< status line
|
||||||
#define SHAPE_IDX_STATUS 10 /* A status line */
|
SHAPE_IDX_SDRAG = 11, ///< dragging a status line
|
||||||
#define SHAPE_IDX_SDRAG 11 /* dragging a status line */
|
SHAPE_IDX_VSEP = 12, ///< A vertical separator line
|
||||||
#define SHAPE_IDX_VSEP 12 /* A vertical separator line */
|
SHAPE_IDX_VDRAG = 13, ///< dragging a vertical separator line
|
||||||
#define SHAPE_IDX_VDRAG 13 /* dragging a vertical separator line */
|
SHAPE_IDX_MORE = 14, ///< Hit-return or More
|
||||||
#define SHAPE_IDX_MORE 14 /* Hit-return or More */
|
SHAPE_IDX_MOREL = 15, ///< Hit-return or More in last line
|
||||||
#define SHAPE_IDX_MOREL 15 /* Hit-return or More in last line */
|
SHAPE_IDX_SM = 16, ///< showing matching paren
|
||||||
#define SHAPE_IDX_SM 16 /* showing matching paren */
|
SHAPE_IDX_COUNT = 17
|
||||||
#define SHAPE_IDX_COUNT 17
|
} MouseMode;
|
||||||
|
|
||||||
#define SHAPE_BLOCK 0 /* block cursor */
|
typedef enum {
|
||||||
#define SHAPE_HOR 1 /* horizontal bar cursor */
|
SHAPE_BLOCK = 0, ///< block cursor
|
||||||
#define SHAPE_VER 2 /* vertical bar cursor */
|
SHAPE_HOR = 1, ///< horizontal bar cursor
|
||||||
|
SHAPE_VER = 2 ///< vertical bar cursor
|
||||||
|
} CursorShape;
|
||||||
|
|
||||||
#define MSHAPE_NUMBERED 1000 /* offset for shapes identified by number */
|
#define MSHAPE_NUMBERED 1000 /* offset for shapes identified by number */
|
||||||
#define MSHAPE_HIDE 1 /* hide mouse pointer */
|
#define MSHAPE_HIDE 1 /* hide mouse pointer */
|
||||||
@@ -35,16 +37,17 @@
|
|||||||
#define SHAPE_CURSOR 2 /* used for text cursor shape */
|
#define SHAPE_CURSOR 2 /* used for text cursor shape */
|
||||||
|
|
||||||
typedef struct cursor_entry {
|
typedef struct cursor_entry {
|
||||||
int shape; /* one of the SHAPE_ defines */
|
char *full_name; ///< mode full name
|
||||||
int mshape; /* one of the MSHAPE defines */
|
CursorShape shape; ///< cursor shape: one of the SHAPE_ defines
|
||||||
int percentage; /* percentage of cell for bar */
|
int mshape; ///< mouse shape: one of the MSHAPE defines
|
||||||
long blinkwait; /* blinking, wait time before blinking starts */
|
int percentage; ///< percentage of cell for bar
|
||||||
long blinkon; /* blinking, on time */
|
long blinkwait; ///< blinking, wait time before blinking starts
|
||||||
long blinkoff; /* blinking, off time */
|
long blinkon; ///< blinking, on time
|
||||||
int id; /* highlight group ID */
|
long blinkoff; ///< blinking, off time
|
||||||
int id_lm; /* highlight group ID for :lmap mode */
|
int id; ///< highlight group ID
|
||||||
char *name; /* mode name (fixed) */
|
int id_lm; ///< highlight group ID for :lmap mode
|
||||||
char used_for; /* SHAPE_MOUSE and/or SHAPE_CURSOR */
|
char *name; ///< mode short name
|
||||||
|
char used_for; ///< SHAPE_MOUSE and/or SHAPE_CURSOR
|
||||||
} cursorentry_T;
|
} cursorentry_T;
|
||||||
|
|
||||||
|
|
||||||
|
@@ -42,29 +42,29 @@
|
|||||||
|
|
||||||
static bool did_syntax_onoff = false;
|
static bool did_syntax_onoff = false;
|
||||||
|
|
||||||
// Structure that stores information about a highlight group.
|
/// Structure that stores information about a highlight group.
|
||||||
// The ID of a highlight group is also called group ID. It is the index in
|
/// The ID of a highlight group is also called group ID. It is the index in
|
||||||
// the highlight_ga array PLUS ONE.
|
/// the highlight_ga array PLUS ONE.
|
||||||
struct hl_group {
|
struct hl_group {
|
||||||
char_u *sg_name; // highlight group name
|
char_u *sg_name; ///< highlight group name
|
||||||
char_u *sg_name_u; // uppercase of sg_name
|
char_u *sg_name_u; ///< uppercase of sg_name
|
||||||
int sg_attr; // Screen attr
|
int sg_attr; ///< Screen attr
|
||||||
int sg_link; // link to this highlight group ID
|
int sg_link; ///< link to this highlight group ID
|
||||||
int sg_set; // combination of SG_* flags
|
int sg_set; ///< combination of SG_* flags
|
||||||
scid_T sg_scriptID; // script in which the group was last set
|
scid_T sg_scriptID; ///< script in which the group was last set
|
||||||
// for terminal UIs
|
// for terminal UIs
|
||||||
int sg_cterm; // "cterm=" highlighting attr
|
int sg_cterm; ///< "cterm=" highlighting attr
|
||||||
int sg_cterm_fg; // terminal fg color number + 1
|
int sg_cterm_fg; ///< terminal fg color number + 1
|
||||||
int sg_cterm_bg; // terminal bg color number + 1
|
int sg_cterm_bg; ///< terminal bg color number + 1
|
||||||
int sg_cterm_bold; // bold attr was set for light color
|
int sg_cterm_bold; ///< bold attr was set for light color
|
||||||
// for RGB UIs
|
// for RGB UIs
|
||||||
int sg_gui; // "gui=" highlighting attributes
|
int sg_gui; ///< "gui=" highlighting attributes
|
||||||
RgbValue sg_rgb_fg; // RGB foreground color
|
RgbValue sg_rgb_fg; ///< RGB foreground color
|
||||||
RgbValue sg_rgb_bg; // RGB background color
|
RgbValue sg_rgb_bg; ///< RGB background color
|
||||||
RgbValue sg_rgb_sp; // RGB special color
|
RgbValue sg_rgb_sp; ///< RGB special color
|
||||||
uint8_t *sg_rgb_fg_name; // RGB foreground color name
|
uint8_t *sg_rgb_fg_name; ///< RGB foreground color name
|
||||||
uint8_t *sg_rgb_bg_name; // RGB background color name
|
uint8_t *sg_rgb_bg_name; ///< RGB background color name
|
||||||
uint8_t *sg_rgb_sp_name; // RGB special color name
|
uint8_t *sg_rgb_sp_name; ///< RGB special color name
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SG_CTERM 2 // cterm has been set
|
#define SG_CTERM 2 // cterm has been set
|
||||||
@@ -7165,12 +7165,13 @@ int syn_namen2id(char_u *linep, int len)
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Find highlight group name in the table and return it's ID.
|
||||||
* Find highlight group name in the table and return it's ID.
|
/// If it doesn't exist yet, a new entry is created.
|
||||||
* The argument is a pointer to the name and the length of the name.
|
///
|
||||||
* If it doesn't exist yet, a new entry is created.
|
/// @param pp Highlight group name
|
||||||
* Return 0 for failure.
|
/// @param len length of \p pp
|
||||||
*/
|
///
|
||||||
|
/// @return 0 for failure else the id of the group
|
||||||
int syn_check_group(char_u *pp, int len)
|
int syn_check_group(char_u *pp, int len)
|
||||||
{
|
{
|
||||||
char_u *name = vim_strnsave(pp, len);
|
char_u *name = vim_strnsave(pp, len);
|
||||||
|
@@ -31,6 +31,8 @@
|
|||||||
#include "nvim/ugrid.h"
|
#include "nvim/ugrid.h"
|
||||||
#include "nvim/tui/input.h"
|
#include "nvim/tui/input.h"
|
||||||
#include "nvim/tui/tui.h"
|
#include "nvim/tui/tui.h"
|
||||||
|
#include "nvim/cursor_shape.h"
|
||||||
|
#include "nvim/syntax.h"
|
||||||
|
|
||||||
// Space reserved in the output buffer to restore the cursor to normal when
|
// Space reserved in the output buffer to restore the cursor to normal when
|
||||||
// flushing. No existing terminal will require 32 bytes to do that.
|
// flushing. No existing terminal will require 32 bytes to do that.
|
||||||
@@ -69,12 +71,12 @@ typedef struct {
|
|||||||
bool can_use_terminal_scroll;
|
bool can_use_terminal_scroll;
|
||||||
bool mouse_enabled;
|
bool mouse_enabled;
|
||||||
bool busy;
|
bool busy;
|
||||||
|
cursorentry_T cursor_shapes[SHAPE_IDX_COUNT];
|
||||||
HlAttrs print_attrs;
|
HlAttrs print_attrs;
|
||||||
int showing_mode;
|
int showing_mode;
|
||||||
struct {
|
struct {
|
||||||
int enable_mouse, disable_mouse;
|
int enable_mouse, disable_mouse;
|
||||||
int enable_bracketed_paste, disable_bracketed_paste;
|
int enable_bracketed_paste, disable_bracketed_paste;
|
||||||
int set_cursor_shape_bar, set_cursor_shape_ul, set_cursor_shape_block;
|
|
||||||
int set_rgb_foreground, set_rgb_background;
|
int set_rgb_foreground, set_rgb_background;
|
||||||
int enable_focus_reporting, disable_focus_reporting;
|
int enable_focus_reporting, disable_focus_reporting;
|
||||||
} unibi_ext;
|
} unibi_ext;
|
||||||
@@ -97,6 +99,7 @@ UI *tui_start(void)
|
|||||||
ui->clear = tui_clear;
|
ui->clear = tui_clear;
|
||||||
ui->eol_clear = tui_eol_clear;
|
ui->eol_clear = tui_eol_clear;
|
||||||
ui->cursor_goto = tui_cursor_goto;
|
ui->cursor_goto = tui_cursor_goto;
|
||||||
|
ui->cursor_style_set = tui_cursor_style_set;
|
||||||
ui->update_menu = tui_update_menu;
|
ui->update_menu = tui_update_menu;
|
||||||
ui->busy_start = tui_busy_start;
|
ui->busy_start = tui_busy_start;
|
||||||
ui->busy_stop = tui_busy_stop;
|
ui->busy_stop = tui_busy_stop;
|
||||||
@@ -131,9 +134,6 @@ static void terminfo_start(UI *ui)
|
|||||||
data->unibi_ext.disable_mouse = -1;
|
data->unibi_ext.disable_mouse = -1;
|
||||||
data->unibi_ext.enable_bracketed_paste = -1;
|
data->unibi_ext.enable_bracketed_paste = -1;
|
||||||
data->unibi_ext.disable_bracketed_paste = -1;
|
data->unibi_ext.disable_bracketed_paste = -1;
|
||||||
data->unibi_ext.set_cursor_shape_bar = -1;
|
|
||||||
data->unibi_ext.set_cursor_shape_ul = -1;
|
|
||||||
data->unibi_ext.set_cursor_shape_block = -1;
|
|
||||||
data->unibi_ext.enable_focus_reporting = -1;
|
data->unibi_ext.enable_focus_reporting = -1;
|
||||||
data->unibi_ext.disable_focus_reporting = -1;
|
data->unibi_ext.disable_focus_reporting = -1;
|
||||||
data->out_fd = 1;
|
data->out_fd = 1;
|
||||||
@@ -147,7 +147,6 @@ static void terminfo_start(UI *ui)
|
|||||||
}
|
}
|
||||||
fix_terminfo(data);
|
fix_terminfo(data);
|
||||||
// Initialize the cursor shape.
|
// Initialize the cursor shape.
|
||||||
unibi_out(ui, data->unibi_ext.set_cursor_shape_block);
|
|
||||||
// Set 't_Co' from the result of unibilium & fix_terminfo.
|
// Set 't_Co' from the result of unibilium & fix_terminfo.
|
||||||
t_colors = unibi_get_num(data->ut, unibi_max_colors);
|
t_colors = unibi_get_num(data->ut, unibi_max_colors);
|
||||||
// Enter alternate screen and clear
|
// Enter alternate screen and clear
|
||||||
@@ -434,6 +433,64 @@ static void tui_cursor_goto(UI *ui, int row, int col)
|
|||||||
unibi_goto(ui, row, col);
|
unibi_goto(ui, row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CursorShape tui_cursor_decode_shape(const char *shape_str)
|
||||||
|
{
|
||||||
|
CursorShape shape = 0;
|
||||||
|
if (strcmp(shape_str, "block") == 0) {
|
||||||
|
shape = SHAPE_BLOCK;
|
||||||
|
} else if (strcmp(shape_str, "vertical") == 0) {
|
||||||
|
shape = SHAPE_VER;
|
||||||
|
} else if (strcmp(shape_str, "horizontal") == 0) {
|
||||||
|
shape = SHAPE_HOR;
|
||||||
|
} else {
|
||||||
|
EMSG2(_(e_invarg2), shape_str);
|
||||||
|
}
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cursorentry_T decode_cursor_entry(Dictionary args)
|
||||||
|
{
|
||||||
|
cursorentry_T r;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < args.size; i++) {
|
||||||
|
char *keyStr = args.items[i].key.data;
|
||||||
|
Object value = args.items[i].value;
|
||||||
|
|
||||||
|
if (strcmp(keyStr, "cursor_shape") == 0) {
|
||||||
|
r.shape = tui_cursor_decode_shape(args.items[i].value.data.string.data);
|
||||||
|
} else if (strcmp(keyStr, "blinkon") == 0) {
|
||||||
|
r.blinkon = (int)value.data.integer;
|
||||||
|
} else if (strcmp(keyStr, "blinkoff") == 0) {
|
||||||
|
r.blinkoff = (int)value.data.integer;
|
||||||
|
} else if (strcmp(keyStr, "hl_id") == 0) {
|
||||||
|
r.id = (int)value.data.integer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tui_cursor_style_set(UI *ui, Dictionary args)
|
||||||
|
{
|
||||||
|
TUIData *data = ui->data;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < args.size; i++) {
|
||||||
|
char *mode_name = args.items[i].key.data;
|
||||||
|
const int mode_id = cursor_mode_str2int(mode_name);
|
||||||
|
|
||||||
|
if (mode_id < 0) {
|
||||||
|
WLOG("Unknown mode '%s'", mode_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cursorentry_T r = decode_cursor_entry(args.items[i].value.data.dictionary);
|
||||||
|
r.full_name = mode_name;
|
||||||
|
data->cursor_shapes[mode_id] = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// force redrawal
|
||||||
|
MouseMode cursor_mode = tui_mode2cursor(data->showing_mode);
|
||||||
|
tui_set_cursor(ui, cursor_mode);
|
||||||
|
}
|
||||||
|
|
||||||
static void tui_update_menu(UI *ui)
|
static void tui_update_menu(UI *ui)
|
||||||
{
|
{
|
||||||
// Do nothing; menus are for GUI only
|
// Do nothing; menus are for GUI only
|
||||||
@@ -467,26 +524,83 @@ static void tui_mouse_off(UI *ui)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @param mode one of SHAPE_XXX
|
||||||
|
static void tui_set_cursor(UI *ui, MouseMode mode)
|
||||||
|
{
|
||||||
|
TUIData *data = ui->data;
|
||||||
|
cursorentry_T c = data->cursor_shapes[mode];
|
||||||
|
int shape = c.shape;
|
||||||
|
bool inside_tmux = os_getenv("TMUX") != NULL;
|
||||||
|
unibi_var_t vars[26 + 26] = { { 0 } };
|
||||||
|
|
||||||
|
# define TMUX_WRAP(seq) (inside_tmux ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq)
|
||||||
|
// Support changing cursor shape on some popular terminals.
|
||||||
|
const char *term_prog = os_getenv("TERM_PROGRAM");
|
||||||
|
const char *vte_version = os_getenv("VTE_VERSION");
|
||||||
|
|
||||||
|
if ((term_prog && !strcmp(term_prog, "Konsole"))
|
||||||
|
|| os_getenv("KONSOLE_DBUS_SESSION") != NULL) {
|
||||||
|
// Konsole uses a proprietary escape code to set the cursor shape
|
||||||
|
// and does not support DECSCUSR.
|
||||||
|
switch (shape) {
|
||||||
|
case SHAPE_BLOCK: shape = 0; break;
|
||||||
|
case SHAPE_VER: shape = 1; break;
|
||||||
|
case SHAPE_HOR: shape = 3; break;
|
||||||
|
default: WLOG("Unknown shape value %d", shape); break;
|
||||||
|
}
|
||||||
|
printf(TMUX_WRAP("\x1b]50;CursorShape=%d;BlinkingCursorEnabled=%d\x07"),
|
||||||
|
shape, (c.blinkon !=0));
|
||||||
|
} else if (!vte_version || atoi(vte_version) >= 3900) {
|
||||||
|
// Assume that the terminal supports DECSCUSR unless it is an
|
||||||
|
// old VTE based terminal. This should not get wrapped for tmux,
|
||||||
|
// which will handle it via its Ss/Se terminfo extension - usually
|
||||||
|
// according to its terminal-overrides.
|
||||||
|
|
||||||
|
switch (shape) {
|
||||||
|
case SHAPE_BLOCK: shape = 1; break;
|
||||||
|
case SHAPE_VER: shape = 5; break;
|
||||||
|
case SHAPE_HOR: shape = 3; break;
|
||||||
|
default: WLOG("Unknown shape value %d", shape); break;
|
||||||
|
}
|
||||||
|
data->params[0].i = shape + (c.blinkon ==0);
|
||||||
|
unibi_format(vars, vars + 26, "\x1b[%p1%d q",
|
||||||
|
data->params, out, ui, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns cursor mode from edit mode
|
||||||
|
static MouseMode tui_mode2cursor(int mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case INSERT: return SHAPE_IDX_I;
|
||||||
|
case CMDLINE: return SHAPE_IDX_C;
|
||||||
|
case REPLACE: return SHAPE_IDX_R;
|
||||||
|
case NORMAL:
|
||||||
|
default: return SHAPE_IDX_N;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @param mode editor mode
|
||||||
static void tui_mode_change(UI *ui, int mode)
|
static void tui_mode_change(UI *ui, int mode)
|
||||||
{
|
{
|
||||||
TUIData *data = ui->data;
|
TUIData *data = ui->data;
|
||||||
|
|
||||||
if (mode == INSERT) {
|
if (mode == INSERT) {
|
||||||
if (data->showing_mode != INSERT) {
|
if (data->showing_mode != INSERT) {
|
||||||
unibi_out(ui, data->unibi_ext.set_cursor_shape_bar);
|
tui_set_cursor(ui, SHAPE_IDX_I);
|
||||||
}
|
}
|
||||||
} else if (mode == CMDLINE) {
|
} else if (mode == CMDLINE) {
|
||||||
if (data->showing_mode != CMDLINE) {
|
if (data->showing_mode != CMDLINE) {
|
||||||
unibi_out(ui, data->unibi_ext.set_cursor_shape_bar);
|
tui_set_cursor(ui, SHAPE_IDX_C);
|
||||||
}
|
}
|
||||||
} else if (mode == REPLACE) {
|
} else if (mode == REPLACE) {
|
||||||
if (data->showing_mode != REPLACE) {
|
if (data->showing_mode != REPLACE) {
|
||||||
unibi_out(ui, data->unibi_ext.set_cursor_shape_ul);
|
tui_set_cursor(ui, SHAPE_IDX_R);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(mode == NORMAL);
|
assert(mode == NORMAL);
|
||||||
if (data->showing_mode != NORMAL) {
|
if (data->showing_mode != NORMAL) {
|
||||||
unibi_out(ui, data->unibi_ext.set_cursor_shape_block);
|
tui_set_cursor(ui, SHAPE_IDX_N);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data->showing_mode = mode;
|
data->showing_mode = mode;
|
||||||
@@ -831,8 +945,6 @@ static void fix_terminfo(TUIData *data)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inside_tmux = os_getenv("TMUX") != NULL;
|
|
||||||
|
|
||||||
#define STARTS_WITH(str, prefix) (!memcmp(str, prefix, sizeof(prefix) - 1))
|
#define STARTS_WITH(str, prefix) (!memcmp(str, prefix, sizeof(prefix) - 1))
|
||||||
|
|
||||||
if (STARTS_WITH(term, "rxvt")) {
|
if (STARTS_WITH(term, "rxvt")) {
|
||||||
@@ -890,40 +1002,6 @@ static void fix_terminfo(TUIData *data)
|
|||||||
unibi_set_str(ut, unibi_set_a_background, XTERM_SETAB);
|
unibi_set_str(ut, unibi_set_a_background, XTERM_SETAB);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * env_cusr_shape = os_getenv("NVIM_TUI_ENABLE_CURSOR_SHAPE");
|
|
||||||
if (env_cusr_shape && strncmp(env_cusr_shape, "0", 1) == 0) {
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
bool cusr_blink = env_cusr_shape && strncmp(env_cusr_shape, "2", 1) == 0;
|
|
||||||
|
|
||||||
#define TMUX_WRAP(seq) (inside_tmux ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq)
|
|
||||||
// Support changing cursor shape on some popular terminals.
|
|
||||||
const char *term_prog = os_getenv("TERM_PROGRAM");
|
|
||||||
const char *vte_version = os_getenv("VTE_VERSION");
|
|
||||||
|
|
||||||
if ((term_prog && !strcmp(term_prog, "Konsole"))
|
|
||||||
|| os_getenv("KONSOLE_DBUS_SESSION") != NULL) {
|
|
||||||
// Konsole uses a proprietary escape code to set the cursor shape
|
|
||||||
// and does not support DECSCUSR.
|
|
||||||
data->unibi_ext.set_cursor_shape_bar = (int)unibi_add_ext_str(ut, NULL,
|
|
||||||
TMUX_WRAP("\x1b]50;CursorShape=1\x07"));
|
|
||||||
data->unibi_ext.set_cursor_shape_ul = (int)unibi_add_ext_str(ut, NULL,
|
|
||||||
TMUX_WRAP("\x1b]50;CursorShape=2\x07"));
|
|
||||||
data->unibi_ext.set_cursor_shape_block = (int)unibi_add_ext_str(ut, NULL,
|
|
||||||
TMUX_WRAP("\x1b]50;CursorShape=0\x07"));
|
|
||||||
} else if (!vte_version || atoi(vte_version) >= 3900) {
|
|
||||||
// Assume that the terminal supports DECSCUSR unless it is an
|
|
||||||
// old VTE based terminal. This should not get wrapped for tmux,
|
|
||||||
// which will handle it via its Ss/Se terminfo extension - usually
|
|
||||||
// according to its terminal-overrides.
|
|
||||||
data->unibi_ext.set_cursor_shape_bar =
|
|
||||||
(int)unibi_add_ext_str(ut, NULL, cusr_blink ? "\x1b[5 q" : "\x1b[6 q");
|
|
||||||
data->unibi_ext.set_cursor_shape_ul =
|
|
||||||
(int)unibi_add_ext_str(ut, NULL, cusr_blink ? "\x1b[3 q" : "\x1b[4 q");
|
|
||||||
data->unibi_ext.set_cursor_shape_block =
|
|
||||||
(int)unibi_add_ext_str(ut, NULL, cusr_blink ? "\x1b[1 q" : "\x1b[2 q");
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
end:
|
||||||
// Fill some empty slots with common terminal strings
|
// Fill some empty slots with common terminal strings
|
||||||
data->unibi_ext.enable_mouse = (int)unibi_add_ext_str(ut, NULL,
|
data->unibi_ext.enable_mouse = (int)unibi_add_ext_str(ut, NULL,
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
#ifndef NVIM_TUI_TUI_H
|
#ifndef NVIM_TUI_TUI_H
|
||||||
#define NVIM_TUI_TUI_H
|
#define NVIM_TUI_TUI_H
|
||||||
|
|
||||||
|
#include "nvim/cursor_shape.h"
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "tui/tui.h.generated.h"
|
# include "tui/tui.h.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
#include "nvim/screen.h"
|
#include "nvim/screen.h"
|
||||||
#include "nvim/syntax.h"
|
#include "nvim/syntax.h"
|
||||||
#include "nvim/window.h"
|
#include "nvim/window.h"
|
||||||
|
#include "nvim/cursor_shape.h"
|
||||||
#ifdef FEAT_TUI
|
#ifdef FEAT_TUI
|
||||||
# include "nvim/tui/tui.h"
|
# include "nvim/tui/tui.h"
|
||||||
#else
|
#else
|
||||||
@@ -179,6 +180,7 @@ void ui_refresh(void)
|
|||||||
row = col = 0;
|
row = col = 0;
|
||||||
screen_resize(width, height);
|
screen_resize(width, height);
|
||||||
pum_set_external(pum_external);
|
pum_set_external(pum_external);
|
||||||
|
ui_cursor_style_set();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ui_refresh_event(void **argv)
|
static void ui_refresh_event(void **argv)
|
||||||
@@ -376,6 +378,13 @@ void ui_cursor_goto(int new_row, int new_col)
|
|||||||
pending_cursor_update = true;
|
pending_cursor_update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ui_cursor_style_set(void)
|
||||||
|
{
|
||||||
|
Dictionary style = cursor_shape_dict();
|
||||||
|
UI_CALL(cursor_style_set, style);
|
||||||
|
api_free_dictionary(style);
|
||||||
|
}
|
||||||
|
|
||||||
void ui_update_menu(void)
|
void ui_update_menu(void)
|
||||||
{
|
{
|
||||||
UI_CALL(update_menu);
|
UI_CALL(update_menu);
|
||||||
|
@@ -22,6 +22,7 @@ struct ui_t {
|
|||||||
void (*clear)(UI *ui);
|
void (*clear)(UI *ui);
|
||||||
void (*eol_clear)(UI *ui);
|
void (*eol_clear)(UI *ui);
|
||||||
void (*cursor_goto)(UI *ui, int row, int col);
|
void (*cursor_goto)(UI *ui, int row, int col);
|
||||||
|
void (*cursor_style_set)(UI *ui, Dictionary cursor_shapes);
|
||||||
void (*update_menu)(UI *ui);
|
void (*update_menu)(UI *ui);
|
||||||
void (*busy_start)(UI *ui);
|
void (*busy_start)(UI *ui);
|
||||||
void (*busy_stop)(UI *ui);
|
void (*busy_stop)(UI *ui);
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include "nvim/memory.h"
|
#include "nvim/memory.h"
|
||||||
#include "nvim/ui_bridge.h"
|
#include "nvim/ui_bridge.h"
|
||||||
#include "nvim/ugrid.h"
|
#include "nvim/ugrid.h"
|
||||||
|
#include "nvim/api/private/helpers.h"
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "ui_bridge.c.generated.h"
|
# include "ui_bridge.c.generated.h"
|
||||||
@@ -59,6 +60,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
|
|||||||
rv->bridge.clear = ui_bridge_clear;
|
rv->bridge.clear = ui_bridge_clear;
|
||||||
rv->bridge.eol_clear = ui_bridge_eol_clear;
|
rv->bridge.eol_clear = ui_bridge_eol_clear;
|
||||||
rv->bridge.cursor_goto = ui_bridge_cursor_goto;
|
rv->bridge.cursor_goto = ui_bridge_cursor_goto;
|
||||||
|
rv->bridge.cursor_style_set = ui_bridge_cursor_styleset;
|
||||||
rv->bridge.update_menu = ui_bridge_update_menu;
|
rv->bridge.update_menu = ui_bridge_update_menu;
|
||||||
rv->bridge.busy_start = ui_bridge_busy_start;
|
rv->bridge.busy_start = ui_bridge_busy_start;
|
||||||
rv->bridge.busy_stop = ui_bridge_busy_stop;
|
rv->bridge.busy_stop = ui_bridge_busy_stop;
|
||||||
@@ -178,6 +180,23 @@ static void ui_bridge_cursor_goto_event(void **argv)
|
|||||||
ui->cursor_goto(ui, PTR2INT(argv[1]), PTR2INT(argv[2]));
|
ui->cursor_goto(ui, PTR2INT(argv[1]), PTR2INT(argv[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ui_bridge_cursor_styleset(UI *b, Dictionary style)
|
||||||
|
{
|
||||||
|
Object copy = copy_object(DICTIONARY_OBJ(style));
|
||||||
|
Object *pobj = xmalloc(sizeof(copy));
|
||||||
|
*pobj = copy;
|
||||||
|
UI_CALL(b, cursor_styleset, 2, b, pobj);
|
||||||
|
}
|
||||||
|
static void ui_bridge_cursor_styleset_event(void **argv)
|
||||||
|
{
|
||||||
|
UI *ui = UI(argv[0]);
|
||||||
|
Object *styles = (Object *)argv[1];
|
||||||
|
|
||||||
|
ui->cursor_style_set(ui, styles->data.dictionary);
|
||||||
|
api_free_object(*styles);
|
||||||
|
xfree(styles);
|
||||||
|
}
|
||||||
|
|
||||||
static void ui_bridge_update_menu(UI *b)
|
static void ui_bridge_update_menu(UI *b)
|
||||||
{
|
{
|
||||||
UI_CALL(b, update_menu, 1, b);
|
UI_CALL(b, update_menu, 1, b);
|
||||||
|
@@ -313,6 +313,8 @@ function Screen:_redraw(updates)
|
|||||||
if handler ~= nil then
|
if handler ~= nil then
|
||||||
handler(self, unpack(update[i]))
|
handler(self, unpack(update[i]))
|
||||||
else
|
else
|
||||||
|
assert(self._on_event, "Either add an Screen:_handle_XXX method "..
|
||||||
|
" or call Screen:set_on_event_handler")
|
||||||
self._on_event(method, update[i])
|
self._on_event(method, update[i])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -343,6 +345,10 @@ function Screen:_handle_resize(width, height)
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Screen:_handle_cursor_style_set(styles)
|
||||||
|
self._cursor_styles = styles
|
||||||
|
end
|
||||||
|
|
||||||
function Screen:_handle_clear()
|
function Screen:_handle_clear()
|
||||||
self:_clear_block(self._scroll_region.top, self._scroll_region.bot,
|
self:_clear_block(self._scroll_region.top, self._scroll_region.bot,
|
||||||
self._scroll_region.left, self._scroll_region.right)
|
self._scroll_region.left, self._scroll_region.right)
|
||||||
|
Reference in New Issue
Block a user