mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 09:09:03 -04:00
[ncplane_put] admit tab characters #1233
This commit is contained in:
parent
b326d43885
commit
7c8cf1e6e8
@ -2165,8 +2165,9 @@ ncplane_putc(struct ncplane* n, const nccell* c){
|
||||
}
|
||||
|
||||
// Replace the cell at the specified coordinates with the provided 7-bit char
|
||||
// 'c'. Advance the cursor by 1. On success, returns 1. On failure, returns -1.
|
||||
// This works whether the underlying char is signed or unsigned.
|
||||
// 'c'. Advance the cursor by 1. On success, returns the number of columns the
|
||||
// cursor was advanced. On failure, returns -1. This works whether the
|
||||
// underlying char is signed or unsigned.
|
||||
static inline int
|
||||
ncplane_putchar_yx(struct ncplane* n, int y, int x, char c){
|
||||
nccell ce = NCCELL_INITIALIZER((uint32_t)c, ncplane_styles(n), ncplane_channels(n));
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "banner.h"
|
||||
|
||||
#define ESC "\x1b"
|
||||
#define TABSTOP 8
|
||||
|
||||
void notcurses_version_components(int* major, int* minor, int* patch, int* tweak){
|
||||
*major = NOTCURSES_VERNUM_MAJOR;
|
||||
@ -1858,8 +1859,6 @@ ncplane_put(ncplane* n, int y, int x, const char* egc, int cols,
|
||||
}
|
||||
if(*egc == '\n'){
|
||||
scroll_down(n);
|
||||
}else if(*egc == '\t'){
|
||||
// FIXME do what, exactly?
|
||||
}
|
||||
// A wide character obliterates anything to its immediate right (and marks
|
||||
// that cell as wide). Any character placed atop one cell of a wide character
|
||||
@ -1884,13 +1883,30 @@ ncplane_put(ncplane* n, int y, int x, const char* egc, int cols,
|
||||
}
|
||||
targ->stylemask = stylemask;
|
||||
targ->channels = channels;
|
||||
if(cell_load_direct(n, targ, egc, bytes, cols) < 0){
|
||||
return -1;
|
||||
// tabs get replaced with spaces, up to the next tab stop. we always try to
|
||||
// write at least one. if there are no more tabstops on the current line, if
|
||||
// autogrowing to the right, extend as necessary. otherwise, if scrolling,
|
||||
// move to the next line. otherwise, simply fill any spaces we can. this has
|
||||
// already taken place by the time we get here, if it ought have happened.
|
||||
if(*egc == '\t'){
|
||||
if(n->x >= n->lenx){
|
||||
if(!n->scrolling && n->autogrow){
|
||||
// FIXME might need autogrow to the next tab stop out
|
||||
}
|
||||
}
|
||||
if(cell_load_direct(n, targ, egc, bytes, cols) < 0){
|
||||
return -1;
|
||||
}
|
||||
cols = (n->x + TABSTOP) / TABSTOP * TABSTOP;
|
||||
}else{
|
||||
if(cell_load_direct(n, targ, egc, bytes, cols) < 0){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
//fprintf(stderr, "%08x %016lx %c %d %d\n", targ->gcluster, targ->channels, nccell_double_wide_p(targ) ? 'D' : 'd', bytes, cols);
|
||||
// must set our right hand sides wide, and check for further damage
|
||||
if(*egc != '\n'){
|
||||
++n->x;
|
||||
// if wide, set our right hand columns wide, and check for further damage
|
||||
for(int i = 1 ; i < cols ; ++i){
|
||||
nccell* candidate = &n->fb[nfbcellidx(n, n->y, n->x)];
|
||||
int off = nccell_cols(candidate);
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <cstdlib>
|
||||
#include "main.h"
|
||||
|
||||
constexpr int TABWIDTH = 8;
|
||||
|
||||
TEST_CASE("TaBs") { // refreshing and delicious
|
||||
auto nc_ = testing_notcurses();
|
||||
if(!nc_){
|
||||
@ -15,10 +17,31 @@ TEST_CASE("TaBs") { // refreshing and delicious
|
||||
nopts.cols = 80;
|
||||
auto n = ncplane_create(n_, &nopts);
|
||||
unsigned y, x;
|
||||
CHECK(1 == ncplane_putchar(n, '\t'));
|
||||
CHECK(TABWIDTH == ncplane_putchar(n, '\t'));
|
||||
ncplane_cursor_yx(n, &y, &x);
|
||||
CHECK(y == 0);
|
||||
CHECK(x == 8);
|
||||
CHECK(x == TABWIDTH);
|
||||
for(unsigned i = 0 ; i < x ; ++i){
|
||||
char* c = ncplane_at_yx(n, 0, i, nullptr, nullptr);
|
||||
REQUIRE(c);
|
||||
CHECK(0 == strcmp(c, " "));
|
||||
free(c);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("PutXoffsetTaBs") {
|
||||
struct ncplane_options nopts{};
|
||||
nopts.rows = 2;
|
||||
nopts.cols = TABWIDTH;
|
||||
auto n = ncplane_create(n_, &nopts);
|
||||
unsigned y, x;
|
||||
for(int i = 0 ; i < TABWIDTH ; ++i){
|
||||
CHECK(TABWIDTH - i == ncplane_putchar(n, '\t'));
|
||||
ncplane_cursor_yx(n, &y, &x);
|
||||
CHECK(y == 0);
|
||||
CHECK(x == TABWIDTH - i);
|
||||
CHECK(0 == ncplane_cursor_move_yx(n, 0, i + 1));
|
||||
}
|
||||
for(unsigned i = 0 ; i < x ; ++i){
|
||||
char* c = ncplane_at_yx(n, 0, i, nullptr, nullptr);
|
||||
REQUIRE(c);
|
||||
@ -30,13 +53,13 @@ TEST_CASE("TaBs") { // refreshing and delicious
|
||||
SUBCASE("PutwcTaB") {
|
||||
struct ncplane_options nopts{};
|
||||
nopts.rows = 2;
|
||||
nopts.cols = 80;
|
||||
nopts.cols = TABWIDTH;
|
||||
auto n = ncplane_create(n_, &nopts);
|
||||
unsigned y, x;
|
||||
CHECK(1 == ncplane_putwc(n, L'\t'));
|
||||
CHECK(TABWIDTH == ncplane_putwc(n, L'\t'));
|
||||
ncplane_cursor_yx(n, &y, &x);
|
||||
CHECK(y == 0);
|
||||
CHECK(x == 8);
|
||||
CHECK(x == TABWIDTH);
|
||||
for(unsigned i = 0 ; i < x ; ++i){
|
||||
char* c = ncplane_at_yx(n, 0, i, nullptr, nullptr);
|
||||
REQUIRE(c);
|
||||
@ -48,14 +71,14 @@ TEST_CASE("TaBs") { // refreshing and delicious
|
||||
SUBCASE("PutCellTaB") {
|
||||
struct ncplane_options nopts{};
|
||||
nopts.rows = 2;
|
||||
nopts.cols = 80;
|
||||
nopts.cols = TABWIDTH;
|
||||
auto n = ncplane_create(n_, &nopts);
|
||||
nccell c = NCCELL_CHAR_INITIALIZER('\t');
|
||||
unsigned y, x;
|
||||
CHECK(1 == ncplane_putc(n, &c));
|
||||
ncplane_cursor_yx(n, &y, &x);
|
||||
CHECK(y == 0);
|
||||
CHECK(x == 8);
|
||||
CHECK(x == TABWIDTH);
|
||||
for(unsigned i = 0 ; i < x ; ++i){
|
||||
char* s = ncplane_at_yx(n, 0, i, nullptr, nullptr);
|
||||
REQUIRE(s);
|
||||
@ -67,7 +90,7 @@ TEST_CASE("TaBs") { // refreshing and delicious
|
||||
SUBCASE("PutMultipleTaBs") {
|
||||
struct ncplane_options nopts{};
|
||||
nopts.rows = 2;
|
||||
nopts.cols = 80;
|
||||
nopts.cols = TABWIDTH;
|
||||
auto n = ncplane_create(n_, &nopts);
|
||||
unsigned y, x;
|
||||
CHECK(1 == ncplane_putstr(n, "\t\t"));
|
||||
@ -85,7 +108,7 @@ TEST_CASE("TaBs") { // refreshing and delicious
|
||||
SUBCASE("PutRowOfTaBs") {
|
||||
struct ncplane_options nopts{};
|
||||
nopts.rows = 2;
|
||||
nopts.cols = 80;
|
||||
nopts.cols = TABWIDTH;
|
||||
auto n = ncplane_create(n_, &nopts);
|
||||
unsigned y, x;
|
||||
CHECK(1 == ncplane_putstr(n, "\t\t\t\t\t\t\t\t\t\t"));
|
||||
|
Loading…
x
Reference in New Issue
Block a user