Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --line-numbers flag #38

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 32 additions & 7 deletions files_to_prompt/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,39 @@ def read_gitignore(path):
return []


def print_path(writer, path, content, xml):
def add_line_numbers(content):
lines = content.splitlines()

padding = len(str(len(lines)))

numbered_lines = [f"{i+1:{padding}} {line}" for i, line in enumerate(lines)]
return "\n".join(numbered_lines)


def print_path(writer, path, content, xml, line_numbers):
if xml:
print_as_xml(writer, path, content)
print_as_xml(writer, path, content, line_numbers)
else:
print_default(writer, path, content)
print_default(writer, path, content, line_numbers)


def print_default(writer, path, content):
def print_default(writer, path, content, line_numbers):
writer(path)
writer("---")
if line_numbers:
content = add_line_numbers(content)
writer(content)
writer("")
writer("---")


def print_as_xml(writer, path, content):
def print_as_xml(writer, path, content, line_numbers):
global global_index
writer(f'<document index="{global_index}">')
writer(f"<source>{path}</source>")
writer("<document_content>")
if line_numbers:
content = add_line_numbers(content)
writer(content)
writer("</document_content>")
writer("</document>")
Expand All @@ -60,11 +73,12 @@ def process_path(
ignore_patterns,
writer,
claude_xml,
line_numbers=False,
):
if os.path.isfile(path):
try:
with open(path, "r") as f:
print_path(writer, path, f.read(), claude_xml)
print_path(writer, path, f.read(), claude_xml, line_numbers)
except UnicodeDecodeError:
warning_message = f"Warning: Skipping file {path} due to UnicodeDecodeError"
click.echo(click.style(warning_message, fg="red"), err=True)
Expand Down Expand Up @@ -101,7 +115,9 @@ def process_path(
file_path = os.path.join(root, file)
try:
with open(file_path, "r") as f:
print_path(writer, file_path, f.read(), claude_xml)
print_path(
writer, file_path, f.read(), claude_xml, line_numbers
)
except UnicodeDecodeError:
warning_message = (
f"Warning: Skipping file {file_path} due to UnicodeDecodeError"
Expand Down Expand Up @@ -143,6 +159,13 @@ def process_path(
is_flag=True,
help="Output in XML-ish format suitable for Claude's long context window.",
)
@click.option(
"line_numbers",
"-n",
"--line-numbers",
is_flag=True,
help="Add line numbers to the output",
)
@click.version_option()
def cli(
paths,
Expand All @@ -152,6 +175,7 @@ def cli(
ignore_patterns,
output_file,
claude_xml,
line_numbers,
):
"""
Takes one or more paths to files or directories and outputs every file,
Expand Down Expand Up @@ -204,6 +228,7 @@ def cli(
ignore_patterns,
writer,
claude_xml,
line_numbers,
)
if claude_xml:
writer("</documents>")
Expand Down
28 changes: 28 additions & 0 deletions tests/test_files_to_prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,3 +279,31 @@ def test_output_option(tmpdir, arg):
---
"""
assert expected.strip() == actual.strip()


def test_line_numbers(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
test_content = "First line\nSecond line\nThird line\nFourth line\n"
with open("test_dir/multiline.txt", "w") as f:
f.write(test_content)

result = runner.invoke(cli, ["test_dir"])
assert result.exit_code == 0
assert "1 First line" not in result.output
assert test_content in result.output

result = runner.invoke(cli, ["test_dir", "-n"])
assert result.exit_code == 0
assert "1 First line" in result.output
assert "2 Second line" in result.output
assert "3 Third line" in result.output
assert "4 Fourth line" in result.output

result = runner.invoke(cli, ["test_dir", "--line-numbers"])
assert result.exit_code == 0
assert "1 First line" in result.output
assert "2 Second line" in result.output
assert "3 Third line" in result.output
assert "4 Fourth line" in result.output