TextArea¶
Tip
Added in version 0.38.0. Soft wrapping added in version 0.48.0.
A widget for editing text which may span multiple lines. Supports text selection, soft wrapping, optional syntax highlighting with tree-sitter and a variety of keybindings.
- Focusable
- Container
Guide¶
Code editing vs plain text editing¶
By default, the TextArea
widget is a standard multi-line input box with soft-wrapping enabled.
If you're interested in editing code, you may wish to use the TextArea.code_editor
convenience constructor.
This is a method which, by default, returns a new TextArea
with soft-wrapping disabled, line numbers enabled, and the tab key behavior configured to insert \t
.
Syntax highlighting dependencies¶
To enable syntax highlighting, you'll need to install the syntax
extra dependencies:
This will install tree-sitter
and tree-sitter-languages
.
These packages are distributed as binary wheels, so it may limit your applications ability to run in environments where these wheels are not available.
After installing, you can set the language
reactive attribute on the TextArea
to enable highlighting.
Loading text¶
In this example we load some initial text into the TextArea
, and set the language to "python"
to enable syntax highlighting.
from textual.app import App, ComposeResult
from textual.widgets import TextArea
TEXT = """\
def hello(name):
print("hello" + name)
def goodbye(name):
print("goodbye" + name)
"""
class TextAreaExample(App):
def compose(self) -> ComposeResult:
yield TextArea.code_editor(TEXT, language="python")
app = TextAreaExample()
if __name__ == "__main__":
app.run()
To update the content programmatically, set the text
property to a string value.
To update the parser used for syntax highlighting, set the language
reactive attribute:
Note
More built-in languages will be added in the future. For now, you can add your own.
Reading content from TextArea
¶
There are a number of ways to retrieve content from the TextArea
:
- The
TextArea.text
property returns all content in the text area as a string. - The
TextArea.selected_text
property returns the text corresponding to the current selection. - The
TextArea.get_text_range
method returns the text between two locations.
In all cases, when multiple lines of text are retrieved, the document line separator will be used.
Editing content inside TextArea
¶
The content of the TextArea
can be updated using the replace
method.
This method is the programmatic equivalent of selecting some text and then pasting.
Some other convenient methods are available, such as insert
, delete
, and clear
.
Tip
The TextArea.document.end
property returns the location at the end of the
document, which might be convenient when editing programmatically.
Working with the cursor¶
Moving the cursor¶
The cursor location is available via the cursor_location
property, which represents
the location of the cursor as a tuple (row_index, column_index)
. These indices are zero-based and represent the position of the cursor in the content.
Writing a new value to cursor_location
will immediately update the location of the cursor.
>>> text_area = TextArea()
>>> text_area.cursor_location
(0, 0)
>>> text_area.cursor_location = (0, 4)
>>> text_area.cursor_location
(0, 4)
cursor_location
is a simple way to move the cursor programmatically, but it doesn't let us select text.
Selecting text¶
To select text, we can use the selection
reactive attribute.
Let's select the first two lines of text in a document by adding text_area.selection = Selection(start=(0, 0), end=(2, 0))
to our code:
from textual.app import App, ComposeResult
from textual.widgets import TextArea
from textual.widgets.text_area import Selection
TEXT = """\
def hello(name):
print("hello" + name)
def goodbye(name):
print("goodbye" + name)
"""
class TextAreaSelection(App):
def compose(self) -> ComposeResult:
text_area = TextArea.code_editor(TEXT, language="python")
text_area.selection = Selection(start=(0, 0), end=(2, 0)) # (1)!
yield text_area
app = TextAreaSelection()
if __name__ == "__main__":
app.run()
- Selects the first two lines of text.
Note that selections can happen in both directions, so Selection((2, 0), (0, 0))
is also valid.
Tip
The end
attribute of the selection
is always equal to TextArea.cursor_location
. In other words,
the cursor_location
attribute is simply a convenience for accessing text_area.selection.end
.
More cursor utilities¶
There are a number of additional utility methods available for interacting with the cursor.
Location information¶
Many properties exist on TextArea
which give information about the current cursor location.
These properties begin with cursor_at_
, and return booleans.
For example, cursor_at_start_of_line
tells us if the cursor is at a start of line.
We can also check the location the cursor would arrive at if we were to move it.
For example, get_cursor_right_location
returns the location
the cursor would move to if it were to move right.
A number of similar methods exist, with names like get_cursor_*_location
.
Cursor movement methods¶
The move_cursor
method allows you to move the cursor to a new location while selecting
text, or move the cursor and scroll to keep it centered.
# Move the cursor from its current location to row index 4,
# column index 8, while selecting all the text between.
text_area.move_cursor((4, 8), select=True)
The move_cursor_relative
method offers a very similar interface, but moves the cursor relative
to its current location.
Common selections¶
There are some methods available which make common selections easier:
select_line
selects a line by index. Bound to F6 by default.select_all
selects all text. Bound to F7 by default.
Themes¶
TextArea
ships with some builtin themes, and you can easily add your own.
Themes give you control over the look and feel, including syntax highlighting, the cursor, selection, gutter, and more.
Default theme¶
The default TextArea
theme is called css
, which takes it's values entirely from CSS.
This means that the default appearance of the widget fits nicely into a standard Textual application,
and looks right on both dark and light mode.
When using the css
theme, you can make use of component classes to style elements of the TextArea
.
For example, the CSS code TextArea .text-area--cursor { background: green; }
will make the cursor green
.
More complex applications such as code editors may want to use pre-defined themes such as monokai
.
This involves using a TextAreaTheme
object, which we cover in detail below.
This allows full customization of the TextArea
, including syntax highlighting, at the code level.
Using builtin themes¶
The initial theme of the TextArea
is determined by the theme
parameter.
# Create a TextArea with the 'dracula' theme.
yield TextArea.code_editor("print(123)", language="python", theme="dracula")
You can check which themes are available using the available_themes
property.
>>> text_area = TextArea()
>>> print(text_area.available_themes)
{'css', 'dracula', 'github_light', 'monokai', 'vscode_dark'}
After creating a TextArea
, you can change the theme by setting the theme
attribute to one of the available themes.
On setting this attribute the TextArea
will immediately refresh to display the updated theme.
Custom themes¶
Note
Custom themes are only relevant for people who are looking to customize syntax highlighting.
If you're only editing plain text, and wish to recolor aspects of the TextArea
, you should use the provided component classes.
Using custom (non-builtin) themes is a two-step process:
- Create an instance of
TextAreaTheme
. - Register it using
TextArea.register_theme
.
1. Creating a theme¶
Let's create a simple theme, "my_cool_theme"
, which colors the cursor blue, and the cursor line yellow.
Our theme will also syntax highlight strings as red, and comments as magenta.
from rich.style import Style
from textual.widgets.text_area import TextAreaTheme
# ...
my_theme = TextAreaTheme(
# This name will be used to refer to the theme...
name="my_cool_theme",
# Basic styles such as background, cursor, selection, gutter, etc...
cursor_style=Style(color="white", bgcolor="blue"),
cursor_line_style=Style(bgcolor="yellow"),
# `syntax_styles` is for syntax highlighting.
# It maps tokens parsed from the document to Rich styles.
syntax_styles={
"string": Style(color="red"),
"comment": Style(color="magenta"),
}
)
Attributes like cursor_style
and cursor_line_style
apply general language-agnostic
styling to the widget.
If you choose not to supply a value for one of these attributes, it will be taken from the CSS component styles.
The syntax_styles
attribute of TextAreaTheme
is used for syntax highlighting and
depends on the language
currently in use.
For more details, see syntax highlighting.
If you wish to build on an existing theme, you can obtain a reference to it using the TextAreaTheme.get_builtin_theme
classmethod:
from textual.widgets.text_area import TextAreaTheme
monokai = TextAreaTheme.get_builtin_theme("monokai")
2. Registering a theme¶
Our theme can now be registered with the TextArea
instance.
After registering a theme, it'll appear in the available_themes
:
>>> print(text_area.available_themes)
{'dracula', 'github_light', 'monokai', 'vscode_dark', 'my_cool_theme'}
We can now switch to it:
This immediately updates the appearance of the TextArea
:
Tab and Escape behaviour¶
Pressing the Tab key will shift focus to the next widget in your application by default. This matches how other widgets work in Textual.
To have Tab insert a \t
character, set the tab_behavior
attribute to the string value "indent"
.
While in this mode, you can shift focus by pressing the Esc key.
Indentation¶
The character(s) inserted when you press tab is controlled by setting the indent_type
attribute to either tabs
or spaces
.
If indent_type == "spaces"
, pressing Tab will insert up to indent_width
spaces in order to align with the next tab stop.
Undo and redo¶
TextArea
offers undo
and redo
methods.
By default, undo
is bound to Ctrl+Z and redo
to Ctrl+Y.
The TextArea
uses a heuristic to place checkpoints after certain types of edit.
When you call undo
, all of the edits between now and the most recent checkpoint are reverted.
You can manually add a checkpoint by calling the TextArea.history.checkpoint()
instance method.
The undo and redo history uses a stack-based system, where a single item on the stack represents a single checkpoint.
In memory-constrained environments, you may wish to reduce the maximum number of checkpoints that can exist.
You can do this by passing the max_checkpoints
argument to the TextArea
constructor.
Read-only mode¶
TextArea.read_only
is a boolean reactive attribute which, if True
, will prevent users from modifying content in the TextArea
.
While read_only=True
, you can still modify the content programmatically.
While this mode is active, the TextArea
receives the -read-only
CSS class, which you can use to supply custom styles for read-only mode.
Line separators¶
When content is loaded into TextArea
, the content is scanned from beginning to end
and the first occurrence of a line separator is recorded.
This separator will then be used when content is later read from the TextArea
via
the text
property. The TextArea
widget does not support exporting text which
contains mixed line endings.
Similarly, newline characters pasted into the TextArea
will be converted.
You can check the line separator of the current document by inspecting TextArea.document.newline
:
Line numbers¶
The gutter (column on the left containing line numbers) can be toggled by setting
the show_line_numbers
attribute to True
or False
.
Setting this attribute will immediately repaint the TextArea
to reflect the new value.
Extending TextArea
¶
Sometimes, you may wish to subclass TextArea
to add some extra functionality.
In this section, we'll briefly explore how we can extend the widget to achieve common goals.
Hooking into key presses¶
You may wish to hook into certain key presses to inject some functionality.
This can be done by over-riding _on_key
and adding the required functionality.
Example - closing parentheses automatically¶
Let's extend TextArea
to add a feature which automatically closes parentheses and moves the cursor to a sensible location.
from textual import events
from textual.app import App, ComposeResult
from textual.widgets import TextArea
class ExtendedTextArea(TextArea):
"""A subclass of TextArea with parenthesis-closing functionality."""
def _on_key(self, event: events.Key) -> None:
if event.character == "(":
self.insert("()")
self.move_cursor_relative(columns=-1)
event.prevent_default()
class TextAreaKeyPressHook(App):
def compose(self) -> ComposeResult:
yield ExtendedTextArea.code_editor(language="python")
app = TextAreaKeyPressHook()
if __name__ == "__main__":
app.run()
This intercepts the key handler when "("
is pressed, and inserts "()"
instead.
It then moves the cursor so that it lands between the open and closing parentheses.
Typing "def hello(
" into the TextArea
now results in the bracket automatically being closed:
Advanced concepts¶
Syntax highlighting¶
Syntax highlighting inside the TextArea
is powered by a library called tree-sitter
.
Each time you update the document in a TextArea
, an internal syntax tree is updated.
This tree is frequently queried to find location ranges relevant to syntax highlighting.
We give these ranges names, and ultimately map them to Rich styles inside TextAreaTheme.syntax_styles
.
To illustrate how this works, lets look at how the "Monokai" TextAreaTheme
highlights Markdown files.
When the language
attribute is set to "markdown"
, a highlight query similar to the one below is used (trimmed for brevity).
This highlight query maps heading_content
nodes returned by the Markdown parser to the name @heading
,
and link
nodes to the name @link
.
Inside our TextAreaTheme.syntax_styles
dict, we can map the name @heading
to a Rich style.
Here's a snippet from the "Monokai" theme which does just that:
TextAreaTheme(
name="monokai",
base_style=Style(color="#f8f8f2", bgcolor="#272822"),
gutter_style=Style(color="#90908a", bgcolor="#272822"),
# ...
syntax_styles={
# Colorise @heading and make them bold
"heading": Style(color="#F92672", bold=True),
# Colorise and underline @link
"link": Style(color="#66D9EF", underline=True),
# ...
},
)
To understand which names can be mapped inside syntax_styles
, we recommend looking at the existing
themes and highlighting queries (.scm
files) in the Textual repository.
Tip
You may also wish to take a look at the contents of TextArea._highlights
on an
active TextArea
instance to see which highlights have been generated for the
open document.
Adding support for custom languages¶
To add support for a language to a TextArea
, use the register_language
method.
To register a language, we require two things:
- A tree-sitter
Language
object which contains the grammar for the language. - A highlight query which is used for syntax highlighting.
Example - adding Java support¶
The easiest way to obtain a Language
object is using the py-tree-sitter-languages
package. Here's how we can use this package to obtain a reference to a Language
object representing Java:
The exact version of the parser used when you call get_language
can be checked via
the repos.txt
file in
the version of py-tree-sitter-languages
you're using. This file contains links to the GitHub
repos and commit hashes of the tree-sitter parsers. In these repos you can often find pre-made highlight queries at queries/highlights.scm
,
and a file showing all the available node types which can be used in highlight queries at src/node-types.json
.
Since we're adding support for Java, lets grab the Java highlight query from the repo by following these steps:
- Open
repos.txt
file from thepy-tree-sitter-languages
repo. - Find the link corresponding to
tree-sitter-java
and go to the repo on GitHub (you may also need to go to the specific commit referenced inrepos.txt
). - Go to
queries/highlights.scm
to see the example highlight query for Java.
Be sure to check the license in the repo to ensure it can be freely copied.
Warning
It's important to use a highlight query which is compatible with the parser in use, so
pay attention to the commit hash when visiting the repo via repos.txt
.
We now have our Language
and our highlight query, so we can register Java as a language.
from pathlib import Path
from tree_sitter_languages import get_language
from textual.app import App, ComposeResult
from textual.widgets import TextArea
java_language = get_language("java")
java_highlight_query = (Path(__file__).parent / "java_highlights.scm").read_text()
java_code = """\
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
"""
class TextAreaCustomLanguage(App):
def compose(self) -> ComposeResult:
text_area = TextArea.code_editor(text=java_code)
text_area.cursor_blink = False
# Register the Java language and highlight query
text_area.register_language(java_language, java_highlight_query)
# Switch to Java
text_area.language = "java"
yield text_area
app = TextAreaCustomLanguage()
if __name__ == "__main__":
app.run()
Running our app, we can see that the Java code is highlighted. We can freely edit the text, and the syntax highlighting will update immediately.
Recall that we map names (like @heading
) from the tree-sitter highlight query to Rich style objects inside the TextAreaTheme.syntax_styles
dictionary.
If you notice some highlights are missing after registering a language, the issue may be:
- The current
TextAreaTheme
doesn't contain a mapping for the name in the highlight query. Adding a new tosyntax_styles
should resolve the issue. - The highlight query doesn't assign a name to the pattern you expect to be highlighted. In this case you'll need to update the highlight query to assign to the name.
Tip
The names assigned in tree-sitter highlight queries are often reused across multiple languages.
For example, @string
is used in many languages to highlight strings.
Navigation and wrapping information¶
If you're building functionality on top of TextArea
, it may be useful to inspect the navigator
and wrapped_document
attributes.
navigator
is aDocumentNavigator
instance which can give us general information about the cursor's location within a document, as well as where the cursor will move to when certain actions are performed.wrapped_document
is aWrappedDocument
instance which can be used to convert document locations to visual locations, taking wrapping into account. It also offers a variety of other convenience methods and properties.
A detailed view of these classes is out of scope, but do note that a lot of the functionality of TextArea
exists within them, so inspecting them could be worthwhile.
Reactive attributes¶
Name | Type | Default | Description |
---|---|---|---|
language |
str | None |
None |
The language to use for syntax highlighting. |
theme |
str |
"css" |
The theme to use. |
selection |
Selection |
Selection() |
The current selection. |
show_line_numbers |
bool |
False |
Show or hide line numbers. |
indent_width |
int |
4 |
The number of spaces to indent and width of tabs. |
match_cursor_bracket |
bool |
True |
Enable/disable highlighting matching brackets under cursor. |
cursor_blink |
bool |
True |
Enable/disable blinking of the cursor when the widget has focus. |
soft_wrap |
bool |
True |
Enable/disable soft wrapping. |
read_only |
bool |
False |
Enable/disable read-only mode. |
Messages¶
Bindings¶
The TextArea
widget defines the following bindings:
Key(s) | Description |
---|---|
up | Move the cursor up. |
down | Move the cursor down. |
left | Move the cursor left. |
ctrl+left | Move the cursor to the start of the word. |
ctrl+shift+left | Move the cursor to the start of the word and select. |
right | Move the cursor right. |
ctrl+right | Move the cursor to the end of the word. |
ctrl+shift+right | Move the cursor to the end of the word and select. |
home,ctrl+a | Move the cursor to the start of the line. |
end,ctrl+e | Move the cursor to the end of the line. |
shift+home | Move the cursor to the start of the line and select. |
shift+end | Move the cursor to the end of the line and select. |
pageup | Move the cursor one page up. |
pagedown | Move the cursor one page down. |
shift+up | Select while moving the cursor up. |
shift+down | Select while moving the cursor down. |
shift+left | Select while moving the cursor left. |
shift+right | Select while moving the cursor right. |
backspace | Delete character to the left of cursor. |
ctrl+w | Delete from cursor to start of the word. |
delete,ctrl+d | Delete character to the right of cursor. |
ctrl+f | Delete from cursor to end of the word. |
ctrl+x | Delete the current line. |
ctrl+u | Delete from cursor to the start of the line. |
ctrl+k | Delete from cursor to the end of the line. |
f6 | Select the current line. |
f7 | Select all text in the document. |
ctrl+z | Undo. |
ctrl+y | Redo. |
Component classes¶
The TextArea
defines component classes that can style various aspects of the widget.
Styles from the theme
attribute take priority.
TextArea
offers some component classes which can be used to style aspects of the widget.
Note that any attributes provided in the chosen TextAreaTheme
will take priority here.
Class | Description |
---|---|
text-area--cursor |
Target the cursor. |
text-area--gutter |
Target the gutter (line number column). |
text-area--cursor-gutter |
Target the gutter area of the line the cursor is on. |
text-area--cursor-line |
Target the line the cursor is on. |
text-area--selection |
Target the current selection. |
text-area--matching-bracket |
Target matching brackets. |
See also¶
Input
- single-line text input widgetTextAreaTheme
- theming theTextArea
DocumentNavigator
- guides cursor movementWrappedDocument
- manages wrapping the documentEditHistory
- manages the undo stack- The tree-sitter documentation website.
- The tree-sitter Python bindings repository.
py-tree-sitter-languages
repository (provides binary wheels for a large variety of tree-sitter languages).
Additional notes¶
- To remove the outline effect when the
TextArea
is focused, you can setborder: none; padding: 0;
in your CSS.
textual.widgets._text_area.TextArea
class
¶
def __init__(
self,
text="",
*,
language=None,
theme="css",
soft_wrap=True,
tab_behavior="focus",
read_only=False,
show_line_numbers=False,
max_checkpoints=50,
name=None,
id=None,
classes=None,
disabled=False
):
Bases: ScrollView
Parameters
Parameter | Default | Description |
---|---|---|
text
str
|
''
|
The initial text to load into the TextArea. |
language
str | None
|
None
|
The language to use. |
theme
str
|
'css'
|
The theme to use. |
soft_wrap
bool
|
True
|
Enable soft wrapping. |
tab_behavior
Literal['focus', 'indent']
|
'focus'
|
If 'focus', pressing tab will switch focus. If 'indent', pressing tab will insert a tab. |
read_only
bool
|
False
|
Enable read-only mode. This prevents edits using the keyboard. |
show_line_numbers
bool
|
False
|
Show line numbers on the left edge. |
max_checkpoints
int
|
50
|
The maximum number of undo history checkpoints to retain. |
name
str | None
|
None
|
The name of the |
id
str | None
|
None
|
The ID of the widget, used to refer to it from Textual CSS. |
classes
str | None
|
None
|
One or more Textual CSS compatible class names separated by spaces. |
disabled
bool
|
False
|
True if the widget is disabled. |
BINDINGS
instance-attribute
class-attribute
¶
BINDINGS = [
Binding("up", "cursor_up", "cursor up", show=False),
Binding(
"down", "cursor_down", "cursor down", show=False
),
Binding(
"left", "cursor_left", "cursor left", show=False
),
Binding(
"right", "cursor_right", "cursor right", show=False
),
Binding(
"ctrl+left",
"cursor_word_left",
"cursor word left",
show=False,
),
Binding(
"ctrl+right",
"cursor_word_right",
"cursor word right",
show=False,
),
Binding(
"home,ctrl+a",
"cursor_line_start",
"cursor line start",
show=False,
),
Binding(
"end,ctrl+e",
"cursor_line_end",
"cursor line end",
show=False,
),
Binding(
"pageup",
"cursor_page_up",
"cursor page up",
show=False,
),
Binding(
"pagedown",
"cursor_page_down",
"cursor page down",
show=False,
),
Binding(
"ctrl+shift+left",
"cursor_word_left(True)",
"cursor left word select",
show=False,
),
Binding(
"ctrl+shift+right",
"cursor_word_right(True)",
"cursor right word select",
show=False,
),
Binding(
"shift+home",
"cursor_line_start(True)",
"cursor line start select",
show=False,
),
Binding(
"shift+end",
"cursor_line_end(True)",
"cursor line end select",
show=False,
),
Binding(
"shift+up",
"cursor_up(True)",
"cursor up select",
show=False,
),
Binding(
"shift+down",
"cursor_down(True)",
"cursor down select",
show=False,
),
Binding(
"shift+left",
"cursor_left(True)",
"cursor left select",
show=False,
),
Binding(
"shift+right",
"cursor_right(True)",
"cursor right select",
show=False,
),
Binding("f6", "select_line", "select line", show=False),
Binding("f7", "select_all", "select all", show=False),
Binding(
"backspace",
"delete_left",
"delete left",
show=False,
),
Binding(
"ctrl+w",
"delete_word_left",
"delete left to start of word",
show=False,
),
Binding(
"delete,ctrl+d",
"delete_right",
"delete right",
show=False,
),
Binding(
"ctrl+f",
"delete_word_right",
"delete right to start of word",
show=False,
),
Binding(
"ctrl+x", "delete_line", "delete line", show=False
),
Binding(
"ctrl+u",
"delete_to_start_of_line",
"delete to line start",
show=False,
),
Binding(
"ctrl+k",
"delete_to_end_of_line_or_delete_line",
"delete to line end",
show=False,
),
Binding("ctrl+z", "undo", "Undo", show=False),
Binding("ctrl+y", "redo", "Redo", show=False),
]
Key(s) | Description |
---|---|
up | Move the cursor up. |
down | Move the cursor down. |
left | Move the cursor left. |
ctrl+left | Move the cursor to the start of the word. |
ctrl+shift+left | Move the cursor to the start of the word and select. |
right | Move the cursor right. |
ctrl+right | Move the cursor to the end of the word. |
ctrl+shift+right | Move the cursor to the end of the word and select. |
home,ctrl+a | Move the cursor to the start of the line. |
end,ctrl+e | Move the cursor to the end of the line. |
shift+home | Move the cursor to the start of the line and select. |
shift+end | Move the cursor to the end of the line and select. |
pageup | Move the cursor one page up. |
pagedown | Move the cursor one page down. |
shift+up | Select while moving the cursor up. |
shift+down | Select while moving the cursor down. |
shift+left | Select while moving the cursor left. |
shift+right | Select while moving the cursor right. |
backspace | Delete character to the left of cursor. |
ctrl+w | Delete from cursor to start of the word. |
delete,ctrl+d | Delete character to the right of cursor. |
ctrl+f | Delete from cursor to end of the word. |
ctrl+x | Delete the current line. |
ctrl+u | Delete from cursor to the start of the line. |
ctrl+k | Delete from cursor to the end of the line. |
f6 | Select the current line. |
f7 | Select all text in the document. |
ctrl+z | Undo. |
ctrl+y | Redo. |
COMPONENT_CLASSES
class-attribute
¶
COMPONENT_CLASSES: set[str] = {
"text-area--cursor",
"text-area--gutter",
"text-area--cursor-gutter",
"text-area--cursor-line",
"text-area--selection",
"text-area--matching-bracket",
}
TextArea
offers some component classes which can be used to style aspects of the widget.
Note that any attributes provided in the chosen TextAreaTheme
will take priority here.
Class | Description |
---|---|
text-area--cursor |
Target the cursor. |
text-area--gutter |
Target the gutter (line number column). |
text-area--cursor-gutter |
Target the gutter area of the line the cursor is on. |
text-area--cursor-line |
Target the line the cursor is on. |
text-area--selection |
Target the current selection. |
text-area--matching-bracket |
Target matching brackets. |
available_languages
property
¶
A list of the names of languages available to the TextArea
.
The values in this list can be assigned to the language
reactive attribute
of TextArea
.
The returned list contains the builtin languages plus those registered via the
register_language
method. Builtin languages will be listed before
user-registered languages, but there are no other ordering guarantees.
available_themes
property
¶
A list of the names of the themes available to the TextArea
.
The values in this list can be assigned theme
reactive attribute of
TextArea
.
You can retrieve the full specification for a theme by passing one of
the strings from this list into TextAreaTheme.get_by_name(theme_name: str)
.
Alternatively, you can directly retrieve a list of TextAreaTheme
objects
(which contain the full theme specification) by calling
TextAreaTheme.builtin_themes()
.
cursor_at_end_of_line
property
¶
True if and only if the cursor is at the end of a row.
cursor_at_end_of_text
property
¶
True if and only if the cursor is at the very end of the document.
cursor_at_first_line
property
¶
True if and only if the cursor is on the first line.
cursor_at_last_line
property
¶
True if and only if the cursor is on the last line.
cursor_at_start_of_line
property
¶
True if and only if the cursor is at column 0.
cursor_at_start_of_text
property
¶
True if and only if the cursor is at location (0, 0)
cursor_blink
instance-attribute
class-attribute
¶
True if the cursor should blink.
cursor_location
writable
property
¶
The current location of the cursor in the document.
This is a utility for accessing the end
of TextArea.selection
.
cursor_screen_offset
property
¶
The offset of the cursor relative to the screen.
document
instance-attribute
¶
The document this widget is currently editing.
gutter_width
property
¶
The width of the gutter (the left column containing line numbers).
Returns
Type | Description |
---|---|
int
|
The cell-width of the line number column. If |
history
instance-attribute
¶
history: EditHistory = EditHistory(
max_checkpoints=max_checkpoints,
checkpoint_timer=2.0,
checkpoint_max_characters=100,
)
A stack (the end of the list is the top of the stack) for tracking edits.
indent_type
instance-attribute
¶
Whether to indent using tabs or spaces.
indent_width
instance-attribute
class-attribute
¶
The width of tabs or the multiple of spaces to align to on pressing the tab
key.
If the document currently open contains tabs that are currently visible on screen, altering this value will immediately change the display width of the visible tabs.
is_syntax_aware
property
¶
True if the TextArea is currently syntax aware - i.e. it's parsing document content.
language
instance-attribute
class-attribute
¶
The language to use.
This must be set to a valid, non-None value for syntax highlighting to work.
If the value is a string, a built-in language parser will be used if available.
If you wish to use an unsupported language, you'll have to register
it first using TextArea.register_language
.
match_cursor_bracket
instance-attribute
class-attribute
¶
If the cursor is at a bracket, highlight the matching bracket (if found).
navigator
instance-attribute
¶
Queried to determine where the cursor should move given a navigation action, accounting for wrapping etc.
read_only
instance-attribute
class-attribute
¶
True if the content is read-only.
Read-only means end users cannot insert, delete or replace content.
The document can still be edited programmatically via the API.
selected_text
property
¶
The text between the start and end points of the current selection.
selection
instance-attribute
class-attribute
¶
The selection start and end locations (zero-based line_index, offset).
This represents the cursor location and the current selection.
The Selection.end
always refers to the cursor location.
If no text is selected, then Selection.end == Selection.start
is True.
The text selected in the document is available via the TextArea.selected_text
property.
show_line_numbers
instance-attribute
class-attribute
¶
True to show the line number column on the left edge, otherwise False.
Changing this value will immediately re-render the TextArea
.
soft_wrap
instance-attribute
class-attribute
¶
True if text should soft wrap.
theme
instance-attribute
class-attribute
¶
The name of the theme to use.
Themes must be registered using TextArea.register_theme
before they can be used.
Syntax highlighting is only possible when the language
attribute is set.
wrap_width
property
¶
The width which gets used when the document wraps.
Accounts for gutter, scrollbars, etc.
wrapped_document
instance-attribute
¶
The wrapped view of the document.
Changed
class
¶
Bases: Message
Posted when the content inside the TextArea changes.
Handle this message using the on
decorator - @on(TextArea.Changed)
or a method named on_text_area_changed
.
SelectionChanged
class
¶
action_cursor_down
method
¶
Move the cursor down one cell.
Parameters
Parameter | Default | Description |
---|---|---|
select
bool
|
False
|
If True, select the text while moving. |
action_cursor_left
method
¶
Move the cursor one location to the left.
If the cursor is at the left edge of the document, try to move it to the end of the previous line.
Parameters
Parameter | Default | Description |
---|---|---|
select
bool
|
False
|
If True, select the text while moving. |
action_cursor_line_end
method
¶
Move the cursor to the end of the line.
action_cursor_line_start
method
¶
Move the cursor to the start of the line.
action_cursor_page_down
method
¶
Move the cursor and scroll down one page.
action_cursor_page_up
method
¶
Move the cursor and scroll up one page.
action_cursor_right
method
¶
Move the cursor one location to the right.
If the cursor is at the end of a line, attempt to go to the start of the next line.
Parameters
Parameter | Default | Description |
---|---|---|
select
bool
|
False
|
If True, select the text while moving. |
action_cursor_up
method
¶
Move the cursor up one cell.
Parameters
Parameter | Default | Description |
---|---|---|
select
bool
|
False
|
If True, select the text while moving. |
action_cursor_word_left
method
¶
Move the cursor left by a single word, skipping trailing whitespace.
Parameters
Parameter | Default | Description |
---|---|---|
select
bool
|
False
|
Whether to select while moving the cursor. |
action_cursor_word_right
method
¶
Move the cursor right by a single word, skipping leading whitespace.
action_delete_left
method
¶
Deletes the character to the left of the cursor and updates the cursor location.
If there's a selection, then the selected range is deleted.
action_delete_line
method
¶
Deletes the lines which intersect with the selection.
action_delete_right
method
¶
Deletes the character to the right of the cursor and keeps the cursor at the same location.
If there's a selection, then the selected range is deleted.
action_delete_to_end_of_line
method
¶
Deletes from the cursor location to the end of the line.
action_delete_to_end_of_line_or_delete_line
async
¶
Deletes from the cursor location to the end of the line, or deletes the line.
The line will be deleted if the line is empty.
action_delete_to_start_of_line
method
¶
Deletes from the cursor location to the start of the line.
action_delete_word_left
method
¶
Deletes the word to the left of the cursor and updates the cursor location.
action_delete_word_right
method
¶
Deletes the word to the right of the cursor and keeps the cursor at the same location.
Note that the location that we delete to using this action is not the same as the location we move to when we move the cursor one word to the right. This action does not skip leading whitespace, whereas cursor movement does.
action_undo
method
¶
Undo the edits since the last checkpoint (the most recent batch of edits).
cell_width_to_column_index
method
¶
Return the column that the cell width corresponds to on the given row.
Parameters
Parameter | Default | Description |
---|---|---|
cell_width
int
|
required | The cell width to convert. |
row_index
int
|
required | The index of the row to examine. |
Returns
Type | Description |
---|---|
int
|
The column corresponding to the cell width on that row. |
clamp_visitable
method
¶
clear
method
¶
Delete all text from the document.
Returns
Type | Description |
---|---|
EditResult
|
An EditResult relating to the deletion of all content. |
code_editor
classmethod
¶
def code_editor(
cls,
text="",
*,
language=None,
theme="monokai",
soft_wrap=False,
tab_behavior="indent",
read_only=False,
show_line_numbers=True,
max_checkpoints=50,
name=None,
id=None,
classes=None,
disabled=False
):
Construct a new TextArea
with sensible defaults for editing code.
This instantiates a TextArea
with line numbers enabled, soft wrapping
disabled, "indent" tab behavior, and the "monokai" theme.
Parameters
Parameter | Default | Description |
---|---|---|
text
str
|
''
|
The initial text to load into the TextArea. |
language
str | None
|
None
|
The language to use. |
theme
str
|
'monokai'
|
The theme to use. |
soft_wrap
bool
|
False
|
Enable soft wrapping. |
tab_behavior
Literal['focus', 'indent']
|
'indent'
|
If 'focus', pressing tab will switch focus. If 'indent', pressing tab will insert a tab. |
show_line_numbers
bool
|
True
|
Show line numbers on the left edge. |
name
str | None
|
None
|
The name of the |
id
str | None
|
None
|
The ID of the widget, used to refer to it from Textual CSS. |
classes
str | None
|
None
|
One or more Textual CSS compatible class names separated by spaces. |
disabled
bool
|
False
|
True if the widget is disabled. |
delete
method
¶
Delete the text between two locations in the document.
Parameters
Parameter | Default | Description |
---|---|---|
start
Location
|
required | The start location. |
end
Location
|
required | The end location. |
maintain_selection_offset
bool
|
True
|
If True, the active Selection will be updated such that the same text is selected before and after the selection, if possible. Otherwise, the cursor will jump to the end point of the edit. |
Returns
Type | Description |
---|---|
EditResult
|
An |
edit
method
¶
Perform an Edit.
Parameters
Parameter | Default | Description |
---|---|---|
edit
Edit
|
required | The Edit to perform. |
Returns
Type | Description |
---|---|
EditResult
|
Data relating to the edit that may be useful. The data returned |
EditResult
|
may be different depending on the edit performed. |
find_matching_bracket
method
¶
If the character is a bracket, find the matching bracket.
Parameters
Parameter | Default | Description |
---|---|---|
bracket
str
|
required | The character we're searching for the matching bracket of. |
search_from
Location
|
required | The location to start the search. |
Returns
Type | Description |
---|---|
Location | None
|
The |
Location | None
|
If the character is not available for bracket matching, |
get_column_width
method
¶
Get the cell offset of the column from the start of the row.
Parameters
Parameter | Default | Description |
---|---|---|
row
int
|
required | The row index. |
column
int
|
required | The column index (codepoint offset from start of row). |
Returns
Type | Description |
---|---|
int
|
The cell width of the column relative to the start of the row. |
get_cursor_down_location
method
¶
Get the location the cursor will move to if it moves down.
Returns
Type | Description |
---|---|
Location
|
The location the cursor will move to if it moves down. |
get_cursor_left_location
method
¶
Get the location the cursor will move to if it moves left.
Returns
Type | Description |
---|---|
Location
|
The location of the cursor if it moves left. |
get_cursor_line_end_location
method
¶
Get the location of the end of the current line.
Returns
Type | Description |
---|---|
Location
|
The (row, column) location of the end of the cursors current line. |
get_cursor_line_start_location
method
¶
Get the location of the start of the current line.
Parameters
Parameter | Default | Description |
---|---|---|
smart_home
bool
|
False
|
If True, use "smart home key" behavior - go to the first non-whitespace character on the line, and if already there, go to offset 0. Smart home only works when wrapping is disabled. |
Returns
Type | Description |
---|---|
Location
|
The (row, column) location of the start of the cursors current line. |
get_cursor_right_location
method
¶
Get the location the cursor will move to if it moves right.
Returns
Type | Description |
---|---|
Location
|
the location the cursor will move to if it moves right. |
get_cursor_up_location
method
¶
Get the location the cursor will move to if it moves up.
Returns
Type | Description |
---|---|
Location
|
The location the cursor will move to if it moves up. |
get_cursor_word_left_location
method
¶
Get the location the cursor will jump to if it goes 1 word left.
Returns
Type | Description |
---|---|
Location
|
The location the cursor will jump on "jump word left". |
get_cursor_word_right_location
method
¶
Get the location the cursor will jump to if it goes 1 word right.
Returns
Type | Description |
---|---|
Location
|
The location the cursor will jump on "jump word right". |
get_line
method
¶
Retrieve the line at the given line index.
You can stylize the Text object returned here to apply additional styling to TextArea content.
Parameters
Parameter | Default | Description |
---|---|---|
line_index
int
|
required | The index of the line. |
Returns
Type | Description |
---|---|
Text
|
A |
get_target_document_location
method
¶
Given a MouseEvent, return the row and column offset of the event in document-space.
Parameters
Parameter | Default | Description |
---|---|---|
event
MouseEvent
|
required | The MouseEvent. |
Returns
Type | Description |
---|---|
Location
|
The location of the mouse event within the document. |
get_text_range
method
¶
insert
method
¶
Insert text into the document.
Parameters
Parameter | Default | Description |
---|---|---|
text
str
|
required | The text to insert. |
location
Location | None
|
None
|
The location to insert text, or None to use the cursor location. |
maintain_selection_offset
bool
|
True
|
If True, the active Selection will be updated such that the same text is selected before and after the selection, if possible. Otherwise, the cursor will jump to the end point of the edit. |
Returns
Type | Description |
---|---|
EditResult
|
An |
load_text
method
¶
Load text into the TextArea.
This will replace the text currently in the TextArea and clear the edit history.
Parameters
Parameter | Default | Description |
---|---|---|
text
str
|
required | The text to load into the TextArea. |
move_cursor
method
¶
Move the cursor to a location.
Parameters
Parameter | Default | Description |
---|---|---|
location
Location
|
required | The location to move the cursor to. |
select
bool
|
False
|
If True, select text between the old and new location. |
center
bool
|
False
|
If True, scroll such that the cursor is centered. |
record_width
bool
|
True
|
If True, record the cursor column cell width after navigating so that we jump back to the same width the next time we move to a row that is wide enough. |
move_cursor_relative
method
¶
def move_cursor_relative(
self,
rows=0,
columns=0,
select=False,
center=False,
record_width=True,
):
Move the cursor relative to its current location in document-space.
Parameters
Parameter | Default | Description |
---|---|---|
rows
int
|
0
|
The number of rows to move down by (negative to move up) |
columns
int
|
0
|
The number of columns to move right by (negative to move left) |
select
bool
|
False
|
If True, select text between the old and new location. |
center
bool
|
False
|
If True, scroll such that the cursor is centered. |
record_width
bool
|
True
|
If True, record the cursor column cell width after navigating so that we jump back to the same width the next time we move to a row that is wide enough. |
record_cursor_width
method
¶
Record the current cell width of the cursor.
This is used where we navigate up and down through rows. If we're in the middle of a row, and go down to a row with no content, then we go down to another row, we want our cursor to jump back to the same offset that we were originally at.
register_language
method
¶
Register a language and corresponding highlight query.
Calling this method does not change the language of the TextArea
.
On switching to this language (via the language
reactive attribute),
syntax highlighting will be performed using the given highlight query.
If a string name
is supplied for a builtin supported language, then
this method will update the default highlight query for that language.
Registering a language only registers it to this instance of TextArea
.
Parameters
Parameter | Default | Description |
---|---|---|
language
'str | Language'
|
required | A string referring to a builtin language or a tree-sitter |
highlight_query
str
|
required | The highlight query to use for syntax highlighting this language. |
register_theme
method
¶
Register a theme for use by the TextArea
.
After registering a theme, you can set themes by assigning the theme
name to the TextArea.theme
reactive attribute. For example
text_area.theme = "my_custom_theme"
where "my_custom_theme"
is the
name of the theme you registered.
If you supply a theme with a name that already exists that theme will be overwritten.
replace
method
¶
Replace text in the document with new text.
Parameters
Parameter | Default | Description |
---|---|---|
insert
str
|
required | The text to insert. |
start
Location
|
required | The start location |
end
Location
|
required | The end location. |
maintain_selection_offset
bool
|
True
|
If True, the active Selection will be updated such that the same text is selected before and after the selection, if possible. Otherwise, the cursor will jump to the end point of the edit. |
Returns
Type | Description |
---|---|
EditResult
|
An |
scroll_cursor_visible
method
¶
Scroll the TextArea
such that the cursor is visible on screen.
Parameters
Parameter | Default | Description |
---|---|---|
center
bool
|
False
|
True if the cursor should be scrolled to the center. |
animate
bool
|
False
|
True if we should animate while scrolling. |
Returns
Type | Description |
---|---|
Offset
|
The offset that was scrolled to bring the cursor into view. |
select_line
method
¶
Select all the text in the specified line.
Parameters
Parameter | Default | Description |
---|---|---|
index
int
|
required | The index of the line to select (starting from 0). |
undo
method
¶
Undo the edits since the last checkpoint (the most recent batch of edits).
Highlight
module-attribute
¶
A tuple representing a syntax highlight within one line.
Location
module-attribute
¶
A location (row, column) within the document. Indexing starts at 0.
Document
class
¶
Bases: DocumentBase
A document which can be opened in a TextArea.
lines
property
¶
Get the document as a list of strings, where each string represents a line.
Newline characters are not included in at the end of the strings.
The newline character used in this document can be found via the Document.newline
property.
get_index_from_location
method
¶
get_line
method
¶
get_location_from_index
method
¶
get_size
method
¶
get_text_range
method
¶
Get the text that falls between the start and end locations.
Returns the text between start
and end
, including the appropriate
line separator character as specified by Document._newline
. Note that
_newline
is set automatically to the first line separator character
found in the document.
Parameters
Parameter | Default | Description |
---|---|---|
start
Location
|
required | The start location of the selection. |
end
Location
|
required | The end location of the selection. |
Returns
Type | Description |
---|---|
str
|
The text between start (inclusive) and end (exclusive). |
replace_range
method
¶
Replace text at the given range.
This is the only method by which a document may be updated.
Parameters
Parameter | Default | Description |
---|---|---|
start
Location
|
required | A tuple (row, column) where the edit starts. |
end
Location
|
required | A tuple (row, column) where the edit ends. |
text
str
|
required | The text to insert between start and end. |
Returns
Type | Description |
---|---|
EditResult
|
The EditResult containing information about the completed replace operation. |
DocumentBase
class
¶
Bases: ABC
Describes the minimum functionality a Document implementation must provide in order to be used by the TextArea widget.
lines
property
abstractmethod
¶
Get the lines of the document as a list of strings.
The strings should not include newline characters. The newline character used for the document can be retrieved via the newline property.
start
property
abstractmethod
¶
Returns the location of the start of the document (0, 0).
get_line
abstractmethod
¶
Returns the line with the given index from the document.
This is used in rendering lines, and will be called by the TextArea for each line that is rendered.
Parameters
Parameter | Default | Description |
---|---|---|
index
int
|
required | The index of the line in the document. |
Returns
Type | Description |
---|---|
str
|
The str instance representing the line. |
get_size
abstractmethod
¶
Get the size of the document.
The height is generally the number of lines, and the width is generally the maximum cell length of all the lines.
Parameters
Parameter | Default | Description |
---|---|---|
indent_width
int
|
required | The width to use for tab characters. |
Returns
Type | Description |
---|---|
Size
|
The Size of the document bounding box. |
get_text_range
abstractmethod
¶
Get the text that falls between the start and end locations.
Parameters
Parameter | Default | Description |
---|---|---|
start
Location
|
required | The start location of the selection. |
end
Location
|
required | The end location of the selection. |
Returns
Type | Description |
---|---|
str
|
The text between start (inclusive) and end (exclusive). |
query_syntax_tree
method
¶
Query the tree-sitter syntax tree.
The default implementation always returns an empty list.
To support querying in a subclass, this must be implemented.
Parameters
Parameter | Default | Description |
---|---|---|
query
Query
|
required | The tree-sitter Query to perform. |
start_point
tuple[int, int] | None
|
None
|
The (row, column byte) to start the query at. |
end_point
tuple[int, int] | None
|
None
|
The (row, column byte) to end the query at. |
Returns
Type | Description |
---|---|
list[tuple[Node, str]]
|
A tuple containing the nodes and text captured by the query. |
replace_range
abstractmethod
¶
Replace the text at the given range.
Parameters
Parameter | Default | Description |
---|---|---|
start
Location
|
required | A tuple (row, column) where the edit starts. |
end
Location
|
required | A tuple (row, column) where the edit ends. |
text
str
|
required | The text to insert between start and end. |
Returns
Type | Description |
---|---|
EditResult
|
The new end location after the edit is complete. |
DocumentNavigator
class
¶
Cursor navigation in the TextArea is "wrapping-aware".
Although the cursor location (the selection) is represented as a location in the raw document, when you actually move the cursor, it must take wrapping into account (otherwise things start to look really confusing to the user where wrapping is involved).
Your cursor visually moves through the wrapped version of the document, rather than the raw document. So, for example, pressing down on the keyboard may move your cursor to a position further along the current raw document line, rather than on to the next line in the raw document.
The DocumentNavigator class manages that behaviour.
Given a cursor location in the unwrapped document, and a cursor movement action, this class can inform us of the destination the cursor will move to considering the current wrapping width and document content. It can also translate between document-space (a location/(row,col) in the raw document), and visual-space (x and y offsets) as the user will see them on screen after the document has been wrapped.
For this to work correctly, the wrapped_document and document must be synchronised. This means that if you make an edit to the document, you must then update the wrapped document, and then you may query the document navigator.
Naming conventions:
A "location" refers to a location, in document-space (in the raw document). It is entirely unrelated to visually positioning. A location in a document can appear in any visual position, as it is influenced by scrolling, wrapping, gutter settings, and the cell width of characters to its left.
A "wrapped section" refers to a portion of the line accounting for wrapping. For example the line "ABCDEF" when wrapped at width 3 will result in 2 sections: "ABC" and "DEF". In this case, we call "ABC" is the first section/wrapped section.
A "wrap offset" is an integer representing the index at which wrapping occurs in a document-space line. This is a codepoint index, rather than a visual offset. In "ABCDEF" with wrapping at width 3, there is a single wrap offset of 3.
"Smart home" refers to a modification of the "home" key behaviour. If smart home is enabled, the first non-whitespace character is considered to be the home location. If the cursor is currently at this position, then the normal home behaviour applies. This is designed to make cursor movement more useful to end users.
Parameters
Parameter | Default | Description |
---|---|---|
wrapped_document
WrappedDocument
|
required | The WrappedDocument to be used when making navigation decisions. |
last_x_offset
instance-attribute
¶
Remembers the last x offset (cell width) the cursor was moved horizontally to, so that it can be restored on vertical movement where possible.
clamp_reachable
method
¶
get_location_above
method
¶
get_location_at_y_offset
method
¶
Apply a visual vertical offset to a location and check the resulting location.
Parameters
Parameter | Default | Description |
---|---|---|
location
Location
|
required | The location to start from. |
vertical_offset
int
|
required | The vertical offset to move (negative=up, positive=down). |
Returns
Type | Description |
---|---|
Location
|
The location after the offset has been applied. |
get_location_below
method
¶
Given a location in the raw document, return the raw document location corresponding to moving down in the wrapped representation of the document.
Parameters
Parameter | Default | Description |
---|---|---|
location
Location
|
required | The location in the raw document. |
Returns
Type | Description |
---|---|
Location
|
The location which is visually below the given location. |
get_location_end
method
¶
get_location_home
method
¶
Get the "home location" corresponding to the given location.
Parameters
Parameter | Default | Description |
---|---|---|
location
Location
|
required | The location to consider. |
smart_home
bool
|
False
|
Enable/disable 'smart home' behaviour. |
Returns
Type | Description |
---|---|
Location
|
The home location, relative to the given location. |
get_location_left
method
¶
Get the location to the left of the given location.
Note that if the given location is at the start of the line, then this will return the end of the preceding line, since that's where you would expect the cursor to move.
Parameters
Parameter | Default | Description |
---|---|---|
location
Location
|
required | The location to start from. |
Returns
Type | Description |
---|---|
Location
|
The location to the right. |
get_location_right
method
¶
Get the location to the right of the given location.
Note that if the given location is at the end of the line, then this will return the start of the following line, since that's where you would expect the cursor to move.
Parameters
Parameter | Default | Description |
---|---|---|
location
Location
|
required | The location to start from. |
Returns
Type | Description |
---|---|
Location
|
The location to the right. |
is_end_of_document
method
¶
is_end_of_document_line
method
¶
True if the location is at the end of a line in the document.
Note that the "end" of a line is equal to its length (one greater than the final index), since there is a space at the end of the line for the cursor to rest.
Parameters
Parameter | Default | Description |
---|---|---|
location
Location
|
required | The location to examine. |
Returns
Type | Description |
---|---|
bool
|
True if and only if the document is at the end of a line in the document. |
is_end_of_wrapped_line
method
¶
is_first_document_line
method
¶
is_first_wrapped_line
method
¶
is_last_document_line
method
¶
is_last_wrapped_line
method
¶
Check if the given location is on the last wrapped section of the last line.
That is, the cursor is visually on the last rendered row.
Parameters
Parameter | Default | Description |
---|---|---|
location
Location
|
required | The location to examine. |
Returns
Type | Description |
---|---|
bool
|
True if and only if the cursor is on the last section of the last line. |
is_start_of_document
method
¶
is_start_of_document_line
method
¶
is_start_of_wrapped_line
method
¶
Edit
class
¶
Implements the Undoable protocol to replace text at some range within a document.
bottom
property
¶
The Location impacted by this edit that is nearest the end of the document.
maintain_selection_offset
instance-attribute
¶
If True, the selection will maintain its offset to the replacement range.
top
property
¶
The Location impacted by this edit that is nearest the start of the document.
after
method
¶
Hook for running code after an Edit has been performed via Edit.do
and
side effects such as re-wrapping the document and refreshing the display
have completed.
For example, we can't record cursor visual offset until we know where the cursor will land after wrapping has been performed, so we must wait until here to do it.
Parameters
Parameter | Default | Description |
---|---|---|
text_area
TextArea
|
required | The |
do
method
¶
Perform the edit operation.
Parameters
Parameter | Default | Description |
---|---|---|
text_area
TextArea
|
required | The |
record_selection
bool
|
True
|
If True, record the current selection in the TextArea so that it may be restored if this Edit is undone in the future. |
Returns
Type | Description |
---|---|
EditResult
|
An |
undo
method
¶
Undo the edit operation.
Looks at the data stored in the edit, and performs the inverse operation of Edit.do
.
Parameters
Parameter | Default | Description |
---|---|---|
text_area
TextArea
|
required | The |
Returns
Type | Description |
---|---|
EditResult
|
An |
EditHistory
class
¶
Manages batching/checkpointing of Edits into groups that can be undone/redone in the TextArea.
checkpoint_max_characters
instance-attribute
¶
Maximum number of characters that can appear in a batch before a new batch is formed.
checkpoint_timer
instance-attribute
¶
Maximum number of seconds since last edit until a new batch is created.
redo_stack
property
¶
A copy of the redo stack, with references to the original Edits.
undo_stack
property
¶
A copy of the undo stack, with references to the original Edits.
record
method
¶
Record an Edit so that it may be undone and redone.
Determines whether to batch the Edit with previous Edits, or create a new batch/checkpoint.
This method must be called exactly once per edit, in chronological order.
A new batch/checkpoint is created when:
- The undo stack is empty.
- The checkpoint timer expires.
- The maximum number of characters permitted in a checkpoint is reached.
- A redo is performed (we should not add new edits to a batch that has been redone).
- The programmer has requested a new batch via a call to
force_new_batch
.- e.g. the TextArea widget may call this method in some circumstances.
- Clicking to move the cursor elsewhere in the document should create a new batch.
- Movement of the cursor via a keyboard action that is NOT an edit.
- Blurring the TextArea creates a new checkpoint.
- The current edit involves a deletion/replacement and the previous edit did not.
- The current edit is a pure insertion and the previous edit was not.
- The edit involves insertion or deletion of one or more newline characters.
- An edit which inserts more than a single character (a paste) gets an isolated batch.
Parameters
Parameter | Default | Description |
---|---|---|
edit
Edit
|
required | The edit to record. |
EditResult
class
¶
LanguageDoesNotExist
class
¶
Bases: Exception
Raised when the user tries to use a language which does not exist. This means a language which is not builtin, or has not been registered.
Selection
class
¶
Bases: NamedTuple
A range of characters within a document from a start point to the end point.
The location of the cursor is always considered to be the end
point of the selection.
The selection is inclusive of the minimum point and exclusive of the maximum point.
end
instance-attribute
class-attribute
¶
The end location of the selection.
If you were to click and drag a selection inside a text-editor, this is where you finished dragging.
is_empty
property
¶
Return True if the selection has 0 width, i.e. it's just a cursor.
start
instance-attribute
class-attribute
¶
The start location of the selection.
If you were to click and drag a selection inside a text-editor, this is where you started dragging.
SyntaxAwareDocument
class
¶
Bases: Document
A wrapper around a Document which also maintains a tree-sitter syntax tree when the document is edited.
The primary reason for this split is actually to keep tree-sitter stuff separate, since it isn't supported in Python 3.7. By having the tree-sitter code isolated in this subclass, it makes it easier to conditionally import. However, it does come with other design flaws (e.g. Document is required to have methods which only really make sense on SyntaxAwareDocument).
If you're reading this and Python 3.7 is no longer supported by Textual,
consider merging this subclass into the Document
superclass.
Parameters
Parameter | Default | Description |
---|---|---|
text
str
|
required | The initial text contained in the document. |
language
str | Language
|
required | The language to use. You can pass a string to use a supported
language, or pass in your own tree-sitter |
language
instance-attribute
¶
The tree-sitter Language or None if tree-sitter is unavailable.
get_line
method
¶
prepare_query
method
¶
Prepare a tree-sitter tree query.
Queries should be prepared once, then reused.
To execute a query, call query_syntax_tree
.
Parameters
Parameter | Default | Description |
---|---|---|
query
str
|
required | The string query to prepare. |
Returns
Type | Description |
---|---|
Query | None
|
The prepared query. |
query_syntax_tree
method
¶
Query the tree-sitter syntax tree.
The default implementation always returns an empty list.
To support querying in a subclass, this must be implemented.
Parameters
Parameter | Default | Description |
---|---|---|
query
Query
|
required | The tree-sitter Query to perform. |
start_point
tuple[int, int] | None
|
None
|
The (row, column byte) to start the query at. |
end_point
tuple[int, int] | None
|
None
|
The (row, column byte) to end the query at. |
Returns
Type | Description |
---|---|
list[tuple['Node', str]]
|
A tuple containing the nodes and text captured by the query. |
replace_range
method
¶
Replace text at the given range.
Parameters
Parameter | Default | Description |
---|---|---|
start
Location
|
required | A tuple (row, column) where the edit starts. |
end
Location
|
required | A tuple (row, column) where the edit ends. |
text
str
|
required | The text to insert between start and end. |
Returns
Type | Description |
---|---|
EditResult
|
The new end location after the edit is complete. |
TextAreaTheme
class
¶
A theme for the TextArea
widget.
Allows theming the general widget (gutter, selections, cursor, and so on) and mapping of tree-sitter tokens to Rich styles.
For example, consider the following snippet from the markdown.scm
highlight
query file. We've assigned the heading_content
token type to the name heading
.
Now, we can map this heading
name to a Rich style, and it will be styled as
such in the TextArea
, assuming a parser which returns a heading_content
node is used (as will be the case when language="markdown").
We can register this theme with our TextArea
using the TextArea.register_theme
method,
and headings in our markdown files will be styled bold cyan.
base_style
instance-attribute
class-attribute
¶
The background style of the text area. If None
the parent style will be used.
bracket_matching_style
instance-attribute
class-attribute
¶
The style to apply to matching brackets. If None
, a legible Style will be generated.
cursor_line_gutter_style
instance-attribute
class-attribute
¶
The style to apply to the gutter of the line the cursor is on. If None
, a legible Style will be
generated.
cursor_line_style
instance-attribute
class-attribute
¶
The style to apply to the line the cursor is on.
cursor_style
instance-attribute
class-attribute
¶
The style of the cursor. If None
, a legible Style will be generated.
gutter_style
instance-attribute
class-attribute
¶
The style of the gutter. If None
, a legible Style will be generated.
selection_style
instance-attribute
class-attribute
¶
The style of the selection. If None
a default selection Style will be generated.
syntax_styles
instance-attribute
class-attribute
¶
The mapping of tree-sitter names from the highlight_query
to Rich styles.
apply_css
method
¶
Apply CSS rules from a TextArea to be used for fallback styling.
If any attributes in the theme aren't supplied, they'll be filled with the appropriate base CSS (e.g. color, background, etc.) and component CSS (e.g. text-area--cursor) from the supplied TextArea.
Parameters
Parameter | Default | Description |
---|---|---|
text_area
TextArea
|
required | The TextArea instance to retrieve fallback styling from. |
builtin_themes
classmethod
¶
Get a list of all builtin TextAreaThemes.
Returns
Type | Description |
---|---|
list[TextAreaTheme]
|
A list of all builtin TextAreaThemes. |
get_builtin_theme
classmethod
¶
Get a TextAreaTheme
by name.
Given a theme_name
, return the corresponding TextAreaTheme
object.
Parameters
Parameter | Default | Description |
---|---|---|
theme_name
str
|
required | The name of the theme. |
Returns
Type | Description |
---|---|
TextAreaTheme | None
|
The |
get_highlight
method
¶
ThemeDoesNotExist
class
¶
Bases: Exception
Raised when the user tries to use a theme which does not exist. This means a theme which is not builtin, or has not been registered.
WrappedDocument
class
¶
A view into a Document which wraps the document at a certain width and can be queried to retrieve lines from the wrapped version of the document.
Allows for incremental updates, ensuring that we only re-wrap ranges of the document that were influenced by edits.
By default, a WrappedDocument is wrapped with width=0 (no wrapping). To wrap the document, use the wrap() method.
Parameters
Parameter | Default | Description |
---|---|---|
document
DocumentBase
|
required | The document to wrap. |
width
int
|
0
|
The width to wrap at. |
tab_width
int
|
4
|
The maximum width to consider for tab characters. |
lines
property
¶
The lines of the wrapped version of the Document.
Each index in the returned list represents a line index in the raw document. The list[str] at each index is the content of the raw document line split into multiple lines via wrapping.
Note that this is expensive to compute and is not cached.
Returns
Type | Description |
---|---|
list[list[str]]
|
A list of lines from the wrapped version of the document. |
wrapped
property
¶
True if the content is wrapped. This is not the same as wrapping being "enabled". For example, an empty document can have wrapping enabled, but no wrapping has actually occurred.
In other words, this is True if the length of any line in the document is greater than the available width.
get_offsets
method
¶
Given a line index, get the offsets within that line where wrapping should occur for the current document.
Parameters
Parameter | Default | Description |
---|---|---|
line_index
int
|
required | The index of the line within the document. |
Raises
Type | Description |
---|---|
ValueError
|
When |
Returns
Type | Description |
---|---|
list[int]
|
The offsets within the line where wrapping should occur. |
get_sections
method
¶
Return the sections for the given line index.
When wrapping is enabled, a single line in the document can visually span multiple lines. The list returned represents that visually (each string in the list represents a single section (y-offset) after wrapping happens).
Parameters
Parameter | Default | Description |
---|---|---|
line_index
int
|
required | The index of the line to get sections for. |
Returns
Type | Description |
---|---|
list[str]
|
The wrapped line as a list of strings. |
get_tab_widths
method
¶
get_target_document_column
method
¶
Given a line index and the offsets within the wrapped version of that line, return the corresponding column index in the raw document.
Parameters
Parameter | Default | Description |
---|---|---|
line_index
int
|
required | The index of the line in the document. |
x_offset
int
|
required | The x-offset within the wrapped line. |
y_offset
int
|
required | The y-offset within the wrapped line (supports negative indexing). |
Returns
Type | Description |
---|---|
int
|
The column index corresponding to the line index and y offset. |
location_to_offset
method
¶
Convert a location in the document to an offset within the wrapped/visual display of the document.
Parameters
Parameter | Default | Description |
---|---|---|
location
Location
|
required | The location in the document. |
Returns
Type | Description |
---|---|
Offset
|
The Offset in the document's visual display corresponding to the given location. |
offset_to_location
method
¶
Given an offset within the wrapped/visual display of the document, return the corresponding location in the document.
Parameters
Parameter | Default | Description |
---|---|---|
offset
Offset
|
required | The y-offset within the document. |
Raises
Type | Description |
---|---|
ValueError
|
When the given offset does not correspond to a line in the document. |
Returns
Type | Description |
---|---|
Location
|
The Location in the document corresponding to the given offset. |
wrap
method
¶
wrap_range
method
¶
Incrementally recompute wrapping based on a performed edit.
This must be called after the source document has been edited.
Parameters
Parameter | Default | Description |
---|---|---|
start
Location
|
required | The start location of the edit that was performed in document-space. |
old_end
Location
|
required | The old end location of the edit in document-space. |
new_end
Location
|
required | The new end location of the edit in document-space. |