Crates.io | nsys-curses-utils |
lib.rs | nsys-curses-utils |
version | 0.1.0 |
created_at | 2025-07-13 06:24:20.388867+00 |
updated_at | 2025-07-13 06:24:20.388867+00 |
description | Rust *curses utilities |
homepage | |
repository | https://gitlab.com/spearman/curses-utils-rs |
max_upload_size | |
id | 1750037 |
size | 80,967 |
curses_utils
libncurses
ncurses represents the terminal screen using two data structures:
a window is a two-dimensional array of characters representing all or part of the terminal screen
characters in a window are of type chtype
containing character and
attribute data;
on a 64-bit system, a chtype
will be a 64-bit unsigned integer
there is also a type alias for chtype
, attr_t
in ncurses there is a default window called stdscr
that is the size of the
terminal screen
Defines
#define NCURSES_ATTR_SHIFT 8
-- bitshift to start of attribute bits
#define NCURSES_BITS (mask, shift) ...
-- takes a chtype
mask and
left-shifts it by NCURSES_ATTR_SHIFT + shift
#define COLOR_PAIR (n) ...
-- takes a color pair number and shifts it into a
chtype
using NCURSES_BITS (n, 0)
, and masks the result with A_COLOR
to
clear out any bits outside of the color byte
#define PAIR_NUMBER (attr) ...
-- inverse of COLOR_PAIR
, masking the color
byte of a chtype with A_COLOR
and shifting it into a color pair number
Functions
initscr()
-- initializes the curses system, allocates the stdscr
, and
refreshes the screen; this is equivalent to:
newterm(getenv("TERM"), stdout, stdin);
return stdscr;
and must be called before any other screen manipulation functions
wnoutrefresh(WINDOW*)
copies named window to the virtual screen
doupdate()
compares virtual screen to physical screen and does the "actual
update"
wrefresh(WINDOW*)
equivalent to calling wnoutrefresh
followed by doupdate
(wnoutrefresh
), then compares the virtual screen to the physical screen and
does the update (doupdate
)
refresh()
equivalent to wrefresh(stdscr)
border()
box()
calls border()
with given top/bottom and left/right edges and
corners
Global variables
int COLORS
-- number of colors supported by terminal; this is 256
on a
256-color terminal
int COLOR_PAIRS
-- number of color pairs supported by terminal; this is 256
on a 256-color terminal
int COLS
int LINES
WINDOW* stdscr
ncurses
Rust bindings to libncurses
most of the C interface should be exposed in this crate
note that as the libncurses interface uses a number of #define
s, they are
recreated in this crate as const functions
lib.rs
:
const fn NCURSES_BITS (mask:u32, shift:u32) -> u32
const fn A_NORMAL() -> attr_t
const fn A_ATTRIBUTES() -> attr_t
COLOR_PAIR(n)
is recreated as a function, but it is not a const function:
fn COLOR_PAIR (n : i16) -> attr_t
note that PAIR_NUMBER
is a safe wrapper over an ll
raw function
in ll.rs
, a number of typedefs are made and extern "C"
functions are
declared that will link to libncurses; these are called in the wrapper functions
defined elsewhere in the crate
in constants.rs
some more constants are defined (the contents of this module
are re-exported at the crate root):
const ERR : i32 = -1
const OK : i32 = 0
const NCURSES_ATTR_SHIFT : u32 = 8
const COLOR_BLACK : i16 = 0
const COLOR_RED : i16 = 1
some extern "C"
global variables are also wrapped in constants.rs
:
static stdscr : WINDOW
static COLORS : c_int
static COLOR_PAIRS : c_int
static LINES : c_int
static COLS : c_int
...
pancurses
pancurses provides a cross-platform curses library using ncurses
for Linux and
pdcurses
on Windows; most of the method names are the same, and on Linux, it
seems to mostly call raw ncurses::ll
functions instead of the "safe" ncurses
wrapped functions
pancurses re-defines a number of constants from ncurses
, such at OK
,
ERR
, COLOR_BLACK
, A_ATTRIBUTES
, etc., and some const funtions like
NCURSES_BITS(mask,shift)
(private) and COLOR_PAIR(n)
(public)
Traits
trait ToChtype
-- trait with a single to_chtype (&self) -> chtype
method;
this is only implemented for char
as a primitive cast (as chtype
), and
for chtype
itself
Structs
Window
-- contains a pointer to the backend WINDOW
pointer, and a couple
flags to indicate if it is the stdscr
or a deleted window; methods:
window.noutrefresh()
-- copies touched lines to the virtual screen;
equivalent to ncurses::wnoutrefresh (window)
window.refresh()
-- copies window to the physical screen; must be called to
get output to terminal; equivalent to ncurses::wrefresh(window)
window.touch()
-- sets entire window as touchedwindow.untouch()
-- unset the entire window as touchedAttributes { chtype, ColorPair }
-- an attributes builder; can be converted
Into<chtype>
ColorPair (u8)
Enums
Attribute
Input
Functions
note that ncurses::refresh()
is not exported; instead call refresh()
on the
initial Window
representing the stdscr
initscr() -> Window
-- initialize the curses system and return the stdscr
window
doupdate()
-- compare virtual screen to physical screen and perform update of
the physical screen; this should be called once per frame; if there is only one
window in use, instead calling the refresh()
method on that window will
automatically call doupdate()
after first calling noutrefresh()
on that
window
curs_set(i32)
-- set cursor visibility (0
invisible, 1
visible, 2
very
visible)
endwin()
easycurses
re-exports pancurses::Input
as easycurses::Input
Structs
struct EasyCurses {
pub win : pancurses::Window
auto_resize : bool = true
color_support : bool
}
-- ; methods:
set_color_pair (&mut self, ColorPair)
-- calls
pancurses::Window::color_set
with the color pair number contained in the
color pair; with the ncurses backend, this will set the color in the attribute
returned by pancurses::Window.attrget()
, but not with PDCurses, i.e. the
second byte is always 0x0
-- however in both backends, the color pair
number will be returned in the right member of the tuple returned by
pancurses::Window.attrget()
, so the preferred way to clear the screen with
the current window color
would be to construct the attribute with
color_pair(color)
supplied in the argument to bkgd
or bkgdset
struct ColorPair (i16)
-- uses an internal function fgbg_pairid
to combine
a pair of foreground and background color numbers into a color pair number,
using the formula:
1 + (8 * fg + bg)
during intialization, each fg/bg combination of the 8 base colors are
initialized for a total of 8 * 8 = 64
colors, using the above formula gives
color pairs numbered from 1
to 64
; it should be noted that this will not
work on a terminal that supports only 64 colors, since color 0
is
technically reserved for white/black, the maximum allowed color pair would be
63
Enums
Color
-- an enumeration convertible to i16
color numbers (i.e.
COLOR_BLACK
, COLOR_RED
, etc.)
Functions
initialize_system() -> EasyCurses
-- initializes the curses system through
pancurses::initscr()
and subsequently sets up the colors
Curses
Newtype wrapping an EasyCurses
window.
The new()
creation method will construct an EasyCurses
window with the
following settings:
There are a number of methods to get input which will set the input mode as needed, depending on the type of input:
getch_wait() -> Option<pancurses::Input>
-- get single character, block
indefinitelygetch_timeout(timeout) -> Option<pancurses::Input>
-- get single character,
block until timeoutgetch_nowait() -> Option<pancurses::Input>
-- get single character, returns
immediately if no input is waitinggetline_wait() -> Option<pancurses::Input>
-- get line, block indefinitelygetline_nowait() -> Option<pancurses::Input>
-- get line, returns
immediately if no input is waitingThe newly created window (the stdscr
) will have attributes A_NORMAL = 0
, and
background chtype
of (A_NORMAL | ' ' as chtype)
.
curses_utils
defines a few utility functions for working with curses chtype
s
(attributes + character data):
color_pair_number (fg, bg) -> i16
-- gives the color pair number that
easycurses
uses to identify the fg/bg combination
character (chtype) -> char
-- returns the first byte of the chtype
(the
character data), cast to a char
color_pair (chtype) -> i16
-- returns the second byte of the chtype
(the
color pair number), cast to an i16
ncurses:
PAIR_NUMBER (attr : i32) -> i32
-- inverse of COLOR_PAIR
: masks out the
color byte and right-shifts into a color pair numberPancurses:
fn COLOR_PAIR (n : chtype) -> attr_t
-- turns a color pair number into an
attribute (left-shifts by 8 bits and masks the color byte)window.attrget() -> (attrs, color_pair : i16)
-- this returns the current
window attributes (including the color attribute), along with the color pair
number corresponding to the color attribute, equal to PAIR_NUMBER(attrs)
window.color_set (color_pair : i16)
-- change the color attribute to the
given color pair number, equal to COLOR_PAIR(color_pair)
window.chgat (n, attrs, color_pair : i16)
window.mvchgat (y, x, n, attrs, color_pair : i16)
ColorPair (u8)
-- this type only appears to be used by the Attribute
builder type; it is the color number which will be set in the 2nd byte of the
attribute chtype
attributes.color_pair() -> ColorPair
-- get color pair of an attribute
builderattributes.set_color_pair(color_pair : ColorPair)
-- set color pair of an
attribute builderEasycurses:
Color
-- an enumeration of base colors that can be converted to i16
color
numbersColorPair (i16)
-- easycurses defines a color pair number by the formula
1 + 8*fg + bg
, giving a range of color pair numbers from 1-64easycurses.set_color_pair (color_pair : ColorPair)
the easycurses::ColorPair
type is only used as the argument to the
set_color_pair
method; as a convenience, curses_utils
defines a function
color_pair_number
which applies the above formula and returns a raw i16
, so
that it can be used in other places where a color pair number is needed
pancurses::Window::attrset (chtype)
-- sets the current window attributes; if
there is any character data here it will be "combined" with all inputs
pancurses::Window::bkgdset (chtype)
-- sets the current window "background"
chtype
; inserted text will be "combined" with the attributes set in this
variable, and any blank characters (spaces) will show the background character
data, if any; note that this function does not immediately change any window
contents, to fill the window with the background use erase
or bkgd
pancurses::Window::bkgd (chtype)
-- sets the current background and
immediately applies it to all cells in the window; note that this will copy
the background character into blank cells (spaces), but will not clear cells
with existing character data
pancurses::Window::erase()
-- copies blanks to every cell of the window, in
combination with the background chtype
pancurses::Window::clearok(bool)
-- if true, the next time this window calls
window.refresh()
, the entire screen will clear and re-draw
pancurses::Window::clear()
-- equivalent to window.erase()
followed by
window.clearok(true)
easycurses::Easycurses::clear()
-- just calls pancurses window.clear()
internally
pancurses::Window::noutrefresh()
-- copies the window to the virtual screen
pancurses::doupdate()
-- compares the virtual screen to the physical screen
and copies updated portions to the physical screen
pancurses::Window::refresh()
-- equivalent to window.noutrefresh()
followed
by doupdate()
pancurses::Window::addch(chtype)
-- "adds" the chtype (attribute + character
data) to the window; note that if the cursor is moved past the end of the window
(i.e. the cursor was at (ncurses::LINES()-1, ncurses::COLS()-1)
, then this
function will return '-1' (pancurses::ERR
), but the character will still be
drawn-- this is also true for addstr
and printw
pancurses::Window::chgat(n:i32, ch:chtype, color_pair:i16)
-- "changes" n
consecutive characters to the given chtype and color pair number; this method
"combines" the character data with the current character data at the target
using a bitwise OR operation;
note that only character data and non-color attributes are taken from the
chtype argument-- a color number needs to be given in the color pair argument.
pancurses::Window::hline/vline
-- note that this will return -1
on windows
if called with ncols=0
... TODO: box drawing functions
pancurses::Window::mvinch (row:i32, col:i32) -> chtype
-- returns the rendered
chtype at the given position, or else returns -1
(0xFFFFFFFF)