mirror of
https://github.com/Aider-AI/aider.git
synced 2025-05-29 16:54:59 +00:00
Implement multiline-mode, swaps Enter & Meta-Enter
This commit is contained in:
parent
fbde0936e7
commit
aaf7e3f943
6 changed files with 66 additions and 2 deletions
|
@ -795,6 +795,12 @@ def get_parser(default_config_files, git_root):
|
||||||
default=True,
|
default=True,
|
||||||
help="Enable/disable fancy input with history and completion (default: True)",
|
help="Enable/disable fancy input with history and completion (default: True)",
|
||||||
)
|
)
|
||||||
|
group.add_argument(
|
||||||
|
"--multiline",
|
||||||
|
action=argparse.BooleanOptionalAction,
|
||||||
|
default=False,
|
||||||
|
help="Enable/disable multi-line input mode with Meta-Enter to submit (default: False, env: AIDER_MULTILINE)",
|
||||||
|
)
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--detect-urls",
|
"--detect-urls",
|
||||||
action=argparse.BooleanOptionalAction,
|
action=argparse.BooleanOptionalAction,
|
||||||
|
|
|
@ -248,6 +248,9 @@ class Coder:
|
||||||
if self.done_messages:
|
if self.done_messages:
|
||||||
lines.append("Restored previous conversation history.")
|
lines.append("Restored previous conversation history.")
|
||||||
|
|
||||||
|
if self.io.multiline_mode:
|
||||||
|
lines.append("Multiline mode: Enabled. Enter inserts newline, Alt-Enter submits text")
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|
|
@ -1363,6 +1363,10 @@ class Commands:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.io.tool_error(f"Error saving commands to file: {e}")
|
self.io.tool_error(f"Error saving commands to file: {e}")
|
||||||
|
|
||||||
|
def cmd_multiline_mode(self, args):
|
||||||
|
"Toggle multiline mode (swaps behavior of Enter and Meta+Enter)"
|
||||||
|
self.io.toggle_multiline_mode()
|
||||||
|
|
||||||
def cmd_copy(self, args):
|
def cmd_copy(self, args):
|
||||||
"Copy the last assistant message to the clipboard"
|
"Copy the last assistant message to the clipboard"
|
||||||
all_messages = self.coder.done_messages + self.coder.cur_messages
|
all_messages = self.coder.done_messages + self.coder.cur_messages
|
||||||
|
|
50
aider/io.py
50
aider/io.py
|
@ -202,11 +202,19 @@ class InputOutput:
|
||||||
editingmode=EditingMode.EMACS,
|
editingmode=EditingMode.EMACS,
|
||||||
fancy_input=True,
|
fancy_input=True,
|
||||||
file_watcher=None,
|
file_watcher=None,
|
||||||
|
multiline_mode=False,
|
||||||
):
|
):
|
||||||
self.placeholder = None
|
self.placeholder = None
|
||||||
self.interrupted = False
|
self.interrupted = False
|
||||||
self.never_prompts = set()
|
self.never_prompts = set()
|
||||||
self.editingmode = editingmode
|
self.editingmode = editingmode
|
||||||
|
# Base multiline setting that can be temporarily overridden
|
||||||
|
# Command line argument takes precedence over environment variable
|
||||||
|
self.base_multiline_mode = multiline_mode if multiline_mode is not None else (
|
||||||
|
os.environ.get('AIDER_MULTILINE', '').lower() in ('true', '1', 'yes', 'on')
|
||||||
|
)
|
||||||
|
# Current multiline state that can be temporarily disabled for prompts
|
||||||
|
self.multiline_mode = self.base_multiline_mode
|
||||||
no_color = os.environ.get("NO_COLOR")
|
no_color = os.environ.get("NO_COLOR")
|
||||||
if no_color is not None and no_color != "":
|
if no_color is not None and no_color != "":
|
||||||
pretty = False
|
pretty = False
|
||||||
|
@ -412,6 +420,8 @@ class InputOutput:
|
||||||
show = self.format_files_for_input(rel_fnames, rel_read_only_fnames)
|
show = self.format_files_for_input(rel_fnames, rel_read_only_fnames)
|
||||||
if edit_format:
|
if edit_format:
|
||||||
show += edit_format
|
show += edit_format
|
||||||
|
if self.multiline_mode:
|
||||||
|
show += (" " if edit_format else "") + "multi"
|
||||||
show += "> "
|
show += "> "
|
||||||
|
|
||||||
inp = ""
|
inp = ""
|
||||||
|
@ -456,9 +466,25 @@ class InputOutput:
|
||||||
"Navigate forward through history"
|
"Navigate forward through history"
|
||||||
event.current_buffer.history_forward()
|
event.current_buffer.history_forward()
|
||||||
|
|
||||||
@kb.add("escape", "c-m", eager=True)
|
@kb.add("enter", eager=True)
|
||||||
def _(event):
|
def _(event):
|
||||||
event.current_buffer.insert_text("\n")
|
"Handle Enter key press"
|
||||||
|
if self.multiline_mode:
|
||||||
|
# In multiline mode, Enter adds a newline
|
||||||
|
event.current_buffer.insert_text("\n")
|
||||||
|
else:
|
||||||
|
# In normal mode, Enter submits
|
||||||
|
event.current_buffer.validate_and_handle()
|
||||||
|
|
||||||
|
@kb.add("escape", "enter", eager=True) # This is Alt+Enter
|
||||||
|
def _(event):
|
||||||
|
"Handle Alt+Enter key press"
|
||||||
|
if self.multiline_mode:
|
||||||
|
# In multiline mode, Alt+Enter submits
|
||||||
|
event.current_buffer.validate_and_handle()
|
||||||
|
else:
|
||||||
|
# In normal mode, Alt+Enter adds a newline
|
||||||
|
event.current_buffer.insert_text("\n")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if multiline_input:
|
if multiline_input:
|
||||||
|
@ -629,6 +655,9 @@ class InputOutput:
|
||||||
group=None,
|
group=None,
|
||||||
allow_never=False,
|
allow_never=False,
|
||||||
):
|
):
|
||||||
|
# Temporarily disable multiline mode for yes/no prompts
|
||||||
|
orig_multiline = self.multiline_mode
|
||||||
|
self.multiline_mode = False
|
||||||
self.num_user_asks += 1
|
self.num_user_asks += 1
|
||||||
|
|
||||||
question_id = (question, subject)
|
question_id = (question, subject)
|
||||||
|
@ -726,9 +755,15 @@ class InputOutput:
|
||||||
hist = f"{question.strip()} {res}"
|
hist = f"{question.strip()} {res}"
|
||||||
self.append_chat_history(hist, linebreak=True, blockquote=True)
|
self.append_chat_history(hist, linebreak=True, blockquote=True)
|
||||||
|
|
||||||
|
# Restore original multiline mode
|
||||||
|
self.multiline_mode = orig_multiline
|
||||||
|
|
||||||
return is_yes
|
return is_yes
|
||||||
|
|
||||||
def prompt_ask(self, question, default="", subject=None):
|
def prompt_ask(self, question, default="", subject=None):
|
||||||
|
# Temporarily disable multiline mode for prompts
|
||||||
|
orig_multiline = self.multiline_mode
|
||||||
|
self.multiline_mode = False
|
||||||
self.num_user_asks += 1
|
self.num_user_asks += 1
|
||||||
|
|
||||||
if subject:
|
if subject:
|
||||||
|
@ -752,6 +787,9 @@ class InputOutput:
|
||||||
if self.yes in (True, False):
|
if self.yes in (True, False):
|
||||||
self.tool_output(hist)
|
self.tool_output(hist)
|
||||||
|
|
||||||
|
# Restore original multiline mode
|
||||||
|
self.multiline_mode = orig_multiline
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _tool_message(self, message="", strip=True, color=None):
|
def _tool_message(self, message="", strip=True, color=None):
|
||||||
|
@ -821,6 +859,14 @@ class InputOutput:
|
||||||
def print(self, message=""):
|
def print(self, message=""):
|
||||||
print(message)
|
print(message)
|
||||||
|
|
||||||
|
def toggle_multiline_mode(self):
|
||||||
|
"""Toggle between normal and multiline input modes"""
|
||||||
|
self.multiline_mode = not self.multiline_mode
|
||||||
|
if self.multiline_mode:
|
||||||
|
self.tool_output("Multiline mode: Enabled. Enter inserts newline, Alt-Enter submits text")
|
||||||
|
else:
|
||||||
|
self.tool_output("Multiline mode: Disabled. Alt-Enter inserts newline, Enter submits text")
|
||||||
|
|
||||||
def append_chat_history(self, text, linebreak=False, blockquote=False, strip=True):
|
def append_chat_history(self, text, linebreak=False, blockquote=False, strip=True):
|
||||||
if blockquote:
|
if blockquote:
|
||||||
if strip:
|
if strip:
|
||||||
|
|
|
@ -515,6 +515,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||||
llm_history_file=args.llm_history_file,
|
llm_history_file=args.llm_history_file,
|
||||||
editingmode=editing_mode,
|
editingmode=editing_mode,
|
||||||
fancy_input=args.fancy_input,
|
fancy_input=args.fancy_input,
|
||||||
|
multiline_mode=args.multiline,
|
||||||
)
|
)
|
||||||
|
|
||||||
io = get_io(args.pretty)
|
io = get_io(args.pretty)
|
||||||
|
|
|
@ -5,6 +5,10 @@ You can send long, multi-line messages in the chat in a few ways:
|
||||||
- Use Meta-ENTER to start a new line without sending the message (Esc+ENTER in some environments).
|
- Use Meta-ENTER to start a new line without sending the message (Esc+ENTER in some environments).
|
||||||
- Use `/paste` to paste text from the clipboard into the chat.
|
- Use `/paste` to paste text from the clipboard into the chat.
|
||||||
- Use the `/editor` command to open your editor to create the next chat message. See [editor configuration docs](/docs/config/editor.html) for more info.
|
- Use the `/editor` command to open your editor to create the next chat message. See [editor configuration docs](/docs/config/editor.html) for more info.
|
||||||
|
- Use multiline-mode, which swaps the function of Meta-Enter and Enter, so that Enter inserts a newline, and Meta-Enter submits your command. You can enable multiline mode in three ways:
|
||||||
|
- Use the `/multiline-mode` command to toggle it during a session
|
||||||
|
- Start aider with the `--multiline` flag
|
||||||
|
- Start aider with the environment variable AIDER\_MULTILINE=true
|
||||||
|
|
||||||
Example with a tag:
|
Example with a tag:
|
||||||
```
|
```
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue