Implement tab setting/resetting.
This commit is contained in:
parent
8019063214
commit
8f0be20b35
@ -47,6 +47,14 @@
|
|||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of custom tab stops.
|
||||||
|
*/
|
||||||
|
#define GUAC_TERMINAL_MAX_TABS 16
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of rows to scroll per scroll wheel event.
|
||||||
|
*/
|
||||||
#define GUAC_SSH_WHEEL_SCROLL_AMOUNT 3
|
#define GUAC_SSH_WHEEL_SCROLL_AMOUNT 3
|
||||||
|
|
||||||
typedef struct guac_terminal guac_terminal;
|
typedef struct guac_terminal guac_terminal;
|
||||||
@ -179,6 +187,18 @@ struct guac_terminal {
|
|||||||
*/
|
*/
|
||||||
guac_terminal_buffer* buffer;
|
guac_terminal_buffer* buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically place a tabstop every N characters. If zero, then no
|
||||||
|
* tabstops exist automatically.
|
||||||
|
*/
|
||||||
|
int tab_interval;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of all tabs set. Each entry is the column number of a tab + 1,
|
||||||
|
* or 0 if that tab cell is unset.
|
||||||
|
*/
|
||||||
|
int custom_tabs[GUAC_TERMINAL_MAX_TABS];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array of arrays of mapped characters, where the character N is located at the N-32
|
* Array of arrays of mapped characters, where the character N is located at the N-32
|
||||||
* position within the array. Each element in a contained array is the corresponding Unicode
|
* position within the array. Each element in a contained array is the corresponding Unicode
|
||||||
@ -374,5 +394,26 @@ int guac_terminal_send_string(guac_terminal* term, const char* data);
|
|||||||
*/
|
*/
|
||||||
int guac_terminal_sendf(guac_terminal* term, const char* format, ...);
|
int guac_terminal_sendf(guac_terminal* term, const char* format, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a tabstop in the given column.
|
||||||
|
*/
|
||||||
|
void guac_terminal_set_tab(guac_terminal* term, int column);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the tabstop at the given column.
|
||||||
|
*/
|
||||||
|
void guac_terminal_unset_tab(guac_terminal* term, int column);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all tabstops.
|
||||||
|
*/
|
||||||
|
void guac_terminal_clear_tabs(guac_terminal* term);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a column within the given terminal, returns the location of the
|
||||||
|
* next tabstop (or the rightmost character, if no more tabstops exist).
|
||||||
|
*/
|
||||||
|
int guac_terminal_next_tab(guac_terminal* term, int column);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -83,6 +83,10 @@ void guac_terminal_reset(guac_terminal* term) {
|
|||||||
term->automatic_carriage_return = false;
|
term->automatic_carriage_return = false;
|
||||||
term->insert_mode = false;
|
term->insert_mode = false;
|
||||||
|
|
||||||
|
/* Reset tabs */
|
||||||
|
term->tab_interval = 8;
|
||||||
|
memset(term->custom_tabs, 0, sizeof(term->custom_tabs));
|
||||||
|
|
||||||
/* Clear terminal */
|
/* Clear terminal */
|
||||||
for (row=0; row<term->term_height; row++)
|
for (row=0; row<term->term_height; row++)
|
||||||
guac_terminal_set_columns(term, row, 0, term->term_width, &(term->default_char));
|
guac_terminal_set_columns(term, row, 0, term->term_width, &(term->default_char));
|
||||||
@ -787,4 +791,66 @@ int guac_terminal_sendf(guac_terminal* term, const char* format, ...) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void guac_terminal_set_tab(guac_terminal* term, int column) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Search for available space, set if available */
|
||||||
|
for (i=0; i<GUAC_TERMINAL_MAX_TABS; i++) {
|
||||||
|
|
||||||
|
/* Set tab if space free */
|
||||||
|
if (term->custom_tabs[i] == 0) {
|
||||||
|
term->custom_tabs[i] = column+1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void guac_terminal_unset_tab(guac_terminal* term, int column) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Search for given tab, unset if found */
|
||||||
|
for (i=0; i<GUAC_TERMINAL_MAX_TABS; i++) {
|
||||||
|
|
||||||
|
/* Unset tab if found */
|
||||||
|
if (term->custom_tabs[i] == column+1) {
|
||||||
|
term->custom_tabs[i] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void guac_terminal_clear_tabs(guac_terminal* term) {
|
||||||
|
term->tab_interval = 0;
|
||||||
|
memset(term->custom_tabs, 0, sizeof(term->custom_tabs));
|
||||||
|
}
|
||||||
|
|
||||||
|
int guac_terminal_next_tab(guac_terminal* term, int column) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Determine tab stop from interval */
|
||||||
|
int tabstop;
|
||||||
|
if (term->tab_interval != 0)
|
||||||
|
tabstop = (column / term->tab_interval + 1) * term->tab_interval;
|
||||||
|
else
|
||||||
|
tabstop = term->term_width - 1;
|
||||||
|
|
||||||
|
/* Walk custom tabs, trying to find an earlier occurrence */
|
||||||
|
for (i=0; i<GUAC_TERMINAL_MAX_TABS; i++) {
|
||||||
|
|
||||||
|
int custom_tabstop = term->custom_tabs[i] - 1;
|
||||||
|
if (custom_tabstop != -1 && custom_tabstop > column && custom_tabstop < tabstop)
|
||||||
|
tabstop = custom_tabstop;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return tabstop;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,6 +127,11 @@ int guac_terminal_echo(guac_terminal* term, char c) {
|
|||||||
term->cursor_col--;
|
term->cursor_col--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Tab */
|
||||||
|
case 0x09:
|
||||||
|
term->cursor_col = guac_terminal_next_tab(term, term->cursor_col);
|
||||||
|
break;
|
||||||
|
|
||||||
/* Line feed / VT / FF */
|
/* Line feed / VT / FF */
|
||||||
case '\n':
|
case '\n':
|
||||||
case 0x0B: /* VT */
|
case 0x0B: /* VT */
|
||||||
@ -304,6 +309,11 @@ int guac_terminal_escape(guac_terminal* term, char c) {
|
|||||||
term->char_handler = guac_terminal_echo;
|
term->char_handler = guac_terminal_echo;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Set Tab (HTS) */
|
||||||
|
case 'H':
|
||||||
|
guac_terminal_set_tab(term, term->cursor_col);
|
||||||
|
break;
|
||||||
|
|
||||||
/* Reverse Linefeed */
|
/* Reverse Linefeed */
|
||||||
case 'M':
|
case 'M':
|
||||||
|
|
||||||
@ -685,6 +695,19 @@ int guac_terminal_csi(guac_terminal* term, char c) {
|
|||||||
term->cursor_row = row;
|
term->cursor_row = row;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* g: Clear tab */
|
||||||
|
case 'g':
|
||||||
|
|
||||||
|
/* Clear tab at current location */
|
||||||
|
if (argv[0] == 0)
|
||||||
|
guac_terminal_unset_tab(term, term->cursor_col);
|
||||||
|
|
||||||
|
/* Clear all tabs */
|
||||||
|
else if (argv[0] == 3)
|
||||||
|
guac_terminal_clear_tabs(term);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
/* h: Set Mode */
|
/* h: Set Mode */
|
||||||
case 'h':
|
case 'h':
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user