class TermBuf::LineBuffer

Overview

Editable text and a cursor, in grapheme clusters.

A cluster is what a cursor moves over and what occupies a cell, so it is what this counts in. Every index here is a cluster index, from zero to #size, and the cursor sits between clusters rather than on one. Nothing in here knows about terminals, drawing, or keys; Editor binds keys to it and Field draws it.

Widths come from a Unicode::WidthPolicy, which has to be the one the terminal was measured with or the column this reports is not the column the cursor lands in.

Defined in:

termbuf/widgets/line_buffer.cr

Constant Summary

DEFAULT_WORD = ->(cluster : String) do char = cluster[0]? if char else return false end char.alphanumeric? || (char == '_') end

Alphanumerics and the underscore, which is what readline means by a word.

NEWLINE = "\n"

Constructors

Instance Method Summary

Constructor Detail

def self.new(text : String = "", policy : Unicode::WidthPolicy = Unicode::WidthPolicy::DEFAULT) #

[View source]

Instance Method Detail

def [](index : Int32) : String | Nil #

The cluster at index, or nil past either end.


[View source]
def anchor : Int32 | Nil #

Where a selection started, or nil when nothing is selected. The cursor is the other end.


[View source]
def clear : Nil #

Empties it.


[View source]
def collapse : Nil #

Drops the selection, leaving the cursor where it is.


[View source]
def column : Int32 #

Cells between the start of the cursor's line and the cursor. What a caller needs to put the terminal's own cursor in the right place.


[View source]
def cursor : Int32 #

Where the next cluster goes, between zero and #size.


[View source]
def delete(range : Range(Int32, Int32)) : String #

Removes range and puts the cursor where it started. Returns what it took.


[View source]
def delete_backward : Nil #

Removes the cluster before the cursor, or the selection if there is one.


[View source]
def delete_forward : Nil #

Removes the cluster after the cursor, or the selection if there is one.


[View source]
def delete_selection : Bool #

Removes what is selected. Returns whether anything was.


[View source]
def empty? : Bool #

Whether there is nothing to edit.


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

Inserts text at the cursor, replacing the selection if there is one.


[View source]
def insert(char : Char) : Nil #

Inserts text at the cursor, replacing the selection if there is one.


[View source]
def kill_to_end : Nil #

Removes from the cursor to the end of the line, keeping it for #yank.


[View source]
def kill_to_start : Nil #

Removes from the start of the line to the cursor, keeping it for #yank.


[View source]
def kill_word_backward : Nil #

Removes the word before the cursor, keeping it for #yank.


[View source]
def kill_word_forward : Nil #

Removes the word after the cursor, keeping it for #yank.


[View source]
def killed : String #

What the last kill took, which #yank puts back.


[View source]
def line_end : Int32 #

End of the line the cursor is on, before the break.


[View source]
def line_index : Int32 #

Which line the cursor is on, counting from zero.


[View source]
def line_start : Int32 #

Start of the line the cursor is on.


[View source]
def lines : Array(String) #

The text split on its line breaks.


[View source]
def move_end : Nil #

To the end of the line the cursor is on.


[View source]
def move_home : Nil #

To the start of the line the cursor is on.


[View source]
def move_left : Nil #

One cluster left.


[View source]
def move_right : Nil #

One cluster right.


[View source]
def move_to(index : Int32) : Nil #

Moves the cursor to index, clamped, and drops any selection.


[View source]
def move_word_left : Nil #

Back over one word, and the space before it.


[View source]
def move_word_right : Nil #

Forward to the end of the next word.


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

How clusters are measured, which has to be the policy the terminal was measured with or the column reported here is not the one the cursor lands in.


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

Throws away everything and starts again with text, cursor at the end. What history recall does.


[View source]
def select_all : Nil #

Selects everything, leaving the cursor at the end.


[View source]
def select_to(index : Int32) : Nil #

Moves the cursor to index keeping the anchor where it is, which is what a shift-modified motion does.


[View source]
def selected? : Bool #

Whether anything is selected.


[View source]
def selected_text : String #

What is selected, or an empty string when nothing is.


[View source]
def selection : Range(Int32, Int32) | Nil #

The selected clusters, or nil when nothing is selected.


[View source]
def size : Int32 #

Clusters, not characters and not bytes.


[View source]
def slice(range : Range(Int32, Int32)) : String #

The text of a range of clusters.


[View source]
def text : String #

Everything, as one string.


[View source]
def to_s(io : IO) : Nil #
Description copied from class Reference

Appends a short String representation of this object which includes its class name and its object address.

class Person
  def initialize(@name : String, @age : Int32)
  end
end

Person.new("John", 32).to_s # => #<Person:0x10a199f20>

[View source]
def transpose : Nil #

Swaps the two clusters around the cursor, which is what Ctrl+T does.


[View source]
def width : Int32 #

Cells the whole text takes, ignoring line breaks.


[View source]
def width_at(index : Int32) : Int32 #

Cells the cluster at index takes.


[View source]
def width_between(from : Int32, to : Int32) : Int32 #

Cells between two cluster indices.


[View source]
def word : Proc(String, Bool) #

What counts as part of a word, for the motions and deletions that move by one. A shell, a search box, and an expression evaluator disagree, so this is replaceable.


[View source]
def word=(word : Proc(String, Bool)) #

What counts as part of a word, for the motions and deletions that move by one. A shell, a search box, and an expression evaluator disagree, so this is replaceable.


[View source]
def word_left : Int32 #

Where the cursor would land moving one word left: back over anything that is not a word, then back over the word.


[View source]
def word_right : Int32 #

Where the cursor would land moving one word left: back over anything that is not a word, then back over the word.


[View source]
def yank : Nil #

Puts back what the last kill took.


[View source]