#NoEnv SetWorkingDir %A_ScriptDir% #SingleInstance, force Menu Tray, Icon, shell32.dll, 20 /* 1. Скрипт использует вставку текста средствами Autohotkey, а не самой CLCL. Это позволяет работать с окнами программ, не поддерживающих простую вставку, а так же с некоторыми (необязательно старыми) программами, использование CLCL c которыми вызывает их падение (Ctrl+V Autohotkey отрабатывает гораздо нежнее, чем это делает CLCL). Можно прописать исполняемые файлы программ, в окна которых посылается "медленное, но верное" Send или SendInput (вставка растров и файлов всегда осуществляется обычным путем). Для настройки необходимо зайти в Options - Keys и назначить на вставку сочетание Ctrl+Alt+0 вместо стандартного Ctrl+V (задержку можно за ненадобностью обнулить). Делать это следует до запуска скрипта! 2. Эта подмена резко расширяет возможности программы: вместо неизменяемых фрагментов в шаблоны программы становится возможным вписать сложные "думающие" заготовки и навороченную обработку выделенного текста (горячие клавиши шаблонам назначаются из контекстного меню вьювера). Так %clipboard% будет заменено текущим текстовым буфером обмена, %sel_text% - выделенным текстом (возможно использование только одной из этих переменных), %date% и %time% - настраиваемыми значениями текущих даты и времени. 3. Помимо этого, любой (в том числе и многострочный) фрагмент шаблона, заключенный в скобки вида вида "<@ ... @>" будет рассматриваться как скрипт Autohotkey, и будет заменен значением переменной out, в нем явно определяемой (например, <@ StringUpper, out, sel_text @> будет преобразовывать выделенный текст в верхний регистр и т.д.). Возможно использование вышеперечисленных переменных и любых функций, находящихся в локальной, пользовательской или стандартной библиотеках. Работает это через генерацию "виртуальных" скриптов вида temp_n.ahk (где n - номер вычисляемого фрагмента) в каталоге основного скрипта, и возникающие ошибки будут относиться к ним же. Можно отключить их автоматическое удаление в настройках и посмотреть что к чему. 4. Нажатие средней кнопки мыши, Ctrl или Alt в открытом меню программы изменяет текущий буфер обмена без его вставки. Это позволяет применять шаблоны к скопированному ранее тексту. Ниже в скрипте описано как настроить автоматический вызов меню шаблонов после этого. 5. Если после такого копирования текста в течении 10 секунд, до изменения буфера или вставки, будет использован шаблон, переменные sel_text в нем будут заменены на clipboard, так что писать отдельные шаблоны для обработки выделенного текста и старых значений буфера нет необходимости. В течении этого времени индикация буфера обмена (смотри ниже) не будет убираться автоматически. 6. Скрипт отображает первые непустые строки изменившегося текстового буфера обмена во всплывающем окне над панелью задач (как в CopyQ). Вид и время показа настраиваются, в полноэкранном режиме и настраиваемых приложениях показ выключается автоматически. 7. Имеет смысл отметить в настройках программы (Options - History) пункт Except from Template - это уменьшит появление лишних пунктов в истории. */ del:=1 ; удалять "виртуальные" скрипты после вставки send:="XBMC.exe,Kodi.exe" ; исполняемые файлы приложений, в окна которых посылается Send, через запятую sendinput:="" ; то же для SendInput date_format:="dd.MM.yyyy" ; формат даты, используемый в переменной date time_format:="HH:mm" ; формат времени, используемый в переменной time win:=1 ; отображать изменившийся буфер в виде всплывющего окна bitmap:=1 ; отображать и изменения нетекстового буфера empty:=0 ; отображать очистку буфера exclude:="JPEGView.exe,AutoHotkey.exe" ; исполняемые файлы приложений, в которых не показывается текстовый буфер, через запятую font:=12 ; размер шрифта color:="DCDCDC" ; цвет фона lines:=2 ; число показываемых первых непустых строк shift:=0 ; вертикальное смещение show:=1500 ; время показа, мс ^!0:: Sleep 100 If A_PriorHotkey~="^(MButton|Ctrl|LAlt|RAlt)$" { ;~ SendInput !{vk57} ; если вписать сюда горячую клавишу папки шаблонов, назначенную в программе (Option - Action), ее меню будет автоматически открываться после копирования буфера по нажатию Ctrl, Alt или средней кнопке мыши m:=1 return } If (!Clipboard || Clipboard~="^([a-zA-Z]:\\.+\R?){1,}") { Send ^{vk56} return } clip:=RegExReplace(Clipboard,"\s+$"), clip_old:=old If m clip:=StrReplace(clip,"sel_text","clipboard"), m:=0 WinGet exe, ProcessName, A FormatTime date, , % date_format FormatTime time, , % time_format If clip~="s)(%clipboard%|<@.*clipboard.*@>)" { If (clip_old="") { MsgBox, 262160, , Буфер обмена пуст или в буфере не текст!, 1.5 return } Clipboard:=clip_old } else If clip~="s)(%sel_text%|<@.*sel_text.*@>)" { Clipboard:="" Send ^{Ins} ClipWait 1 If ErrorLevel { MsgBox, 262160, , Ничего не выделено!, 1.5 return } sel_text:=Clipboard Send {Del} } start:=Clipboard If clip~="s)<@.+@>" { FileDelete temp_*.ahk n:=1 Loop { Clipboard:=start p:=RegExMatch(clip,"s)<@.+?@>",a,n) If (!a || A_Index>10) break RegExMatch(a,"s)<@\K.+(?=@>)",f) FileAppend % "sel_text:=Clipboard`r`ndate=" date "`r`ntime=" time "`r`n" Trim(f) "`r`nClipboard:=out`r`nExitApp", % "temp_" A_Index ".ahk", utf-8 RunWait % "temp_" A_Index ".ahk" ClipWait 2 clip:=StrReplace(clip,a,Clipboard) n:=p+1 } } clip:=StrReplace(clip,"%date%",date) clip:=StrReplace(clip,"%time%",time) clip:=StrReplace(clip,"%clipboard%",clip_old) clip:=StrReplace(clip,"%sel_text%",sel_text) If exe in % send { Send % clip return } If exe in % sendinput { SendInput % clip return } Clipboard:=clip Sleep 100 Send ^{vk56} If del FileDelete temp_*.ahk return #IfWinExist ahk_class #32768 ahk_exe CLCL.exe MButton:: KeyWait MButton, T1 Ctrl:: LAlt:: RAlt:: SendInput {Enter} return #IfWinActive OnClipboardChange: e:=A_EventInfo, old:=new, new:=Clipboard, text:="" Gui Destroy WinGet exe2, ProcessName, A If exe2 in % exclude return SysGet, D, Monitor WinGetPos, , , w, h, A If new~="s)<@.+@>" || (w>=DRight && h>=DBottom) return If (e=0 && empty) text:="### Empty! ###" If (e=2 && bitmap) text:="### Bitmap? ###" If (e=1) { n:=0, text:="" Loop Parse, new, `r`n { If A_LoopField~="^\s*$" continue n+=1, string:=Trim(A_LoopField) If (StrLen(string)>80) string:=SubStr(string,1,80) " (...)" text.=string "`r`n" If (n=lines) break } } If (win && text) { Sleep 100 SysGet, M, MonitorWorkArea Gui Destroy Gui font, s%font% Arial Gui Margin , 6, 2 Gui Color, % color Gui, -Caption +AlwaysOnTop +ToolWindow -DPIScale +LastFound Gui, Add, Text, ,% RegExReplace(text,"`r`n$") Gui Show, NA y%MBottom% xCenter WinGetPos , , , , height WinMove , , , , % MBottom-height-shift SetTimer ClipbShow, Off t:=show If A_PriorHotkey~="^(MButton|Ctrl|LAlt|RAlt)$" t:=10000 SetTimer ClipbShow, % t } return ~^vk56:: ClipbShow: SetTimer ClipbShow, Off Gui Destroy m:=0 return |