Навигация по секциям списков

Здесь обсуждается всё, что касается макросов.
User avatar
John Doe
Бюрократ
Posts: 11398
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 17 times
Been thanked: 101 times

Навигация по секциям списков

Post by John Doe » Fri 29 May, 2015 13:18

С помощью предлагаемых макросов удобно перемещаться по секциям списков (разделённых сепараторами).
Работает в автодополнении, во всех меню (включая Главное и Пользовательское), в историях, листбоксах диалогов (на всякий случай).

Code: Select all

--http://forum.farmanager.com/viewtopic.php?f=15&t=9596
local F = far.Flags
local areas = "ShellAutoCompletion DialogAutoCompletion Menu UserMenu MainMenu Dialog"

local DELAY = 300
local function Jump(dir)
  local hDlg = far.AdvControl(F.ACTL_GETWINDOWINFO).Id
  local list = far.GetDlgItem(hDlg,1)[6]
  for i=list.SelectIndex+dir,dir<0 and 1 or #list, dir do
    if band(list[i].Flags,F.LIF_SEPARATOR)~=0 or i==1 then
      hDlg:send(F.DM_LISTSETCURPOS,1,{SelectPos=i,TopPos=i})
      return
    end
  end
  if mf.waitkey(DELAY)==mf.akey(1,1) then
    Keys(dir>0 and "Home" or "End")
  else
    mf.beep()
  end
end

Macro { description="Navigate to prev/next section";
  area=areas; key="/[LR]CtrlShift(Up|Down)/";
  id="1BAED6ED-E6F0-4313-BDC3-F8466BEEDB68";
  condition=function()
    return not Area.Dialog or (Dlg.ItemType==F.DI_LISTBOX)
  end;
  action=function()
    if Area.MainMenu and Object.Height==1 then
      Keys "Up"
    else
      Jump(mf.akey(1,1):match"Up$" and -1 or 1)
    end
  end;
}
Last edited by John Doe on Sat 07 Oct, 2017 10:32, edited 2 times in total.
Reason: doubletap to pass over edge

User avatar
HaRT
Moderator
Posts: 8109
Joined: Tue 30 Aug, 2005 17:21
Location: Санкт-Петербург
Has thanked: 67 times
Been thanked: 103 times

Навигация по секциям списков

Post by HaRT » Fri 29 May, 2015 14:10

Спасибо, интересно.
Опробовал на историях — там у меня убираются разделители, но при вводе фильтра они сразу снова появляются. И вот там как-то странно работает прыжок вверх — перескакивает через целые секции, позиционируется не рядом с разделителем. Вниз прыгает вроде нормально.
Far 3.0 build 4363 x86
Фар есть инструмент, а не нянька. © 2009 DrKnS

User avatar
John Doe
Бюрократ
Posts: 11398
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 17 times
Been thanked: 101 times

Навигация по секциям списков

Post by John Doe » Fri 29 May, 2015 15:16

HaRT wrote: Опробовал на историях — там у меня убираются разделители
В текущем варианте можно позиционироваться и на скрытый разделитель, возможно стоит это запретить.
HaRT wrote: перескакивает через целые секции, позиционируется не рядом с разделителем.
Что если строку 14 заменить на hDlg:send(F.DM_LISTSETCURPOS,1,{SelectPos=i,TopPos=i})

User avatar
HaRT
Moderator
Posts: 8109
Joined: Tue 30 Aug, 2005 17:21
Location: Санкт-Петербург
Has thanked: 67 times
Been thanked: 103 times

Навигация по секциям списков

Post by HaRT » Fri 29 May, 2015 16:01

John Doe wrote: Что если строку 14 заменить
Теперь прыгает строго на две секции вверх вместо одной.
Фар есть инструмент, а не нянька. © 2009 DrKnS

User avatar
John Doe
Бюрократ
Posts: 11398
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 17 times
Been thanked: 101 times

Навигация по секциям списков

Post by John Doe » Fri 29 May, 2015 16:05

Перемудрил зачем-то...
Исправлено.

User avatar
HaRT
Moderator
Posts: 8109
Joined: Tue 30 Aug, 2005 17:21
Location: Санкт-Петербург
Has thanked: 67 times
Been thanked: 103 times

Навигация по секциям списков

Post by HaRT » Fri 29 May, 2015 21:12

John Doe wrote: Исправлено.
Спасибо, вроде теперь всё гладко.
Фар есть инструмент, а не нянька. © 2009 DrKnS

User avatar
John Doe
Бюрократ
Posts: 11398
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 17 times
Been thanked: 101 times

Навигация по секциям списков

Post by John Doe » Fri 06 Oct, 2017 07:35

Макрос не учитывал возможность того, что главное меню не раскрыто. Исправлено.

User avatar
sToLp
Posts: 763
Joined: Thu 23 Jul, 2009 10:16
Has thanked: 56 times
Been thanked: 5 times

Навигация по секциям списков

Post by sToLp » Fri 06 Oct, 2017 21:49

Макрос несомненно полезный. Хорошо бы он ещё и по кругу ходил. Т.е. после последней нижней позиции переходил бы на первую верхнюю и наоборот.

User avatar
HaRT
Moderator
Posts: 8109
Joined: Tue 30 Aug, 2005 17:21
Location: Санкт-Петербург
Has thanked: 67 times
Been thanked: 103 times

Навигация по секциям списков

Post by HaRT » Fri 06 Oct, 2017 21:56

sToLp wrote:
Fri 06 Oct, 2017 21:49
Макрос несомненно полезный. Хорошо бы он ещё и по кругу ходил. Т.е. после последней нижней позиции переходил бы на первую верхнюю и наоборот.
Только, пожалуйста, опционально. Идеально — если эту опцию можно будет переключать на лету (например по CtrlShiftL — чтобы пальцы с модификаторов не снимать и руку не двигать).
Фар есть инструмент, а не нянька. © 2009 DrKnS

User avatar
sToLp
Posts: 763
Joined: Thu 23 Jul, 2009 10:16
Has thanked: 56 times
Been thanked: 5 times

Навигация по секциям списков

Post by sToLp » Fri 06 Oct, 2017 22:27

HaRT wrote:
Fri 06 Oct, 2017 21:56
Идеально — если эту опцию можно будет переключать на лету (например по CtrlShiftL — чтобы пальцы с модификаторов не снимать и руку не двигать).
Будь такая возможность, я бы этот принцип для всех бы опций практиковал бы.

User avatar
John Doe
Бюрократ
Posts: 11398
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 17 times
Been thanked: 101 times

Навигация по секциям списков

Post by John Doe » Sat 07 Oct, 2017 09:26

sToLp wrote:
Fri 06 Oct, 2017 21:49
Хорошо бы он ещё и по кругу ходил.
После mf.beep() добавьте

Code: Select all

  Keys(dir>0 and "Home" or "End")
А идея с CtrlShiftL мне не кажется удобной.
Возможно лучше, если при достижении края прозвучит бип, а при повторном нажатии будет переход.

User avatar
sToLp
Posts: 763
Joined: Thu 23 Jul, 2009 10:16
Has thanked: 56 times
Been thanked: 5 times

Навигация по секциям списков

Post by sToLp » Sat 07 Oct, 2017 10:06

John Doe wrote:
Sat 07 Oct, 2017 09:26
sToLp wrote:
Fri 06 Oct, 2017 21:49
Хорошо бы он ещё и по кругу ходил.
После mf.beep() добавьте

Code: Select all

  Keys(dir>0 and "Home" or "End")
А идея с CtrlShiftL мне не кажется удобной.
Возможно лучше, если при достижении края прозвучит бип, а при повторном нажатии будет переход.
Лично мне такой вариант вполне подходит.
Однако дело ещё и в том, что на практике существуют множество терминалов, на которых в распоряжении пользователя лишь монитор (зачастую ещё такой, что обзавидуешься) и клавиатура. Так что там просто нечему бипать. А для сисадмина Far в таких условиях просто палочка-выручалочка. Да и пользователи периодически вынужденно его применяют и нередко бывают довольны этим.

User avatar
John Doe
Бюрократ
Posts: 11398
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 17 times
Been thanked: 101 times

