mirror of
https://github.com/NCBM/plyngent.git
synced 2026-07-23 05:55:16 +08:00
tools/file: add with_lineno option to read_file
When true, prefix each returned line with absolute 1-based line numbers (N|…) for edit_lineno-friendly reads; works with offset/limit.
This commit is contained in:
@@ -3,12 +3,33 @@ from __future__ import annotations
|
||||
from plyngent.agent import tool
|
||||
from plyngent.tools.workspace import resolve_path
|
||||
|
||||
_LINENO_WIDTH = 6
|
||||
|
||||
|
||||
def _format_with_lineno(lines: list[str], *, start_lineno: int) -> str:
|
||||
"""Prefix each line with a 1-based absolute line number (``edit_lineno`` style)."""
|
||||
out: list[str] = []
|
||||
for index, line in enumerate(lines):
|
||||
lineno = start_lineno + index
|
||||
# Strip keepends for the body; re-add a single newline after the prefix.
|
||||
body = line.rstrip("\r\n")
|
||||
out.append(f"{lineno:>{_LINENO_WIDTH}}|{body}\n")
|
||||
return "".join(out)
|
||||
|
||||
|
||||
@tool
|
||||
def read_file(path: str, *, offset: int = 0, limit: int | None = None) -> str:
|
||||
def read_file(
|
||||
path: str,
|
||||
*,
|
||||
offset: int = 0,
|
||||
limit: int | None = None,
|
||||
with_lineno: bool = False,
|
||||
) -> str:
|
||||
"""Read a text file under the workspace.
|
||||
|
||||
``offset`` is 0-based line start; ``limit`` is max lines (None = rest of file).
|
||||
When ``with_lineno`` is true, each line is prefixed with its 1-based file line
|
||||
number (`` N|…``), matching ``edit_lineno`` numbering.
|
||||
"""
|
||||
target = resolve_path(path)
|
||||
if not target.is_file():
|
||||
@@ -21,4 +42,7 @@ def read_file(path: str, *, offset: int = 0, limit: int | None = None) -> str:
|
||||
end = len(lines) if limit is None else min(len(lines), start + limit)
|
||||
if start >= len(lines):
|
||||
return ""
|
||||
return "".join(lines[start:end])
|
||||
slice_lines = lines[start:end]
|
||||
if with_lineno:
|
||||
return _format_with_lineno(slice_lines, start_lineno=start + 1)
|
||||
return "".join(slice_lines)
|
||||
|
||||
@@ -35,6 +35,18 @@ def test_read_offset_limit(workspace: object) -> None:
|
||||
assert call_sync(read_file, "lines.txt", offset=1, limit=2) == "b\nc\n"
|
||||
|
||||
|
||||
def test_read_with_lineno(workspace: object) -> None:
|
||||
del workspace
|
||||
_ = call_sync(write_file, "num.txt", "a\nb\nc\n")
|
||||
out = call_sync(read_file, "num.txt", with_lineno=True)
|
||||
assert " 1|a\n" in out
|
||||
assert " 2|b\n" in out
|
||||
assert " 3|c\n" in out
|
||||
# offset is 0-based; line numbers stay absolute 1-based file lines
|
||||
mid = call_sync(read_file, "num.txt", offset=1, limit=1, with_lineno=True)
|
||||
assert mid == " 2|b\n"
|
||||
|
||||
|
||||
def test_listdir_missing(workspace: object) -> None:
|
||||
del workspace
|
||||
assert "error" in call_sync(listdir, "nope")
|
||||
|
||||
Reference in New Issue
Block a user