Skip to content
Merged
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
17 changes: 11 additions & 6 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ GPT Copy is a command-line tool that recursively scans a directory, collects rea
- **Structured Output:** Concatenates file contents into a structured markdown document with file-specific code fences.
- **File Filtering:** Supports glob-style include (`-i/--include`) and exclude (`-e/--exclude`) patterns for precise file selection.
- **Force Mode:** The `-f/--force` option bypasses ignore rules and Git-tracked file restrictions.
- **Line Numbering:** Add zero-padded line numbers to each file's content using the `-n/--number` option (similar to `cat -n`).
- **Line Numbering:** Zero-padded line numbers are added to each file's content by default (similar to `cat -n`). Use `--no-number` to disable.
- **Token Counting:** Includes a separate `tokens` CLI command to count the number of tokens in text using OpenAI’s `tiktoken` library with GPT-4o model encoding.

## Installation
Expand Down Expand Up @@ -76,12 +76,17 @@ Ignore `.gitignore` and Git-tracked file restrictions to process **all** files:
gpt-copy /path/to/directory -f
```

### Add Line Numbers (`-n` or `--number`)
Enable line numbering for the content of each file. This option prefixes each line with a zero-padded line number, similar to the Unix `cat -n` command.
### Line Numbers (enabled by default)
Line numbering is **enabled by default** for the content of each file. Each line is prefixed with a zero-padded line number, similar to the Unix `cat -n` command.

**Usage Example:**
**Basic usage (line numbers included):**
```sh
gpt-copy /path/to/directory -n
gpt-copy /path/to/directory
```

**Disable line numbers:**
```sh
gpt-copy /path/to/directory --no-number
```
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since line numbers are enabled by default, word it differently,
do an example to disable the line numers, and do not mention how to enable them, since they are already enabled

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the documentation to focus only on disabling line numbers since they're now enabled by default. Removed the section about enabling them explicitly. (f59c4fb)


### Count Tokens with `tokens`
Expand All @@ -107,7 +112,7 @@ Count the number of tokens in a given text using GPT-4o encoding. The command re
3. **Reads and Formats Files:**
- Detects file type based on extension.
- Wraps file contents in appropriate markdown code fences.
- Adds line numbers if the `-n/--number` option is enabled.
- Adds line numbers by default (can be disabled with `--no-number`).
- Skips binary or unrecognized file types.

4. **Applies File Filtering:**
Expand Down
15 changes: 8 additions & 7 deletions src/gpt_copy/gpt_copy.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,19 +500,19 @@ def write_output(
help="Glob pattern(s) to exclude files (e.g., 'src/tests/*')",
)
@click.option(
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the -n altogether

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the -n flag completely as requested. Line numbers are now enabled by default with only --no-number to disable them when needed. This simplifies the interface since the -n flag was redundant. (ae95b81)

"-n",
"--number",
"line_numbers",
"--no-number",
"no_line_numbers",
is_flag=True,
help="Add line numbers to file content.",
default=False,
help="Disable line numbers for file content.",
)
def main(
root_path: Path,
output_file: str | None,
force: bool,
include_patterns: tuple[str, ...],
exclude_patterns: tuple[str, ...],
line_numbers: bool,
no_line_numbers: bool,
) -> None:
"""
Main function to start the script.
Expand All @@ -523,8 +523,9 @@ def main(
force (bool): If True, ignore .gitignore and Git-tracked files.
include_patterns (Tuple[str, ...]): The tuple of include glob patterns.
exclude_patterns (Tuple[str, ...]): The tuple of exclude glob patterns.
line_numbers (bool): If True, add line numbers to the file contents.
no_line_numbers (bool): If True, disable line numbers.
"""

root_path = root_path.resolve()
print(f"Starting script for directory: {root_path}", file=sys.stderr)
gitignore_specs, tracked_files = get_ignore_settings(root_path, force)
Expand All @@ -538,7 +539,7 @@ def main(
tracked_files,
include_patterns=list(include_patterns),
exclude_patterns=list(exclude_patterns),
line_numbers=line_numbers,
line_numbers=not no_line_numbers,
)

if output_file:
Expand Down
1 change: 1 addition & 0 deletions test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test content
42 changes: 42 additions & 0 deletions tests/test_line_numbers_default.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""Test that line numbers are enabled by default."""

from pathlib import Path

from click.testing import CliRunner
from gpt_copy.gpt_copy import main


def test_line_numbers_enabled_by_default(tmp_path: Path):
"""Test that line numbers are enabled by default without -n flag."""
# Create a test file with multiple lines
test_file = tmp_path / "test.txt"
test_file.write_text("line one\nline two\nline three\n", encoding="utf-8")

runner = CliRunner()
result = runner.invoke(main, [tmp_path.as_posix()])

assert result.exit_code == 0
# Check that line numbers are present in the output
assert "1: line one" in result.output
assert "2: line two" in result.output
assert "3: line three" in result.output


def test_no_number_flag_disables_line_numbers(tmp_path: Path):
"""Test that --no-number flag disables line numbers."""
# Create a test file with multiple lines
test_file = tmp_path / "test.txt"
test_file.write_text("line one\nline two\nline three\n", encoding="utf-8")

runner = CliRunner()
result = runner.invoke(main, [tmp_path.as_posix(), "--no-number"])

assert result.exit_code == 0
# Check that line numbers are NOT present in the output
assert "1: line one" not in result.output
assert "2: line two" not in result.output
assert "3: line three" not in result.output
# But the content should still be there
assert "line one" in result.output
assert "line two" in result.output
assert "line three" in result.output