Commit graph

818 commits

Author SHA1 Message Date
Paul Gauthier
4ff5b0e115 Refactor InputOutput class to accept history_file as an argument and remove it from get_input method. 2023-05-12 13:55:03 -07:00
Paul Gauthier
b074cae5c7 Changed the Commands class to use io instead of console and added error handling. 2023-05-12 13:50:17 -07:00
Paul Gauthier
dd82f64a9e wip: Removed unnecessary code and added a console rule when getting input. 2023-05-12 13:44:46 -07:00
Paul Gauthier
85515b4788 Refactored the code to use a new io tool method and removed the tool_error method. 2023-05-12 13:37:22 -07:00
Paul Gauthier
91f23f3700 aider: Replaced self.console.print() calls with self.io.tool_error() calls for [red] strings and added missing instances.
# Context:
USER: replace all the self.console.print() calls that contain [red] with calls to self.io.tool_error() with [red] removed from the string
ASSISTANT: I apologize for the confusion earlier. I see that the changes have already been committed. There is no need to make the same changes again. If you have any other requests or need assistance with the code, please let me know.
USER: you missed 2 that contain " edit to {path}"
ASSISTANT: You're right, I missed those. Here are the changes for the remaining instances:

aider/coder.py
<<<<<<< ORIGINAL
            self.console.print(f"[red]Skipping edit to {path}")
=======
            self.io.tool_error(f"Skipping edit to {path}")
>>>>>>> UPDATED

aider/coder.py
<<<<<<< ORIGINAL
            self.console.print(f"[red]Failed to apply edit to {path}")
=======
            self.io.tool_error(f"Failed to apply edit to {path}")
>>>>>>> UPDATED
2023-05-12 13:32:39 -07:00
Paul Gauthier
fca8ea3c21 aider: Replaced all self.console.print() calls with self.io.tool_error() calls.
# Context:
USER: replace all the self.console.print() calls that contain [red] with calls to self.io.tool_error() with [red] removed from the string
ASSISTANT: aider/coder.py
<<<<<<< ORIGINAL
            self.console.print("[red]^C again to quit")
=======
            self.io.tool_error("^C again to quit")
>>>>>>> UPDATED

aider/coder.py
<<<<<<< ORIGINAL
            self.io.tool_error("Malformed ORIGINAL/UPDATE blocks, retrying...")
            self.io.tool_error(err)
=======
            self.io.tool_error("Malformed ORIGINAL/UPDATE blocks, retrying...")
            self.io.tool_error(str(err))
>>>>>>> UPDATED

aider/coder.py
<<<<<<< ORIGINAL
            self.console.print("[red]Unable to get commit message from gpt-3.5-turbo. Use /commit to try again.\n")
=======
            self.io.tool_error("Unable to get commit message from gpt-3.5-turbo. Use /commit to try again.")
>>>>>>> UPDATED

aider/coder.py
<<<<<<< ORIGINAL
            self.console.print("[red]Skipped commmit.")
=======
            self.io.tool_error("Skipped commmit.")
>>>>>>> UPDATED
2023-05-12 13:31:32 -07:00
Paul Gauthier
92e091f5a6 fix bug if ORIG/UPD block is missing trailing newline; added test 2023-05-12 13:30:39 -07:00
Paul Gauthier
1d7fffe8ab wip: Refactor Input class to InputOutput and add tool_error method. 2023-05-12 13:17:37 -07:00
Paul Gauthier
57f1b3139a wip: Removed unused import and changed Text object to string. 2023-05-12 13:12:50 -07:00
Paul Gauthier
919cfc2359 aider: Replaced all self.console.print() calls with self.io.tool_error() calls with [red] removed from the string.
# Context:
USER: replace all the self.console.print() calls that contain [red] with calls to self.io.tool_error() with [red] removed from the string
ASSISTANT: aider/coder.py
<<<<<<< ORIGINAL
            self.console.print(
                f"[red]This tool will almost certainly fail to work with {main_model}"
            )
=======
            self.io.tool_error(f"This tool will almost certainly fail to work with {main_model}")
>>>>>>> UPDATED

aider/coder.py
<<<<<<< ORIGINAL
            self.console.print("[red]No suitable git repo, will not automatically commit edits.")
=======
            self.io.tool_error("No suitable git repo, will not automatically commit edits.")
>>>>>>> UPDATED

aider/coder.py
<<<<<<< ORIGINAL
            self.console.print("[red]Files are not in a git repo.")
=======
            self.io.tool_error("Files are not in a git repo.")
>>>>>>> UPDATED

aider/coder.py
<<<<<<< ORIGINAL
            self.console.print("[red]Files are in different git repos.")
