Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,76 @@ The project's documentation is built using Jekyll and hosted on GitHub Pages. To

The built documentation will be available in the `aider/website/_site` directory.

## Suggesting UI/UX Style Changes

Aider utilizes `prompt_toolkit` which in turn often uses `Pygments` tokens for styling various text components.

If you have ideas for different colors, text styles (like bold, underline, italics), or other visual enhancements, you can help by:

1. Identifying the specific UI element you'd like to change (e.g., user input prompt, code blocks, AI responses).
2. Using a script to determine the `Pygments` token associated with that element.
3. Suggesting the new style (e.g., color, attributes) for that token.

You can submit these suggestions as GitHub issues or, if you're comfortable, as part of a Pull Request modifying the relevant style definitions in the Aider codebase.

### Example: Identifying Pygments Tokens

The following Python script can help you identify the Pygments tokens used for different text elements. You can adapt it to explore Aider's UI components.

```python
#!/usr/bin/env python
"""
Printing a list of Pygments (Token, text) tuples,
or an output of a Pygments lexer.
"""

import pygments
from pygments.lexers.python import PythonLexer
from pygments.token import Token

from prompt_toolkit import print_formatted_text
from prompt_toolkit.formatted_text import PygmentsTokens
from prompt_toolkit.styles import Style


def main():
# Printing the output of a pygments lexer.
# This example uses MarkdownLexer. You may need to install it
# (e.g., it's part of Pygments' standard lexers) or ensure Pygments is installed.
# You can import it with: from pygments.lexers.markup import MarkdownLexer
from pygments.lexers.markup import MarkdownLexer
tokens = list(pygments.lex("""# some title
* something
* else

some `code`""", lexer=MarkdownLexer()))
print("Tokens found:")
print(tokens)

# With a custom style.
style = Style.from_dict(
{
"pygments.generic.heading": "underline",
"pygments.keyword": "underline", # Example style for keywords
}
)
print("\nFormatted text with custom style:")
print_formatted_text(PygmentsTokens(tokens), style=style)


if __name__ == "__main__":
main()
```

To use this script:

1. **Input Text**: Change the string in `pygments.lex()` to match the UI element you're inspecting.
2. **Lexer**: Select an appropriate lexer. For general input, `TextLexer` (from `pygments.lexers.special`) is a good start. For code, use the relevant language lexer (e.g., `PythonLexer`). Ensure `Pygments` is installed.
3. **Output**: Run the script. It will print `(Token, text)` tuples. The `Token` (e.g., `Token.Generic.Heading`) is what you need.
4. **Styles**: Experiment by modifying the `style` dictionary with token names and `prompt_toolkit` style strings (e.g., `"underline"`, `"#ff0000"`).

This process will help you pinpoint tokens and test styles, providing valuable information for suggesting UI improvements.

## Coding Standards

### Python Compatibility
Expand Down
15 changes: 8 additions & 7 deletions aider/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from rich.markdown import Markdown
from rich.style import Style as RichStyle
from rich.text import Text
from rich.theme import Theme

from aider.mdstream import MarkdownStream

Expand Down Expand Up @@ -356,7 +357,8 @@ def __init__(
session_kwargs["history"] = FileHistory(self.input_history_file)
try:
self.prompt_session = PromptSession(**session_kwargs)
self.console = Console() # pretty console
theme = Theme({"markdown.code": f"bold {self.assistant_output_color}"})
self.console = Console(theme=theme) # pretty console
except Exception as err:
self.console = Console(force_terminal=False, no_color=True)
self.tool_error(f"Can't initialize prompt toolkit: {err}") # non-pretty
Expand Down Expand Up @@ -407,6 +409,8 @@ def _get_style(self):
style_dict.update(
{
"pygments.literal.string": f"bold italic {self.user_input_color}",
"pygments.generic.heading": f"bold {self.user_input_color}",
"pygments.keyword": f"{self.user_input_color}",
}
)

Expand Down Expand Up @@ -1012,12 +1016,9 @@ def tool_output(self, *messages, log_only=False, bold=False):
self.console.print(*messages, style=style)

def get_assistant_mdstream(self):
mdargs = dict(
style=self.assistant_output_color,
code_theme=self.code_theme,
inline_code_lexer="text",
)
mdStream = MarkdownStream(mdargs=mdargs)
mdargs = dict(style=self.assistant_output_color, code_theme=self.code_theme)
console_theme = Theme({"markdown.code": f"bold {self.assistant_output_color}"})
mdStream = MarkdownStream(mdargs=mdargs, console_theme=console_theme)
return mdStream

def assistant_output(self, message, pretty=None):
Expand Down
5 changes: 3 additions & 2 deletions aider/mdstream.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class MarkdownStream:
min_delay = 1.0 / 20 # Minimum time between updates (20fps)
live_window = 6 # Number of lines to keep visible at bottom during streaming

def __init__(self, mdargs=None):
def __init__(self, mdargs=None, console_theme=None):
"""Initialize the markdown stream.

Args:
Expand All @@ -114,6 +114,7 @@ def __init__(self, mdargs=None):
self.mdargs = mdargs
else:
self.mdargs = dict()
self.console_theme = console_theme

# Defer Live creation until the first update.
self.live = None
Expand All @@ -130,7 +131,7 @@ def _render_markdown_to_lines(self, text):
"""
# Render the markdown to a string buffer
string_io = io.StringIO()
console = Console(file=string_io, force_terminal=True)
console = Console(file=string_io, force_terminal=True, theme=self.console_theme)
markdown = NoInsetMarkdown(text, **self.mdargs)
console.print(markdown)
output = string_io.getvalue()
Expand Down
Loading