local BaxUtils = require"BAX.BaxUtils"
--local TabUtils = require"BAX.TabUtils"
local F=far.Flags
local tin=table.insert
local Info = package.loaded.regscript or function(...) return ... end
local CodePage_Setup
local nfo = Info {_filename or ...,
name = "CodePage";
description = "Устанавливает кодовую страницу при открытии редактора и просмотровщика в зависимости от расширения файла";
version = "1.1.5"; --http://semver.org/lang/ru/
author = "BAX";
url = "";
id = "6409EA25-AA64-4749-9E30-BB4E9A936DD7";
--parent_id = "";
--minfarversion = {3,0,0,4744,0};
--files = "*.cfg;*.ru.lng";
--config = function() end
--help = function(nfo,name) end;
--execute = function(nfo,name) end;
--disabled = false;
--options = {};
}
if not nfo then return end
-----------------------------------------------------------------------------
local CpList={}
local DialogItem=BaxUtils.DialogItem
local SetingKey={Author='BAX'; Key='Codepages'}
local Settings0 =
{
{Mask="*.lua,*.fml,*.fmlua,*.lua.*,*.fb2"; Editor=true; Viewer=true; OnlyNew=false; Cp=65001};
{Mask="*.bat,*.cmd,*.prg,*.ch"; Editor=true; Viewer=true; OnlyNew=true; Cp=866};
}
local Settings = mf.mload(SetingKey.Author, SetingKey.Key) or Settings0
CodePage_Setup = function ()
-- Составляю список доступных кодировок
if not next(CpList) then
CpList={}
local cpl, maxl=win.EnumSystemCodePages(), 0
table.sort(cpl, function(a1,a2) maxl = math.max(maxl, a1:len(), a2:len()); return tonumber(a1) <= tonumber(a2) end)
local formatStr=('%%-%ds │ %%s'):format(maxl)
for _,v in ipairs(cpl) do
tin(CpList, {Text=formatStr:format(v, (win.GetCPInfo(tonumber(v)) or {CodePageName=(' '):rep(6)..'<Page='..v..'>'}).CodePageName:sub(7)); Source=v})
end
end
------------------
local DlgItems, y={}, 1
local function Add(Arg) tin(DlgItems, DialogItem(Arg)) end
local function AddP(Arg) Add(Arg); y=y+1 end
local w=math.floor(math.min(200, Far.Width*0.8))
local wList = math.min(math.floor((w-5)/2),50)
local aPos={}
Add{"DI_DOUBLEBOX",0,0,w-1,0,Text="Установка кодовой страницы - настройка"}
y = y + 1
local List={}
for _,v in ipairs(Settings) do
tin(List, {Text=v.Mask})
end
Add{"DI_DOUBLEBOX", 2,y,wList+1,y+5, Flags="", Text=" &1. Маски файлов "}
Add{"DI_LISTBOX", 3,y+1,wList,y+4, Flags="DIF_LISTNOBOX", List=List}; aPos.List=#DlgItems
Add{"DI_BUTTON",3,y+6,Flags="DIF_BTNNOCLOSE|DIF_NOBRACKETS", Text="Add"}; aPos.Add=#DlgItems
Add{"DI_BUTTON",7,y+6,Flags="DIF_BTNNOCLOSE|DIF_NOBRACKETS", Text="Del"}; aPos.Del=#DlgItems
Add{"DI_BUTTON",11,y+6,Flags="DIF_BTNNOCLOSE|DIF_NOBRACKETS", Text="F4"}; aPos.F4=#DlgItems
AddP{"DI_SINGLEBOX",wList+3,y,w-2,y+6; Text="&2. Кодовая страница"}
AddP{"DI_COMBOBOX", wList+5, y,w-4, Flags="DIF_SELECTONENTRY", List=CpList}; aPos.Cp=#DlgItems
AddP{"DI_CHECKBOX", wList+5, y,w-4, Text="Добавить BOM"}; aPos.BOM=#DlgItems
--AddP{"DI_TEXT",math.floor(wList+(w-wList-15)/2),y,-1,y,Text="Использовать в:"}
AddP{"DI_TEXT",wList+9,y,-1,y,Text="Использовать в:"}
do
local txt1,txt2='редакторе','(только в новом)'
local x1=wList+5
local x2 = x1 + txt1:len() + 5
Add{"DI_CHECKBOX",x1,y,txt1:len(),y,Text=txt1}; aPos.Editor=#DlgItems
AddP{"DI_CHECKBOX",x2,y,x2,y,Text=txt2}; aPos.OnlyNew=#DlgItems
end
do
local txt="вьюере"
local x1=(wList+5) -- + math.ceil((w-txt:len()-4)/2+0.5)
Add{"DI_CHECKBOX",x1,y,x1+txt:len()+5,y,Flags="DIF_CENTERTEXT",Text=txt}; aPos.Viewer=#DlgItems
end
y = y + 3
Add{"DI_BUTTON",-1,y,-1,y,Flags="DIF_CENTERGROUP|DIF_DEFAULTBUTTON",Text="Ok"}; aPos.Ok = #DlgItems
Add{"DI_BUTTON",-1,y,-1,y,Flags="DIF_CENTERGROUP",Text="Cancel"}
local h = y + 2
do
local first=DlgItems[1]
first.y2=h-1
DlgItems[1] = DialogItem(first)
end
local LastPos={TopPos=1, SelectPos=1}
local function DlgProc(hDlg, Msg, Param1, Param2)
local function Save(iPos)
local Setting1 = Settings[iPos]
if Setting1 then
local _Cp=hDlg:send("DM_GETTEXT", aPos.Cp)
if tonumber(_Cp) then
Setting1.Cp = tonumber(_Cp)
end
Setting1.Editor = hDlg:send("DM_GETCHECK", aPos.Editor)==1
Setting1.BOM = hDlg:send("DM_GETCHECK", aPos.BOM)==1
Setting1.OnlyNew = hDlg:send("DM_GETCHECK", aPos.OnlyNew)==1
Setting1.Viewer = hDlg:send("DM_GETCHECK", aPos.Viewer)==1
end
end
local bCont, bFirst=true, false
while bCont do
bCont = false
if Msg == F.DN_INITDIALOG then
hDlg:send(F.DM_LISTGETCURPOS, aPos.List, {SelectPos=1})
Msg = F.DN_LISTCHANGE
Param1 = aPos.List
Param2 = 1
bCont = true
bFirst = true
elseif Msg == F.DN_LISTCHANGE then
if not bFirst then
local iPos=hDlg:send("DM_LISTGETCURPOS", aPos.List).SelectPos
Save(iPos)
end
bFirst = false
local Setting1 = Settings[Param2]
if Setting1 then
hDlg:send("DM_SETTEXT", aPos.Cp, Setting1.Cp)
hDlg:send("DM_SETCHECK", aPos.BOM, Setting1.BOM and 1 or 0)
hDlg:send("DM_SETCHECK", aPos.Editor, Setting1.Editor and 1 or 0)
hDlg:send("DM_SETCHECK", aPos.OnlyNew, Setting1.OnlyNew and 1 or 0)
hDlg:send("DM_ENABLE", aPos.OnlyNew, Setting1.Editor and 1 or 0)
hDlg:send("DM_SETCHECK", aPos.Viewer, Setting1.Viewer and 1 or 0)
else
hDlg:send("DM_SETTEXT", aPos.Cp, '')
hDlg:send("DM_SETCHECK", aPos.BOM, 0)
hDlg:send("DM_SETCHECK", aPos.Editor, 1 )
hDlg:send("DM_SETCHECK", aPos.OnlyNew, 0)
hDlg:send("DM_ENABLE", aPos.OnlyNew, 1)
hDlg:send("DM_SETCHECK", aPos.Viewer, 1)
end
elseif (Msg == F.DN_EDITCHANGE and Param1 == aPos.Cp) or
(Msg == F.DN_DROPDOWNOPENED and Param1 == aPos.Cp and Param2 == 0) then
local _Cp=hDlg:send("DM_GETTEXT", aPos.Cp)
local _Cpm=_Cp:match('%d*')
if _Cpm then
hDlg:send("DM_SETTEXT", aPos.Cp, _Cpm)
end
elseif Msg == F.DN_BTNCLICK then
if Param1 == aPos.Add then
local Mask=far.InputBox('', 'Добавление группы', 'Введите маску файлов')
if Mask then
Save((hDlg:send("DM_LISTGETCURPOS", aPos.List)).SelectPos)
tin(Settings,{Mask=Mask; Editor=true; Viewer=true, OnlyNew=false, Cp=''; BOM=false})
hDlg:send("DM_LISTADDSTR", aPos.List, Mask)
hDlg:send("DM_LISTSETCURPOS", aPos.List, {SelectPos=#Settings})
hDlg:send("DM_SETFOCUS", aPos.Cp)
end
elseif Param1 == aPos.Del then
local iPos=hDlg:send("DM_LISTGETCURPOS", aPos.List).SelectPos
if Settings[iPos].Deleted then
if far.Message("Восстановить настройку?", '', ';YesNo', 'w') == 1 then
Settings[iPos].Deleted = false
local CurrItem=hDlg:send("DM_LISTGETITEM", aPos.List, iPos)
CurrItem.Index=iPos
CurrItem.Flags=F.LIF_NONE
hDlg:send("DM_LISTUPDATE", aPos.List, CurrItem)
LastPos.SelectPos = iPos
hDlg:send("DM_LISTSETCURPOS",aPos.List, {SelectPos=iPos+1})
end
else
if far.Message("Удалить настройку?", '', ';YesNo', 'w') == 1 then
Settings[iPos].Deleted = true
local CurrItem=hDlg:send("DM_LISTGETITEM", aPos.List, iPos)
CurrItem.Index=iPos
CurrItem.Flags=F.LIF_GRAYED
hDlg:send("DM_LISTUPDATE", aPos.List, CurrItem)
hDlg:send("DM_LISTSETCURPOS",aPos.List, {SelectPos=iPos+1})
LastPos = hDlg:send("DM_LISTGETCURPOS",aPos.List)
end
end
elseif Param1 == aPos.F4 then
local Mask=far.InputBox('', 'Редактирование группы', 'Введите маску файлов', nil, Settings[(hDlg:send("DM_LISTGETCURPOS", aPos.List)).SelectPos].Mask)
if Mask then
local iPos=hDlg:send("DM_LISTGETCURPOS", aPos.List).SelectPos
Settings[iPos].Mask=Mask
hDlg:send("DM_SETTEXT", aPos.List, Mask)
end
end
elseif Msg == F.DN_CONTROLINPUT and
Param2.EventType == F.KEY_EVENT then
local Key=far.InputRecordToName(Param2)
if Param1 == aPos.List then
if Key == 'Ins' then
Msg = F.DN_BTNCLICK
Param1 = aPos.Add
bCont = true
elseif Key == 'Del' then
Msg = F.DN_BTNCLICK
Param1 = aPos.Del
bCont = true
elseif Key == 'F4' then
Msg = F.DN_BTNCLICK
Param1 = aPos.F4
bCont = true
elseif Key == 'Alt2' then
hDlg:send("DM_SETFOCUS", aPos.Cp)
end
elseif Key == 'Alt1' then
hDlg:send("DM_SETFOCUS", aPos.List)
end
elseif Msg == F.DN_KILLFOCUS and Param1 == aPos.List then
LastPos = hDlg:send("DM_LISTGETCURPOS", Param1)
elseif Msg == F.DN_GOTFOCUS and Param1 == aPos.List then
hDlg:send("DM_LISTSETCURPOS", aPos.List, LastPos)
elseif Msg == F.DN_CLOSE then
Save((hDlg:send("DM_LISTGETCURPOS", aPos.List)).SelectPos)
end -- case Msg
end -- while bCont
end -- DlgProc
if far.Dialog(win.Uuid"5A39EBF9-4F29-49F2-902D-80F32110773E", -1,-1,w,h,nil,DlgItems,F.FDLG_SMALLDIALOG,DlgProc) == aPos.Ok then
for i=#Settings,1,-1 do
if Settings[i].Deleted then
table.remove(Settings, i)
end
end
mf.msave(SetingKey.Author, SetingKey.Key, Settings)
--far.Message"Внимание!\n\2\nИзменения вступят в силу после перезагрузки макросов!"
else
Settings = mf.mload(SetingKey.Author, SetingKey.Key) or Settings0
end
end -- CodePage_Setup
-----------------------------------------------------------------------------
local function PostMacroStr(cp)
local NeedTab = not (Area.Viewer or Area.QView)
if NeedTab then Keys"Tab" end
Keys("ShiftF8")
if Menu.Select(cp,1) > 0 then Keys("Enter") else Keys("Esc") end
if NeedTab then Keys"Tab" end
end -- PostMacroStr
-----------------------------------------------------------------------------
for _,v in ipairs(Settings) do
if v.Editor then
local EventArg =
{
description="Set " .. v.Cp .. ' codepage for ' .. v.Mask;
group="EditorEvent";
filemask=v.Mask;
action = function(_, Event)
if Event == F.EE_READ then
editor.SetParam(nil, F.ESPT_CODEPAGE, v.Cp)
editor.SetParam(nil, F.ESPT_SETBOM, v.BOM)
-- Прибамбас специально для BAX - начало {
if Editor.FileName:sub(-4):lower()=='.lua' and
not _G.BAX and
mf.fexist(win.GetEnv("FARPROFILE") .. [[\Macros\scripts\Bax\Languages\LuaComplete.lua]]) and
mf.fexist(win.GetEnv("FARPROFILE") .. [[\Macros\modules\BAX\init.lua]]) then
require"BAX"
end
-- Прибамбас специально для BAX - конец }
end
end
}
if v.OnlyNew then
EventArg.condition =
function(_,Event)
return Event == F.EE_READ and band(Editor.State,1) == 1
end
end
Event(EventArg)
end -- if v.Editor
if v.Viewer then
Event {
description="Set " .. v.Cp .. " codepage for View " .. v.Mask;
group="ViewerEvent";
filemask=v.Mask;
action=function(Id,Event,Param)
if Event == far.Flags.VE_READ then
--far.MacroPost(PostMacroStr(v.Cp))
mf.postmacro(PostMacroStr, v.Cp)
end
end;
}
end -- if v.Viewer
end
if math.pi > 0 then nfo.config = CodePage_Setup; end -- Всё равно не работает
Macro{
id=win.Uuid"1467FA0A-CE28-4346-9327-019FC07C42CD";
area="Shell";
key="CtrlShiftB-C";
description="Настройка кодовых страниц";
-- filemask="";
flags=""; -- DisableOutput RunAfterFARStart EmptyCommandLine NotEmptyCommandLine NoFilePanels NoFilePPanels NoPluginPanels NoPluginPPanels NoFolders NoPFolders NoFiles NoPFiles Selection PSelection NoSelection NoPSelection EVSelection NoEVSelection NoSendKeysToPlugins
-- priority=50;
-- sortpriority=50;
-- condition=function(key) return true end;
action=CodePage_Setup;
}
--]===]