mirror of
https://github.com/Aider-AI/aider.git
synced 2025-06-01 10:14:59 +00:00
Merge branch 'main' into call-graph
This commit is contained in:
commit
6b4c54d117
7 changed files with 230 additions and 16 deletions
|
@ -3,11 +3,10 @@
|
||||||
`aider` is a command-line chat tool that allows you to write and edit
|
`aider` is a command-line chat tool that allows you to write and edit
|
||||||
code with GPT-4. You can ask GPT to help you start
|
code with GPT-4. You can ask GPT to help you start
|
||||||
a new project, or modify code in your existing git repo.
|
a new project, or modify code in your existing git repo.
|
||||||
Aider has features to
|
Aider makes it easy to git commit, diff & undo changes proposed by GPT.
|
||||||
[help GPT understand and modify larger codebases](https://aider.chat/docs/ctags.html)
|
It also has features that [help GPT understand and modify larger codebases](https://aider.chat/docs/ctags.html).
|
||||||
and aider makes it easy to git commit, diff & undo changes proposed by GPT.
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
- [Example chat transcripts](#example-chat-transcripts)
|
- [Example chat transcripts](#example-chat-transcripts)
|
||||||
- [Features](#features)
|
- [Features](#features)
|
||||||
|
|
17
aider/io.py
17
aider/io.py
|
@ -5,9 +5,10 @@ from pathlib import Path
|
||||||
|
|
||||||
from prompt_toolkit.completion import Completer, Completion
|
from prompt_toolkit.completion import Completer, Completion
|
||||||
from prompt_toolkit.history import FileHistory
|
from prompt_toolkit.history import FileHistory
|
||||||
|
from prompt_toolkit.lexers import PygmentsLexer
|
||||||
from prompt_toolkit.shortcuts import CompleteStyle, PromptSession, prompt
|
from prompt_toolkit.shortcuts import CompleteStyle, PromptSession, prompt
|
||||||
from prompt_toolkit.styles import Style
|
from prompt_toolkit.styles import Style
|
||||||
from pygments.lexers import guess_lexer_for_filename
|
from pygments.lexers import MarkdownLexer, guess_lexer_for_filename
|
||||||
from pygments.token import Token
|
from pygments.token import Token
|
||||||
from pygments.util import ClassNotFound
|
from pygments.util import ClassNotFound
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
|
@ -68,9 +69,11 @@ class FileContentCompleter(Completer):
|
||||||
rel_fnames = self.fname_to_rel_fnames.get(word, [])
|
rel_fnames = self.fname_to_rel_fnames.get(word, [])
|
||||||
if rel_fnames:
|
if rel_fnames:
|
||||||
for rel_fname in rel_fnames:
|
for rel_fname in rel_fnames:
|
||||||
yield Completion(rel_fname, start_position=-len(last_word))
|
yield Completion(
|
||||||
|
f"`{rel_fname}`", start_position=-len(last_word), display=rel_fname
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
yield Completion(word, start_position=-len(last_word))
|
yield Completion(f"`{word}`", start_position=-len(last_word), display=word)
|
||||||
|
|
||||||
|
|
||||||
class InputOutput:
|
class InputOutput:
|
||||||
|
@ -129,7 +132,12 @@ class InputOutput:
|
||||||
multiline_input = False
|
multiline_input = False
|
||||||
|
|
||||||
if self.user_input_color:
|
if self.user_input_color:
|
||||||
style = Style.from_dict({"": self.user_input_color})
|
style = Style.from_dict(
|
||||||
|
{
|
||||||
|
"": self.user_input_color,
|
||||||
|
"pygments.literal.string": f"bold italic {self.user_input_color}",
|
||||||
|
}
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
style = None
|
style = None
|
||||||
|
|
||||||
|
@ -147,6 +155,7 @@ class InputOutput:
|
||||||
"complete_style": CompleteStyle.MULTI_COLUMN,
|
"complete_style": CompleteStyle.MULTI_COLUMN,
|
||||||
"input": self.input,
|
"input": self.input,
|
||||||
"output": self.output,
|
"output": self.output,
|
||||||
|
"lexer": PygmentsLexer(MarkdownLexer),
|
||||||
}
|
}
|
||||||
if style:
|
if style:
|
||||||
session_kwargs["style"] = style
|
session_kwargs["style"] = style
|
||||||
|
|
|
@ -8,7 +8,7 @@ Take requests for changes to the supplied code.
|
||||||
If the request is ambiguous, ask questions.
|
If the request is ambiguous, ask questions.
|
||||||
|
|
||||||
Once you understand the request you MUST:
|
Once you understand the request you MUST:
|
||||||
1. List the files you need to modify. Do not suggest changes to *read-only* files. You *MUST* ask the user to make them *read-write* using the file's full path name. End your reply and wait for their approval.
|
1. List the files you need to modify. *NEVER* suggest changes to *read-only* files. You *MUST* ask the user to make them *read-write* using the file's full path name. End your reply and wait for their approval.
|
||||||
2. Think step-by-step and explain the needed changes.
|
2. Think step-by-step and explain the needed changes.
|
||||||
3. Describe each change with an *edit block* per the example below.
|
3. Describe each change with an *edit block* per the example below.
|
||||||
"""
|
"""
|
||||||
|
@ -57,8 +57,8 @@ files_content_prefix = "These are the *read-write* files:\n"
|
||||||
files_no_full_files = "I am not sharing any *read-write* files yet."
|
files_no_full_files = "I am not sharing any *read-write* files yet."
|
||||||
|
|
||||||
repo_content_prefix = (
|
repo_content_prefix = (
|
||||||
"All the files below here are *read-only* files. Notice that files in directories are indented."
|
"All the files below here are *read-only* files! Do not propose changes to these without asking"
|
||||||
" Use their parent dirs to build their full path.\n"
|
" me first."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -219,6 +219,9 @@ def find_original_update_blocks(content):
|
||||||
pieces.reverse()
|
pieces.reverse()
|
||||||
processed = []
|
processed = []
|
||||||
|
|
||||||
|
# Keep using the same filename in cases where GPT produces an edit block
|
||||||
|
# without a filename.
|
||||||
|
current_filename = None
|
||||||
try:
|
try:
|
||||||
while pieces:
|
while pieces:
|
||||||
cur = pieces.pop()
|
cur = pieces.pop()
|
||||||
|
@ -237,12 +240,20 @@ def find_original_update_blocks(content):
|
||||||
try:
|
try:
|
||||||
if not len(filename) or "`" in filename:
|
if not len(filename) or "`" in filename:
|
||||||
filename = processed[-2].splitlines()[-2].strip()
|
filename = processed[-2].splitlines()[-2].strip()
|
||||||
if not len(filename) or "`" in filename:
|
if not len(filename) or "`" in filename:
|
||||||
|
if current_filename:
|
||||||
|
filename = current_filename
|
||||||
|
else:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Bad/missing filename. It should go right above {ORIGINAL}"
|
f"Bad/missing filename. It should go right above {ORIGINAL}"
|
||||||
)
|
)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
raise ValueError(f"Bad/missing filename. It should go right above {ORIGINAL}")
|
if current_filename:
|
||||||
|
filename = current_filename
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Bad/missing filename. It should go right above {ORIGINAL}")
|
||||||
|
|
||||||
|
current_filename = filename
|
||||||
|
|
||||||
original_text = pieces.pop()
|
original_text = pieces.pop()
|
||||||
processed.append(original_text)
|
processed.append(original_text)
|
||||||
|
|
194
assets/screencast.svg
Normal file
194
assets/screencast.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 115 KiB |
Binary file not shown.
Before Width: | Height: | Size: 49 KiB |
|
@ -195,9 +195,10 @@ tests/test_repomap.py
|
||||||
|
|
||||||
These changes replace the `subprocess.run` patches with `subprocess.check_output` patches in both `test_check_for_ctags_failure` and `test_check_for_ctags_success` tests.
|
These changes replace the `subprocess.run` patches with `subprocess.check_output` patches in both `test_check_for_ctags_failure` and `test_check_for_ctags_success` tests.
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(ValueError) as cm:
|
edit_blocks = list(utils.find_original_update_blocks(edit))
|
||||||
list(utils.find_original_update_blocks(edit))
|
self.assertEqual(len(edit_blocks), 2) # 2 edits
|
||||||
self.assertIn("missing filename", str(cm.exception))
|
self.assertEqual(edit_blocks[0][0], "tests/test_repomap.py")
|
||||||
|
self.assertEqual(edit_blocks[1][0], "tests/test_repomap.py")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue