fix(editor): preserve tabs in file views
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/fs/tool-str-replace-editor/README.md
|
||||
README.md: 12224537ab2ca2d2ba97e93fe8dc2192fa9ac1aa
|
||||
README.zh.md: 5481723f8a3077ee329ec202b12a67b678abc691
|
||||
README.md: 97e9e0ab9ade7c7241c1aac3e2489e055d01ff8f
|
||||
README.zh.md: 48358eb3c9d81ddad6a83c4ff3ef0cf6542096b1
|
||||
|
||||
@@ -13,7 +13,7 @@ Standalone model-facing `str_replace_editor` over `ctx.fs`. It can be composed w
|
||||
|
||||
## Tool
|
||||
|
||||
The schema provides `view`, `create`, `str_replace`, and `insert` over absolute paths. File views use one-based line numbers; directory views omit hidden, dependency, and Python-cache entries and descend two levels. Replacement requires one unique literal match and reports errors only in the public `old_str` vocabulary. Insert follows the selected zero-based insertion boundary without adding an implicit trailing newline. Mutations preserve tabs outside the requested edit.
|
||||
The schema provides `view`, `create`, `str_replace`, and `insert` over absolute paths. File views use one-based line numbers and preserve content tabs, so displayed text remains valid literal replacement input; directory views omit hidden, dependency, and Python-cache entries and descend two levels. Replacement requires one unique literal match and reports errors only in the public `old_str` vocabulary. Insert follows the selected zero-based insertion boundary without adding an implicit trailing newline. Mutations preserve tabs outside the requested edit.
|
||||
|
||||
## Model Experience
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
## 工具
|
||||
|
||||
Schema 提供针对绝对路径的 `view`、`create`、`str_replace` 与 `insert`。文件查看使用从一开始的行号;目录查看忽略隐藏、依赖与 Python 缓存条目并下探两层。替换要求字面量唯一匹配,错误只使用公开的 `old_str` 词汇。插入遵循所选的零基插入边界,不会隐式补尾换行。修改操作会保留请求编辑范围之外的制表符。
|
||||
Schema 提供针对绝对路径的 `view`、`create`、`str_replace` 与 `insert`。文件查看使用从一开始的行号,并保留内容中的制表符,因此显示的文本仍可作为有效的字面量替换输入;目录查看忽略隐藏、依赖与 Python 缓存条目并下探两层。替换要求字面量唯一匹配,错误只使用公开的 `old_str` 词汇。插入遵循所选的零基插入边界,不会隐式补尾换行。修改操作会保留请求编辑范围之外的制表符。
|
||||
|
||||
## 模型体验
|
||||
|
||||
|
||||
@@ -35,23 +35,6 @@ function maybeTruncate(content: string, maxOutputChars: number): string {
|
||||
: content.slice(0, maxOutputChars) + TRUNCATED_MESSAGE
|
||||
}
|
||||
|
||||
function expandTabs(content: string, tabSize = 8): string {
|
||||
let column = 0
|
||||
let result = ''
|
||||
for (const character of content) {
|
||||
if (character === '\t') {
|
||||
const spaces = tabSize - (column % tabSize)
|
||||
result += ' '.repeat(spaces)
|
||||
column += spaces
|
||||
continue
|
||||
}
|
||||
result += character
|
||||
if (character === '\n' || character === '\r') column = 0
|
||||
else column += 1
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function codepointCompare(left: string, right: string): number {
|
||||
return left < right ? -1 : left > right ? 1 : 0
|
||||
}
|
||||
@@ -192,9 +175,9 @@ function formatFileView(
|
||||
: allLines.slice(initialLine - 1, finalLine)
|
||||
prompt += ` with view_range=[${initialLine}, ${finalLine}]`
|
||||
}
|
||||
const numbered = expandTabs(lines
|
||||
.map((line, index) => `${String(initialLine + index).padStart(6, ' ')}\t${line}`)
|
||||
.join('\n'))
|
||||
const numbered = lines
|
||||
.map((line, index) => `${String(initialLine + index).padStart(6, ' ')} ${line}`)
|
||||
.join('\n')
|
||||
return maybeTruncate(`${prompt}:\n${numbered}\n`, maxOutputChars)
|
||||
}
|
||||
|
||||
|
||||
@@ -470,11 +470,13 @@ describe('tool-str-replace-editor', () => {
|
||||
const { ctx, root, owner } = await setup()
|
||||
const path = join(root, 'Makefile')
|
||||
await writeFile(path, 'target:\n\told\nremove\n')
|
||||
expect(text(await call(ctx, owner, { command: 'view', path })))
|
||||
.toContain(' 2 \told')
|
||||
await call(ctx, owner, {
|
||||
command: 'str_replace',
|
||||
path,
|
||||
old_str: 'old',
|
||||
new_str: 'new',
|
||||
old_str: '\told',
|
||||
new_str: '\tnew',
|
||||
})
|
||||
await call(ctx, owner, {
|
||||
command: 'str_replace',
|
||||
|
||||
Reference in New Issue
Block a user