class TermBuf::Cursor

Overview

A place to write, and the state to write it in.

A cursor is where streamed output goes: it holds a position, a Style, and the Region it lives inside, and it works out which cell each grapheme cluster lands in as text arrives. Wrapping and scrolling happen against the region's edges, so a cursor bound to a pane behaves like a small terminal inside that pane.

It is not the terminal's own cursor. That one is a property of the device, associated with a cursor of this kind through Terminal#hardware_cursor= and moved to match it after each paint.

A cursor is application-side state and emits the same commands the drawing API does, so it needs no privileged access to the buffer and works against a Batcher as readily as against a Terminal. Nothing here is fibre-safe: a cursor belongs to whoever made it.

Defined in:

termbuf/cursor.cr

Constructors

Instance Method Summary

Constructor Detail

def self.full(target : Drawing, columns : Int32, rows : Int32, scrollback : Int32 = 0) : Cursor #

A cursor over the whole of a columns by rows screen.


[View source]
def self.new(target : Drawing, region : Region, style : Style = Style::DEFAULT, raw : Bool = false, autowrap : Bool = true, scrolls : Bool = true, tab_width : Int32 = 8) #

[View source]

Instance Method Detail

def autowrap=(autowrap : Bool) #

Whether text running past the right edge continues on the next row.

With this off the cursor stops at the right margin and each further character replaces the one standing there, which is what a terminal with DECAWM reset does.


[View source]
def autowrap? : Bool #

Whether text running past the right edge continues on the next row.

With this off the cursor stops at the right margin and each further character replaces the one standing there, which is what a terminal with DECAWM reset does.


[View source]
def carriage_return : Nil #

Back to the left edge of the region, staying on this row.


[View source]
def home : Nil #

Puts the cursor at the region's top left.


[View source]
def io : CursorIO #

An IO that writes here, so printf, Colorize, and anything else expecting an IO can be pointed at a region of the screen.


[View source]
def line_feed : Nil #

Down one row, scrolling the region if there is nowhere further to go.


[View source]
def move_by(columns : Int32, rows : Int32) : Nil #

Moves columns right and rows down, negative going the other way.


[View source]
def move_to(x : Int32, y : Int32) : Nil #

Puts the cursor at (x, y), in buffer coordinates, clamped to the region. Coordinates are absolute everywhere in this shard, and a cursor is no exception; #home is the one that speaks in the region's terms.


[View source]
def newline : Nil #

A carriage return and a line feed, which is what a \n does here: the terminal is in raw mode, so nothing else is going to add the return.


[View source]
def policy : Unicode::WidthPolicy #

How clusters are measured, which has to match what the buffer being written to uses or the cursor and the cells disagree about where the next character goes. Terminal#cursor sets it from the buffer's.


[View source]
def policy=(policy : Unicode::WidthPolicy) #

How clusters are measured, which has to match what the buffer being written to uses or the cursor and the cells disagree about where the next character goes. Terminal#cursor sets it from the buffer's.


[View source]
def print(text : String) : Nil #

Writes text, one grapheme cluster per cell, wrapping and scrolling at the region's edges.


[View source]
def print(value) : Nil #

Writes text, one grapheme cluster per cell, wrapping and scrolling at the region's edges.


[View source]
def puts(text : String = "") : Nil #

Writes text and then a newline.


[View source]
def puts(value) : Nil #

Writes text and then a newline.


[View source]
def raw=(raw : Bool) #

Whether written text is scanned for escape sequences.

Off by default. Turn it on for an application that changes appearance by assigning to #style and never writes an escape sequence of its own: the scan is skipped outright, which is worth having on the path that carries every character.


[View source]
def raw? : Bool #

Whether written text is scanned for escape sequences.

Off by default. Turn it on for an application that changes appearance by assigning to #style and never writes an escape sequence of its own: the scan is skipped outright, which is worth having on the path that carries every character.


[View source]
def region : Region #

The rectangle the cursor writes inside, and scrolls when it runs off the bottom.


[View source]
def scroll(lines : Int32) : Nil #

Scrolls the region by lines, positive moving content up.

The vacated rows take the cursor's background and nothing else. Carrying the whole style would leave underlines and strike-throughs hanging in empty space, and dropping the background as well would punch holes in a tinted pane.


[View source]
def scrolls=(scrolls : Bool) #

Whether a line feed on the bottom row scrolls the region. With this off the cursor stays on the bottom row and writing there overwrites it.


[View source]
def scrolls? : Bool #

Whether a line feed on the bottom row scrolls the region. With this off the cursor stays on the bottom row and writing there overwrites it.


[View source]
def style : Style #

What subsequent text is written in.


[View source]
def style=(style : Style) #

What subsequent text is written in.


[View source]
def tab_width : Int32 #

Columns between tab stops, measured from the region's left edge.


[View source]
def tab_width=(tab_width : Int32) #

Columns between tab stops, measured from the region's left edge.


[View source]
def target : Drawing #

Where drawing commands go.


[View source]
def write(bytes : Bytes) : Nil #

Writes UTF-8 bytes.

A character split by the end of bytes is held until the rest of it arrives, since a write boundary lands wherever the caller's buffer happened to fill.


[View source]
def x : Int32 #

Column of the next cell to be written.


[View source]
def y : Int32 #

Row of the next cell to be written.


[View source]