mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
ncreader: conform to the New Way #627
This commit is contained in:
parent
8f089bc017
commit
c3e5e47a2a
8
NEWS.md
8
NEWS.md
@ -10,10 +10,14 @@ rearrangements of Notcurses.
|
|||||||
of the provided `ncplane`. On an error in these functions, the `ncplane`
|
of the provided `ncplane`. On an error in these functions, the `ncplane`
|
||||||
will be destroyed. Otherwise, the `ncplane` is destroyed by
|
will be destroyed. Otherwise, the `ncplane` is destroyed by
|
||||||
`ncselector_destroy()` or `ncmultiselector_destroy()`.
|
`ncselector_destroy()` or `ncmultiselector_destroy()`.
|
||||||
* `ncselector_create()` and `ncmultiselector_create()` no longer accept
|
* `ncselector_create()`, `ncmultiselector_create()`, and
|
||||||
`int y, int x` placement parameters. Just place the `ncplane`.
|
`ncreader_create()` no longer accept `int y, int x` placement
|
||||||
|
parameters. Just place the `ncplane`.
|
||||||
* `ncselector_options` and `ncmultiselector_options` have lost their
|
* `ncselector_options` and `ncmultiselector_options` have lost their
|
||||||
`bgchannels` members. Just set the base character for the `ncplane`.
|
`bgchannels` members. Just set the base character for the `ncplane`.
|
||||||
|
* `ncreader_options` has lost its `echannels`, `eattrword`, `egc`,
|
||||||
|
`physrows`, and `physcols` fields. Just set the base character and size
|
||||||
|
for the `ncplane`.
|
||||||
* ...
|
* ...
|
||||||
|
|
||||||
* 1.7.2 (2020-09-09)
|
* 1.7.2 (2020-09-09)
|
||||||
|
16
USAGE.md
16
USAGE.md
@ -2271,20 +2271,14 @@ xxxxxxxxxxxxxxxx╰─────────────╯xxxxxxxxxxxxxxxxxxx
|
|||||||
```c
|
```c
|
||||||
typedef struct ncreader_options {
|
typedef struct ncreader_options {
|
||||||
uint64_t tchannels; // channels used for input
|
uint64_t tchannels; // channels used for input
|
||||||
uint64_t echannels; // channels used for empty space
|
|
||||||
uint32_t tattrword; // attributes used for input
|
uint32_t tattrword; // attributes used for input
|
||||||
uint32_t eattrword; // attributes used for empty space
|
|
||||||
const char* egc; // egc used for empty space
|
|
||||||
int physrows;
|
|
||||||
int physcols;
|
|
||||||
bool scroll; // allow more than the physical area's worth of input
|
bool scroll; // allow more than the physical area's worth of input
|
||||||
} ncreader_options;
|
} ncreader_options;
|
||||||
|
|
||||||
// ncreaders provide freeform input in a (possibly multiline) region,
|
// ncreaders provide freeform input in a (possibly multiline) region, supporting
|
||||||
// supporting readline keybindings. 'rows' and 'cols' both must be negative.
|
// optional readline keybindings. takes ownership of 'n', destroying it on any
|
||||||
// there are no restrictions on 'y' or 'x'. creates its own plane.
|
// error (ncreader_destroy() otherwise destroys the ncplane).
|
||||||
struct ncreader* ncreader_create(struct notcurses* nc, int y, int x,
|
struct ncreader* ncreader_create(struct ncplane* n, const ncreader_options* opts);
|
||||||
const ncreader_options* opts);
|
|
||||||
|
|
||||||
// empty the ncreader of any user input, and home the cursor.
|
// empty the ncreader of any user input, and home the cursor.
|
||||||
int ncreader_clear(struct ncreader* n);
|
int ncreader_clear(struct ncreader* n);
|
||||||
@ -2299,7 +2293,7 @@ bool ncreader_offer_input(struct ncreader* n, const struct ncinput* ni);
|
|||||||
// return a nul-terminated heap copy of the current (UTF-8) contents.
|
// return a nul-terminated heap copy of the current (UTF-8) contents.
|
||||||
char* ncreader_contents(const struct ncreader* n);
|
char* ncreader_contents(const struct ncreader* n);
|
||||||
|
|
||||||
// destroy the reader and its bound plane. if 'contents' is not NULL, the
|
// destroy the reader and its bound plane(s). if 'contents' is not NULL, the
|
||||||
// UTF-8 input will be heap-duplicated and written to 'contents'.
|
// UTF-8 input will be heap-duplicated and written to 'contents'.
|
||||||
void ncreader_destroy(struct ncreader* n, char** contents);
|
void ncreader_destroy(struct ncreader* n, char** contents);
|
||||||
```
|
```
|
||||||
|
@ -23,17 +23,12 @@ struct notcurses;
|
|||||||
|
|
||||||
typedef struct ncreader_options {
|
typedef struct ncreader_options {
|
||||||
uint64_t tchannels; // channels used for input
|
uint64_t tchannels; // channels used for input
|
||||||
uint64_t echannels; // channels used for empty space
|
|
||||||
uint32_t tattrword; // attributes used for input
|
uint32_t tattrword; // attributes used for input
|
||||||
uint32_t eattrword; // attributes used for empty space
|
|
||||||
const char* egc; // egc used for empty space
|
|
||||||
int physrows;
|
|
||||||
int physcols;
|
|
||||||
unsigned flags; // bitfield over NCREADER_OPTION_*
|
unsigned flags; // bitfield over NCREADER_OPTION_*
|
||||||
} ncreader_options;
|
} ncreader_options;
|
||||||
```
|
```
|
||||||
|
|
||||||
**struct ncreader* ncreader_create(struct notcurses* nc, int y, int x, const ncreader_options* opts);**
|
**struct ncreader* ncreader_create(struct notcurses* nc, const ncreader_options* opts);**
|
||||||
|
|
||||||
**int ncreader_clear(struct ncreader* n);**
|
**int ncreader_clear(struct ncreader* n);**
|
||||||
|
|
||||||
@ -59,8 +54,9 @@ typedef struct ncreader_options {
|
|||||||
|
|
||||||
The **ncreader** widget supports free-form, multi-line input. It supports
|
The **ncreader** widget supports free-form, multi-line input. It supports
|
||||||
navigation with the arrow keys and scrolling. While the visible portion of
|
navigation with the arrow keys and scrolling. While the visible portion of
|
||||||
the **ncreader** is always the same size (**physrows** by **physcols**), the
|
the **ncreader** is always the same size (defined by the provided **ncplane**),
|
||||||
actual text backing this visible region can grow arbitrarily large.
|
the actual text backing this visible region can grow arbitrarily large if
|
||||||
|
scrolling is enabled.
|
||||||
|
|
||||||
The following option flags are supported:
|
The following option flags are supported:
|
||||||
|
|
||||||
|
@ -12,27 +12,27 @@ namespace ncpp
|
|||||||
class NCPP_API_EXPORT Reader : public Root
|
class NCPP_API_EXPORT Reader : public Root
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Reader (Plane *p, int y, int x, const ncreader_options *opts)
|
explicit Reader (Plane *p, const ncreader_options *opts)
|
||||||
: Reader (static_cast<const Plane*>(p), y, x, opts)
|
: Reader (static_cast<const Plane*>(p), opts)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
explicit Reader (Plane const* p, int y, int x, const ncreader_options *opts)
|
explicit Reader (Plane const* p, const ncreader_options *opts)
|
||||||
: Root (Utilities::get_notcurses_cpp (p))
|
: Root (Utilities::get_notcurses_cpp (p))
|
||||||
{
|
{
|
||||||
if (p == nullptr)
|
if (p == nullptr)
|
||||||
throw invalid_argument ("'plane' must be a valid pointer");
|
throw invalid_argument ("'plane' must be a valid pointer");
|
||||||
|
|
||||||
common_init (Utilities::to_ncplane (p), y, x, opts);
|
common_init (Utilities::to_ncplane (p), opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit Reader (Plane &p, int y, int x, const ncreader_options *opts)
|
explicit Reader (Plane &p, const ncreader_options *opts)
|
||||||
: Reader (static_cast<Plane const&>(p), y, x, opts)
|
: Reader (static_cast<Plane const&>(p), opts)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
explicit Reader (Plane const& p, int y, int x, const ncreader_options *opts)
|
explicit Reader (Plane const& p, const ncreader_options *opts)
|
||||||
: Root (Utilities::get_notcurses_cpp (p))
|
: Root (Utilities::get_notcurses_cpp (p))
|
||||||
{
|
{
|
||||||
common_init (Utilities::to_ncplane (p), y, x, opts);
|
common_init (Utilities::to_ncplane (p), opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
~Reader ()
|
~Reader ()
|
||||||
@ -58,9 +58,9 @@ namespace ncpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void common_init (ncplane *n, int y, int x, const ncreader_options *opts)
|
void common_init (ncplane *n, const ncreader_options *opts)
|
||||||
{
|
{
|
||||||
reader = ncreader_create (n, y, x, opts);
|
reader = ncreader_create (n, opts);
|
||||||
if (reader == nullptr)
|
if (reader == nullptr)
|
||||||
throw init_error ("Notcurses failed to create a new reader");
|
throw init_error ("Notcurses failed to create a new reader");
|
||||||
}
|
}
|
||||||
|
@ -3034,20 +3034,14 @@ API int ncplane_qrcode(struct ncplane* n, ncblitter_e blitter, int* ymax,
|
|||||||
|
|
||||||
typedef struct ncreader_options {
|
typedef struct ncreader_options {
|
||||||
uint64_t tchannels; // channels used for input
|
uint64_t tchannels; // channels used for input
|
||||||
uint64_t echannels; // channels used for empty space
|
|
||||||
uint32_t tattrword; // attributes used for input
|
uint32_t tattrword; // attributes used for input
|
||||||
uint32_t eattrword; // attributes used for empty space
|
|
||||||
const char* egc; // egc used for empty space
|
|
||||||
int physrows;
|
|
||||||
int physcols;
|
|
||||||
uint64_t flags; // bitfield of NCREADER_OPTION_*
|
uint64_t flags; // bitfield of NCREADER_OPTION_*
|
||||||
} ncreader_options;
|
} ncreader_options;
|
||||||
|
|
||||||
// ncreaders provide freeform input in a (possibly multiline) region,
|
// ncreaders provide freeform input in a (possibly multiline) region, supporting
|
||||||
// supporting readline keybindings. 'rows' and 'cols' both must be negative.
|
// optional readline keybindings. takes ownership of 'n', destroying it on any
|
||||||
// there are no restrictions on 'y' or 'x'. creates its own plane.
|
// error (ncreader_destroy() otherwise destroys the ncplane).
|
||||||
API struct ncreader* ncreader_create(struct ncplane* n, int y, int x,
|
API struct ncreader* ncreader_create(struct ncplane* n, const ncreader_options* opts)
|
||||||
const ncreader_options* opts)
|
|
||||||
__attribute__ ((nonnull (1)));
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
// empty the ncreader of any user input, and home the cursor.
|
// empty the ncreader of any user input, and home the cursor.
|
||||||
|
@ -389,15 +389,10 @@ struct ncplane* ncsubproc_plane(struct ncsubproc* n);
|
|||||||
int ncsubproc_destroy(struct ncsubproc* n);
|
int ncsubproc_destroy(struct ncsubproc* n);
|
||||||
typedef struct ncreader_options {
|
typedef struct ncreader_options {
|
||||||
uint64_t tchannels; // channels used for input
|
uint64_t tchannels; // channels used for input
|
||||||
uint64_t echannels; // channels used for empty space
|
|
||||||
uint32_t tattrword; // attributes used for input
|
uint32_t tattrword; // attributes used for input
|
||||||
uint32_t eattrword; // attributes used for empty space
|
|
||||||
const char* egc; // egc used for empty space
|
|
||||||
int physrows;
|
|
||||||
int physcols;
|
|
||||||
unsigned flags; // bitfield over NCREADER_OPTION_*
|
unsigned flags; // bitfield over NCREADER_OPTION_*
|
||||||
} ncreader_options;
|
} ncreader_options;
|
||||||
struct ncreader* ncreader_create(struct ncplane* n, int y, int x, const ncreader_options* opts);
|
struct ncreader* ncreader_create(struct ncplane* n, const ncreader_options* opts);
|
||||||
int ncreader_clear(struct ncreader* n);
|
int ncreader_clear(struct ncreader* n);
|
||||||
struct ncplane* ncreader_plane(struct ncreader* n);
|
struct ncplane* ncreader_plane(struct ncreader* n);
|
||||||
bool ncreader_offer_input(struct ncreader* n, const struct ncinput* ni);
|
bool ncreader_offer_input(struct ncreader* n, const struct ncinput* ni);
|
||||||
|
@ -372,16 +372,15 @@ reader_demo(struct notcurses* nc){
|
|||||||
const int READER_ROWS = 8;
|
const int READER_ROWS = 8;
|
||||||
ncreader_options nopts = {
|
ncreader_options nopts = {
|
||||||
.tchannels = CHANNELS_RGB_INITIALIZER(0xa0, 0xe0, 0xe0, 0, 0, 0),
|
.tchannels = CHANNELS_RGB_INITIALIZER(0xa0, 0xe0, 0xe0, 0, 0, 0),
|
||||||
.echannels = CHANNELS_RGB_INITIALIZER(0x20, 0xe0, 0xe0, 0, 0, 0),
|
|
||||||
.egc = " ",
|
|
||||||
.physcols = READER_COLS,
|
|
||||||
.physrows = READER_ROWS,
|
|
||||||
};
|
};
|
||||||
channels_set_bg_alpha(&nopts.echannels, CELL_ALPHA_BLEND);
|
uint64_t echannels = CHANNELS_RGB_INITIALIZER(0x20, 0xe0, 0xe0, 0, 0, 0);
|
||||||
const int x = ncplane_align(std, NCALIGN_CENTER, nopts.physcols);
|
channels_set_bg_alpha(&echannels, CELL_ALPHA_BLEND);
|
||||||
|
const int x = ncplane_align(std, NCALIGN_CENTER, READER_COLS);
|
||||||
struct ncselector* selector = NULL;
|
struct ncselector* selector = NULL;
|
||||||
struct ncmultiselector* mselector = NULL;
|
struct ncmultiselector* mselector = NULL;
|
||||||
struct ncreader* reader = ncreader_create(std, dimy, x, &nopts);
|
struct ncplane* rp = ncplane_new(nc, READER_ROWS, READER_COLS, dimy, x, NULL);
|
||||||
|
ncplane_set_base(rp, " ", 0, echannels);
|
||||||
|
struct ncreader* reader = ncreader_create(rp, &nopts);
|
||||||
if(reader == NULL){
|
if(reader == NULL){
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -1,53 +1,35 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
ncreader* ncreader_create(ncplane* n, int y, int x, const ncreader_options* opts){
|
ncreader* ncreader_create(ncplane* n, const ncreader_options* opts){
|
||||||
ncreader_options zeroed = {};
|
ncreader_options zeroed = {};
|
||||||
if(!opts){
|
if(!opts){
|
||||||
opts = &zeroed;
|
opts = &zeroed;
|
||||||
}
|
}
|
||||||
if(opts->physrows <= 0 || opts->physcols <= 0){
|
|
||||||
logerror(n->nc, "Provided illegal geometry %dx%d\n", opts->physcols, opts->physrows);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if(opts->flags > NCREADER_OPTION_CURSOR){
|
if(opts->flags > NCREADER_OPTION_CURSOR){
|
||||||
logwarn(n->nc, "Provided unsupported flags %016lx\n", opts->flags);
|
logwarn(n->nc, "Provided unsupported flags %016lx\n", opts->flags);
|
||||||
}
|
}
|
||||||
ncreader* nr = malloc(sizeof(*nr));
|
ncreader* nr = malloc(sizeof(*nr));
|
||||||
if(nr){
|
if(nr == NULL){
|
||||||
nr->ncp = ncplane_new(n->nc, opts->physrows, opts->physcols, y, x, NULL);
|
ncplane_destroy(n);
|
||||||
if(!nr->ncp){
|
return NULL;
|
||||||
free(nr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
// do *not* bind it to the visible plane; we always want it offscreen,
|
|
||||||
// to the upper left of the true origin
|
|
||||||
if((nr->textarea = ncplane_new(n->nc, opts->physrows, opts->physcols, -opts->physrows, -opts->physcols, NULL)) == NULL){
|
|
||||||
ncplane_destroy(nr->ncp);
|
|
||||||
free(nr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
const char* egc = opts->egc ? opts->egc : "_";
|
|
||||||
if(ncplane_set_base(nr->ncp, egc, opts->eattrword, opts->echannels) <= 0){
|
|
||||||
ncreader_destroy(nr, NULL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
nr->horscroll = opts->flags & NCREADER_OPTION_HORSCROLL;
|
|
||||||
nr->xproject = 0;
|
|
||||||
nr->tchannels = opts->tchannels;
|
|
||||||
nr->tattrs = opts->tattrword;
|
|
||||||
nr->no_cmd_keys = opts->flags & NCREADER_OPTION_NOCMDKEYS;
|
|
||||||
nr->manage_cursor = opts->flags & NCREADER_OPTION_CURSOR;
|
|
||||||
ncplane_set_channels(nr->ncp, opts->tchannels);
|
|
||||||
ncplane_set_attr(nr->ncp, opts->tattrword);
|
|
||||||
if(nr->manage_cursor){
|
|
||||||
if(notcurses_cursor_enable(n->nc, nr->ncp->absy, nr->ncp->absx)){
|
|
||||||
ncplane_destroy(nr->textarea);
|
|
||||||
ncplane_destroy(nr->ncp);
|
|
||||||
free(nr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
nr->ncp = n;
|
||||||
|
// do *not* bind it to the visible plane; we always want it offscreen,
|
||||||
|
// to the upper left of the true origin
|
||||||
|
if((nr->textarea = ncplane_new(n->nc, ncplane_dim_y(n), ncplane_dim_x(n),
|
||||||
|
-ncplane_dim_y(n), -ncplane_dim_x(n), NULL)) == NULL){
|
||||||
|
ncplane_destroy(nr->ncp);
|
||||||
|
free(nr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
nr->horscroll = opts->flags & NCREADER_OPTION_HORSCROLL;
|
||||||
|
nr->xproject = 0;
|
||||||
|
nr->tchannels = opts->tchannels;
|
||||||
|
nr->tattrs = opts->tattrword;
|
||||||
|
nr->no_cmd_keys = opts->flags & NCREADER_OPTION_NOCMDKEYS;
|
||||||
|
nr->manage_cursor = opts->flags & NCREADER_OPTION_CURSOR;
|
||||||
|
ncplane_set_channels(nr->ncp, opts->tchannels);
|
||||||
|
ncplane_set_attr(nr->ncp, opts->tattrword);
|
||||||
return nr;
|
return nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,16 +31,14 @@ auto main(int argc, const char** argv) -> int {
|
|||||||
nopts.flags = NCOPTION_INHIBIT_SETLOCALE;
|
nopts.flags = NCOPTION_INHIBIT_SETLOCALE;
|
||||||
NotCurses nc(nopts);
|
NotCurses nc(nopts);
|
||||||
int dimy, dimx;
|
int dimy, dimx;
|
||||||
std::unique_ptr<Plane *> n = std::make_unique<Plane *>(nc.get_stdplane(&dimy, &dimx));
|
auto n = std::make_unique<Plane *>(nc.get_stdplane(&dimy, &dimx));
|
||||||
nc.get_term_dim(&dimy, &dimx);
|
nc.get_term_dim(&dimy, &dimx);
|
||||||
ncreader_options opts{};
|
ncreader_options opts{};
|
||||||
opts.physrows = dimy / 8;
|
|
||||||
opts.physcols = dimx / 2;
|
|
||||||
opts.egc = "░";
|
|
||||||
opts.flags = NCREADER_OPTION_CURSOR | (horscroll ? NCREADER_OPTION_HORSCROLL : 0);
|
opts.flags = NCREADER_OPTION_CURSOR | (horscroll ? NCREADER_OPTION_HORSCROLL : 0);
|
||||||
// FIXME c++ is crashing
|
// can't use Plane until we have move constructor for Reader
|
||||||
//Reader nr(nc, 0, 0, &opts);
|
struct ncplane* rp = ncplane_new(nc, dimy / 8, dimx / 2, 2, 2, nullptr);
|
||||||
auto nr = ncreader_create(**n, 2, 2, &opts);
|
ncplane_set_base(rp, "░", 0, 0);
|
||||||
|
auto nr = ncreader_create(rp, &opts);
|
||||||
if(nr == nullptr){
|
if(nr == nullptr){
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -67,7 +65,7 @@ auto main(int argc, const char** argv) -> int {
|
|||||||
nc.render();
|
nc.render();
|
||||||
char* contents;
|
char* contents;
|
||||||
ncreader_destroy(nr, &contents);
|
ncreader_destroy(nr, &contents);
|
||||||
nc.stop();
|
//nc.stop();
|
||||||
if(contents){
|
if(contents){
|
||||||
printf("\n input: %s\n", contents);
|
printf("\n input: %s\n", contents);
|
||||||
}
|
}
|
||||||
|
@ -12,32 +12,13 @@ TEST_CASE("Readers") {
|
|||||||
REQUIRE(n_);
|
REQUIRE(n_);
|
||||||
REQUIRE(0 == ncplane_cursor_move_yx(n_, 0, 0));
|
REQUIRE(0 == ncplane_cursor_move_yx(n_, 0, 0));
|
||||||
|
|
||||||
SUBCASE("ReaderBadOptions") {
|
|
||||||
ncreader_options opts{};
|
|
||||||
auto nr = ncreader_create(n_, 0, 0, &opts);
|
|
||||||
CHECK(!nr);
|
|
||||||
opts.physrows = 1;
|
|
||||||
nr = ncreader_create(n_, 0, 0, &opts);
|
|
||||||
CHECK(!nr);
|
|
||||||
opts.physcols = 1;
|
|
||||||
opts.physrows = 0;
|
|
||||||
nr = ncreader_create(n_, 0, 0, &opts);
|
|
||||||
CHECK(!nr);
|
|
||||||
}
|
|
||||||
|
|
||||||
SUBCASE("ReaderRender") {
|
SUBCASE("ReaderRender") {
|
||||||
ncreader_options opts{};
|
ncreader_options opts{};
|
||||||
opts.physrows = dimy / 2;
|
auto ncp = ncplane_new(nc_, dimy / 2, dimx / 2, 0, 0, nullptr);
|
||||||
opts.physcols = dimx / 2;
|
uint64_t echannels = CHANNELS_RGB_INITIALIZER(0xff, 0x44, 0xff, 0, 0, 0);
|
||||||
if(enforce_utf8()){
|
ncplane_set_base(ncp, enforce_utf8() ? strdup("▒") : strdup("x"), 0, echannels);
|
||||||
opts.egc = strdup("▒");
|
auto nr = ncreader_create(ncp, &opts);
|
||||||
}else{
|
|
||||||
opts.egc = strdup("x");
|
|
||||||
}
|
|
||||||
auto nr = ncreader_create(n_, 0, 0, &opts);
|
|
||||||
REQUIRE(nullptr != nr);
|
REQUIRE(nullptr != nr);
|
||||||
channels_set_fg(&opts.echannels, 0xff44ff);
|
|
||||||
ncplane_set_base(n_, opts.egc, opts.eattrword, opts.echannels);
|
|
||||||
CHECK(0 == notcurses_render(nc_));
|
CHECK(0 == notcurses_render(nc_));
|
||||||
char* contents = nullptr;
|
char* contents = nullptr;
|
||||||
ncreader_destroy(nr, &contents);
|
ncreader_destroy(nr, &contents);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user