Skip to content

Instantly share code, notes, and snippets.

@johnd0e
Last active May 6, 2023 19:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnd0e/573e90c46059e14f3cdf4855d24f6414 to your computer and use it in GitHub Desktop.
Save johnd0e/573e90c46059e14f3cdf4855d24f6414 to your computer and use it in GitHub Desktop.
[FAR macro] HlfTools
local Info = Info or package.loaded.regscript or function(...) return ... end --luacheck: ignore 113/Info
local nfo = Info { _filename or ...,
name = "HlfTools";
description = "Misc tools for FAR help files";
version = "0.1"; --http://semver.org/lang/ru/
author = "jd";
url = "http://forum.farmanager.com/viewtopic.php?f=15&t=10903";
id = "98B719AC-42B1-49D3-AF03-17DF9A3636FC";
minfarversion = {3,0,0,4138,0}; --ACTL_GETWINDOWINFO возвращает все окна в порядке текущего z-order'а.
help = function(nfo) far.Message(nfo.helpstr, nfo.name, nil, "l") end;
helpstr = [[
Common:
• CtrlAltF1 — Повторный вызов справки.
При закрытии справки запоминается последний топик, после чего
по команде его можно восстановить (независимо от текущего контекста).
Клавиатурную комбинацию можно изменить в опциях.
Editor
• F1 — Отображение текущего редактируемого hlf-файла в виде справки.
При наличии, использует функции плагина HlfView.
Help
• CtrlIns — Копирует в буфер обмена название текущего топика справки.
• F4 — Открывает в редакторе текущий топик справки.
Если файл уже открыт, то переключается в нужный редактор, и
позиционируется к нужному месту.
Опционально: закрывает препятствующие переключению модальные окна.
• BS, AltF1 — Стандартное действие (переход к предыдущую страницу) закрывает
справку в случае если уже открыта начальная страница.
Макросы из данного набора опционально предотвращают закрытие справки.
• AltI — Открывает @Index или @Contents.
]];
options = {
LastHelp = "CtrlAltF1",
PreventQuitBS = true,
close_modals = true,
}
--disabled = false;
}
if not nfo or nfo.disabled then return end
local O = nfo.options
local F = far.Flags
local helpflags = F.FHELP_CUSTOMFILE
--------------------------------------------------------------------------------
--?? remember last ten?
local lasthelp
Macro { description="Store last help info";
area="Help"; key="Esc F10 BS";
id="8E45F727-EA31-42F0-BEC1-485D13FE82DF";
condition=function()
lasthelp = {filename=Help.FileName, topic=Help.Topic}
end;
action=function()end;
}
local function recallLast()
if lasthelp then
if not far.ShowHelp(lasthelp.filename, lasthelp.topic, helpflags) then -- make use of std error message
if win.GetFileAttr(lasthelp.filename) then
far.ShowHelp(lasthelp.filename, nil, helpflags) -- show @Contents
end
end
end
end
if O.PreventQuitBS then Macro { description="Prevent BS to exit help";
area="Help"; key="BS AltF1";
id="7FD50E06-A58A-409D-944F-B92BAD90FE5F";
action=function()
Keys"AKey"
if not Area.Help then mf.acall(recallLast) end
end;
}end
Macro { description="Recall last help topic";
area="Common"; key=O.LastHelp;
id="72744538-64C3-4220-BF6D-B580BF3C38FE";
condition=function() return not Area.Help end;
action=function() mf.acall(recallLast) end;
}
--------------------------------------------------------------------------------
local open
Macro { description="Show index";
area="Help"; key="AltI";
id="40BF0EA5-360E-46A6-ABB0-EFF8F67EDB68";
action=function()
if open then Keys"F10" end -- prevent nested call
open = true
far.ShowHelp(Help.FileName, "Index", bor(helpflags,F.FHELP_USECONTENTS))
open = false
end;
}
--------------------------------------------------------------------------------
Macro { description="Show current hlf topic";
area="Editor"; key="F1"; filemask="*.hlf;*.hlf.m4";
id="459B31C4-B5AC-49E3-9334-6FD3196768DB";
action=function()
if not Plugin.Call("1AF0754D-5020-49CB-9474-1F82691C84C1") then --HlfViewer
local topic
local ei = editor.GetInfo()
for i=ei.CurLine,1,-1 do
--https://api.farmanager.com/ru/language/help_files.html
topic = editor.GetString(ei.EditorID,i,3):match"^@([^-+=][^=]-)%s*$"
if topic then break end
end
far.ShowHelp(ei.FileName, topic, helpflags)
end
end;
}
--------------------------------------------------------------------------------
local function MessagePopup(msg,title,flags,delay)
local s = far.SaveScreen()
far.Message(msg, title or "", "", flags)
mf.waitkey(delay or 500); far.RestoreScreen(s)
end
Macro { description="Copy <Help.Topic>";
area="Help"; key="CtrlIns";
id="DA0F91F7-2EAD-4494-97C3-74504DFCEC30";
action=function()
if far.CopyToClipboard(Help.Topic) then
MessagePopup(("'%s' has been copied to clipboard"):format(Help.Topic), Help.FileName, nil, 1000)
end
end;
}
--------------------------------------------------------------------------------
local function searchWindow(filename)
local n = far.AdvControl(F.ACTL_GETWINDOWCOUNT)-1
local function find(i)
local w = far.AdvControl(F.ACTL_GETWINDOWINFO,i)
return w.Type==F.WTYPE_EDITOR and editor.GetFileName(w.Id)==filename,
band(w.Flags,F.WIF_MODAL)~=0
end
local has_modal
for i=n,1,-1 do
local found,modal = find(i)
has_modal = has_modal or modal
if found then
return i,has_modal
end
end
end
local function findLine(filename,topic)
local file = assert(io.open(filename))
local str = "@"..topic
local found
local i = 1
for line in file:lines() do
if line==str then
found = i
break
end
i = i+1
end
file:close()
return found
end
local function posEditor(topic)
local str = "@"..topic
local ei = editor.GetInfo()
for i=1,ei.TotalLines do
if editor.GetString(ei.EditorID,i,3)==str then
editor.SetPosition(ei.EditorID,i,1)
return true
end
end
end
local function closeModals(pos)
--??ask if try to close modals
local n = far.AdvControl(F.ACTL_GETWINDOWCOUNT)
repeat
local last = n
Keys"F10"
n = far.AdvControl(F.ACTL_GETWINDOWCOUNT)
if n==pos or 0==band(F.WIF_MODAL, far.AdvControl(F.ACTL_GETWINDOWINFO,n).Flags) then
return true
end
until n>=last
end
--origin: http://forum.farmanager.com/viewtopic.php?f=15&t=4144
Macro { description="Open <Help.Topic> in editor";
area="Help"; key="F4";
id="7AFDF945-930C-4984-AAB0-82101EF2BB5E";
action=function()
local filename = Help.FileName
local topic = Help.Topic
local pos,modal = searchWindow(filename)
if not pos then
Keys"F10"
if not win.GetFileAttr(filename) then return end --file was temporary (from HlfViewer)
local res = editor.Editor(filename,nil,nil,nil,nil,nil,nil,findLine(filename,topic),1)
if res==F.EEC_OPEN_ERROR then
far.Message(("Unable to open in editor:\n%s"):format(filename), "Error", nil, "w")
end
if not far.ShowHelp(filename, topic, helpflags) then -- make use of std error message
far.ShowHelp(filename, nil, helpflags) -- show @Contents
end
else --hlf already open in editor
if modal then
if not O.close_modals or not closeModals(pos) then
MessagePopup("Unable to leave modal window",nil)
return
end
else
Keys"F10"
end
far.AdvControl(F.ACTL_SETCURRENTWINDOW,pos)
if not posEditor(topic) then
MessagePopup(("Topic '%s' not found"):format(topic),nil)
end
end
end;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment