Compare commits
5
Commits
15d4c2066d
...
b973c8d62a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b973c8d62a
|
||
|
|
02b86cd5cd
|
||
|
|
587862ed4d
|
||
|
|
0dea1fabb4
|
||
|
|
98692cb80f
|
No files matched your search
Generated
+1
-1
@@ -1923,7 +1923,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ely-gpui-component"
|
||||
version = "0.1.1"
|
||||
source = "git+https://git.zacharyzhang.com/ZacharyZhang-NY/Ely-GPUI-Components?rev=2b8bd9fcf3ab94a3399ca70bfaf0a6764291f5ec#2b8bd9fcf3ab94a3399ca70bfaf0a6764291f5ec"
|
||||
source = "git+https://git.zacharyzhang.com/ZacharyZhang-NY/Ely-GPUI-Components?rev=2b6bd1d36951713e61763bcd9572bbd42464dd7d#2b6bd1d36951713e61763bcd9572bbd42464dd7d"
|
||||
dependencies = [
|
||||
"alacritty_terminal",
|
||||
"anyhow",
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ jiff = "0.2"
|
||||
anyhow = "1"
|
||||
directories = "6"
|
||||
dunce = "1"
|
||||
ely-gpui-component = { git = "https://git.zacharyzhang.com/ZacharyZhang-NY/Ely-GPUI-Components", rev = "2b8bd9fcf3ab94a3399ca70bfaf0a6764291f5ec" }
|
||||
ely-gpui-component = { git = "https://git.zacharyzhang.com/ZacharyZhang-NY/Ely-GPUI-Components", rev = "2b6bd1d36951713e61763bcd9572bbd42464dd7d" }
|
||||
env_logger = "0.11"
|
||||
gpui = { package = "gpui-pre", version = "=0.3.8", default-features = false, features = ["stacker"] }
|
||||
gpui_platform = { package = "gpui-pre-platform", version = "=0.3.8", features = ["font-kit", "wayland", "x11"] }
|
||||
|
||||
@@ -40,7 +40,7 @@ site/ 官网(Vite 8、pnpm、TypeScript,无框架;等轴 SVG 积木
|
||||
|
||||
## 组件映射
|
||||
|
||||
依赖 `ely-gpui-component`(pin 2b8bd9f,gpui 为 crates.io 的 `gpui-pre` =0.3.8)。名字取自 `reference/Ely-GPUI-Components/src`。gpui 用法规则见该仓库 `AGENTS.md`。`tests/scripts/agents_md.py` 核对下表每个名字都是组件库公开项。
|
||||
依赖 `ely-gpui-component`(pin 2b6bd1d,gpui 为 crates.io 的 `gpui-pre` =0.3.8)。名字取自 `reference/Ely-GPUI-Components/src`。gpui 用法规则见该仓库 `AGENTS.md`。`tests/scripts/agents_md.py` 核对下表每个名字都是组件库公开项。
|
||||
|
||||
| 需要 | 用 |
|
||||
| --- | --- |
|
||||
@@ -296,3 +296,4 @@ cargo run -p ely-doc 启动一个应用(ElyDoc 先 cargo build -p ely
|
||||
- 2026-10-14:ElyMark 的右键菜单(R4.10)。项、次序与显隐规则取自 Typora 1.14.10 的 `resources/window.html`(`#context-menu` 与其子菜单)与 `frame.js` 的显隐函数,记在 `.work/R4.10/typora-context-menu.txt`。菜单在 `view/menu.rs`,`MarkView` 自持(`ely_office::menu::Offer` 与 `ContextMenu::manual`):可视模式由组件的 `DocumentEvent::Pointed` 开在指针处,源码与预览由视图自己的右键开。剪切、复制、粘贴、删除所选范围为图标行,按下即把其键交回菜单打开前的焦点(`dispatch_keystroke`),与键盘同一路径;无选区时剪切、复制、删除灰显。其余项经各自的动作,显示所绑的键。组件 013f142、1b5fb07:文本框与代码编辑器右键落在选区里时保留选区,否则把插入点移到所点处;可视模式打开的块右键不写回、不关闭,目标在后台按全文读出(块外的引用定义照样解析);`MarkdownDocument::delete_image`(删除图片,一步撤销,无图片即 `EditRefusal::NoImage`);可视无块时 Ctrl+V 粘贴文字(原只收图片,文字被丢弃)。复制为 HTML 代码的图片照原地址(`Pictures::Written`,同 Typora),复制为富文本照旧内嵌。“编辑”菜单的复制项照 Typora 次序:纯文本、Markdown、HTML 代码、富文本。Typora 有而不做的:缩进与减少缩进行(可视只在打开的块里有)、复制表格、代码自动缩进、图片上传、缩放、移动与语法切换、拼写、表情复制、检查元素。gpui 的测试只发按下,菜单在 Enter 松开时选中,测试另发松开(`blocks/context.rs` 的 `choose`)。第 1 轮后:右键的目标按所点的字节读(组件 79e94f7),保留的选区只供剪贴板,删除图片删所点的那张;三种“复制为”在后台转换,界面线程只写剪贴板,新的复制取代未完成的旧复制(`Desk::copying`);`ely_office::menu::Offer` 只在首次绘制时把请求交给宿主(宿主按元素存的“已开”记录随标签切走而丢,切回会重开),ElyDoc、ElyTable、ElyShow 同受其益。第 2 轮后:转换完成时剪贴板已不是开始时的内容(此后有任何复制,含编辑器自己的 Ctrl+C)即丢弃这次结果,同内容的再次写入分不出;打开的块里只认最后一次右键(组件 2b8bd9f),所点字节对回所画字节的读法逐段只对齐一次(原逐字重读,8000 字的段落要近 2 秒)。第 3 轮后:剪贴板的比对另含其 HTML(gpui 读剪贴板不含 HTML,纯文字相同而富文本不同的后来复制原被盖掉;`ely_platform::clipboard::html`);组件的计时测试改用 `web_time::Instant`(组件 e07fd34)。
|
||||
- 2026-10-14(用户报:整个软件中文显示问题很多):中文显示(R4.13)。Windows 上 gpui 以用户区域(本机为 en-US)排版全部文字,DirectWrite 按日文为汉字选回退字体,日文字体缺的简体字再落到另一字体,同一个词里字形与粗细不一(ElyTree 的“打开仓库”:“打开”粗、“仓库”细)。`vendor/gpui-pre-windows` 的 `text_locale`:用户区域不是中日韩时,改用 Windows 语言列表(WinRT `GlobalizationPreferences::Languages`,Win32 的界面语言只给 en-US)里第一个中日韩语言排版(日志 `text: laid out as …`);在 Windows 上打中文须把中文加进该列表,所以它就是用户读的汉字。只换排版的区域,字体族名与字体列表仍按用户区域。读不出语言列表即记警告、照用户区域。Ely 的界面语言是中文时(设置或 `ELY_LOCALE`),`ely_ui::i18n::install_as` 经 `gpui_windows::set_text_language` 让排版随它,不论 Windows 区域(日文区域下“打开仓库”原为 Yu Gothic UI 600 与 Microsoft JhengHei UI 700 两种字);语言下次启动生效,故启动时设一次。组件库 6df9ab0:Ely 用到的组件里写死的英文(下拉的“Choose…”、清除、关闭、移除、取消固定的提示,公式补全的“No suggestions”,设置里字号的重置提示与示例句)改走内建中英目录。a4bf696:查找框(计数、三个选项与上下一处的提示、替换与全部替换)、排序与筛选(添加规则、满足全部或任一、条件、升降序、添加排序)、密码框的显示与隐藏提示同此;筛选条件以目录键为值(`Test::key`);ElyMark 的删除图片按右键所点的字节(`delete_image(at)`)。仍为英文的是内核的文字(LibreOffice 界面语言固定英文:幻灯片占位“Click to add Title”、母版“Default”、配色名、数字格式代码“General”、函数名),以及启动失败对话框(出现在读入语言之前,中英并列)。
|
||||
- 2026-10-14(用户定:dmg 不再显示未公证):macOS 发布以 Developer ID Application 证书签名、经 `notarytool` 公证并钉票。证书与公证凭据(`xcrun notarytool store-credentials`,App 专用密码只在钥匙串里)装在构建用的 Mac 上;发布流程的 macOS 任务从仓库变量 `ELY_SIGN_IDENTITY`(证书全名)与 `ELY_NOTARY_PROFILE`(凭据名)取得,`ci.sh` 在 macOS 上缺任一即失败,不出未公证的包。本机手动出包同样设这两个变量再跑 `packaging/macos/release.sh`。
|
||||
- 2026-10-15(用户报:ElyMark 点表格整个表格变成源码,应在格内编辑;用户定:格内显示该格原文):表格单元格编辑(R6.1)。组件库 2594b3f:可视模式按下表格只打开所按的那一格,在格内原位以单行输入框显示该格的 Markdown 原文(`**粗体**` 带记号),表格其余照常画出;按在格内文字上即落在所按的字,按在格内空白落在格末;以表格边缘、键盘或上下键从邻块进入的表格块打开其首格或末格;Tab、Shift+Tab 到下一格、上一格(跨行),上下键到上下一格,越出表格即到邻块;回车与 Esc 写回,写回为一步撤销;格内键入的 `|` 写回时转义为 `\|`(表格编辑读到的也是转义后的文字);格开着时做表格编辑(插删行列、整理等)先写回该格再执行,格随之关闭。列表、引用里的表格同此。表格绘制移入组件 `render/table.rs`,按格的空白处也带出所按的格(`Place::Cell`)。第 1 轮后(组件库 6a3f348):开着的格里的按下只给其输入框,插入点落在所按处、仍是一步撤销;格末单数的反斜杠写回时补成一对,不吞下一格的竖线;查找在可视模式里打开匹配所在的格并选中,跨格的匹配转到其行;格开着时右键所按的字节随格内键入的竖线换算;在未开的格的空白处右键,目标为该格末尾。第 2 轮后(组件库 2b6bd1d):格末的反斜杠只在紧接竖线时补成一对(`| a\ |` 的反斜杠后是空格,原样写回,只打开不键入不改一个字节);改首格后仍认得所在表格(无外侧竖线的表格首格始于块首,原被当作写掉了块),Tab 与按邻格照常;开着的格的空白处左键把插入点移到格末、右键以格末为目标,都不写回,仍是一步撤销。
|
||||
@@ -82,6 +82,26 @@ fn a_file_opens_with_its_outline_and_joins_the_recent_list(cx: &mut TestAppConte
|
||||
assert!(!kept.contains(r"\\\\?\\"), "plain paths only: {kept}");
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn the_recent_list_clears_from_its_button(cx: &mut TestAppContext) {
|
||||
let (data, files) = (
|
||||
tempfile::tempdir().expect("data"),
|
||||
tempfile::tempdir().expect("files"),
|
||||
);
|
||||
let path = files.path().join("a.md");
|
||||
std::fs::write(&path, "Text.\n").expect("a file");
|
||||
let (desk, cx) = start(cx, data.path());
|
||||
open(&desk, &path, cx);
|
||||
assert!(desk.read_with(cx, |desk, _| !desk.recent.is_empty()));
|
||||
let button = cx.debug_bounds("mark-clear-recent").expect("the button");
|
||||
cx.simulate_click(button.center(), gpui::Modifiers::none());
|
||||
cx.run_until_parked();
|
||||
assert!(desk.read_with(cx, |desk, _| desk.recent.is_empty()));
|
||||
let kept = std::fs::read_to_string(data.path().join("recent.json")).expect("the list");
|
||||
assert_eq!(kept, "[]");
|
||||
assert!(cx.debug_bounds("mark-clear-recent").is_none(), "nothing left to clear");
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn the_outline_follows_typing(cx: &mut TestAppContext) {
|
||||
let (data, files) = (
|
||||
|
||||
@@ -108,6 +108,22 @@ impl Desk {
|
||||
}
|
||||
}
|
||||
|
||||
/// Empties the recent list.
|
||||
pub fn clear_recent(&mut self, cx: &mut Context<Self>) {
|
||||
match ely_files::recent::clear(&self.recent_file) {
|
||||
Ok(()) => {
|
||||
log::info!("mark: the recent list is cleared");
|
||||
self.recent.clear();
|
||||
cx.notify();
|
||||
}
|
||||
Err(error) => {
|
||||
log::error!("mark: the recent list did not clear: {error}");
|
||||
let said = text(cx, "office.error.engine", &[("error", &error.to_string())]);
|
||||
self.toast(said, Severity::Danger, cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Line and column `at` in a tab or file.
|
||||
pub fn open_at(
|
||||
&mut self,
|
||||
|
||||
+27
-10
@@ -200,7 +200,7 @@ impl Side {
|
||||
.action(open)
|
||||
.into_any_element();
|
||||
}
|
||||
let opener = desk.downgrade();
|
||||
let (opener, clearer) = (desk.downgrade(), desk.downgrade());
|
||||
let rows = read.recent.iter().map(|path| {
|
||||
let name = path
|
||||
.file_name()
|
||||
@@ -214,15 +214,32 @@ impl Side {
|
||||
);
|
||||
(key, item)
|
||||
});
|
||||
rows.fold(
|
||||
SelectableList::new("mark-recent").label(text(cx, "mark.recent", &[])),
|
||||
|list, (key, item)| list.row(key, item),
|
||||
)
|
||||
.on_activate(move |key, _, cx| {
|
||||
let path = PathBuf::from(key.as_ref());
|
||||
opener.update(cx, |desk, cx| desk.open_path(path, cx)).ok();
|
||||
})
|
||||
.into_any_element()
|
||||
let list = rows
|
||||
.fold(
|
||||
SelectableList::new("mark-recent").label(text(cx, "mark.recent", &[])),
|
||||
|list, (key, item)| list.row(key, item),
|
||||
)
|
||||
.on_activate(move |key, _, cx| {
|
||||
let path = PathBuf::from(key.as_ref());
|
||||
opener.update(cx, |desk, cx| desk.open_path(path, cx)).ok();
|
||||
});
|
||||
let clear = Button::new("mark-clear-recent", text(cx, "mark.recent.clear", &[]))
|
||||
.size(ControlSize::Sm)
|
||||
.on_click(move |_, _, cx| {
|
||||
clearer.update(cx, |desk, cx| desk.clear_recent(cx)).ok();
|
||||
});
|
||||
div()
|
||||
.flex()
|
||||
.flex_col()
|
||||
.gap_2()
|
||||
.size_full()
|
||||
.child(div().flex_1().min_h_0().child(list))
|
||||
.child(
|
||||
div()
|
||||
.debug_selector(|| "mark-clear-recent".into())
|
||||
.child(clear),
|
||||
)
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
fn outline(&self, desk: &Entity<Desk>, cx: &mut Context<Self>) -> AnyElement {
|
||||
|
||||
@@ -39,6 +39,14 @@ pub fn forget(file: &Path, root: &Path) -> io::Result<()> {
|
||||
.map(drop)
|
||||
}
|
||||
|
||||
/// Empties the list.
|
||||
pub fn clear(file: &Path) -> io::Result<()> {
|
||||
if let Some(dir) = file.parent() {
|
||||
std::fs::create_dir_all(dir)?;
|
||||
}
|
||||
crate::save_atomic(file, b"[]", 0).map(drop)
|
||||
}
|
||||
|
||||
/// Puts `root` first in the list and writes it.
|
||||
pub fn remember(file: &Path, root: &Path) -> io::Result<Vec<PathBuf>> {
|
||||
let mut list = recent(file)?;
|
||||
@@ -60,7 +68,7 @@ pub fn remember(file: &Path, root: &Path) -> io::Result<Vec<PathBuf>> {
|
||||
mod tests {
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use super::{forget, recent, remember};
|
||||
use super::{clear, forget, recent, remember};
|
||||
|
||||
#[test]
|
||||
fn the_list_puts_the_newest_first_and_keeps_twenty() {
|
||||
@@ -82,6 +90,8 @@ mod tests {
|
||||
let plain = [PathBuf::from(r"C:\r\old"), PathBuf::from(r"C:\r\new")];
|
||||
assert_eq!(recent(&file).expect("reads"), plain);
|
||||
}
|
||||
clear(&file).expect("clears");
|
||||
assert!(recent(&file).expect("reads").is_empty());
|
||||
std::fs::write(&file, "not json").expect("writes");
|
||||
assert!(
|
||||
remember(&file, Path::new("/r/1")).is_err(),
|
||||
|
||||
@@ -6,6 +6,7 @@ pub(super) const EN: &[(&str, &str)] = &[
|
||||
("mark.pane.search", "Search"),
|
||||
("mark.recent", "Recent"),
|
||||
("mark.recent.none", "Nothing opened yet"),
|
||||
("mark.recent.clear", "Clear Recent Files"),
|
||||
("mark.outline.none", "No headings"),
|
||||
("mark.search", "Results"),
|
||||
("mark.search.file", "This file"),
|
||||
@@ -106,6 +107,7 @@ pub(super) const ZH_CN: &[(&str, &str)] = &[
|
||||
("mark.pane.search", "搜索"),
|
||||
("mark.recent", "最近"),
|
||||
("mark.recent.none", "还没有打开过文件"),
|
||||
("mark.recent.clear", "清除最近文件"),
|
||||
("mark.outline.none", "没有标题"),
|
||||
("mark.search", "结果"),
|
||||
("mark.search.file", "本文件"),
|
||||
|
||||
@@ -36,7 +36,7 @@ fetch() { # name url rev [sparse paths...]
|
||||
echo "fetch $name $rev"
|
||||
}
|
||||
|
||||
fetch Ely-GPUI-Components https://git.zacharyzhang.com/ZacharyZhang-NY/Ely-GPUI-Components.git 2b8bd9fcf3ab94a3399ca70bfaf0a6764291f5ec
|
||||
fetch Ely-GPUI-Components https://git.zacharyzhang.com/ZacharyZhang-NY/Ely-GPUI-Components.git 2b6bd1d36951713e61763bcd9572bbd42464dd7d
|
||||
fetch zed https://github.com/zed-industries/zed.git 1a28cff4b409169bac058bca40dfbfeb7621d19b
|
||||
fetch libreoffice-core https://github.com/LibreOffice/core.git 8221e31b3ac356a1623c672912a3d2b492f7e3d1 \
|
||||
include/LibreOfficeKit libreofficekit desktop/source/lib desktop/inc \
|
||||
|
||||
@@ -156,4 +156,5 @@ P0 次序:W-01、K-01、L-01、O-01、W-02、L-02、W-03、L-03、W-04、L-04
|
||||
- [ ] P3-13 Windows:ElyPDF 三个单测恒失败(2026-10-14 组件 6b033f3 下实测,与组件无关):`reads::a_failed_read_is_not_asked_again` 用 `kill -9` 杀 worker(同 P3-07);`sign::a_signed_file_lists_its_checks_and_saves_as_a_copy` 报 “self-signed”(证书信任在 Windows 未构建,未细查);`organize::a_save_writes_the_edits_and_undo_after_it_is_unsaved_again` 报状态未落定(原因未查)
|
||||
- [ ] P3-14 Windows:ElyTree 九个单测恒失败:五个比对 Git 写出的文字,本机 Git 的 `core.autocrlf` 写成 CRLF(测试仓库未设 `core.autocrlf false`);其余写 Windows 不许的文件名(os error 123)。代码行为未见错,未修
|
||||
- [ ] P3-15 Windows:全量并行单测中偶有一个 LOK worker 读到的 BuildId 为 `development`(`desktop/source/app/app.cxx` 读不到 bootstrap 的 buildid 时的默认值),握手照规则拒绝;同一时刻别的 worker 读到正确的 8221e31,内核与 worker 都未重建,单独重跑即过(2026-10-14 ElyDoc `review::tests::one_unreadable_time_spares_the_other_notes`,三次重跑皆过)。疑为并发时读 `version.ini` 偶发失败,原因未查
|
||||
- [ ] P3-16 发布:`ci.sh` 在三端各自调用 `packaging/source.sh` 并上传同名的源码包与上游源码包,发布里同名文件出现三份(Gitea 允许重名);上游源码包打的是各机的 `engines/mupdf-src`,含构建留下的文件,三份大小不同(v0.1.5:Linux 108 MB,macOS 161 MB)。v0.1.5 手动删去后到的两份,留 Linux 的一份。应只出一份,且上游包只含源码
|
||||
|
||||
+8
-1
@@ -255,4 +255,11 @@
|
||||
- [x] R5.5 ElyTable 右键(用户 2026-10-14 要求核对同类问题):网格右键原无菜单(内核给了,Ely 丢弃),行列表头只收左键;照 Excel 按目标出 Ely 的菜单:单元格(剪切、复制、粘贴,插入、删除、清除内容,合并拆分,设置单元格格式;ElyTable 无批注界面,不列),行与列表头(插入、删除、行高或列宽、隐藏、取消隐藏);可否取自内核对各项命令的状态(补丁 0045);表头在选中对象或编辑图形文字时照样选行列(补丁 0046);ElyDoc 的菜单机制移入 `ely-office` 共用 — 三轮用完,末轮修复已测(编辑图形文字时右键表头:补丁 0046 结束编辑、留下文字、退出绘图模式再选行列;行与列两种表头各有回归测试,存出的文件里两个图形的文字都在)
|
||||
- [x] R5.6 ElyShow 右键与表格:画布右键原无菜单;照 PowerPoint 按目标出菜单(幻灯片、文本框、图形、表格、图片);表格菜单在光标进单元格后才有可否(内核对整表选中全报不可用);拖动表格边线照 R5.3(Impress 的 `LOK_CALLBACK_TABLE_SELECTED` 以字符串写数值,`table::read` 须收下) — R3 PASS(补丁 0047:Impress 两轴首尾边线带上下限,内侧行线取行自身最小高度,最左列边线可拖并随之移动表格;正编辑表格单元格时在空白处右键无菜单为内核所限,BUGS P3-11)
|
||||
- [x] R5.7 Gitea #1:ElyShow 左侧缩略图条滚轮不滚动(同窗口右栏正常,Linux Wayland 报);查明根因再修,加滚轮回归测试 — R1 PASS(根因:列表包在无尺寸的 `ContextMenu` 宿主里,从不溢出;宿主改为 `size_full`,`tests/strip.rs` 以 24 张幻灯片核对)
|
||||
- [ ] R5.8 0.1.5 发布(用户 2026-10-14 定):等 ElyMark 会话的 R4 做完;版本 0.1.5,Windows 与 WSL2 的 Linux 在本机建,macOS 在 Mac mini 上拉取后本机建;全部产物上传到 Gitea 的 v0.1.5 发布
|
||||
- [x] R5.8 0.1.5 发布(用户 2026-10-14 定):等 ElyMark 会话的 R4 做完;版本 0.1.5,Windows 与 WSL2 的 Linux 在本机建,macOS 在 Mac mini 上拉取后本机建;全部产物上传到 Gitea 的 v0.1.5 发布。2026-10-14 完成:v0.1.5 = 15d4c20;三端以 `ci.sh` 在本机、WSL2 与 Mac mini 上建并上传(发布流程的运行已取消),44 个文件:六个 dmg(Developer ID 签名、公证、钉票,`spctl` 认作 Notarized Developer ID)与更新清单、六个 Windows 安装程序、Linux 的 AppImage、deb、rpm、Arch 包,源码包与上游源码包各一份(重名见 BUGS P3-16);ElyTree 清单的散列与下载相符
|
||||
|
||||
## R6 0.1.5 重发前的修复(用户 2026-10-15 报:ElyMark 点表格整表变成源码;级联菜单斜移到子菜单时被路过的项抢走,七个应用同此;最近列表不能清除。用户定:先删 Gitea 上 v0.1.5 的全部文件,修好后在修复的提交上重打 v0.1.5;单元格编辑显示该格原文)
|
||||
|
||||
- [ ] R6.1 ElyMark 表格单元格编辑:可视模式按下表格只打开所按的那一格(单行输入框,显示该格的 Markdown 原文,表格其余照常显示),按格内文字落在所按的字,按格内空白落在格末;写回为一步撤销,格内键入的 `|` 写回时转义;Tab、Shift+Tab 到下一格、上一格;Esc 与失焦写回(组件库 `MarkdownDocument`)
|
||||
- [ ] R6.2 级联菜单的悬停意图(`menus` 的 `ContextMenu`、`MenuBar` 共用的面板):菜单面板挡住其下的元素(原先子菜单盖在父菜单上时,父菜单被盖住的行照收悬停,“底层”的项弹出自己的子菜单);子菜单右侧放不下即开在父菜单左侧,不盖父菜单;悬停子菜单项延时打开;指针在“当前位置与子菜单上下两角”的三角区内移动时不切换路过的项,停下超过延时才切换
|
||||
- [ ] R6.3 ElyMark 侧栏清除最近列表:核对 98692cb 已做到(文件页能清空最近列表),随本次发布
|
||||
- [ ] R6.4 重发 0.1.5:删去 v0.1.5 的标签与发布,在修复的提交上重打;Windows、WSL2 的 Linux、Mac mini 本机建(签名、公证)并上传;本机装上
|
||||
@@ -0,0 +1,11 @@
|
||||
FAIL
|
||||
|
||||
1. `reference/Ely-GPUI-Components/src/documents/render/table.rs:69` — [P1] The activation handler also wraps the active cell's `TextInput`. Its mouse-down bubbles into `pressed_cell`, which commits the field and reopens it at the end. Reproduction: open the cell `alpha`, then click its second character; the probe gets caret 5 instead of 1. Type `X`, click inside the field, type `Y`, press Esc, then undo once: `alphaX` remains instead of the original `alpha`. This breaks R6.1's caret placement and single write-back transaction. Keep presses inside the active field from reactivating its cell, preserving its caret, selection and transaction; add these interaction regressions. Both failures are recorded in `.work/R6.1-r1/probes-expanded.log`.
|
||||
|
||||
2. `reference/Ely-GPUI-Components/src/documents/document/edit.rs:108` — [P2] Changing `Landing::End` to open the last table cell breaks `show_match`, which still calls it and selects offsets relative to the whole block (`document/finding.rs:45`). In `| needle | B |\n| --- | --- |\n| C | tail |\n`, finding `needle` opens `tail`; the requested selection also lies outside that field and is discarded. ElyMark's Find navigation calls this method, so table matches are no longer selected (PRD MARK-10). Open the cell containing the match and calculate selection relative to that cell, retaining correct handling of matches spanning cells. Add a visual-mode table-search regression; `review_probe_find_selects_its_table_cell` reproduces the failure.
|
||||
|
||||
3. `reference/Ely-GPUI-Components/src/documents/document/cells.rs:146` — [P2] `guarded` protects pipes inside the input but leaves a trailing odd backslash able to escape the following table separator. Open the first header cell of `|a|b|\n|---|---|\n|c|d|\n`, append `\`, and press Esc. The result is `|a\|b|\n|---|---|\n|c|d|\n`, which the parser reads as a paragraph rather than a table. Editing one cell therefore changes the neighboring cell boundary, contrary to R6.1 and PRD §14.3. Protect the boundary when writing compact cells, keeping snapshot and commit consistent; test that a terminal backslash preserves the table and adjacent cells. `review_probe_trailing_slash_cannot_consume_next_cell` confirms the failure.
|
||||
|
||||
4. `reference/Ely-GPUI-Components/src/documents/document/point.rs:185` — [P2] `point_open` passes the raw input hit offset into the escaped snapshot. The new `snapshot` code inserts backslashes before typed pipes and remaps the selection, but this independent hit offset is not remapped. In an open cell, type `||||||||||[go](https://ely.dev)` and right-click `g`: the probe receives `link: None`, so ElyMark omits the link actions required by MARK-16. Convert the pressed byte through the same escaping transformation before calling `target_at`, and test right-click targets after newly typed pipes. `review_probe_right_click_after_raw_pipes_targets_the_link` confirms the missing target.
|
||||
|
||||
5. `reference/Ely-GPUI-Components/src/documents/document/cells.rs:12` — [P3] Seven added comments violate the explicit ten-word limit: this line has 12 words; `cells.rs:104`, `:129`, and `:146` have 11, 13, and 11; `document/lists.rs:225` has 14; `document/tests/cells.rs:10` has 11; `render/table.rs:12` has 12. Counting whitespace-separated words in the added comment lines reproduces these failures (`.work/R6.1-r1/static-audit.log`). Shorten each to at most ten words while retaining one line.
|
||||
@@ -0,0 +1,7 @@
|
||||
FAIL
|
||||
|
||||
1. `reference/Ely-GPUI-Components/src/documents/document/cells.rs:164` — [P2] `kept` doubles every odd trailing backslash, including unchanged source whose existing padding already protects the separator. Open the first cell of `| a\ | b |\n| --- | --- |\n| c | d |\n`, then switch to Source without typing: `a\` becomes `a\\`. Merely opening and switching modes therefore rewrites the file, violating PRD §14.3. Preserve unchanged cell bytes and account for the retained suffix when protecting a separator; add no-edit commit/mode-switch regressions alongside the compact-cell backslash test. `review_probe_untouched_trailing_slash_preserves_source` fails in `.work/R6.1-r2/probes-expanded.log`.
|
||||
|
||||
2. `reference/Ely-GPUI-Components/src/documents/document/lists.rs:241` — [P2] Moving between cells calls `open` on the same block, but `open` loses that block when the committed cell includes its starting byte (`document/edit.rs:87`). In the valid table `alpha | beta\n--- | ---\nc | d\n`, open `alpha`, type `X`, then press Tab or click `beta`: `alphaX` is committed, but no cell remains open. This breaks R6.1's cell navigation and click-to-edit behavior for tables without a leading pipe. Preserve the table's identity across a write to its first cell instead of treating its replaced start as a missing block. Add both navigation regressions; `review_probe_tab_after_unprefixed_header_edit` and `review_probe_neighbor_click_after_unprefixed_header_edit` fail in `.work/R6.1-r2/probes-expanded.log`, while the no-edit control passes.
|
||||
|
||||
3. `reference/Ely-GPUI-Components/src/documents/render/table.rs:64` — [P2] The new stop-propagation handlers cover the entire active cell, including padding outside its input, and discard those presses. Open `alpha`, place the caret after its first character, then click the cell's blank padding: the caret stays at 1 instead of moving to 5 as R6.1 requires. Right-clicking the same padding emits no `DocumentEvent::Pointed`, so ElyMark also opens no context menu (MARK-16). Route padding presses to the active cell's end and right-click target while keeping input presses within the existing transaction. Both padding probes fail in `.work/R6.1-r2/probes-expanded.log`.
|
||||
Reference in new issue
Block a user