AutoHotkey v2: практичные скрипты для разработчика

AutoHotkey — это, пожалуй, самый недооценённый инструмент в арсенале Windows-разработчика. Пара строк кода — и у вас есть текстовые сниппеты, которые разворачиваются на лету, горячие клавиши для управления окнами, шаблоны кода по нажатию двух символов и быстрый запуск любых инструментов. Долгое время скрипты писались на AutoHotkey v1 — языке с причудливым синтаксисом, который копился годами. В декабре 2022 года официальной стала версия v2, и это полноценный редизайн языка. В этой статье разберём, что реально изменилось при переходе с v1 на v2, и соберём 4–5 готовых к работе скриптов, которые можно сразу бросить в свой autostart.ahk.
Что изменилось в v2 относительно v1
AutoHotkey v2 — это не косметика, а переписанный с нуля язык. Старые скрипты v1 в большинстве своём в v2 не работают без правок. Если коротко, разработчики навели порядок в трёх областях: синтаксис команд, выражения и объекты.
Команды стали функциями
В v1 был дуализм: «командный» синтаксис (MsgBox, Привет) и «функциональный». Это путало: запятые, проценты для подстановки переменных, разные правила экранирования. В v2 командного синтаксиса больше нет — всё это обычные вызовы функций со скобками и кавычками для строк.
; v1
MsgBox, Привет, %name%
; v2
MsgBox("Привет, " name)
Выражения и строки
В v2 нет «голых» переменных в подстановке через проценты. Строки всегда в кавычках, переменные — без них, конкатенация — через точку или просто пробел. Сравнение и присваивание чётко разделены: := для присваивания, = и == для сравнения. Появился чистый тернарный оператор, оператор «ленивого» присваивания ??= и слияние через ??. Объявление переменных стало строже: обращение к необъявленной переменной — это ошибка времени выполнения, что ловит опечатки на корню.
Полноценные объекты
Главное достижение v2 — нормальная объектная модель. Появились настоящие классы (class), массивы (Array, индексация с 1) и ассоциативные массивы (Map) как отдельные типы. В v1 «объект» был и массивом, и словарём одновременно, что порождало неоднозначности. Теперь [1, 2, 3] — это Array, а Map("ключ", "значение") — это Map. Циклы по ним делаются через for:
tools := Map(
"code", "C:\Users\me\AppData\Local\Programs\Microsoft VS Code\Code.exe",
"term", "wt.exe"
)
for name, path in tools
MsgBox(name " => " path)
Ещё пара важных мелочей: горячие клавиши и хоткстринги теперь могут иметь тело в фигурных скобках (как функция), а #Requires AutoHotkey v2.0 в начале файла гарантирует, что скрипт не запустится случайно под v1.
Скрипт 1. Текстовые сниппеты (hotstrings)
Hotstrings — это автозамена: вы печатаете короткую аббревиатуру, и AutoHotkey подменяет её на полный текст. Незаменимо для email, шаблонных фраз, текущей даты и часто набираемых конструкций. Синтаксис в v2 тот же, что и в v1: двоеточия, аббревиатура, двоеточие, замена.
#Requires AutoHotkey v2.0
::eml::me@example.com
::adr::ул. Примерная, 12, Киев
; Многострочный сниппет — флаг "c" для разбора и continuation section
::sig::
(
С уважением,
Иван Разработчик
GitHub: github.com/example
)
; Текущая дата в формате ГГГГ-ММ-ДД через выполнение кода (флаг X)
:X:dt::SendText(FormatTime(, "yyyy-MM-dd"))
:X:now::SendText(FormatTime(, "yyyy-MM-dd HH:mm"))
Флаг X означает «execute»: вместо подстановки текста выполняется функция. FormatTime без первого аргумента берёт текущее время. SendText отправляет строку как есть, не интерпретируя спецсимволы вроде { или ! — для вставки готового текста это всегда правильный выбор.
Скрипт 2. Горячие клавиши для управления окнами
Постоянно таскать окна между половинами экрана мышкой — потеря времени. Назначим Win+стрелки на привязку активного окна, а Win+C — на центрирование. Символ # в v2 по-прежнему означает клавишу Win.
#Requires AutoHotkey v2.0
; Левая половина экрана
#Left:: SnapWindow(0)
; Правая половина
#Right:: SnapWindow(1)
SnapWindow(rightHalf) {
if !(hwnd := WinExist("A")) ; "A" — активное окно
return
MonitorGetWorkArea(MonitorGetPrimary(), &l, &t, &r, &b)
w := (r - l) // 2
x := rightHalf ? l + w : l
WinMove(x, t, w, b - t, hwnd)
}
; Win+C — центрировать окно в его текущем размере
#c:: {
if !(hwnd := WinExist("A"))
return
WinGetPos(&x, &y, &w, &h, hwnd)
MonitorGetWorkArea(MonitorGetPrimary(), &l, &t, &r, &b)
WinMove((r - l - w) // 2 + l, (b - t - h) // 2 + t, , , hwnd)
}
Обратите внимание на &l, &t — в v2 это передача по ссылке (ByRef через амперсанд). Функции вроде WinGetPos и MonitorGetWorkArea записывают результат в переданные переменные. Целочисленное деление в v2 — оператор //.
Скрипт 3. Вставка шаблонов кода
Многострочные шаблоны (boilerplate) удобно вешать на хоткстринги с continuation section. Покажем заготовку для HTML-документа и блока try/catch. Поскольку внутри кода есть фигурные скобки и спецсимволы, используем SendText, чтобы AHK ничего не интерпретировал.
#Requires AutoHotkey v2.0
; Печатаем "htm5" -> базовый HTML5-каркас
:*:htm5::
{
tpl := "
(
<!DOCTYPE html>
<html lang=`"ru`">
<head>
<meta charset=`"UTF-8`">
<title></title>
</head>
<body>
</body>
</html>
)"
SendText(tpl)
}
; "tryc" -> блок try/catch
:*:tryc::
{
SendText("try {`n `n} catch Error as e {`n MsgBox(e.Message)`n}")
}
Флаг * (звёздочка) срабатывает без завершающего символа — не нужно жать пробел или Enter после аббревиатуры. Внутри строк v2 кавычку экранируют обратным апострофом `", а `n — это перевод строки. В continuation section (текст между скобок) кавычки внутри можно не экранировать, но переносы строк сохраняются буквально.
Скрипт 4. Авто-переключение раскладки и умный буфер обмена
Две частые боли: набрал фразу не в той раскладке и хочешь её «перебить», и хочешь вставить скопированный текст без форматирования. Решим обе.
#Requires AutoHotkey v2.0
; Ctrl+Shift+V — вставить как простой текст (без форматирования)
^+v:: {
saved := ClipboardAll() ; сохраняем всё содержимое буфера
A_Clipboard := A_Clipboard ; присвоение строки сбрасывает форматирование
Send("^v")
Sleep(80)
A_Clipboard := saved ; возвращаем исходный буфер
}
; Pause — переключить раскладку выделенного текста через эмуляцию Win+Space
; и заодно показать текущий буфер
^!c:: {
prev := A_Clipboard
A_Clipboard := ""
Send("^c")
if ClipWait(1) ; ждём до 1 сек, пока буфер заполнится
ToolTip("В буфере: " SubStr(A_Clipboard, 1, 100))
SetTimer(() => ToolTip(), -2000) ; убрать подсказку через 2 сек
}
Ключевые моменты v2: буфер обмена теперь называется A_Clipboard (а не Clipboard, как в v1), бинарную копию делает функция ClipboardAll(). Приём «присвоить переменную самой себе» (A_Clipboard := A_Clipboard) отбрасывает RTF/HTML-форматирование, оставляя голый текст. ClipWait надёжнее, чем фиксированный Sleep: он ждёт реального появления данных. А () => ToolTip() — это стрелочная функция v2, удобная для одноразовых колбэков в SetTimer.
Скрипт 5. Быстрый запуск инструментов
Соберём «панель запуска» на одной клавише-модификаторе. Назначим CapsLock как префикс (он всё равно почти бесполезен) и повесим на него запуск редактора, терминала и браузера. Если окно уже открыто — активируем его, иначе запускаем.
#Requires AutoHotkey v2.0
; CapsLock сам по себе ничего не печатает, но работает как модификатор
SetCapsLockState("AlwaysOff")
; CapsLock + E -> VS Code
CapsLock & e:: Run("code")
; CapsLock + T -> Windows Terminal (или активировать, если открыт)
CapsLock & t:: ActivateOrRun("ahk_exe WindowsTerminal.exe", "wt.exe")
; CapsLock + G -> открыть GitHub в браузере по умолчанию
CapsLock & g:: Run("https://github.com")
ActivateOrRun(winCriteria, target) {
if WinExist(winCriteria)
WinActivate(winCriteria)
else
Run(target)
}
Синтаксис CapsLock & e — это «составная горячая клавиша»: первая клавиша становится модификатором для второй. Run в v2 умеет запускать как исполняемые файлы, так и URL и документы — система сама подберёт обработчик. WinExist с критерием ahk_exe ... проверяет, запущен ли процесс по имени exe, а WinActivate выводит его окно на передний план.
Итого
AutoHotkey v2 — это зрелый, последовательный язык, на котором приятно писать утилиты для собственного рабочего процесса. Если вы только начинаете, нет смысла учить v1: ставьте сразу v2.
- Синтаксис v1→v2: команды стали функциями со скобками, строки всегда в кавычках, переменные без процентов, обращение к необъявленным переменным теперь ошибка.
- Объекты: появились раздельные типы
ArrayиMap, настоящие классы и стрелочные функции. - Hotstrings разворачивают аббревиатуры в текст, даты и подписи — флаг
Xдля выполнения кода,*для срабатывания без завершающего символа. - Управление окнами через
WinMoveиMonitorGetWorkAreaс передачей по ссылке (&var). - Шаблоны кода удобно хранить в continuation section и вставлять через
SendText, чтобы не интерпретировались спецсимволы. - Буфер обмена:
A_ClipboardиClipboardAll(), приём со сбросом форматирования, надёжное ожидание черезClipWait. - Запуск инструментов одной клавишей-префиксом (
CapsLock & key) с логикой «активировать или запустить».
Начните с небольшого файла autostart.ahk, добавьте в него пару сниппетов из статьи и положите ярлык в папку автозагрузки. Дальше скрипт будет расти вместе с вашими привычками — это и есть главная ценность AutoHotkey.