terminal: implement IL/DL in vga terminal; experiment with scrollable regions
This commit is contained in:
parent
a6d9b7c320
commit
1abba60e76
57
apps/bim.c
57
apps/bim.c
@ -1,9 +1,9 @@
|
||||
/**
|
||||
* This is a baked, single-file version of bim.
|
||||
* It was built Tue Dec 17 13:18:29 2019
|
||||
* It is based on git commit 2f4da2036745c3f1b7d532988f346abcca0e59eb
|
||||
* It was built Thu Dec 19 13:41:35 2019
|
||||
* It is based on git commit 8860761a4e0906246a38f41939551fe7ed050c5b
|
||||
*/
|
||||
#define GIT_TAG "2f4da20-baked"
|
||||
#define GIT_TAG "8860761-baked"
|
||||
/* Bim - A Text Editor
|
||||
*
|
||||
* Copyright (C) 2012-2019 K. Lange
|
||||
@ -197,6 +197,7 @@ typedef struct {
|
||||
unsigned int can_24bit:1;
|
||||
unsigned int can_256color:1;
|
||||
unsigned int can_italic:1;
|
||||
unsigned int can_insert:1;
|
||||
unsigned int history_enabled:1;
|
||||
unsigned int highlight_parens:1;
|
||||
unsigned int smart_case:1;
|
||||
@ -639,6 +640,7 @@ global_config_t global_config = {
|
||||
.can_24bit = 1, /* can use 24-bit color */
|
||||
.can_256color = 1, /* can use 265 colors */
|
||||
.can_italic = 1, /* can use italics (without inverting) */
|
||||
.can_insert = 0, /* ^[[L */
|
||||
/* Configuration options */
|
||||
.history_enabled = 1,
|
||||
.highlight_parens = 1, /* highlight parens/braces when cursor moves */
|
||||
@ -2396,6 +2398,16 @@ void shift_down(int amount) {
|
||||
printf("\033[%dT", amount);
|
||||
}
|
||||
|
||||
void insert_lines_at(int line, int count) {
|
||||
place_cursor(1, line);
|
||||
printf("\033[%dL", count);
|
||||
}
|
||||
|
||||
void delete_lines_at(int line, int count) {
|
||||
place_cursor(1, line);
|
||||
printf("\033[%dM", count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch to the alternate terminal screen.
|
||||
*/
|
||||
@ -4507,7 +4519,12 @@ BIM_ACTION(cursor_down, 0,
|
||||
|
||||
/* Tell terminal to scroll */
|
||||
if (global_config.can_scroll && !left_buffer) {
|
||||
shift_up(1);
|
||||
if (!global_config.can_insert) {
|
||||
shift_up(1);
|
||||
redraw_tabbar();
|
||||
} else {
|
||||
delete_lines_at(global_config.tabs_visible ? 2 : 1, 1);
|
||||
}
|
||||
|
||||
/* A new line appears on screen at the bottom, draw it */
|
||||
int l = global_config.term_height - global_config.bottom_size - global_config.tabs_visible;
|
||||
@ -4519,7 +4536,6 @@ BIM_ACTION(cursor_down, 0,
|
||||
} else {
|
||||
redraw_text();
|
||||
}
|
||||
redraw_tabbar();
|
||||
redraw_statusbar();
|
||||
redraw_commandline();
|
||||
place_cursor_actual();
|
||||
@ -4593,7 +4609,12 @@ BIM_ACTION(cursor_up, 0,
|
||||
|
||||
/* Tell terminal to scroll */
|
||||
if (global_config.can_scroll && !left_buffer) {
|
||||
shift_down(1);
|
||||
if (!global_config.can_insert) {
|
||||
shift_down(1);
|
||||
redraw_tabbar();
|
||||
} else {
|
||||
insert_lines_at(global_config.tabs_visible ? 2 : 1, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* The line at the top of the screen should always be real
|
||||
@ -4601,9 +4622,9 @@ BIM_ACTION(cursor_up, 0,
|
||||
*/
|
||||
redraw_line(env->offset);
|
||||
} else {
|
||||
redraw_tabbar();
|
||||
redraw_text();
|
||||
}
|
||||
redraw_tabbar();
|
||||
redraw_statusbar();
|
||||
redraw_commandline();
|
||||
place_cursor_actual();
|
||||
@ -7058,14 +7079,19 @@ void handle_common_mouse(int buttons, int x, int y) {
|
||||
env->loading = 0;
|
||||
if (!shifted) return;
|
||||
if (global_config.can_scroll && !left_buffer) {
|
||||
shift_down(shifted);
|
||||
if (!global_config.can_insert) {
|
||||
shift_down(shifted);
|
||||
redraw_tabbar();
|
||||
} else {
|
||||
insert_lines_at(global_config.tabs_visible ? 2 : 1, shifted);
|
||||
}
|
||||
for (int i = 0; i < shifted; ++i) {
|
||||
redraw_line(env->offset+i);
|
||||
}
|
||||
} else {
|
||||
redraw_tabbar();
|
||||
redraw_text();
|
||||
}
|
||||
redraw_tabbar();
|
||||
redraw_statusbar();
|
||||
redraw_commandline();
|
||||
place_cursor_actual();
|
||||
@ -7093,7 +7119,12 @@ void handle_common_mouse(int buttons, int x, int y) {
|
||||
env->loading = 0;
|
||||
if (!shifted) return;
|
||||
if (global_config.can_scroll && !left_buffer) {
|
||||
shift_up(shifted);
|
||||
if (!global_config.can_insert) {
|
||||
shift_up(shifted);
|
||||
redraw_tabbar();
|
||||
} else {
|
||||
delete_lines_at(global_config.tabs_visible ? 2 : 1, shifted);
|
||||
}
|
||||
int l = global_config.term_height - global_config.bottom_size - global_config.tabs_visible;
|
||||
for (int i = 0; i < shifted; ++i) {
|
||||
if (env->offset + l - i < env->line_count + 1) {
|
||||
@ -7103,9 +7134,9 @@ void handle_common_mouse(int buttons, int x, int y) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
redraw_tabbar();
|
||||
redraw_text();
|
||||
}
|
||||
redraw_tabbar();
|
||||
redraw_statusbar();
|
||||
redraw_commandline();
|
||||
place_cursor_actual();
|
||||
@ -10258,6 +10289,10 @@ void detect_weird_terminals(void) {
|
||||
if (term && strstr(term,"toaru-vga") == term) {
|
||||
global_config.can_24bit = 0; /* Also not strictly true */
|
||||
global_config.can_256color = 0; /* Not strictly true */
|
||||
global_config.can_insert = 1;
|
||||
}
|
||||
if (term && strstr(term,"xterm-256color") == term) {
|
||||
global_config.can_insert = 1;
|
||||
}
|
||||
|
||||
if (!global_config.can_unicode) {
|
||||
|
@ -503,32 +503,57 @@ void term_redraw_all() {
|
||||
}
|
||||
}
|
||||
|
||||
void term_scroll(int how_much) {
|
||||
if (how_much >= term_height || -how_much >= term_height) {
|
||||
term_clear();
|
||||
return;
|
||||
void term_shift_region(int top, int height, int how_much) {
|
||||
if (how_much == 0) return;
|
||||
|
||||
void * destination, * source;
|
||||
int count, new_top, new_bottom;
|
||||
if (how_much > height) {
|
||||
count = 0;
|
||||
new_top = top;
|
||||
new_bottom = top + height;
|
||||
} else if (how_much > 0) {
|
||||
destination = term_buffer + term_width * top;
|
||||
source = term_buffer + term_width * (top + how_much);
|
||||
count = height - how_much;
|
||||
new_top = top + height - how_much;
|
||||
new_bottom = top + height;
|
||||
} else if (how_much < 0) {
|
||||
destination = term_buffer + term_width * (top - how_much);
|
||||
source = term_buffer + term_width * top;
|
||||
count = height + how_much;
|
||||
new_top = top;
|
||||
new_bottom = top - how_much;
|
||||
}
|
||||
if (how_much == 0) {
|
||||
return;
|
||||
|
||||
/* Move from top+how_much to top */
|
||||
if (count) {
|
||||
memmove(destination, source, count * term_width * sizeof(term_cell_t));
|
||||
|
||||
}
|
||||
if (how_much > 0) {
|
||||
/* Shift terminal cells one row up */
|
||||
memmove(term_buffer, (void *)((uintptr_t)term_buffer + sizeof(term_cell_t) * term_width * how_much), sizeof(term_cell_t) * term_width * (term_height - how_much));
|
||||
/* Reset the "new" row to clean cells */
|
||||
memset((void *)((uintptr_t)term_buffer + sizeof(term_cell_t) * term_width * (term_height - how_much)), 0x0, sizeof(term_cell_t) * term_width * how_much);
|
||||
for (int i = 0; i < how_much; ++i) {
|
||||
for (uint16_t x = 0; x < term_width; ++x) {
|
||||
cell_set(x,term_height - how_much,' ', current_fg, current_bg, ansi_state->flags);
|
||||
}
|
||||
|
||||
/* Clear new lines at bottom */
|
||||
for (int i = new_top; i < new_bottom; ++i) {
|
||||
for (uint16_t x = 0; x < term_width; ++x) {
|
||||
cell_set(x, i, ' ', current_fg, current_bg, ansi_state->flags);
|
||||
}
|
||||
term_redraw_all();
|
||||
}
|
||||
|
||||
term_redraw_all();
|
||||
}
|
||||
|
||||
void term_scroll(int how_much) {
|
||||
term_shift_region(0,term_height,how_much);
|
||||
}
|
||||
|
||||
void insert_delete_lines(int how_many) {
|
||||
if (how_many == 0) return;
|
||||
|
||||
if (how_many > 0) {
|
||||
/* Insert lines is equivalent to scrolling from the current line */
|
||||
term_shift_region(csr_y,term_height-csr_y,-how_many);
|
||||
} else {
|
||||
how_much = -how_much;
|
||||
/* Shift terminal cells one row up */
|
||||
memmove((void *)((uintptr_t)term_buffer + sizeof(term_cell_t) * term_width * how_much), term_buffer, sizeof(term_cell_t) * term_width * (term_height - how_much));
|
||||
/* Reset the "new" row to clean cells */
|
||||
memset(term_buffer, 0x0, sizeof(term_cell_t) * term_width * how_much);
|
||||
term_redraw_all();
|
||||
term_shift_region(csr_y,term_height-csr_y,-how_many);
|
||||
}
|
||||
}
|
||||
|
||||
@ -910,6 +935,7 @@ term_callbacks_t term_callbacks = {
|
||||
unsupported_int,
|
||||
term_set_csr_show,
|
||||
term_switch_buffer,
|
||||
insert_delete_lines,
|
||||
};
|
||||
|
||||
void reinit(void) {
|
||||
|
@ -37,6 +37,7 @@ typedef struct {
|
||||
int (*get_cell_height)(void);
|
||||
void (*set_csr_on)(int);
|
||||
void (*switch_buffer)(int);
|
||||
void (*insert_delete_lines)(int);
|
||||
} term_callbacks_t;
|
||||
|
||||
typedef struct {
|
||||
@ -90,6 +91,8 @@ typedef struct {
|
||||
#define ANSI_RCP 'u' /* Restore Cursor Position */
|
||||
#define ANSI_HIDE 'l' /* DECTCEM - Hide Cursor */
|
||||
#define ANSI_SHOW 'h' /* DECTCEM - Show Cursor */
|
||||
#define ANSI_IL 'L' /* Insert Line(s) */
|
||||
#define ANSI_DL 'M' /* Delete Line(s) */
|
||||
/* Display flags */
|
||||
#define ANSI_BOLD 0x01
|
||||
#define ANSI_UNDERLINE 0x02
|
||||
|
@ -450,6 +450,24 @@ static void _ansi_put(term_state_t * s, char c) {
|
||||
callbacks->scroll(-how_many);
|
||||
}
|
||||
break;
|
||||
case ANSI_IL:
|
||||
{
|
||||
int how_many = 1;
|
||||
if (argc > 0) {
|
||||
how_many = atoi(argv[0]);
|
||||
}
|
||||
callbacks->insert_delete_lines(how_many);
|
||||
}
|
||||
break;
|
||||
case ANSI_DL:
|
||||
{
|
||||
int how_many = 1;
|
||||
if (argc > 0) {
|
||||
how_many = atoi(argv[0]);
|
||||
}
|
||||
callbacks->insert_delete_lines(-how_many);
|
||||
}
|
||||
break;
|
||||
case 'X':
|
||||
{
|
||||
int how_many = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user