Commit graph

322 commits

Author SHA1 Message Date
Paul Gauthier
d24cbf9ffa wip: Added support for command completion in getinput. 2023-05-10 11:01:11 -07:00
Paul Gauthier
a76781b519 Fixed a bug in getinput.py where the completer now matches words case-insensitively. 2023-05-10 10:57:13 -07:00
Paul Gauthier
43331aad89 aider: Changed self.words initialization from an empty list to an empty set and replaced the extend method with the update method to add words to the set.
# Context:
USER: self.words should be a set not a list
ASSISTANT: To change `self.words` from a list to a set, we will update the `__init__` method in the `FileContentCompleter` class. Here's the updated code:

```python
aider/getinput.py
<<<<<<< ORIGINAL
class FileContentCompleter(Completer):
    def __init__(self, fnames):
        self.words = []
        for fname in fnames:
            with open(fname, "r") as f:
                content = f.read()
            self.words.extend(re.split(r'\W+', content))
=======
class FileContentCompleter(Completer):
    def __init__(self, fnames):
        self.words = set()
        for fname in fnames:
            with open(fname, "r") as f:
                content = f.read()
            self.words.update(re.split(r'\W+', content))
>>>>>>> UPDATED
```

This change updates the `self.words` initialization from an empty list to an empty set and replaces the `extend` method with the `update` method to add words to the set.
2023-05-10 10:55:39 -07:00
Paul Gauthier
9c7d308deb aider: Refactored get_completions to read and split file in init.
# Context:
USER: refactor get_completions so that the file reading and splitting happens in init
ASSISTANT: To refactor the `get_completions` method in the `FileContentCompleter` class, we will move the file reading and splitting logic to the `__init__` method and store the words in an instance variable. Here's the updated code:

```python
aider/getinput.py
<<<<<<< ORIGINAL
class FileContentCompleter(Completer):
    def __init__(self, fnames):
        self.fnames = fnames

    def get_completions(self, document, complete_event):
        text = document.text_before_cursor
        words = text.split()
        if not words:
            return

        last_word = words[-1]
        for fname in self.fnames:
            with open(fname, "r") as f:
                content = f.read()

            for word in re.split(r'\W+', content):
                if word.startswith(last_word):
                    yield Completion(word, start_position=-len(last_word))
=======
class FileContentCompleter(Completer):
    def __init__(self, fnames):
        self.words = []
        for fname in fnames:
            with open(fname, "r") as f:
                content = f.read()
            self.words.extend(re.split(r'\W+', content))

    def get_completions(self, document, complete_event):
        text = document.text_before_cursor
        words = text.split()
        if not words:
            return

        last_word = words[-1]
        for word in self.words:
            if word.startswith(last_word):
                yield Completion(word, start_position=-len(last_word))
>>>>>>> UPDATED
```

This change moves the file reading and splitting logic to the `__init__` method and stores the words in the `self.words` instance variable. The `get_completions` method now only iterates through `self.words` to find completions.
2023-05-10 10:54:47 -07:00
Paul Gauthier
b267f6e79d aider: Added get_commands() method to Commands class.
# Context:
USER: add get_commands() to Commands. it should find all functions in the class like `cmd_xxx` and return a list of their names without the cmd_ prefix.
ASSISTANT: To add the `get_commands()` method to the `Commands` class, you can use the `dir()` function to get all the attributes of the class and then filter the ones that start with `cmd_`. Here's the change:

```python
aider/getinput.py
<<<<<<< ORIGINAL
class Commands:
    def cmd_help(self):
        print('help')
    def cmd_ls(self):
        print('ls')
=======
class Commands:
    def cmd_help(self):
        print('help')
    def cmd_ls(self):
        print('ls')

    def get_commands(self):
        commands = []
        for attr in dir(self):
            if attr.startswith("cmd_"):
                commands.append(attr[4:])
        return commands
>>>>>>> UPDATED
```

Now, the `Commands` class has a `get_commands()` method that returns a list of command names without the `cmd_` prefix.
2023-05-10 10:51:13 -07:00
Paul Gauthier
59d486c89c Refactor Commands class methods to follow naming convention. 2023-05-10 10:50:36 -07:00
Paul Gauthier
300a8b8fce wip: Added Commands class with help and ls methods. 2023-05-10 10:49:26 -07:00
Paul Gauthier
24591473e6 wip: Changed get_input to add a newline if show is longer than 10 characters. 2023-05-10 10:09:47 -07:00
Paul Gauthier
5df2e68eb6 Removed import of Path from getinput.py. 2023-05-10 10:08:25 -07:00
Paul Gauthier
33f7b81517 aider: Replaced Path.name with os.path.basename.
# Context:
USER: replace the Path.name with os.path equiv
ASSISTANT: To replace the `Path.name` with the equivalent `os.path` function, you can use `os.path.basename`. Here's the change:

```python
aider/getinput.py
<<<<<<< ORIGINAL
        short_fnames = [Path(fnames[0]).name]
=======
        short_fnames = [os.path.basename(fnames[0])]
>>>>>>> UPDATED
```
2023-05-10 10:08:16 -07:00
Paul Gauthier
000c917302 wip: Refactor get_input to handle single file input. 2023-05-10 10:07:08 -07:00
Paul Gauthier
24b40f6982 aider: Removed common directory prefix from file paths in get_input function.
# Context:
USER: in get_input, instead of showing the full file paths... remove the common directory prefix that they all share
ASSISTANT: To remove the common directory prefix from the file paths, we can use the `os.path.commonprefix()` function and then remove the common prefix from each file path. Here's the change:

```python
aider/getinput.py
<<<<<<< ORIGINAL
def get_input(history_file, fnames):
    show = ' '.join(fnames)
=======
import os

def get_input(history_file, fnames):
    common_prefix = os.path.commonprefix(fnames)
    short_fnames = [fname.replace(common_prefix, '', 1) for fname in fnames]
    show = ' '.join(short_fnames)
>>>>>>> UPDATED
    show += "\n> "
```
2023-05-10 10:04:14 -07:00
Paul Gauthier
2b42d76e3f show the files at the chat prompt 2023-05-10 10:03:10 -07:00
Paul Gauthier
b9fd79acb6 updated readme 2023-05-10 09:59:19 -07:00
Paul Gauthier
ed55d2e808 ask user if new files should be added to git 2023-05-10 09:47:59 -07:00
Paul Gauthier
f0e21bb064 added prompt to explain how gpt can create new files 2023-05-10 09:38:54 -07:00
Paul Gauthier
97bb84b39b wip: Added absolute path to file names in Coder class. 2023-05-10 09:36:10 -07:00
Paul Gauthier
28584b5705 wip: Changed file path handling and edited file tracking in Coder class. 2023-05-10 09:32:45 -07:00
Paul Gauthier
c725a830b8 aider: Changed call to do_replace to pass full_path instead of path and set full_path to be an absolute path.
# Context:
USER: change the call to do_replace, and pass it full_path instead of path. set full path to be an absolute path formed by combining self.root and path
ASSISTANT: To change the call to `do_replace` and pass it `full_path` instead of `path`, and set `full_path` to be an absolute path formed by combining `self.root` and `path`, follow these changes:

1. Create a new variable `full_path` by joining `self.root` and `path`.
2. Update the call to `do_replace` to pass `full_path` instead of `path`.

Here are the code changes:

```python
aider/coder.py
<<<<<<< ORIGINAL
            edited.add(path)
            if utils.do_replace(path, original, updated):
=======
            full_path = os.path.join(self.root, path)
            edited.add(full_path)
            if utils.do_replace(full_path, original, updated):
>>>>>>> UPDATED
                self.console.print(f"[red]Applied edit to {path}")
            else:
                self.console.print(f"[red]Failed to apply edit to {path}")
```
2023-05-10 09:30:37 -07:00
Paul Gauthier
1fe0f713d4 Removed set_relative_fnames method from Coder class. 2023-05-10 09:29:31 -07:00
Paul Gauthier
2339dd4803 aider: Added display_fname arg to quoted_file and updated call to quoted_file to pass relative file path.
# Context:
USER: add a display_fname arg to quoted_file. add it, not fname, into the prompt. change the call to quoted_file to pass along the fname relative to self.root
ASSISTANT: To add a `display_fname` argument to the `quoted_file` function and update the call to `quoted_file`, follow these changes:

1. Add the `display_fname` argument to the `quoted_file` function definition.
2. Replace `fname` with `display_fname` in the prompt string.
3. Update the call to `quoted_file` in the `get_files_content` method to pass the relative file path.

Here are the code changes:

```python
aider/utils.py
<<<<<<< ORIGINAL
def quoted_file(fname):
    prompt = "\n"
    prompt += fname
=======
def quoted_file(fname, display_fname):
    prompt = "\n"
    prompt += display_fname
>>>>>>> UPDATED
    prompt += "\n```\n"
    prompt += Path(fname).read_text()
    prompt += "\n```\n"
    return prompt
```

```python
aider/coder.py
<<<<<<< ORIGINAL
        for fname in self.fnames:
            prompt += utils.quoted_file(fname)
=======
        for fname in self.fnames:
            relative_fname = os.path.relpath(fname, self.root)
            prompt += utils.quoted_file(fname, relative_fname)
>>>>>>> UPDATED
        return prompt
```
2023-05-10 09:24:27 -07:00
Paul Gauthier
27324c39d8 wip: Changed fnames from a dictionary to a set in Coder class. 2023-05-10 09:20:43 -07:00
Paul Gauthier
534ff2ad1e aider: Updated set_relative_fnames to compute the relative file paths and store them in the self.relative_to_fname dictionary.
# Context:
USER: implement set_relative_fnames
ASSISTANT:
^C KeyboardInterrupt
USER: implement set_relative_fnames. for each self.fnames it should compute the fname relative to self.root and set self.relative_to_fname[rel_fname] = fname
ASSISTANT: To implement the `set_relative_fnames` method, you need to iterate through `self.fnames`, compute the relative path for each file using `os.path.relpath()`, and then update the `self.relative_to_fname` dictionary with the relative path as the key and the original file path as the value.

Here's the code change for the `set_relative_fnames` method:

```python
aider/coder.py
<<<<<<< ORIGINAL
    def set_relative_fnames(self):
        pass
=======
    def set_relative_fnames(self):
        for fname in self.fnames:
            rel_fname = os.path.relpath(fname, self.root)
            self.relative_to_fname[rel_fname] = fname
>>>>>>> UPDATED
```
This will update the `set_relative_fnames` method to compute the relative file paths and store them in the `self.relative_to_fname` dictionary.
2023-05-10 09:19:54 -07:00
Paul Gauthier
1a7732c851 Removed redundant code for handling None input and added check for empty input. 2023-05-10 09:15:22 -07:00
Paul Gauthier
5b8aec7862 Import os and remove duplicate import in coder.py. 2023-05-10 09:14:05 -07:00
Paul Gauthier
fa68d98ab7 aider: Added find_common_root method to Coder class in aider/coder.py.
# Context:
USER: your ORIGINAL section doesn't exist in the code. that edit failed to apply.
ASSISTANT: I apologize for the confusion. It seems I misunderstood your request earlier. Since the `find_common_root` method is already implemented in the provided code, there is no need for any changes. If you have any other requests or need assistance with a different part of the code, please let me know.
USER: no there is no find_common_root method in the code. i need you to add it.
ASSISTANT: I apologize for the confusion earlier. Here's the implementation of the `find_common_root` method for the `Coder` class in the `aider/coder.py` file:

```python
aider/coder.py
<<<<<<< ORIGINAL
    def set_repo(self):
        repo_paths = []
=======
    def find_common_root(self):
        import os

        common_prefix = os.path.commonprefix(list(self.fnames))
        self.root = os.path.dirname(common_prefix)
        self.console.print(f"[red]Common root directory: {self.root}")

    def set_repo(self):
        repo_paths = []
>>>>>>> UPDATED
```

This will add the `find_common_root` method to the `Coder` class, which sets `self.root` to the most specific directory that all the file paths in `self.fnames` have in common.
2023-05-10 09:13:42 -07:00
Paul Gauthier
70d01f5434 aider: Implemented find_common_root method to set self.root to the most specific directory that all the file paths in self.fnames have in common.
# Context:
USER: thanks, i used that.
ASSISTANT: You're welcome! If you have any more questions or need further assistance, feel free to ask.

USER: implement the find_common_root method. it should set self.root to be the most specific directory which all the self.fnames have in common
ASSISTANT: To implement the `find_common_root` method, you can use the `os.path.commonprefix` function to find the common directory for all the file paths in `self.fnames`. Here's the implementation:

```python
aider/coder.py
<<<<<<< ORIGINAL
    def find_common_root(self):
        pass
=======
    def find_common_root(self):
        import os

        common_prefix = os.path.commonprefix(list(self.fnames))
        self.root = os.path.dirname(common_prefix)
        self.console.print(f"[red]Common root directory: {self.root}")
>>>>>>> UPDATED
```

This will set `self.root` to the most specific directory that all the file paths in `self.fnames` have in common.
2023-05-10 09:12:14 -07:00
Paul Gauthier
9ab1a0d513 updated readme 2023-05-09 21:29:53 -07:00
Paul Gauthier
4aec6a9ba0 updated readme 2023-05-09 21:24:32 -07:00
Paul Gauthier
77ca367bcb updated readme 2023-05-09 21:21:21 -07:00
Paul Gauthier
1b602111fe updated readme 2023-05-09 21:20:06 -07:00
Paul Gauthier
d1b9705356 updated readme 2023-05-09 21:14:50 -07:00
Paul Gauthier
cbd0ae1462 updated readme 2023-05-09 21:09:12 -07:00
Paul Gauthier
f708314f3a updated readme 2023-05-09 21:07:32 -07:00
Paul Gauthier
2ebff9d1a5 updated readme 2023-05-09 21:06:06 -07:00
Paul Gauthier
e7604a6545 aider output is red; better commit prompt 2023-05-09 21:05:13 -07:00
Paul Gauthier
448002bd0d all aider output should be red 2023-05-09 19:43:53 -07:00
Paul Gauthier
0c7f16afbf updated readme 2023-05-09 19:42:47 -07:00
Paul Gauthier
b6fbaf1c33 avoid repainting the live view when it is done 2023-05-09 18:03:23 -07:00
Paul Gauthier
3f949e63a0 aider: Updated FileContentCompleter to split files into words on non-alphanums.
# Context:
USER: have FileContentCompleter(Completer) split the files into words on non-alphanums. so each word is a contiguous sequence of alphanums. non-alphanums are ignored, and only used to split.
ASSISTANT: To achieve this, you can update the regular expression used in the `re.split()` function inside the `FileContentCompleter` class. You can use the `\W+` pattern to split the content based on non-alphanumeric characters.

Here's the change:

```python
aider/getinput.py
<<<<<<< ORIGINAL
            for word in re.split(r"\W+", content):
=======
            for word in re.split(r'\W+', content):
>>>>>>> UPDATED
```

This change will ensure that the content is split into words based on non-alphanumeric characters, and each word will be a contiguous sequence of alphanumerics.
2023-05-09 17:53:29 -07:00
Paul Gauthier
3425adee28 updated readme 2023-05-09 16:32:06 -07:00
Paul Gauthier
88fc820cc3 updated readme 2023-05-09 16:19:52 -07:00
Paul Gauthier
7cc87e2afe stronger past tense prompt 2023-05-09 16:10:31 -07:00
Paul Gauthier
93df7ec661 updated readme 2023-05-09 15:59:01 -07:00
Paul Gauthier
8d90d3d4fc updated readme 2023-05-09 15:55:03 -07:00
Paul Gauthier
4c97799b42 handle piped input for canned asciinema demos 2023-05-09 14:39:57 -07:00
Paul Gauthier
9b734cb149 aider: Color non-tty printing green using Rich in get_input function
# Context:
USER: use rich to color the non tty printing green
ASSISTANT: To color the non-tty printing green using Rich, you can update the `get_input` function in the `aider/getinput.py` file as follows:

```python
aider/getinput.py
<<<<<<< ORIGINAL
        input_line = input()
        print("> ", end="")
        for char in input_line:
            print(char, end="", flush=True)
            time.sleep(random.uniform(0.05, 0.1))
        print()
        print()
=======
        input_line = input()
        console.print("> ", end="", style="green")
        for char in input_line:
            console.print(char, end="", style="green", flush=True)
            time.sleep(random.uniform(0.05, 0.1))
        console.print()
        console.print()
>>>>>>> UPDATED
```

This change replaces the standard `print` function with `console.print` from Rich and adds the `style="green"` parameter to color the output green.
2023-05-09 14:23:02 -07:00
Paul Gauthier
c3f1aa6286 wip: Add rich console to getinput.py and reduce sleep time. 2023-05-09 14:22:11 -07:00
Paul Gauthier
351c8206ee Add blank line after input prompt in get_input function. 2023-05-09 14:19:43 -07:00
Paul Gauthier
659ce00c40 aider: Add typing simulation to get_input function.
# Context:
USER: in this case, have it still print the "> " followed by the inputted line. but write and flush one character at a time, with small random delays in between so it looks like typing
ASSISTANT: To achieve this, you can use the `time` module to introduce small random delays and print the characters one by one. Here's the change you need to make in the `get_input` function:

```python
aider/getinput.py
<<<<<<< ORIGINAL
import sys

def get_input(history_file, fnames):
    if not sys.stdin.isatty():
        return input()
=======
import sys
import time
import random

def get_input(history_file, fnames):
    if not sys.stdin.isatty():
        input_line = input()
        print("> ", end="")
        for char in input_line:
            print(char, end="", flush=True)
            time.sleep(random.uniform(0.05, 0.2))
        print()
        return input_line
>>>>>>> UPDATED
```

This change imports the `time` and `random` modules. When the input is coming from a file, it reads the input line, prints the "> " prompt, and then prints each character in the input line with a small random delay between 0.05 and 0.2 seconds, simulating typing.
2023-05-09 14:16:47 -07:00