diff --git a/HISTORY.md b/HISTORY.md index 78e309d3f..c4e57b8b0 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ ### GitHub main branch +- Updated keyboard interrupt logic so that 2 ^C in 2 seconds always forces aider to exit. - Check pypi for newer versions and notify user. - Provide GPT with detailed error if it makes a bad edit block, ask for a retry. - Force `--no-pretty` if aider detects it is running inside a VSCode terminal. diff --git a/README.md b/README.md index c6b6ca399..76bb7caec 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,7 @@ For more information, see the [FAQ](https://aider.chat/docs/faq.html). * *The best AI coding assistant so far.* -- [Matthew Berman](https://www.youtube.com/watch?v=df8afeb1FY8) * *Hands down, this is the best AI coding assistant tool so far.* -- [IndyDevDan](https://www.youtube.com/watch?v=MPYFPvxfGZs) * *Aider ... has easily quadrupled my coding productivity.* -- [SOLAR_FIELDS](https://news.ycombinator.com/item?id=36212100) +* *It's really like having your senior developer live right in your Git repo - truly amazing!* -- [rappster](https://github.com/paul-gauthier/aider/issues/124) * *What an amazing tool. It's incredible.* -- [valyagolev](https://github.com/paul-gauthier/aider/issues/6#issue-1722897858) * *Aider is such an astounding thing!* -- [cgrothaus](https://github.com/paul-gauthier/aider/issues/82#issuecomment-1631876700) * *It was WAY faster than I would be getting off the ground and making the first few working versions.* -- [Daniel Feldman](https://twitter.com/d_feldman/status/1662295077387923456) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index 3e7321520..14e076764 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -4,6 +4,7 @@ import hashlib import json import os import sys +import time import traceback from json.decoder import JSONDecodeError from pathlib import Path, PurePosixPath @@ -46,6 +47,7 @@ class Coder: functions = None total_cost = 0.0 num_exhausted_context_windows = 0 + last_keyboard_interrupt = None @classmethod def create( @@ -120,7 +122,6 @@ class Coder: self.abs_fnames = set() self.cur_messages = [] self.done_messages = [] - self.num_control_c = 0 self.io = io self.stream = stream @@ -395,13 +396,22 @@ class Coder: return except KeyboardInterrupt: - self.num_control_c += 1 - if self.num_control_c >= 2: - break - self.io.tool_error("^C again or /exit to quit") + self.keyboard_interrupt() except EOFError: return + def keyboard_interrupt(self): + now = time.time() + + thresh = 2 # seconds + if self.last_keyboard_interrupt and now - self.last_keyboard_interrupt < thresh: + self.io.tool_error("\n\n^C KeyboardInterrupt") + sys.exit() + + self.io.tool_error("\n\n^C again to exit") + + self.last_keyboard_interrupt = now + def should_dirty_commit(self, inp): cmds = self.commands.matching_commands(inp) if cmds: @@ -438,8 +448,6 @@ class Coder: self.commands, ) - self.num_control_c = 0 - if self.should_dirty_commit(inp): self.io.tool_output("Git repo has uncommitted changes, preparing commit...") self.commit(ask=True, which="repo_files") @@ -521,8 +529,6 @@ class Coder: content = "" if interrupted: - self.io.tool_error("\n\n^C KeyboardInterrupt") - self.num_control_c += 1 content += "\n^C KeyboardInterrupt" self.io.tool_output() @@ -673,6 +679,7 @@ class Coder: else: self.show_send_output(completion, silent) except KeyboardInterrupt: + self.keyboard_interrupt() interrupted = True if not silent: diff --git a/benchmark/benchmark.py b/benchmark/benchmark.py index a0bbb0cef..991d2a9f1 100755 --- a/benchmark/benchmark.py +++ b/benchmark/benchmark.py @@ -531,7 +531,7 @@ def run_test( coder.run(with_message=instructions) dur += time.time() - start - if coder.num_control_c: + if coder.last_keyboard_interrupt: raise KeyboardInterrupt if no_unit_tests: