Choreo is an AVR Studio extension that lets you write and execute macros within the IDE. You can download it from https://github.com/saaadhu/choreo/downloads. The source code is available from https://github.com/saaadhu/choreo/.
If you've used macros in Visual Studio or in any other tool, you probably need no further explanation, but for the others, here's what MSDN says a macro is:
"A macro is a series of commands and instructions that you group together
as a single command to accomplish a task automatically. Macros allow
you to automate repetitive actions."
Choreo macros are just IronPython functions that have access to DTE, the top level automation object exposed by Visual Studio. Choreo discovers the macro functions at start up and creates commands for them inside AVR Studio, and these commands can then be executed through the Command Window, or through shortcut keys (after binding them to keystrokes, of course).
Here's a macro that writes the current date/time at the current cursor position.
from System import DateTime
dte.ActiveDocument.Selection.Text = DateTime.Now.ToString()
To make this macro discoverable by Choreo, save the above code in a .py file (say editor.py), and drop the file inside %localappdata%\Atmel\AvrStudio\5.0\Extensions\Senthil Kumar Selvaraj\Choreo\0.1\Macros. If you're running AVR Studio, you can do Tools -> Refresh Choreo to make Choreo pick up new macros. Choreo creates commands in the format Choreo.<python_file_name>.<python_function_name> for whatever functions it discovers.
You can then bind your macro to a keystroke using the Tools -> Options dialog.
Type the keystroke, say Ctrl followed by ., in the Press shortcut keys box, click Assign and then OK. You should now be able to execute your macro with the configured keystroke when typing in the editor.
Choreo automatically picks up code changes in existing commands, so you don't have to explicitly issue a refresh (Tools -> Refresh Choreo). However, new functions in existing files, as well as new files won't be picked up automatically, so an explicit refresh is needed there.
Record and Replay support is still missing, and commands can't take parameters at the moment, but otherwise, it works pretty well.