Переключение дисков по Ctrl/Alt/Shift+←/→

Здесь выкладываются готовые к использованию макросы и скрипты.
IgorZ
Posts: 790
Joined: Wed 13 Jul, 2011 03:32
Has thanked: 15 times
Been thanked: 93 times

Переключение дисков по Ctrl/Alt/Shift+←/→

Post by IgorZ »

Макрос написан по мотивам анси-плагина Change Active Drive by Ilya V. Gershman
Стрелки (или другие назначенные клавиши) в сочетании с LeftCtrl/LeftAlt/RightCtrl/RightAlt/Shift в указанных комбинациях меняют диск для левой/правой/активной/пассивной (в зависимости от настроек) панели. Замечания и предложения принимаются с благодарностью.

Attachments
CtrlAltMenuDisk.4.1.4.7z
(18.93 KiB) Downloaded 260 times
Last edited by IgorZ on Wed 30 Dec, 2020 09:09, edited 10 times in total.
IgorZ
Posts: 790
Joined: Wed 13 Jul, 2011 03:32
Has thanked: 15 times
Been thanked: 93 times

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by IgorZ »

Latest post of the previous page:

John Doe wrote:Баг1.
Если смены диска не произошло, то панели не перерисовываются.
panel.RedrawPanel(nil,WPanel==APanel and 1 or 0) -- обновим содержимое

Баг2.
Если SwitchPanelsOn = 0, то даже если смена диска произошла, список дисков остаётся на экране.
Ожидаемо, т.к. RedrawPanel не работает при погашенной панели.
Баг2 поправил. Оказывается, таки есть в luafar нужные методы против Кости Сапрыкина работы с экраном. Просто я их не в том разделе раньше искал. Заодно исправился баг1.
IgorZ
Posts: 790
Joined: Wed 13 Jul, 2011 03:32
Has thanked: 15 times
Been thanked: 93 times

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by IgorZ »

В связи с переносом тем посмотрел и обнаружил, что не выкладывал версию с правкой после смены DisableOutput на EnableOutput. Выложена.
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by John Doe »

Code: Select all

local DrvList = "" -- заготовка под список дисков в системе
local drvs = win.GetLogicalDriveStrings()
for i = 1,#drvs do
  local d = drvs[i]:sub(1,1)
  if not ExcludeDrives:find(d) then  DrvList = DrvList..d end -- если не исключён - добавим
end
IgorZ
Posts: 790
Joined: Wed 13 Jul, 2011 03:32
Has thanked: 15 times
Been thanked: 93 times

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by IgorZ »

Версия 2.2.4: Исправлена мелкая, но досадная ошибка с mmode. Вылезла после какого-то из последних рефакторингов. Выложена.

Заодно отвечу (лучше поздно, чем никогда).
John Doe wrote:

Code: Select all

local DrvList = "" -- заготовка под список дисков в системе
local drvs = win.GetLogicalDriveStrings()
for i = 1,#drvs do
  local d = drvs[i]:sub(1,1)
  if not ExcludeDrives:find(d) then  DrvList = DrvList..d end -- если не исключён - добавим
end
1. Проверка дисков на тип ("no root directory") необходима в linux под wine (без неё там вылазит порой куча мусора, что, в частности, мешает переключать вслепую).
2. С вышеуказанной проверкой на быстрых машинах предложенный вариант практически не даёт выигрыша, а на сильно медленных отрабатывает даже медленнее (25 мс против 16).
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by John Doe »

А что там с mmode? Разве вопрос не решается добавлением flags="EnableOutput";?
Ещё замечу что:
- exit() можно смело заменить на return
- Действие макроса можно расширить и на панели Info QView Tree (может и на Search)
AleXH
Posts: 1000
Joined: Sun 12 Apr, 2009 05:21
Been thanked: 1 time

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by AleXH »

onlyVisible и useShift логично было бы сделать логическими переменными true/false
IgorZ
Posts: 790
Joined: Wed 13 Jul, 2011 03:32
Has thanked: 15 times
Been thanked: 93 times

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by IgorZ »

Версия 2.2.5: Правка скрипта (использование нововведений, появившихся после его написания, ~700 билдов Far-а назад :bojan: :) ), причёсывание. Теперь работает и с плагиновыми панелями, а также в области поиска. Требует версию Far 3.0.3209+, а не 3.0.3054+, как предыдущая.
John Doe wrote:А что там с mmode? Разве вопрос не решается добавлением flags="EnableOutput";?
Скрипт старенький. Когда он писался, я ещё только изучал Lua (собственно, на нём и изучал), а EnableOutput ещё не было, как и кое-чего другого. Так оно и тянулось. Поправил.
John Doe wrote:- exit() можно смело заменить на return
Можно, но это чистая вкусовщина с моей стороны. Функционально одно и то же, а exit() кажется мне более наглядным. Впрочем, теперь я вынес эту часть в condition, и exit() не нужен.
John Doe wrote:- Действие макроса можно расширить и на панели Info QView Tree (может и на Search)
На Info/QView/Tree не работает - не меняется диск. На Search расширил.
AleXH wrote:onlyVisible и useShift логично было бы сделать логическими переменными true/false
Логично. Сделал.
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by John Doe »

