aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/buffer.c20
-rw-r--r--src/nvim/api/private/helpers.c39
-rw-r--r--src/nvim/api/vim.c11
-rw-r--r--src/nvim/buffer_defs.h7
-rw-r--r--src/nvim/eval.c57
-rw-r--r--src/nvim/getchar.c25
-rw-r--r--src/nvim/terminal.c2
-rw-r--r--src/nvim/testdir/runtest.vim1
-rw-r--r--src/nvim/tui/tui.c198
9 files changed, 295 insertions, 65 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 0b8d39d0d2..fc11708bd6 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -453,6 +453,26 @@ Integer nvim_buf_get_changedtick(Buffer buffer, Error *err)
return buf->b_changedtick;
}
+/// Get a list of dictionaries describing buffer-local mappings
+/// Note that the buffer key in the dictionary will represent the buffer
+/// handle where the mapping is present
+///
+/// @param mode The abbreviation for the mode
+/// @param buffer_id Buffer handle
+/// @param[out] err Error details, if any
+/// @returns An array of maparg() like dictionaries describing mappings
+ArrayOf(Dictionary) nvim_buf_get_keymap(Buffer buffer, String mode, Error *err)
+ FUNC_API_SINCE(3)
+{
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return (Array)ARRAY_DICT_INIT;
+ }
+
+ return keymap_array(mode, buf);
+}
+
/// Sets a buffer-scoped (b:) variable
///
/// @param buffer Buffer handle
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 1d7b305da3..ef789b3ed4 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -24,6 +24,7 @@
#include "nvim/option_defs.h"
#include "nvim/version.h"
#include "nvim/lib/kvec.h"
+#include "nvim/getchar.h"
/// Helper structure for vim_to_object
typedef struct {
@@ -1034,3 +1035,41 @@ void api_set_error(Error *err, ErrorType errType, const char *format, ...)
err->type = errType;
}
+
+/// Get an array containing dictionaries describing mappings
+/// based on mode and buffer id
+///
+/// @param mode The abbreviation for the mode
+/// @param buf The buffer to get the mapping array. NULL for global
+/// @returns An array of maparg() like dictionaries describing mappings
+ArrayOf(Dictionary) keymap_array(String mode, buf_T *buf)
+{
+ Array mappings = ARRAY_DICT_INIT;
+ dict_T *const dict = tv_dict_alloc();
+
+ // Convert the string mode to the integer mode
+ // that is stored within each mapblock
+ char_u *p = (char_u *)mode.data;
+ int int_mode = get_map_mode(&p, 0);
+
+ // Determine the desired buffer value
+ long buffer_value = (buf == NULL) ? 0 : buf->handle;
+
+ for (int i = 0; i < MAX_MAPHASH; i++) {
+ for (const mapblock_T *current_maphash = get_maphash(i, buf);
+ current_maphash;
+ current_maphash = current_maphash->m_next) {
+ // Check for correct mode
+ if (int_mode & current_maphash->m_mode) {
+ mapblock_fill_dict(dict, current_maphash, buffer_value, false);
+ ADD(mappings, vim_to_object(
+ (typval_T[]) { { .v_type = VAR_DICT, .vval.v_dict = dict } }));
+
+ tv_dict_clear(dict);
+ }
+ }
+ }
+ tv_dict_free(dict);
+
+ return mappings;
+}
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 53e5f71fd4..0cffb2c87d 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -742,6 +742,17 @@ Dictionary nvim_get_mode(void)
return rv;
}
+/// Get a list of dictionaries describing global (i.e. non-buffer) mappings
+/// Note that the "buffer" key will be 0 to represent false.
+///
+/// @param mode The abbreviation for the mode
+/// @returns An array of maparg() like dictionaries describing mappings
+ArrayOf(Dictionary) nvim_get_keymap(String mode)
+ FUNC_API_SINCE(3)
+{
+ return keymap_array(mode, NULL);
+}
+
Array nvim_get_api_info(uint64_t channel_id)
FUNC_API_SINCE(1) FUNC_API_ASYNC FUNC_API_REMOTE_ONLY
{
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 88fa9726a4..d96b9355f1 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -438,6 +438,9 @@ typedef TV_DICTITEM_STRUCT(sizeof("changedtick")) ChangedtickDictItem;
#define BUF_HAS_QF_ENTRY 1
#define BUF_HAS_LL_ENTRY 2
+// Maximum number of maphash blocks we will have
+#define MAX_MAPHASH 256
+
/*
* buffer: structure that holds information about one file
*
@@ -526,8 +529,8 @@ struct file_buffer {
*/
uint64_t b_chartab[4];
- /* Table used for mappings local to a buffer. */
- mapblock_T *(b_maphash[256]);
+ // Table used for mappings local to a buffer.
+ mapblock_T *(b_maphash[MAX_MAPHASH]);
/* First abbreviation local to a buffer. */
mapblock_T *b_first_abbr;
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index e4b3128930..ecef470666 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -12102,22 +12102,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
tv_dict_alloc_ret(rettv);
if (rhs != NULL) {
// Return a dictionary.
- char_u *lhs = str2special_save(mp->m_keys, true);
- char *const mapmode = map_mode_to_chars(mp->m_mode);
- dict_T *dict = rettv->vval.v_dict;
-
- tv_dict_add_str(dict, S_LEN("lhs"), (const char *)lhs);
- tv_dict_add_str(dict, S_LEN("rhs"), (const char *)mp->m_orig_str);
- tv_dict_add_nr(dict, S_LEN("noremap"), mp->m_noremap ? 1 : 0);
- tv_dict_add_nr(dict, S_LEN("expr"), mp->m_expr ? 1 : 0);
- tv_dict_add_nr(dict, S_LEN("silent"), mp->m_silent ? 1 : 0);
- tv_dict_add_nr(dict, S_LEN("sid"), (varnumber_T)mp->m_script_ID);
- tv_dict_add_nr(dict, S_LEN("buffer"), (varnumber_T)buffer_local);
- tv_dict_add_nr(dict, S_LEN("nowait"), mp->m_nowait ? 1 : 0);
- tv_dict_add_str(dict, S_LEN("mode"), mapmode);
-
- xfree(lhs);
- xfree(mapmode);
+ mapblock_fill_dict(rettv->vval.v_dict, mp, buffer_local, true);
}
}
}
@@ -12134,6 +12119,46 @@ static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
executor_eval_lua(cstr_as_string((char *)str), &argvars[1], rettv);
}
+/// Fill a dictionary with all applicable maparg() like dictionaries
+///
+/// @param dict The dictionary to be filled
+/// @param mp The maphash that contains the mapping information
+/// @param buffer_value The "buffer" value
+/// @param compatible True for compatible with old maparg() dict
+void mapblock_fill_dict(dict_T *const dict,
+ const mapblock_T *const mp,
+ long buffer_value,
+ bool compatible)
+ FUNC_ATTR_NONNULL_ALL
+{
+ char_u *lhs = str2special_save(mp->m_keys, true);
+ char *const mapmode = map_mode_to_chars(mp->m_mode);
+ varnumber_T noremap_value;
+
+ if (compatible) {
+ // Keep old compatible behavior
+ // This is unable to determine whether a mapping is a <script> mapping
+ noremap_value = !!mp->m_noremap;
+ } else {
+ // Distinguish between <script> mapping
+ // If it's not a <script> mapping, check if it's a noremap
+ noremap_value = mp->m_noremap == REMAP_SCRIPT ? 2 : !!mp->m_noremap;
+ }
+
+ tv_dict_add_str(dict, S_LEN("lhs"), (const char *)lhs);
+ tv_dict_add_str(dict, S_LEN("rhs"), (const char *)mp->m_orig_str);
+ tv_dict_add_nr(dict, S_LEN("noremap"), noremap_value);
+ tv_dict_add_nr(dict, S_LEN("expr"), mp->m_expr ? 1 : 0);
+ tv_dict_add_nr(dict, S_LEN("silent"), mp->m_silent ? 1 : 0);
+ tv_dict_add_nr(dict, S_LEN("sid"), (varnumber_T)mp->m_script_ID);
+ tv_dict_add_nr(dict, S_LEN("buffer"), (varnumber_T)buffer_value);
+ tv_dict_add_nr(dict, S_LEN("nowait"), mp->m_nowait ? 1 : 0);
+ tv_dict_add_str(dict, S_LEN("mode"), mapmode);
+
+ xfree(lhs);
+ xfree(mapmode);
+}
+
/*
* "map()" function
*/
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index c3c393f1ec..382caa8548 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -18,6 +18,7 @@
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/getchar.h"
+#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/edit.h"
@@ -47,6 +48,7 @@
#include "nvim/event/loop.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
+#include "nvim/api/private/handle.h"
/*
* These buffers are used for storing:
@@ -102,11 +104,10 @@ static int block_redo = FALSE;
(NORMAL + VISUAL + SELECTMODE + \
OP_PENDING)) ? (c1) : ((c1) ^ 0x80))
-/*
- * Each mapping is put in one of the 256 hash lists, to speed up finding it.
- */
-static mapblock_T *(maphash[256]);
-static int maphash_valid = FALSE;
+// Each mapping is put in one of the MAX_MAPHASH hash lists,
+// to speed up finding it.
+static mapblock_T *(maphash[MAX_MAPHASH]);
+static bool maphash_valid = false;
/*
* List used for abbreviations.
@@ -4237,3 +4238,17 @@ static bool typebuf_match_len(const uint8_t *str, int *mlen)
*mlen = i;
return str[i] == NUL; // matched the whole string
}
+
+/// Retrieve the mapblock at the index either globally or for a certain buffer
+///
+/// @param index The index in the maphash[]
+/// @param buf The buffer to get the maphash from. NULL for global
+mapblock_T *get_maphash(int index, buf_T *buf)
+ FUNC_ATTR_PURE
+{
+ if (index > MAX_MAPHASH) {
+ return NULL;
+ }
+
+ return (buf == NULL) ? maphash[index] : buf->b_maphash[index];
+}
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index b8b7085c5e..5b250ebf54 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -237,8 +237,6 @@ Terminal *terminal_open(TerminalOptions opts)
curbuf->b_p_scbk = p_scbk; // 'scrollback'
curbuf->b_p_tw = 0; // 'textwidth'
set_option_value("wrap", false, NULL, OPT_LOCAL);
- set_option_value("number", false, NULL, OPT_LOCAL);
- set_option_value("relativenumber", false, NULL, OPT_LOCAL);
set_option_value("list", false, NULL, OPT_LOCAL);
buf_set_term_title(curbuf, (char *)curbuf->b_ffname);
RESET_BINDING(curwin);
diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim
index a754e5fdfb..732b0aaf74 100644
--- a/src/nvim/testdir/runtest.vim
+++ b/src/nvim/testdir/runtest.vim
@@ -137,6 +137,7 @@ endif
let s:flaky = [
\ 'Test_with_partial_callback()',
\ 'Test_oneshot()'
+ \ 'Test_lambda_with_timer()'
\ ]
" Locate Test_ functions and execute them.
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 4ff7993f4a..736d50ee8b 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -53,6 +53,9 @@ typedef enum TermType {
kTermiTerm,
kTermKonsole,
kTermRxvt,
+ kTermDTTerm,
+ kTermXTerm,
+ kTermTeraTerm,
} TermType;
typedef struct {
@@ -79,7 +82,10 @@ typedef struct {
UGrid grid;
kvec_t(Rect) invalid_regions;
int out_fd;
- bool can_use_terminal_scroll;
+ bool scroll_region_is_full_screen;
+ bool can_change_scroll_region;
+ bool can_set_lr_margin;
+ bool can_set_left_right_margin;
bool mouse_enabled;
bool busy;
cursorentry_T cursor_shapes[SHAPE_IDX_COUNT];
@@ -89,9 +95,12 @@ typedef struct {
struct {
int enable_mouse, disable_mouse;
int enable_bracketed_paste, disable_bracketed_paste;
+ int enable_lr_margin, disable_lr_margin;
int set_rgb_foreground, set_rgb_background;
int set_cursor_color;
int enable_focus_reporting, disable_focus_reporting;
+ int resize_screen;
+ int reset_scroll_region;
} unibi_ext;
} TUIData;
@@ -143,7 +152,7 @@ UI *tui_start(void)
static void terminfo_start(UI *ui)
{
TUIData *data = ui->data;
- data->can_use_terminal_scroll = true;
+ data->scroll_region_is_full_screen = true;
data->bufpos = 0;
data->bufsize = sizeof(data->buf) - CNORM_COMMAND_MAX_SIZE;
data->showing_mode = SHAPE_IDX_N;
@@ -152,8 +161,12 @@ static void terminfo_start(UI *ui)
data->unibi_ext.set_cursor_color = -1;
data->unibi_ext.enable_bracketed_paste = -1;
data->unibi_ext.disable_bracketed_paste = -1;
+ data->unibi_ext.enable_lr_margin = -1;
+ data->unibi_ext.disable_lr_margin = -1;
data->unibi_ext.enable_focus_reporting = -1;
data->unibi_ext.disable_focus_reporting = -1;
+ data->unibi_ext.resize_screen = -1;
+ data->unibi_ext.reset_scroll_region = -1;
data->out_fd = 1;
data->out_isatty = os_isatty(data->out_fd);
// setup unibilium
@@ -164,6 +177,13 @@ static void terminfo_start(UI *ui)
data->ut = unibi_dummy();
}
fix_terminfo(data);
+ data->can_change_scroll_region =
+ !!unibi_get_str(data->ut, unibi_change_scroll_region);
+ data->can_set_lr_margin =
+ !!unibi_get_str(data->ut, unibi_set_lr_margin);
+ data->can_set_left_right_margin =
+ !!unibi_get_str(data->ut, unibi_set_left_margin_parm)
+ && !!unibi_get_str(data->ut, unibi_set_right_margin_parm);
// Set 't_Co' from the result of unibilium & fix_terminfo.
t_colors = unibi_get_num(data->ut, unibi_max_colors);
// Enter alternate screen and clear
@@ -216,11 +236,6 @@ static void tui_terminal_start(UI *ui)
terminfo_start(ui);
update_size(ui);
signal_watcher_start(&data->winch_handle, sigwinch_cb, SIGWINCH);
-
-#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
- data->input.tk_ti_hook_fn = tui_tk_ti_getstr;
-#endif
- term_input_init(&data->input, data->loop);
term_input_start(&data->input);
}
@@ -255,8 +270,14 @@ static void tui_main(UIBridgeData *bridge, UI *ui)
#ifdef UNIX
signal_watcher_start(&data->cont_handle, sigcont_cb, SIGCONT);
#endif
+
+#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
+ data->input.tk_ti_hook_fn = tui_tk_ti_getstr;
+#endif
+ term_input_init(&data->input, &tui_loop);
tui_terminal_start(ui);
data->stop = false;
+
// allow the main thread to continue, we are ready to start handling UI
// callbacks
CONTINUE(bridge);
@@ -418,15 +439,83 @@ static void clear_region(UI *ui, int top, int bot, int left, int right)
unibi_goto(ui, grid->row, grid->col);
}
+static bool can_use_scroll(UI * ui)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+
+ return data->scroll_region_is_full_screen
+ || (data->can_change_scroll_region
+ && ((grid->left == 0 && grid->right == ui->width - 1)
+ || data->can_set_lr_margin
+ || data->can_set_left_right_margin));
+}
+
+static void set_scroll_region(UI *ui)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+
+ data->params[0].i = grid->top;
+ data->params[1].i = grid->bot;
+ unibi_out(ui, unibi_change_scroll_region);
+ if (grid->left != 0 || grid->right != ui->width - 1) {
+ unibi_out(ui, data->unibi_ext.enable_lr_margin);
+ if (data->can_set_lr_margin) {
+ data->params[0].i = grid->left;
+ data->params[1].i = grid->right;
+ unibi_out(ui, unibi_set_lr_margin);
+ } else {
+ data->params[0].i = grid->left;
+ unibi_out(ui, unibi_set_left_margin_parm);
+ data->params[0].i = grid->right;
+ unibi_out(ui, unibi_set_right_margin_parm);
+ }
+ }
+ unibi_goto(ui, grid->row, grid->col);
+}
+
+static void reset_scroll_region(UI *ui)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+
+ if (0 <= data->unibi_ext.reset_scroll_region) {
+ unibi_out(ui, data->unibi_ext.reset_scroll_region);
+ } else {
+ data->params[0].i = 0;
+ data->params[1].i = ui->height - 1;
+ unibi_out(ui, unibi_change_scroll_region);
+ }
+ if (grid->left != 0 || grid->right != ui->width - 1) {
+ if (data->can_set_lr_margin) {
+ data->params[0].i = 0;
+ data->params[1].i = ui->width - 1;
+ unibi_out(ui, unibi_set_lr_margin);
+ } else {
+ data->params[0].i = 0;
+ unibi_out(ui, unibi_set_left_margin_parm);
+ data->params[0].i = ui->width - 1;
+ unibi_out(ui, unibi_set_right_margin_parm);
+ }
+ unibi_out(ui, data->unibi_ext.disable_lr_margin);
+ }
+ unibi_goto(ui, grid->row, grid->col);
+}
+
static void tui_resize(UI *ui, Integer width, Integer height)
{
TUIData *data = ui->data;
ugrid_resize(&data->grid, (int)width, (int)height);
if (!got_winch) { // Try to resize the terminal window.
- char r[16]; // enough for 9999x9999
- snprintf(r, sizeof(r), "\x1b[8;%d;%dt", (int)height, (int)width);
- out(ui, r, strlen(r));
+ data->params[0].i = (int)height;
+ data->params[1].i = (int)width;
+ unibi_out(ui, data->unibi_ext.resize_screen);
+ // DECSLPP does not reset the scroll region.
+ if (data->scroll_region_is_full_screen) {
+ reset_scroll_region(ui);
+ }
} else { // Already handled the SIGWINCH signal; avoid double-resize.
got_winch = false;
}
@@ -613,10 +702,9 @@ static void tui_set_scroll_region(UI *ui, Integer top, Integer bot,
TUIData *data = ui->data;
ugrid_set_scroll_region(&data->grid, (int)top, (int)bot,
(int)left, (int)right);
- data->can_use_terminal_scroll =
+ data->scroll_region_is_full_screen =
left == 0 && right == ui->width - 1
- && ((top == 0 && bot == ui->height - 1)
- || unibi_get_str(data->ut, unibi_change_scroll_region));
+ && top == 0 && bot == ui->height - 1;
}
static void tui_scroll(UI *ui, Integer count)
@@ -626,31 +714,31 @@ static void tui_scroll(UI *ui, Integer count)
int clear_top, clear_bot;
ugrid_scroll(grid, (int)count, &clear_top, &clear_bot);
- if (data->can_use_terminal_scroll) {
+ if (can_use_scroll(ui)) {
+ bool scroll_clears_to_current_colour =
+ unibi_get_bool(data->ut, unibi_back_color_erase);
+
// Change terminal scroll region and move cursor to the top
- data->params[0].i = grid->top;
- data->params[1].i = grid->bot;
- unibi_out(ui, unibi_change_scroll_region);
+ if (!data->scroll_region_is_full_screen) {
+ set_scroll_region(ui);
+ }
unibi_goto(ui, grid->top, grid->left);
// also set default color attributes or some terminals can become funny
- HlAttrs clear_attrs = EMPTY_ATTRS;
- clear_attrs.foreground = grid->fg;
- clear_attrs.background = grid->bg;
- update_attrs(ui, clear_attrs);
- }
+ if (scroll_clears_to_current_colour) {
+ HlAttrs clear_attrs = EMPTY_ATTRS;
+ clear_attrs.foreground = grid->fg;
+ clear_attrs.background = grid->bg;
+ update_attrs(ui, clear_attrs);
+ }
- if (count > 0) {
- if (data->can_use_terminal_scroll) {
+ if (count > 0) {
if (count == 1) {
unibi_out(ui, unibi_delete_line);
} else {
data->params[0].i = (int)count;
unibi_out(ui, unibi_parm_delete_line);
}
- }
-
- } else {
- if (data->can_use_terminal_scroll) {
+ } else {
if (count == -1) {
unibi_out(ui, unibi_insert_line);
} else {
@@ -658,20 +746,16 @@ static void tui_scroll(UI *ui, Integer count)
unibi_out(ui, unibi_parm_insert_line);
}
}
- }
- if (data->can_use_terminal_scroll) {
// Restore terminal scroll region and cursor
- data->params[0].i = 0;
- data->params[1].i = ui->height - 1;
- unibi_out(ui, unibi_change_scroll_region);
+ if (!data->scroll_region_is_full_screen) {
+ reset_scroll_region(ui);
+ }
unibi_goto(ui, grid->row, grid->col);
- if (grid->bg != -1) {
- // Update the cleared area of the terminal if its builtin scrolling
- // facility was used and the background color is not the default. This is
- // required because scrolling may leave wrong background in the cleared
- // area.
+ if (!scroll_clears_to_current_colour) {
+ // This is required because scrolling will leave wrong background in the
+ // cleared area on non-bge terminals.
clear_region(ui, clear_top, clear_bot, grid->left, grid->right);
}
} else {
@@ -956,6 +1040,15 @@ static TermType detect_term(const char *term, const char *colorterm)
if (colorterm && strstr(colorterm, "gnome-terminal")) {
return kTermGnome;
}
+ if (STARTS_WITH(term, "xterm")) {
+ return kTermXTerm;
+ }
+ if (STARTS_WITH(term, "dtterm")) {
+ return kTermDTTerm;
+ }
+ if (STARTS_WITH(term, "teraterm")) {
+ return kTermTeraTerm;
+ }
return kTermUnknown;
}
@@ -976,14 +1069,14 @@ static void fix_terminfo(TUIData *data)
unibi_set_if_empty(ut, unibi_flash_screen, "\x1b[?5h$<20/>\x1b[?5l");
unibi_set_if_empty(ut, unibi_enter_italics_mode, "\x1b[3m");
unibi_set_if_empty(ut, unibi_to_status_line, "\x1b]2");
- } else if (STARTS_WITH(term, "xterm")) {
+ } else if (data->term == kTermXTerm) {
unibi_set_if_empty(ut, unibi_to_status_line, "\x1b]0;");
} else if (STARTS_WITH(term, "screen") || STARTS_WITH(term, "tmux")) {
unibi_set_if_empty(ut, unibi_to_status_line, "\x1b_");
unibi_set_if_empty(ut, unibi_from_status_line, "\x1b\\");
}
- if (STARTS_WITH(term, "xterm") || data->term == kTermRxvt) {
+ if (data->term == kTermXTerm || data->term == kTermRxvt) {
const char *normal = unibi_get_str(ut, unibi_cursor_normal);
if (!normal) {
unibi_set_str(ut, unibi_cursor_normal, "\x1b[?25h");
@@ -997,11 +1090,21 @@ static void fix_terminfo(TUIData *data)
unibi_set_if_empty(ut, unibi_cursor_invisible, "\x1b[?25l");
unibi_set_if_empty(ut, unibi_flash_screen, "\x1b[?5h$<100/>\x1b[?5l");
unibi_set_if_empty(ut, unibi_exit_attribute_mode, "\x1b(B\x1b[m");
+ unibi_set_if_empty(ut, unibi_set_tb_margin, "\x1b[%i%p1%d;%p2%dr");
+ unibi_set_if_empty(ut, unibi_set_lr_margin, "\x1b[%i%p1%d;%p2%ds");
+ unibi_set_if_empty(ut, unibi_set_left_margin_parm, "\x1b[%i%p1%ds");
+ unibi_set_if_empty(ut, unibi_set_right_margin_parm, "\x1b[%i;%p2%ds");
unibi_set_if_empty(ut, unibi_change_scroll_region, "\x1b[%i%p1%d;%p2%dr");
unibi_set_if_empty(ut, unibi_clear_screen, "\x1b[H\x1b[2J");
unibi_set_if_empty(ut, unibi_from_status_line, "\x07");
+ unibi_set_bool(ut, unibi_back_color_erase, true);
}
+ data->unibi_ext.enable_lr_margin = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[?69h");
+ data->unibi_ext.disable_lr_margin = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[?69l");
+
data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str(ut, NULL,
"\x1b[?2004h");
data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str(ut, NULL,
@@ -1028,6 +1131,21 @@ static void fix_terminfo(TUIData *data)
unibi_set_str(ut, unibi_set_a_background, XTERM_SETAB);
}
+ // Only define this capability for terminal types that we know understand it.
+ if (data->term == kTermDTTerm // originated this extension
+ || data->term == kTermXTerm // per xterm ctlseqs doc
+ || data->term == kTermKonsole // per commentary in VT102Emulation.cpp
+ || data->term == kTermTeraTerm // per "Supported Control Functions" doc
+ || data->term == kTermRxvt) { // per command.C
+ data->unibi_ext.resize_screen = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[8;%p1%d;%p2%dt");
+ }
+
+ if (data->term == kTermXTerm || data->term == kTermRxvt) {
+ data->unibi_ext.reset_scroll_region = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[r");
+ }
+
end:
// Fill some empty slots with common terminal strings
if (data->term == kTermiTerm) {