Last active
May 6, 2023 19:29
-
-
Save johnd0e/573e90c46059e14f3cdf4855d24f6414 to your computer and use it in GitHub Desktop.
[FAR macro] HlfTools
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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