IgorZ wrote:а EnableOutput ещё не было
Но вы это уже исправляли в 2.2.3 ;-)
IgorZ wrote:На Info/QView/Tree не работает - не меняется диск.
При этом пассивная панель ведь файловая, и на ней сменить диск возможно.

Просмотрев скрипт свежим взглядом заметил, что в цикле repeat/until 100 раз в секунду перерисовывается панелька дисков.
(Хотя визуально ничего не дёргается, вероятно фар оптимизирует).

Кстати можно обойтись без EnableOutput, используя far.Text()

P.S.
Ещё несколько мыслей:
- SkipShift можно обработать раньше, в определении макроса.
- Не баг, но функции cond/act правильнее сделать локальными
- В условии cond имхо имеет смысл перенести вычисление WPanel в блок if/else. В ущерб компактности, зато конечный пользователь легче сможет подстроить под сеья желаемое поведение.
IgorZ
Posts: 790
Joined: Wed 13 Jul, 2011 03:32
Has thanked: 15 times
Been thanked: 93 times

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by IgorZ »

Версия 2.2.6
John Doe wrote:
IgorZ wrote:а EnableOutput ещё не было
Но вы это уже исправляли в 2.2.3 ;-)
Посмотрел имеющийся у меня архив старых версий. Не было такого. Возможно, Вы это у себя самостоятельно правили? А, вспомнил. Я выкинул DisableOutput и вставил mmode, чтобы работала и на старых, и на новых версиях Far-а. Сейчас уже вряд ли нужна совместимость.
John Doe wrote:
IgorZ wrote:На Info/QView/Tree не работает - не меняется диск.
При этом пассивная панель ведь файловая, и на ней сменить диск возможно.
Менять на другой панели? Вроде идея неплохая. Сделал.
John Doe wrote:Кстати можно обойтись без EnableOutput, используя far.Text()
Нельзя. Я почему и заметил ошибку с mmode: после рефакторинга он перестал работать, и панелька дисков вообще не стала отображаться. Точнее, весь вывод на экран стал накапливаться в буфере и выводиться разом, по итогам отработки скрипта, а не сразу в очередной итерации цикла. Пример:
  1. Macro{
  2.  
  3.   area="Shell";
  4.  
  5.   key="Ctrl1";
  6.  
  7. --  flags="EnableOutput";
  8.  
  9.   action=function()
  10.  
  11. for i = 1, 10 do
  12.  
  13.   far.Text(i*2,0,0x0f,i)
  14.  
  15.   local k = mf.waitkey(1000)
  16.  
  17. end
  18.  
  19.   end;
  20.  
  21. }
Если раскомментировать строчку, работает нормально. Иначе - вываливает всё в конце. Кстати, возможно, это ошибка плагина, но не уверен. Определённая логика в таком поведении есть.
John Doe wrote:- SkipShift можно обработать раньше, в определении макроса.
Логично. Сделал.
John Doe wrote:- Не баг, но функции cond/act правильнее сделать локальными
Банально забыл поставить.
John Doe wrote:- В условии cond имхо имеет смысл перенести вычисление WPanel в блок if/else. В ущерб компактности, зато конечный пользователь легче сможет подстроить под сеья желаемое поведение.
Не понял. Расписать кучей ступенек, примерно так?
  1. WPanel = PPanel
  2.  
  3. if AltMode then
  4.  
  5.   if KeyMod:find("C") then
  6.  
  7.     WPanel = APanel
  8.  
  9.   end
  10.  
  11. else
  12.  
  13.   if KeyMod=="Ctrl" or KeyMod=="RAlt" then
  14.  
  15.     WPanel = APanel
  16.  
  17.   end
  18.  
  19. end
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by John Doe »

