docs: explain Tessera modules and execution flows in Chinese

This commit is contained in:
2026-11-11 23:36:03 +08:00
parent 4c3fc8b5dd
commit 1fedd21d3c
77 changed files with 1418 additions and 0 deletions
+12
View File
@@ -1,3 +1,6 @@
//! 多行文本选择和光标导航。选择端点映射到合法字符边界,避免把 UTF-8 字节中间当成一个字符。
//! 工具只保留当前文本行和选择范围;复制操作取得的是所选内容,不是整份运行时状态。
//!
//! Read-only, grapheme-aware source selection, independent of console editing.
use crate::{
geometry::Point,
@@ -6,6 +9,7 @@ use crate::{
use unicode_segmentation::UnicodeSegmentation;
#[derive(Debug, Default)]
/// 行文本、锚点与选择端点,既供鼠标拖选也供键盘导航使用。
pub(super) struct SourceSelection {
lines: Vec<String>,
anchor: (usize, usize),
@@ -13,6 +17,7 @@ pub(super) struct SourceSelection {
pub dragging: bool,
}
impl SourceSelection {
/// 替换可选择文本行,并把旧选择限制在新文本仍有效的位置。
pub fn set_lines(&mut self, lines: &[String]) {
if self.lines != lines {
self.lines = lines.to_vec();
@@ -21,6 +26,7 @@ impl SourceSelection {
self.dragging = false;
}
}
/// 把工具指针位置换算成合法行号与文本字符边界。
fn locate(p: Point, origin: Point, lines: &[String]) -> (usize, usize) {
let row = (((p.y - origin.y) / super::ROW).floor().max(0.0) as usize)
.min(lines.len().saturating_sub(1));
@@ -39,14 +45,17 @@ impl SourceSelection {
}
(row, byte)
}
/// 在指针位置建立文本选择锚点,开始一次拖动选择。
pub fn begin(&mut self, p: Point, origin: Point, lines: &[String]) {
self.anchor = Self::locate(p, origin, lines);
self.end = self.anchor;
self.dragging = true;
}
/// 保持原锚点,随指针更新选择另一端。
pub fn extend(&mut self, p: Point, origin: Point, lines: &[String]) {
self.end = Self::locate(p, origin, lines);
}
/// 用键盘移动文本选择端点,按扩展模式决定是否保留锚点。
pub fn navigate(
&mut self,
key: &winit::keyboard::NamedKey,
@@ -109,6 +118,7 @@ impl SourceSelection {
}
Some(row)
}
/// 返回排序后的有效选择范围,隐藏拖动方向差异。
fn range(&self, all: bool) -> ((usize, usize), (usize, usize)) {
if all {
return (
@@ -121,6 +131,7 @@ impl SourceSelection {
}
(self.anchor.min(self.end), self.anchor.max(self.end))
}
/// 拼接当前选择范围内的实际文本,保持多行换行与 UTF-8 边界。
pub fn text(&self, all: bool) -> String {
let (a, b) = self.range(all);
self.lines
@@ -135,6 +146,7 @@ impl SourceSelection {
.collect::<Vec<_>>()
.join("\n")
}
/// 取得某行的可见选择片段,供高亮绘制复用。
pub fn span(&self, row: usize, all: bool, lines: &[String]) -> Option<(f32, f32)> {
let (a, b) = self.range(all);
if row < a.0 || row > b.0 || a == b {