Textual Textarea
注意:这不是官方的 TextArea 组件!
从 v0.38.0 开始,Textual 添加了一个内置的 TextArea 组件。您可能希望使用该组件而不是此组件。该项目早于官方组件;版本 < v0.8.0 具有完全独立的实现。
从 v0.8.0 开始,该项目使用内置的 TextArea 组件,但添加了以下概述的功能。
安装
pip install textual-textarea
功能
在您的 Textual 应用中,提供具有类似 VS-Code 键位绑定的功能齐全的文本编辑器体验:
- 语法高亮以及对 Pygments 主题的支持。
- 使用鼠标或按键移动光标和滚动(包括 ctrl+arrow、PgUp/Dn、ctrl+Home/End)。
- 打开(ctrl+o)和保存(ctrl+s)文件。
- 剪切(ctrl+x)、复制(ctrl+c)、粘贴(ctrl+u/v),可选使用系统剪贴板。在支持 Kitty 键盘协议的终端上,cmd 等效键也可用。
- 使用 ctrl+backspace、alt+backspace 或 alt+delete 删除一个单词。
- 使用 ctrl+/ 注释选中的文本。
- 使用 Tab 和 shift+Tab 进行缩进和取消缩进(可选针对多行选择)至制表位。
- 自动补全引号和括号。
- 通过双击、三击或四击选择文本。
- 使用 ctrl+q 退出。
用法
初始化 Widget
TextArea 是一个 Textual Widget。您可以使用 compose 或 mount 将其添加到 Textual
应用中:
from textual_textarea import TextEditor
from textual.app import App, ComposeResult
class TextApp(App, inherit_bindings=False):
def compose(self) -> ComposeResult:
yield TextEditor(text="hi", language="python", theme="nord-darker", id="ta")
def on_mount(self) -> None:
editor = self.query_one("#id", expect_type=TextEditor)
editor.focus()
app = TextApp()
app.run()
除了标准的 Widget 参数外,TextArea 在初始化 widget 时还接受三个额外的可选参数:
- language (str): 必须是
None或 Pygments lexer 的短名称,例如python、sql、as3。默认为None。 - theme (str): 必须是 Pygments style 的名称,例如
bw、github-dark、solarized-light。默认为monokai。 - use_system_clipboard (bool): 设置为
False可使 TextArea 的复制和粘贴操作忽略系统剪贴板。默认为True。某些 Linux 用户可能需要通过 apt 安装xclip或xsel以启用系统剪贴板功能。
TextArea 支持许多操作和按键绑定。为了正确将 ctrl+c 绑定到 COPY 操作,
你必须使用 inherit_bindings=False 初始化你的 App(如上文所示),以便 ctrl+c 不会退出应用。TextArea 将 ctrl+q 实现为退出操作;你可能希望在你的应用中模仿该行为,以便其他获得焦点的 widget 使用相同的行为。
与 Widget 交互
获取和设置文本
TextArea 暴露了一个 text 属性,其中包含 widget 中的完整文本。你可以通过操作此属性来获取或设置文本:
editor = self.query_one(TextEditor)
old_text = editor.text
editor.text = "New Text!\n\nMany Lines!"
类似地,TextEditor 暴露了一个 selected_text 属性(只读):
editor = self.query_one(TextEditor)
selection = editor.selected_text
插入文本
您可以在当前选择位置插入文本:
editor = self.query_one(TextEditor)
editor.text = "01234"
editor.selection = Selection((0, 2), (0, 2))
editor.insert_text_at_selection("\nabc\n")
assert editor.text == "01\nabc\n234"
assert editor.selection == Selection((2, 0), (2, 0))
获取和设置光标位置
TextEditor 暴露了一个 selection 属性,该属性返回一个 textual.widgets.text_area.Selection:
editor = self.query_one(TextEditor)
old_selection = editor.selection
editor.selection = Selection((999, 0),(999, 0)) # the cursor will move as close to line 999, pos 0 as possible
cursor_line_number = editor.selection.end[0]
cursor_x_position = editor.selection.end[1]
获取和设置语言
语法高亮和注释插入取决于为 TextEditor 配置的语言。
TextArea 暴露了一个 language 属性,该属性返回 None 或一个与已安装的 tree-sitter 语言短名称相等的字符串:
editor = self.query_one(TextEditor)
old_language = editor.language
editor.language = "python"
获取主题颜色
如果你希望应用程序的其余部分与 TextArea 主题的颜色相匹配,它们通过 theme_colors 属性暴露。
editor = self.query_one(TextEditor)
color = editor.theme_colors.contrast_text_color
bgcolor = editor.theme_colors.bgcolor
highlight = editor.theme_colors.selection_bgcolor
添加绑定及其他行为
你可以子类化 TextEditor 以添加自定义行为。此代码片段添加了一个操作,当用户按下 ctrl+j 时,发送一条包含 TextEditor 文本的 Submitted 消息:
from textual.message import Message
from textual_textarea import TextEditor
class CodeEditor(TextEditor):
BINDINGS = [
("ctrl+j", "submit", "Run Query"),
]
class Submitted(Message, bubble=True):
def __init__(self, text: str) -> None:
super().__init__()
self.text = text
async def action_submit(self) -> None:
self.post_message(self.Submitted(self.text))