IgorZ wrote:А, вспомнил. Я выкинул DisableOutput и вставил mmode, чтобы работала и на старых, и на новых версиях Far-а.
И сделали вы это ещё в 2.2.3, changelog в шапке.
IgorZ wrote:Сейчас уже вряд ли нужна совместимость.
Сильно подозреваю, что с флагом EnableOutput будет работать и в старых версиях.
John Doe wrote:Кстати можно обойтись без EnableOutput, используя far.Text()
  1. repeat -- Обработаем очередное нажатие стрелки
  2.  
  3.     if Key~="" then
  4.  
  5.       DrvNum = DrvNum + (Key==(KeyMod.."Right") and 1 or -1)
  6.  
  7.       local len = DrvList:len()
  8.  
  9.       DrvNum = DrvNum==0 and len or DrvNum>len and 1 or DrvNum -- корректировка выхода за начало/конец
  10.  
  11.       far.Text(DrvStart,0,far.AdvControl(GetColor,StdColor),"["..DrvList.."]") -- отрисуем список дисков
  12.  
  13.       far.Text(DrvStart+DrvNum,0,far.AdvControl(GetColor,SelColor),DrvList:sub(DrvNum,DrvNum)) -- и курсор
  14.  
  15.       far.Text()
  16.  
  17.     end
  18.  
  19.     Key = mf.waitkey(10)
  20.  
  21.   until band(Mouse.LastCtrlState,bMods[KeyMod])==0
Это просто для информации, я не утверждаю что тут есть хоть какие-то преимущества перед EnableOutput.

IgorZ wrote:
John Doe wrote:- В условии cond имхо имеет смысл перенести вычисление WPanel в блок if/else. В ущерб компактности, зато конечный пользователь легче сможет подстроить под сеья желаемое поведение.
Не понял. Расписать кучей ступенек, примерно так?
Я бы сделал так:
  1. local function cond(key)
  2.  
  3.   Key,KeyMod = key,key:match("..%l+") -- запомним клавишу и модификатор
  4.  
  5.   if Key:find("Ctrl") and not CmdLine.Empty then return end -- Ctrl/стрелки отдаём в командную строку, если не пуста
  6.  
  7.  
  8.  
  9.   if AlternativeMods then
  10.  
  11.     WPanel = KeyMod:find("Ctrl") and APanel or PPanel
  12.  
  13.   else
  14.  
  15.     if KeyMod=="Shift" then
  16.  
  17.       WPanel = APanel
  18.  
  19.     else
  20.  
  21.       WPanel = (KeyMod=="Ctrl" or KeyMod=="RAlt")==APanel.Left and APanel or PPanel
  22.  
  23.     end
  24.  
  25.   end
  26.  
  27.  
  28.  
  29.   return not OnlyVisible or WPanel.Visible
  30.  
  31. end
IgorZ
Posts: 790
Joined: Wed 13 Jul, 2011 03:32
Has thanked: 15 times
Been thanked: 93 times

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by IgorZ »

John Doe wrote:
John Doe wrote:Кстати можно обойтись без EnableOutput, используя far.Text()
Это просто для информации, я не утверждаю что тут есть хоть какие-то преимущества перед EnableOutput.
Ага, понял (про этот нюанс far.Text() я, если честно, просто забыл). Недостаток: дополнительный исполняющийся в цикле код. По факту несущественно, но вообще следует избегать.
John Doe wrote:Я бы сделал так:
А смысл? Проще не стало. Если кому надо разобраться в работе и/или переделать - и так справится. Может, я что-то недопонимаю?
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by John Doe »

IgorZ wrote:Недостаток: дополнительный исполняющийся в цикле код. По факту несущественно, но вообще следует избегать.
В предложенном варианте код выполняется вовсе не в цикле, а только по факту нажатия.
В вашем же да, 100 раз в секунду исполняется значительный объём ненужного кода (вчера уже писал об этом: незачем вызывать функции вывода на экран если ничего не изменилось).
Плюс, цвета можно сразу запомнить (даже до макроса), и не вычислять для каждой итерации заново.
IgorZ wrote:А смысл? Проще не стало. Если кому надо разобраться в работе и/или переделать - и так справится. Может, я что-то недопонимаю?
Идиома a = b or c это действительно просто.
А разбирать двустрочное нагромождение логических выражений это уже задача.

P.S.
Разумеется ваш вариант вполне корректен, и в компактности записи есть своя прелесть.
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by John Doe »

Закомментировал вызов panel.RedrawPanel и ничего не изменилось.
Видимо лишний.
IgorZ
Posts: 790
Joined: Wed 13 Jul, 2011 03:32
Has thanked: 15 times
Been thanked: 93 times

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by IgorZ »