=======
            self.io.tool_error("Files are in different git repos.")
>>>>>>> UPDATED

aider/coder.py
<<<<<<< ORIGINAL
                self.console.print("[red]Skipped adding new files to the git repo.")
=======
                self.io.tool_error("Skipped adding new files to the git repo.")
>>>>>>> UPDATED

aider/coder.py
<<<<<<< ORIGINAL
            self.console.print("[red]Warning: no changes found in tracked files.")
=======
            self.io.tool_error("Warning: no changes found in tracked files.")
>>>>>>> UPDATED

aider/coder.py
<<<<<<< ORIGINAL
            self.console.print("[red]Malformed ORIGINAL/UPDATE blocks, retrying...")
            self.console.print("[red]", Text(err))
=======
            self.io.tool_error("Malformed ORIGINAL/UPDATE blocks, retrying...")
            self.io.tool_error(Text(err))
>>>>>>> UPDATED

Please note that I couldn't find the `self.io.tool_error()` method in the provided code. You may need to create this method in the appropriate class or provide the correct method name to replace the `self.console.print()` calls.
2023-05-12 13:03:34 -07:00
Paul Gauthier
b7299565f1 refac 2023-05-12 10:53:23 -07:00
Paul Gauthier
0325fc40ac roughed in switch to prompt toolkit for _ask funcs 2023-05-12 08:15:32 -07:00
Paul Gauthier
9a4dfae07a wip 2023-05-12 08:05:57 -07:00
Paul Gauthier
36b88d6933 Merge branch 'main' into pattern 2023-05-12 07:15:27 -07:00
Paul Gauthier
5490dc11d0 Updated version number to 0.2.0 in setup.py. 2023-05-11 23:26:22 -07:00
Paul Gauthier
a16f91eed1 aider: Added --no-auto-commits argument to README.md.
# Context:
USER: add the --no-auto-commit arg to readme
ASSISTANT: I will add the `--no-auto-commits` argument to the README.md file.

```markdown
README.md
<<<<<<< ORIGINAL
- `--show-diffs`: Show diffs when committing changes (default: False). Override the default with the environment variable `AIDER_SHOW_DIFFS` (default: 0 for False, 1 for True).
=======
- `--show-diffs`: Show diffs when committing changes (default: False). Override the default with the environment variable `AIDER_SHOW_DIFFS` (default: 0 for False, 1 for True).
- `--no-auto-commits`: Disable auto commit of changes. Override the default with the environment variable `AIDER_AUTO_COMMITS` (default: 1 for enabled, 0 for disabled).
>>>>>>> UPDATED
```
2023-05-11 23:25:51 -07:00
Paul Gauthier
0c3b772172 prompt eng for new files 2023-05-11 23:24:38 -07:00
Paul Gauthier
596a6d1ae1 make parent dirs 2023-05-11 23:24:29 -07:00
Paul Gauthier
d45b7ae752 handle filenames above the triple quotes 2023-05-11 22:59:02 -07:00
Paul Gauthier
9ef50d8f3d make dirs for new files 2023-05-11 22:55:26 -07:00
Paul Gauthier
89149b307d aider: Changed fname.touch() to fname.touch(parents=True) to create any missing directories in the path.
# Context:
USER: when calling Path.touch() can we ask it to make missing dirs?
ASSISTANT: Yes, you can use the `parents` parameter in the `touch()` method to create any missing directories. Set `parents=True` to create any missing directories in the path. Here's the change needed in the `aider/coder.py` file:

