Macro {
area="Common"; key="Shift";
condition=function()
local key = mf.waitkey(1)
if key~="" then
mf.postmacro(far.Show("Shift+"..key))
return 100
end
end;
action=function() end;
}
local NumLock,get = 0,-1
local busy
Macro { description="Shift-<NumPad> heuristics";
area="Common"; key="/Num[\\dD].*/";
id="2EB425EA-751B-431F-8DD8-25E82F3F2C28";
condition=function()
return not busy and 0~=band(1,mf.flock(NumLock,get)) and 100
end;
action=function()
local key = mf.akey(1,1)
if -2==mf.eval("Shift"..key,2) then
busy = true
if -2==mf.eval(key,2) then
Keys(key)
end
busy = false
end
end;
}
John Doe wrote: ↑Tue 26 Sep, 2017 13:11Но можно применить эвристику из Far 1.75:
Macro {
area="Shell"; key="/(Shift)|(ShiftNum[0-9])|(ShiftClear)/";
action=function()
local key2 = mf.waitkey(1)
local key = a=="" and akey(1,0) or "Shift"..key2.." (NumLock)"
far.Show(key)
end;
}
. И поэтому осваивал я их по большей части тем способом, что перенимал из них отдельные блоки и пробовал применять эти блоки в своих экспериментах. А о тех результатах данных опытов, которые представляются мне достоверными, изложу здесь далее. Предположительно, тремя частями.
1) Когда, при включённом NumLock, команда lua: far.Show(mf.waitkey(),mf.waitkey(1)) запускается из комстроки, то на выходе мы получаем нажатый шорткат, разделённый на два аргумента. Например:
Macro { area="Shell";
key="Shift ShiftNum7"; -- если первый Shift из поля убрать, то макрос не запустится
action=function()
far.Show(mf.waitkey(),mf.waitkey(1))
end;}
sToLp wrote: ↑Sat 30 Sep, 2017 21:37Но, будучи, при том же условии, запущенной из макроса, far.Show(mf.waitkey(),mf.waitkey(1)) выдаёт нам только вторую часть нажатого шорката:
Естественно, ведь первую часть "съедает" вызов макроса, он же у вас на Shift.
sToLp wrote: ↑Sat 30 Sep, 2017 21:37Но, будучи, при том же условии, запущенной из макроса, far.Show(mf.waitkey(),mf.waitkey(1)) выдаёт нам только вторую часть нажатого шорката:
Естественно, ведь первую часть "съедает" вызов макроса, он же у вас на Shift.
Однако, если Shift из перечня ключей запуска макроса (поля key) убрать, то макрос совсем не отвечает.
Как же тогда правильно сделать?
Macro {
area="Shell"; key="/(Shift)|(ShiftNum[0-9])|(ShiftClear)/";
action=function()
local key2 = mf.waitkey(1)
local key = a=="" and akey(1,0) or "Shift"..key2.." (NumLock)"
far.Show(key)
end;
}
Об этом макросе я прекрасно помню, поскольку изучал его с большим интересом. Так как он является очень полезным примером того, как макросом показать фактически инициировавший его шорткат. И, вместе с тем, примером впечатляющей лаконичности.
Однако на данный момент теперь уже я акцентирую Ваше внимание не на фактически решённой задаче "как макросом показать шорткат, который нажали". Речь идёт о другой проблеме. А именно о том, как макросом показать то, что "первым приходит отдельно модификатор, а потом уже нажатая клавиша".
Выше я воспроизвёл Ваш пример того, что из комстроки это сделать вполне можно. И далее показал, что из макроса та же самая функция даёт не полный результат. И поставил вопрос как сделать его полным? Извините, что свой новый вопрос я изложил недостаточно понятно. Теперь вот пытаюсь исправить эту свою оплошность.
Macro { area="Shell"; key="CtrlAltN"; id="F1100E7A-C473-45CD-A88B-CCCDF8031CBA";
description="tes&t демонстрация того, что при включенном NumLock первыми приходят отдельно модификаторы Shift[Ctrl][Alt], а потом уже нажатая клавиша NumPad`а (sToLp) CtrlAltN";
action=function() mf.flock(NumLock,1) -- подстрахуем включённость NumLock`а
far.Message("\nЧтобы убедиться в том,\nчто при включенном NumLock\nпервыми приходят отдельно модификаторы Shift[Ctrl][Alt],\nа потом уже нажатая клавиша NumPad`а,\nпрямо сейчас сначала нажмите Enter,\nа затем тестируемое клавишесочетание.\n\n... ","Тест ключей Shift[Ctrl][Alt]-<NumPad>:","")
Keys("l u a : f a r . S h o w ( m f . w a i t k e y ( ) , m f . w a i t k e y ( 1 ) )") exit() end; }
Несколько экзотично, но это, по крайней мере, работает.
И здесь ещё нужно уточнить, что отдельно приходят не "модификаторы и клавиша", а "модификаторы и клавиша с модификаторами без Shift`а".
local F = far.Flags
Macro {
area="Common"; key="Num7 ShiftNum7";
action=function()
far.Message("Press key","","")
local key0 = mf.waitkey()
if band(1,mf.flock(0,-1))~=0 then
local key,key2 = mf.waitkey(),mf.waitkey(1)
if key2=="" then
key,key2 = key0,key
end
far.Show(key,key2)
else
far.Show(key0)
end
end;
}
P.S.
Напоминаю, что эта эвристика основана на недокументированных особенностях, зависящих от версии Windows.
Нет гарантии, что с очередным обновлением Windows ничего не поломается (в частности в Windows XP всё иначе).
А единственный надёжный способ это не назначать этот диагностический макрос на Shift<NumPad>, и перед запросом клавиши погасить NumLock (ваша собственная идея).
Текст макроса уже приведён в соответствующей теме http://forum.farmanager.com/viewtopic.p ... 75#p145975.
sToLp wrote: ↑Sun 01 Oct, 2017 09:40Увы, нет. Тогда тот макрос не будет работать.
Чтобы надёжно работало надо исключить или Shift (например Num7) или NumPad (например ShiftSpace).
В таких то случаях, разумеется, что будет работать.
Но в этой теме рассматривается не привычный, а особый случай с NumPad`овскими клавишами-цифрами в сочетаниях с модификаторами экстравагантного поведения. Один из которых — Alt и сам по себе (независимо от состояния NumLock), и совместно с Shift`ом (при горящем NumLock) работает абсолютно особым образом. А другой — Shift, и того похлеще, при взаимодействии с NumPad`овскими цифрами при горящем NumLock от системы как бы и вовсе прячется.
И мне бы желательно не просто знать о том, как взаимодействуют эти клавиши-фокусники, а и уметь это знание правильно излагать. Так, чтобы и другому человеку было понятно о чём идёт речь и почему это именно так. И поэтому для полноты картины ещё очень желательно иметь навык правильно производить манипуляции с NumPad`овскими клавишами-цифрами и быть в состоянии эти действия более-менее грамотно воспроизводить макросами. И я Вам очень благодарен за то, что Вы мне во всём этом эффективно содействуете.
John Doe wrote: ↑Sun 01 Oct, 2017 11:03Нет, можно конечно сделать, чтобы работало и с Shift<NumPad>
local F = far.Flags
Macro {
area="Common"; key="Num7 ShiftNum7";
action=function()
far.Message("Press key","","")
local key0 = mf.waitkey()
if band(1,mf.flock(0,-1))~=0 then
local key,key2 = mf.waitkey(),mf.waitkey(1)
if key2=="" then
key,key2 = key0,key
end
far.Show(key,key2)
else
far.Show(key0)
end
end;
}
, но не стоит всё усложнять.
Просто превосходно!
Что же касается некоторого усложнения макроса, то, на мой взгляд, оно в данном случае вовсе не искусственное, а вполне соответствующее случаю. И как раз облегчающее иллюстрирование сложного и даже можно сказать запутанного случая. При том, что код этого макроса получился у Вас, по-моему, как раз весьма лаконичным.
John Doe wrote: ↑Sun 01 Oct, 2017 12:29P.S.
Напоминаю, что эта эвристика основана на недокументированных особенностях, зависящих от версии Windows.
Нет гарантии, что с очередным обновлением Windows ничего не поломается (в частности в Windows XP всё иначе).
Благодарю Вас за предупреждение! Но что будет с новыми версиями Windows одному Microsoft`у известно. А XP в нашей, например, "фирме" уже нет ни одной.
John Doe wrote: ↑Sun 01 Oct, 2017 12:29А единственный надёжный способ это не назначать этот диагностический макрос на Shift<NumPad>, и перед запросом клавиши погасить NumLock (ваша собственная идея).
Текст макроса уже приведён в соответствующей теме http://forum.farmanager.com/viewtopic.p ... 75#p145975.
Большое спасибо! Как только вполне завершу с этой темой (по ней у меня остались ещё два не до конца исследованных момента) и выпадет относительно свободное время, продолжу и с той темой.
sToLp wrote: ↑Sat 30 Sep, 2017 21:37А о тех результатах данных опытов, которые представляются мне достоверными, изложу здесь далее. Предположительно, тремя частями.
Однако оба неясных для меня до сегодняшнего дня момента благополучно прояснились. Один — как правильно инициировать макросы с Shift-<NumPad>-ключами и другой — о перспективах применения в этих макросах функции akey(). Причём оба эти вопроса сошлись в одном примере. Поэтому завершающей будет вторая часть изложения результатов опытов с этими ключами. Как я их на текущий момент понимаю.
2) "Макросы Shift-<NumPad>" — так для удобства далее здесь буду обозначать макросы, назначаемые на шорткаты, состоящие из клавиш-цифр NumPad`а и модификаторов, в составе которых модификатор Shift.
Опыты показали, что в поле key (т.е. в перечень ключей, запускающих макрос) данных макросов можно дополнительно включать соответствующие "голые" модификаторы (Shift, CtrlShift, AltShift, CtrlAltShift). И тогда данные Shift-<NumPad>-макросы активируются ключами [Ctrl][Alt]ShiftNum#, которыми, казалось бы, они и без дополнений должны были бы активироваться. Но если в поле key оставить только [Ctrl][Alt]ShiftNum#, то эти макросы не запускаются.
Но это дополнительное включение Shift`а приводит к тому большому неудобству, что при наличии других макросов, назначенных на данные "голые" модификаторы, нажатие на них вызывает вывод меню выбора макросов, которые в данном случае фактически-то не имеют отношения к макросам Shift-<NumPad>. Поэтому в таком случае желательно этот дополнительный Shift как ни будь нейтрализовать.
И экспериментально выяснено, что нейтрализовать дополнительные включения Shift, CtrlShift, AltShift и CtrlAltShift в поле key макросов Shift-<NumPad> вроде бы можно с помощью condition подобного следующему.
condition=function()
local key1=mf.waitkey()
return key1~="Shift" -- исключить голый Shift из ключей, вызывающих данный макрос
end;
При этом данный способ совсем не подходит для ранее приведённых четырёх тестовых макросов. Поскольку при включении в них подобного condition результат "первичного" mf.waitkey() далее в тестах проявляться перестаёт. Но в других случаях в макросах Shift-<NumPad> с дублирующим ключом-пустышкой этот condition, по-видимому, применять возможно. Но, вероятно, от таких макросов можно ожидать и разных других сюрпризов.
И поэтому будет гораздо лучше применять предложенный Вами образец составления Shift-<NumPad>-макроса, в котором поле key дополняется не чистым(и) модификатор(ом/ами), а, наоборот, <NumPad>-клавишей (одиночной или с модификаторами Ctrl, Alt или CtrlAlt) без модификатора Shift. И вот опробованный рабочий вариант такого макроса:
Macro { area="Shell"; key="Num7 ShiftNum7";
-- если Num7 из key убрать, то при горящем NumLock макрос не запускается
action=function()
if band(1,mf.flock(0,-1))~=0 then
mf.msgbox("Если NumLock горит:","\nДелаем какое-то действие.",0x00010000)
else
-- при выключенном NumLock при нажатии Num7 эмулируем Home и завершаем макрос:
if mf.akey(1,0)=="Num7" then Keys("Home") exit() end
mf.msgbox("Если NumLock погашен:","Делаем какое-то другое действие.",0x00010000)
end end; }
sToLp wrote: ↑Sun 01 Oct, 2017 16:59Но это дополнительное включение Shift`а приводит к тому большому неудобству, что при наличии других макросов, назначенных на данные "голые" модификаторы, нажатие на них вызывает вывод меню выбора макросов, которые в данном случае фактически-то не имеют отношения к макросам Shift-<NumPad>. Поэтому в таком случае желательно этот дополнительный Shift как ни будь нейтрализовать.
sToLp wrote: ↑Sun 01 Oct, 2017 16:59И поэтому будет гораздо лучше применять предложенный Вами образец составления Shift-<NumPad>-макроса, в котором поле key дополняется не чистым(и) модификатор(ом/ами), а, наоборот, <NumPad>-клавишей (одиночной или с модификаторами Ctrl, Alt или CtrlAlt) без модификатора Shift.
, целенаправленно вызывающем меню выбора макросов.
Результаты нажатий хоткеев фиксировались визуально по обозначению нажимаемой клавиши в заголовке меню выбора макросов и по действию макроса, данным хоткеем инициировавшегося.
Каждая из клавиш NumPad`а вызывает меню выбора макросов, в заголовке которого она обозначена соответствующим образом (совпадающим с результатами выполнения команды lua:far.Show(mf.waitkey()) из комстроки), а исполнение назначенного на клавишу макроса вызывает соответствующую ей штатную команду. Результаты существенно различаются в зависимости от состояния NumLock.
При погашенном NumLock:
Клавиша: Обозначена: Действие:
Num1 Num1 End
Num2 Num2 Down
Num3 Num3 PgDn
Num4 Num4 Left
Num5 Clear "Просмотр файла", на папке – "Вычислить и показать размеры выбранных папок"
Num6 Num6 Right
Num7 Num7 Home
Num8 Num8 Up
Num9 Num9 PgUp
Num0 Num0 Ins / Divide Divide выводит в комстроку прямой слеш "/" * Multiply Multiply исполняет команду "Инвертировать пометку" - Subtract Subtract вызывает меню "Снять" штатной команды "Снять пометку с группы" + Add Add вызывает меню "Пометить" штатной команды "Пометить группу" . (точка) NumDel NumDelключ не задействован внутренней командой Far`а
NumEnter NumEnter исполняет ассоциацию, назначенную на Enter для объекта под курсором
При горящем NumLock:
Клавиша Обозначена Действие
Num1 1 выводит в комстроку цифру 1
Num2 2 выводит в комстроку цифру 2
Num3 3 выводит в комстроку цифру 3
Num4 4 выводит в комстроку цифру 4
Num5 5 выводит в комстроку цифру 5
Num6 6 выводит в комстроку цифру 6
Num7 7 выводит в комстроку цифру 7
Num8 8 выводит в комстроку цифру 8
Num9 9 выводит в комстроку цифру 9
Num0 0 выводит в комстроку цифру 0 / Divide Divide выводит в комстроку прямой слеш "/"; * Multiply Multiply исполняет команду "Инвертировать пометку"; - Subtract Subtract меню "Снять" штатной команды "Снять пометку с группы"; + Add Add меню "Пометить" штатной команды "Пометить группу"; . (точка) NumDel Decimal выводит в комстроку . (точку)
NumEnter NumEnter исполняет ассоциацию, назначенную на Enter для объекта под курсором
Last edited by sToLp on Mon 02 Oct, 2017 22:15, edited 1 time in total.
local key
Macro { description="Shift-<NumPad> heuristics";
area="Common"; key="Shift CtrlShift CtrlAltShift";
id="2520EA89-3211-4D00-B552-AB0D000442DB";
condition=function()
key = mf.waitkey(1)
return key~=""
end;
action=function()
local akey = mf.akey(1,1)
local numkey = key:sub(akey:len()-4,-1)
if -2==mf.eval(akey..numkey,2) then
if -2==mf.eval(key,2) then
Keys(key)
end
end
end;
}
, который обеспечивает одинаковую работу модификаторов Shift CtrlShift CtrlAltShift с клавишами NumPad`а независимо от того включен ли NumLock. И теперь данный макрос нахожу необходимым.
Сначала я круто затормозил с этим макросом, поскольку воспринимал его как сугубо самостного, самого по себе, без связи с другими. Но теперь начинаю осознавать его значимость и с пользой осваивать его.
Как это было ранее выяснено, при включенном NumLock`е комбинации Shift+NumX, в т.ч. с Ctrl и с CtrlAlt, продуцируют сначала Shift, а потом уже основную клавишу. Именно этот случай и призван отлавливать данный макрос, после чего перевызывать макрос, нужный пользователю. Таким образом нампадовские макросы с Shift`ом, с CtrlShift`ом и с CtrlAltShift`ом при его наличии будут работать независимо от состояния NumLock`а. А это существенно удобнее.
Last edited by sToLp on Sun 08 Oct, 2017 21:49, edited 1 time in total.
* При нажатии CtrlNum5 выполняется нативная команда Far "Восстановить ширину панелей по умолчанию".
Остальные шортакаты типа CtrlNum# внутренними командами не заняты.
Нажатия типа AltNum# командой waitkey() не распознаются — при любом состоянии NumLock клавиши AltNum[1-9] выводят соответствующие знаки (☺☻♥♦♣♠•◘○) по их кодам.
Показ командой lua:far.Show(mf.waitkey(),mf.waitkey(1)) нажатий клавиш-цифр нампада с модификатором Shift и их нативные действия (примечание: waitkey для модификаторов ловит отпускания):
=========================================================================
NumLock горит: NumLock погашен:
Клавиши:
Распознаются Действие: Распознаются: Действие:
раздельно:
ShiftNum1 Shift
Num1 End ShiftNum1 ShiftEnd
ShiftNum2 Shift
Num2 Down ShiftNum2 ShiftDown
ShiftNum3 Shift
Num3 PgDn ShiftNum3 ShiftPgDn
ShiftNum4 Shift
Num5 Left ShiftNum4 ShiftLeft
ShiftNum5 Shift
Clear F3 ShiftClear ShiftF3
ShiftNum6 Shift
Num6 Right ShiftNum6 ShiftRight
ShiftNum7 Shift
Num7 Home ShiftNum7 ShiftHome
ShiftNum8 Shift
Num8 Up ShiftNum8 ShiftUp
ShiftNum9 Shift
Num9 PgUp ShiftNum9 ShiftPgUp
S
hiftNum0 Shift
Num0 Ins ShiftNum0 ShiftIns
=========================================================================
Примечание: Фича Windows: https://blogs.msdn.microsoft.com/oldnew ... /?p=37953/ — "Если NumLock включен (как обычно), то нажатие клавиши на цифровой клавиатуре при удерживании клавиши сдвига отменяет NumLock и вместо этого генерирует клавишу со стрелкой (или другую навигационную клавишу), напечатанную мелким шрифтом под большими цифрами".
Т.е. при горящем NumLock нажатие цифровых клавиш нампада с модификатором Shift производит те же действия, что и нажатие этих клавиш самих по себе без модификатора Shift при погашенном NumLock.
Показ командой lua:far.Show(mf.waitkey()) нажатий клавиш-цифр нампада с модификаторами CtrlAlt:
* При нажатии CtrlAltNum5 выполняется нативная (внутренняя) команда Far "Восстановить высоту панелей по умолчанию".
Остальные шортакаты типа CtrAltlNum# внутренними командами не заняты.
Показ командой lua:far.Show(mf.waitkey(),mf.waitkey(1)) нажатий клавиш-цифр нампада с модификаторами Ctrl и Shift (примечание: waitkey для модификаторов ловит отпускания):
Шортакаты типа CtrlShiftNum# внутренними командами не заняты.
Примечание: Фича Windows: https://blogs.msdn.microsoft.com/oldnew ... /?p=37953/ — "Если NumLock включен (как обычно), то нажатие клавиши на цифровой клавиатуре при удерживании клавиши сдвига отменяет NumLock и вместо этого генерирует клавишу со стрелкой (или другую навигационную клавишу), напечатанную мелким шрифтом под большими цифрами".
Т.е. при горящем NumLock нажатие цифровых клавиш нампада с модификаторами CtrlShift фактически производит те же действия, что и нажатие этих клавиш с модификатором Ctrl (без модификатора Shift) при погашенном NumLock.
Показ командой lua:far.Show(mf.waitkey()) нажатий клавиш-цифр нампада с модификаторами AltShift и их нативные действия:
Шортакаты типа AltShiftNum# при погашенном NumLock внутренними командами не заняты.
При горящем же NumLock нажатие цифровых клавиш нампада с модификаторами AltShift фактически производит те же действия, что и нажатие этих клавиш с модификатором Alt (без модификатора Shift) при погашенном NumLock. И таким образом при горящем NumLock нажатия типа AltShiftNum[1-9] командой waitkey() не распознаются, поскольку они подобно нажатиям AltNum[1-9] выводят соответствующие знаки (☺☻♥♦♣♠•◘○) по их кодам.
А объясняется это последнее фичей Windows: https://blogs.msdn.microsoft.com/oldnew ... /?p=37953/ — "Если NumLock включен (как обычно), то нажатие клавиши на цифровой клавиатуре при удерживании клавиши сдвига отменяет NumLock и вместо этого генерирует клавишу со стрелкой (или другую навигационную клавишу), напечатанную мелким шрифтом под большими цифрами".
Показ командой lua:far.Show(mf.waitkey(),mf.waitkey(1)) нажатий клавиш-цифр нампада с модификаторами CtrlAltShift (примечание: waitkey для модификаторов ловит отпускания):
Шортакаты типа CtrlAltShiftNum# нативными командами не заняты.
Примечание: Фича Windows: https://blogs.msdn.microsoft.com/oldnew ... /?p=37953/ — "Если NumLock включен (как обычно), то нажатие клавиши на цифровой клавиатуре при удерживании клавиши сдвига отменяет NumLock и вместо этого генерирует клавишу со стрелкой (или другую навигационную клавишу), напечатанную мелким шрифтом под большими цифрами".
Т.е. при горящем NumLock нажатие цифровых клавиш нампада с модификаторами CtrlAltShift фактически производит те же действия, что и нажатие этих клавиш с модификаторами CtrlAlt (без модификатора Shift) при погашенном NumLock.
В качестве бонусов в теме можно почерпнуть несколько полезных макросов, в т.ч. следующие:
Макрос (под спойлером), показывающий, что при включённом NumLock первым(и) приход(ит/ят) отдельно модификатор(ы), а потом уже нажатая клавиша (автор John Doe).
Макрос, обеспечивающий одинаковую работу клавиш Shift+[Ctrl[Alt]]<NumPad> независимо от того включён ли NumLock (автор John Doe). При включенном NumLock комбинации Shift+NumX, в т.ч. с Ctrl и с CtrlAlt, продуцируют сначала Shift, а потом уже основную клавишу, и данный макрос отлавливает это, и перевызывает макрос, нужный пользователю. Таким образом нампадовские макросы с Shift`ом, с CtrlShift`ом и с CtrlAltShift`ом при его наличии будут работать независимо от состояния NumLock`а.
Last edited by sToLp on Sat 21 Oct, 2017 07:37, edited 1 time in total.