Навигация по секциям списков

Post by John Doe » Sat 07 Oct, 2017 10:15

sToLp wrote:
Sat 07 Oct, 2017 10:06
Так что там просто нечему бипать.
Бип это условно.
Вместо него может быть всплывающее сообщение.
Или просто отсутствие действия.

Или для перехода через край использовать двойное нажатие.
В шапке.

User avatar
sToLp
Posts: 763
Joined: Thu 23 Jul, 2009 10:16
Has thanked: 56 times
Been thanked: 5 times

Навигация по секциям списков

Post by sToLp » Sun 08 Oct, 2017 02:21

John Doe wrote:
Sat 07 Oct, 2017 10:15
для перехода через край использовать двойное нажатие.
В шапке.
Шикарно — и "волкам" и "овцам".

User avatar
HaRT
Moderator
Posts: 8109
Joined: Tue 30 Aug, 2005 17:21
Location: Санкт-Петербург
Has thanked: 67 times
Been thanked: 103 times

Навигация по секциям списков

Post by HaRT » Mon 09 Oct, 2017 18:25

John Doe wrote:
Sat 07 Oct, 2017 10:15
для перехода через край использовать двойное нажатие
Спасибо.
Однако если в списке (например, встроенной истории) применён фильтр, то и одиночное нажатие „закругляется“.
Фар есть инструмент, а не нянька. © 2009 DrKnS

User avatar
John Doe
Бюрократ
Posts: 11398
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 17 times
Been thanked: 101 times

Навигация по секциям списков

Post by John Doe » Mon 09 Oct, 2017 20:04

Эх, не хотелось усложнять..

А так?

Code: Select all

local F = far.Flags
local areas = "ShellAutoCompletion DialogAutoCompletion Menu UserMenu MainMenu Dialog"

local NOT_POSITIONABLE = bor(F.LIF_SEPARATOR,F.LIF_DISABLE,F.LIF_HIDDEN)
local DOUBLETAP_DELAY = 300
local AUTOREPEAT_DELAY = 200*1000
local lasttime = 0
local function Jump(dir)
  local ID = Area.Dialog and Dlg.CurPos or 1
  local sep_found,cur_positionable,last_able
  local hDlg = far.AdvControl(F.ACTL_GETWINDOWINFO).Id
  local list = far.GetDlgItem(hDlg,ID)[6]
  for i=list.SelectIndex+dir, dir<0 and 1 or #list, dir do
    local flags = list[i].Flags
    cur_positionable = band(flags,NOT_POSITIONABLE)==0
    last_able = cur_positionable and i or last_able
    if sep_found then
      if cur_positionable then
        hDlg:send(F.DM_LISTSETCURPOS,ID,{SelectPos=i,TopPos=sep_found-1})
        return
      end
    elseif band(flags,F.LIF_SEPARATOR)~=0 and band(flags,F.LIF_HIDDEN)==0 then
      sep_found = i
    end
  end
  if last_able and (last_able-list.SelectIndex>0)==(dir>0) then
    hDlg:send(F.DM_LISTSETCURPOS,ID,{SelectPos=last_able,TopPos=last_able-1})
  elseif far.FarClock()-lasttime>AUTOREPEAT_DELAY and mf.waitkey(DOUBLETAP_DELAY)==mf.akey(1,1) then
    Keys(dir>0 and "Home" or "End")
  else
    mf.beep()
  end
  lasttime = far.FarClock()
end

Macro { description="Navigate to prev/next section";
  area=areas; key="/[LR]CtrlShift(Up|Down)/";
  id="1BAED6ED-E6F0-4313-BDC3-F8466BEEDB68";
  condition=function()
    return not Area.Dialog or (Dlg.ItemType==F.DI_LISTBOX)
  end;
  action=function()
    if Area.MainMenu and Object.Height==1 then --HMenu
      Keys "Up"
    else
      Jump(mf.akey(1,1):match"Up$" and -1 or 1)
    end
  end;
}
Last edited by John Doe on Sat 14 Oct, 2017 12:57, edited 3 times in total.

Post Reply

Return to “Обсуждение макросов”