```python
aider/coder.py
<<<<<<< ORIGINAL
                fname.touch()
=======
                fname.touch(parents=True)
>>>>>>> UPDATED
```
2023-05-11 22:37:59 -07:00
Paul Gauthier
5ddaf55dd2 Merge branch 'main' into pattern 2023-05-11 22:19:12 -07:00
Paul Gauthier
c9ef516bdb cleanup \[ from prompt string which was generating improper escape warnings 2023-05-11 22:19:01 -07:00
Paul Gauthier
52a7c4b786 Merge branch 'main' into pattern 2023-05-11 22:15:39 -07:00
Paul Gauthier
3ec7880dc8 added tests 2023-05-11 22:10:21 -07:00
Paul Gauthier
5444b45a93 aider: Added test for ValueError containing the word "Incomplete" in test_find_original_update_blocks_unclosed.
# Context:
USER: in test_find_original_update_blocks_unclosed, assert that it throws a valueerror containing the word "Incomplete"
ASSISTANT: To add the test for ValueError containing the word "Incomplete" in the `test_find_original_update_blocks_unclosed` function, you can use the `assertRaises` context manager and check if the exception message contains the word "Incomplete". Here's the change:

```python
tests/test_utils.py
<<<<<<< ORIGINAL
        utils.find_original_update_blocks(edit)
=======
        with self.assertRaises(ValueError) as cm:
            utils.find_original_update_blocks(edit)
        self.assertIn("Incomplete", str(cm.exception))
>>>>>>> UPDATED
```
2023-05-11 22:08:30 -07:00
Paul Gauthier
6e4f17d377 cleanup 2023-05-11 22:06:32 -07:00
Paul Gauthier
684b0e4964 Provide structured errors to GPT if it generates malformed ORIG/UPD blocks 2023-05-11 22:06:02 -07:00
Paul Gauthier
6686ea1005 Only ask to commit when dirty files are touched 2023-05-11 21:14:40 -07:00
Paul Gauthier
ae41782cb4 wip 2023-05-11 21:05:15 -07:00
Paul Gauthier
797372c69e refactor orig/upd into utils 2023-05-11 20:57:27 -07:00
Paul Gauthier
5e593eb631 handle no args properly 2023-05-11 20:56:09 -07:00
Paul Gauthier
ed6ceae544 cleanup 2023-05-11 20:45:20 -07:00
Paul Gauthier
dabda6c5ea aider: Replaced console.reset() with reset_terminal() from rich.console module to reset the terminal without clearing the screen.
# Context:
USER: AttributeError: 'Console' object has no attribute 'reset'
ASSISTANT: I apologize for the confusion. It seems I made a mistake in my previous suggestion. The `rich` library does not have a `reset()` method for the `Console` object. Instead, you can use the `reset_terminal()` function from the `rich.console` module. Here's the change for `aider/main.py`:

```python
aider/main.py
<<<<<<< ORIGINAL
from rich.console import Console
=======
from rich.console import Console, reset_terminal
>>>>>>> UPDATED

aider/main.py
<<<<<<< ORIGINAL
    console = Console()
    console.reset()
=======
    reset_terminal()
>>>>>>> UPDATED
```

This change imports the `reset_terminal()` function from the `rich.console` module and replaces the `console.reset()` call with `reset_terminal()` at the end of the `main()` function to reset the terminal without clearing the screen.
2023-05-11 20:44:46 -07:00
Paul Gauthier
0ef2790464 aider: Replaced console.clear() with console.reset() to disable funky terminal modes.
# Context:
USER: i don't want to clear the screen. just disable any funky terminal modes
ASSISTANT: I apologize for the confusion. If you want to disable any funky terminal modes without clearing the screen, you can use the `rich` library's `reset()` method. Here's the change for `aider/main.py`:

```python
aider/main.py
<<<<<<< ORIGINAL
    coder.run()
    console = Console()
    console.clear()
=======
    coder.run()
    console = Console()
    console.reset()
>>>>>>> UPDATED
```

This change replaces the `console.clear()` call with `console.reset()` at the end of the `main()` function to reset the terminal without clearing the screen.
2023-05-11 20:44:01 -07:00
Paul Gauthier
71116a771b aider: Added rich library to reset the terminal at the end of main() function.
# Context:
USER: at the end of main() reset the terminal
ASSISTANT: I need to see the contents of `aider/main.py` to make the requested changes. Please provide the content of that file.
USER: Please note that I shared content of these additional files: aider/main.py
ASSISTANT: I apologize for the oversight. I see the content of `aider/main.py` now. To reset the terminal at the end of the `main()` function, you can use the `os.system()` function with the appropriate command for your operating system. Here's the change for `aider/main.py`:

```python
aider/main.py
<<<<<<< ORIGINAL

^C KeyboardInterrupt
USER: no i need pure python. can rich do it?
ASSISTANT: Yes, you can use the `rich` library to reset the terminal using pure Python. First, you need to import the `Console` class from the `rich.console` module. Then, create a `Console` instance and call its `clear()` method at the end of the `main()` function. Here's the change for `aider/main.py`:

```python
aider/main.py
<<<<<<< ORIGINAL
import os
import sys
import argparse
from dotenv import load_dotenv
from aider.coder import Coder
=======
import os
import sys
import argparse
from dotenv import load_dotenv
from aider.coder import Coder
from rich.console import Console
>>>>>>> UPDATED

aider/main.py
<<<<<<< ORIGINAL
    coder.run()
=======
    coder.run()
    console = Console()
    console.clear()
>>>>>>> UPDATED
```

This change imports the `Console` class from the `rich.console` module and adds the `console.clear()` call at the end of the `main()` function to reset the terminal.
2023-05-11 20:43:11 -07:00
Paul Gauthier
f29eaf451b ensure the Live is stopped if exceptions occur 2023-05-11 20:40:07 -07:00
Paul Gauthier
d44f732d3b main should use argv if args not provided 2023-05-11 20:34:46 -07:00
Paul Gauthier
c368e87c9f bugfix, removed abs_fnames=set() from Coder 2023-05-11 20:21:09 -07:00
Paul Gauthier
3b0c5132f2 aider: Passed temp_dir as the cwd to subprocess in test_main_with_empty_git_dir_new_file.
# Context:
USER: pass temp_dir as the cwd to subprocess in test_main_with_empty_git_dir_new_file
ASSISTANT: Here's the change to pass `temp_dir` as the `cwd` to `subprocess` in the `test_main_with_empty_git_dir_new_file` function:

```python
tests/test_main.py
<<<<<<< ORIGINAL
            subprocess.run(["git", "init"])
=======
            subprocess.run(["git", "init"], cwd=temp_dir)
>>>>>>> UPDATED
```
2023-05-11 17:52:34 -07:00
Paul Gauthier
8a60462167 finished adding --yes 2023-05-11 17:51:50 -07:00
Paul Gauthier
4c97d4e654 Removed confirm_ask and prompt_ask methods and added new implementations with yes flag. 2023-05-11 17:46:54 -07:00
Paul Gauthier
625fd1c3a5 aider: Created new function prompt_ask in Coder class and replaced all calls to Prompt.ask with the new function.
# Context:
USER: make a new func self.prompt_ask which just calls Prompt.ask and returns the result. change all calls to use it.
ASSISTANT: I will create a new function `prompt_ask` in the `Coder` class and replace all calls to `Prompt.ask` with the new function.

```python
aider/coder.py
<<<<<<< ORIGINAL
class Coder:
    abs_fnames = set()

    def confirm_ask(self, question, default=None):
=======
class Coder:
    abs_fnames = set()

    def confirm_ask(self, question, default=None):
        return Confirm.ask(question, console=self.console, default=default)

    def prompt_ask(self, question, default=None):
        return Prompt.ask(question, console=self.console, default=default)
>>>>>>> UPDATED

aider/coder.py
<<<<<<< ORIGINAL
            res = Prompt.ask(
=======
            res = self.prompt_ask(
>>>>>>> UPDATED
                "[bright_black]Commit before the chat proceeds? \[y/n/commit message]",  # noqa: W605 E501
                console=self.console,
                default="y",
            ).strip()
```
2023-05-11 17:46:05 -07:00
Paul Gauthier
428d6f73fc Refactored confirm_ask method to accept None as default and used it in all confirmations. 2023-05-11 17:45:06 -07:00
Paul Gauthier
34c2369380 aider: Created a new function confirm_ask in the Coder class and replaced all calls to Confirm.ask with the new function.
# Context:
USER: make a new func self.confirm_ask which just calls Confirm.ask and returns the result. change all calls to use it.
ASSISTANT: I will create a new function `confirm_ask` in the `Coder` class and replace all calls to `Confirm.ask` with the new function.

```python
aider/coder.py
<<<<<<< ORIGINAL
class Coder:
    abs_fnames = set()
=======
class Coder:
    abs_fnames = set()

    def confirm_ask(self, question, default="y"):
        return Confirm.ask(question, console=self.console, default=default)
>>>>>>> UPDATED

aider/coder.py
<<<<<<< ORIGINAL
            if Confirm.ask("[bright_black]Add them?", console=self.console, default="y"):
=======
            if self.confirm_ask("[bright_black]Add them?"):
>>>>>>> UPDATED

aider/coder.py
<<<<<<< ORIGINAL
            if Confirm.ask("[bright_black]Add {path} to git?", console=self.console, default="y"):
=======
            if self.confirm_ask("[bright_black]Add {path} to git?"):
>>>>>>> UPDATED

aider/coder.py
<<<<<<< ORIGINAL
        ok = Confirm.ask("[bright_black]Add these files?", console=self.console, default="y")
=======
        ok = self.confirm_ask("[bright_black]Add these files?")
>>>>>>> UPDATED
```
2023-05-11 17:43:28 -07:00
Paul Gauthier
0dd35cdaee aider: Added a new argument --yes to always say yes to every confirmation and passed it to the Coder class.
# Context:
USER: add a new arg --yes without env. pass it to Coder and store in self.yes. "Always say yes to every confirmation"
ASSISTANT: To add a new argument `--yes` and pass it to the `Coder` class, we need to make changes in `aider/main.py` and `aider/coder.py`.

In `aider/main.py`, add the new argument `--yes` to the argument parser and pass it to the `Coder` class.

```python
aider/main.py
<<<<<<< ORIGINAL
    parser.add_argument(
        "--show-diffs",
        action="store_true",
        help=f"Show diffs when committing changes (default: False, ${env_prefix}SHOW_DIFFS)",
        default=bool(int(os.environ.get(f"{env_prefix}SHOW_DIFFS", 0))),
    )
=======
    parser.add_argument(
        "--show-diffs",
        action="store_true",
        help=f"Show diffs when committing changes (default: False, ${env_prefix}SHOW_DIFFS)",
        default=bool(int(os.environ.get(f"{env_prefix}SHOW_DIFFS", 0))),
    )
    parser.add_argument(
        "--yes",
        action="store_true",
        help="Always say yes to every confirmation",
    )
>>>>>>> UPDATED
```

```python
aider/main.py
<<<<<<< ORIGINAL
    coder = Coder(args.model, fnames, pretty, args.history_file, args.show_diffs, args.auto_commits)
=======
    coder = Coder(args.model, fnames, pretty, args.history_file, args.show_diffs, args.auto_commits, args.yes)
>>>>>>> UPDATED
```

In `aider/coder.py`, add the `yes` parameter to the `Coder` class and store it in `self.yes`.

```python
aider/coder.py
<<<<<<< ORIGINAL
    def __init__(self, main_model, fnames, pretty, history_file, show_diffs, auto_commits):
=======
    def __init__(self, main_model, fnames, pretty, history_file, show_diffs, auto_commits, yes):
>>>>>>> UPDATED
```

```python
aider/coder.py
<<<<<<< ORIGINAL
        self.show_diffs = show_diffs
=======
        self.show_diffs = show_diffs
        self.yes = yes
>>>>>>> UPDATED
```

Now, the `--yes` argument is added and passed to the `Coder` class. You can use `self.yes` in the `Coder` class to determine if the user wants to always say yes to every confirmation.
2023-05-11 17:41:23 -07:00
Paul Gauthier
09fbbc0dae wip: Added import subprocess to test_main.py. 2023-05-11 17:39:15 -07:00
Paul Gauthier
fa2f76c107 aider: Added subprocess module to run git init in the temporary directory before calling main in test_main_with_empty_git_dir_new_file.
# Context:
USER: in test_main_with_empty_git_dir_new_file, run git init in the new dir before calling main
ASSISTANT: To run `git init` in the new directory before calling `main`, you can use the `subprocess` module to execute the command. Here's the change you need to make in the `test_main_with_empty_git_dir_new_file` function:

```python
tests/test_main.py
<<<<<<< ORIGINAL
    def test_main_with_empty_git_dir_new_file(self):
        with tempfile.TemporaryDirectory() as temp_dir:
            os.chdir(temp_dir)
            with open(os.devnull, 'r') as dev_null:
                save_stdin = sys.stdin
                sys.stdin = dev_null
                main(['foo.txt'])
                sys.stdin = save_stdin
=======
    import subprocess

    def test_main_with_empty_git_dir_new_file(self):
        with tempfile.TemporaryDirectory() as temp_dir:
            os.chdir(temp_dir)
            subprocess.run(["git", "init"])
            with open(os.devnull, 'r') as dev_null:
                save_stdin = sys.stdin
                sys.stdin = dev_null
                main(['foo.txt'])
                sys.stdin = save_stdin
>>>>>>> UPDATED
```

This change imports the `subprocess` module and adds the `subprocess.run(["git", "init"])` line to run `git init` in the temporary directory before calling `main`.
2023-05-11 17:36:33 -07:00
Paul Gauthier
7a29a2911a aider: Added assertion to confirm that foo.txt exists after main exits in test_main_with_empty_dir_new_file.
# Context:
USER: in test_main_with_empty_dir_new_file, confirm that foo.txt exists after main exists
ASSISTANT: To confirm that `foo.txt` exists after `main` exits, you can add an assertion in the `test_main_with_empty_dir_new_file` test case. Here's the change:

```python
tests/test_main.py
<<<<<<< ORIGINAL
                main(['foo.txt'])
                sys.stdin = save_stdin
=======
                main(['foo.txt'])
                sys.stdin = save_stdin
                self.assertTrue(os.path.exists('foo.txt'))
>>>>>>> UPDATED
```
2023-05-11 17:34:35 -07:00
Paul Gauthier
e500f8e37f wip: Refactor main function to include tests for empty directory with no files and new file creation. 2023-05-11 17:33:59 -07:00