Версия 2.2.7: подсвечивается начальный диск, оптимизация всего, что попалось на глаза.
John Doe wrote:
IgorZ wrote:Недостаток: дополнительный исполняющийся в цикле код. По факту несущественно, но вообще следует избегать.
В предложенном варианте код выполняется вовсе не в цикле, а только по факту нажатия.
В вашем же да, 100 раз в секунду исполняется значительный объём ненужного кода (вчера уже писал об этом: незачем вызывать функции вывода на экран если ничего не изменилось).
Мы о разном. Насчёт исполнения в цикле, согласен, поправлю, но я о другом: в коде в цикле стоит и выполняется оператор, который не выполняет асолютно никакой полезной работы (при наличии EnableOutput или, как раньше, mmode(1,0)).
Кстати,
  1. DrvNum = DrvNum + (Key==(KeyMod.."Right") and 1 or -1)
- некорректно. mf.waitkey может ввести любую клавишу. Получится, что всё нажатое, кроме KeyMod.."Right" будет работать, как KeyMod.."Left". Ну это так, придирки.
John Doe wrote:Плюс, цвета можно сразу запомнить (даже до макроса), и не вычислять для каждой итерации заново.
Тут согласен, заодно добавлю подсветку начального диска (полезно, если рабочая панель погашена).
John Doe wrote:
IgorZ wrote:А смысл? Проще не стало. Если кому надо разобраться в работе и/или переделать - и так справится. Может, я что-то недопонимаю?
Идиома a = b or c это действительно просто.
А разбирать двустрочное нагромождение логических выражений это уже задача.
P.S.
Разумеется ваш вариант вполне корректен, и в компактности записи есть своя прелесть.
Ради эксперимента отформатировал выражение, не меняя его (только скобок добавил для единообразия. Насколько изменилась читабельность?
John Doe wrote:Закомментировал вызов panel.RedrawPanel и ничего не изменилось.
Видимо лишний.
Рудимент от тех времён, когда не использовал far.SaveScreen/far.RestoreScreen. Убрал.
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by John Doe »

IgorZ wrote:Мы о разном. Насчёт исполнения в цикле, согласен, поправлю, но я о другом: в коде в цикле стоит и выполняется оператор, который не выполняет асолютно никакой полезной работы (при наличии EnableOutput или, как раньше, mmode(1,0)).
Во-первых, "в цикле" предполагает какое-то существенное число повторений, у нас же только по нажатию клавиши.
Во-вторых, я вовсе не предлагал добавлять вызов far.Text() при включённом флаге EnableOutput.
Что касается полезной работы, то следует учитывать, что при EnableOutput ведь тоже выполняется дополнительная работа, хоть и неявно.

Для информации:
IgorZ wrote:заодно добавлю подсветку начального диска (полезно, если рабочая панель погашена).
Предлагаю подсвечивать тут не фон, а текст, а то похоже на второй курсор.
IgorZ wrote:Ради эксперимента отформатировал выражение, не меняя его (только скобок добавил для единообразия. Насколько изменилась читабельность?
Не особо изменилась. А утрата компактности имхо вообще лишила смысла использование этой идиомы.
Кстати, вот где ещё её можно использовать:

Code: Select all

if WPanel.Left then Keys("CtrlF1") else Keys("CtrlF2") end
IgorZ
Posts: 790
Joined: Wed 13 Jul, 2011 03:32
Has thanked: 15 times
Been thanked: 93 times

Re: Переключение дисков по Ctrl/Alt/Shift+<-/->

Post by IgorZ »

Версия 2.2.7a: Экспериментально: изначальный диск не только подсвечивается, но и выводится строчной буквой. Для возврата на него введена клавиатурная комбинация "Home" с текущим модификатором.
John Doe wrote:
IgorZ wrote:заодно добавлю подсветку начального диска (полезно, если рабочая панель погашена).
Предлагаю подсвечивать тут не фон, а текст, а то похоже на второй курсор.
В скрипте используются стандартные цвета текущей раскраски Far-а. В частности, для кусора - цвета курсора, а для начального диска - цвета выделенного файла (или, соответственно, выделенного файла под курсором). Так что, если у Вас буква начального диска на фоне другого цвета, значит, так настроен Ваш Far (Параметры/Цвета/Панель/Выбранный текст и Выделенный курсор).
В текущей версии для пробы дополнил выделение текущего диска размером буквы (у меня раскраска настроена так, что выбранные файлы выделяются только галкой, а цветом нет, так что выделение диска цветом у меня не работает). Все диски - заглавными буквами, а изначальный - строчной. Если интересно, можно попробовать вариант наоборот: все строчными, а начальный - заглавной. Для этого надо раскомментировать все строки, у которых в комментарии стоит "!!lower" и закоментировать предыдущие. Лично мне не понравилось, но на вкус и цвет все фломастеры разные.
Post Reply

Return to “Полезные макросы и скрипты”