Почти всё переписал. Многое упростилось, сказывается опыт. Стало точнее, но новых возможностей пока почти нет, потому что хочу выйти на уровень, который называют продуктом. Ближайший план: сделать меню по предложению ув. Ann и перейти, наверное, на поиск слов вручную, минуя F7. Чтобы не мешать ручные и автоматические настройки поиска. Вообще, поиск, это то, куда хочу углубиться. Очередная замена обычному поиску грядёт...
---------------------
Пока вместо настоящего меню советую вызывать MacroBrowser. У меня это делает макрос Ctrl`.lua. Меню mbrowser довольно наглядное, можно нажать Ctrl+H, чтобы отображались только те макросы, которые работают в действующем окружении. Там есть справка и сортировки.
---------------------
Чего бы хотелось здесь: обсуждение этого кода и особенно — его применения. Мнения тех, кто не читал и не использовал, странны, а приговоры автору невозможны. То есть тут критики сообщают что-то о себе, что я постараюсь забыть, я умею. Наоборот, даже просто ощущения и общее мнение об использовании тут уместны. Баг репорты не требуются, уж как-нибудь сам пока. Могу помочь написать что-то.
Но всем спасибо за обсуждения. Они порождают идеи. Теперь я записываю замечания к системе, чтобы когда-то их оформить в bug report. Даже жаль, что многое не помню, с чем сначала мучился. Это важный для отладки среды опыт.
1. Несколько скриптов для замены не вполне совершенных из %FARHOME%\Addons\Macros. На сей раз вполне отлаженных и двуязычных.
ShiftBS.lua Shell.AltBS.lua Shell.Alt=.lua
Сразу их код для тех, кто ставить не будет, но почитал бы (я бы так сделал):
-- coding: utf-8
-- Устанавливает папку неактивной панели как у активной, указывает на тот же файл.
-- Работает для погашенной или не файловых панелей.
local MSG = { { 'same inactive panel' }, Rus = { 'та же папка рядом' }, }
local LNG = Far.GetConfig('Language.Help').sub(1, 3); MSG = MSG[LNG] and MSG[LNG] or MSG[1] -- Язык определяется однажды при загрузке макроса.
Macro { key = 'Alt='; area = 'Shell'; description = MSG[1]; action = function()
if not APanel.Visible or APanel.Current:len() <= 0 then return end
local path = far.ConvertPath(APanel.Current)
Panel.SetPath(1, mf.fsplit(path, 1 + 2), mf.fsplit(path, 4 + 8))
if not PPanel.Visible then Keys('CtrlQ')
end -- Не знаешь что делать с панелью? Жми Ctl+Q, пока не заработает!
for _ = 1, 2 do if not PPanel.FilePanel then Keys('CtrlQ') end
end
end
}
-- coding: utf-8
local MSG = { { 'folder back' }, Rus = { 'назад в папку' }, }
local LNG = Far.GetConfig('Language.Help').sub(1, 3); MSG = MSG[LNG] and MSG[LNG] or MSG[1] -- Язык определяется однажды при загрузке макроса.
local altbs
Macro { key = 'AltBS'; area = 'Shell'; description = MSG[1]; action = function()
Keys('AltF12')
altbs = Object.CurPos == Object.ItemCount and not altbs
Keys((altbs and '' or 'Up')..' ShiftEnter')
end
}
-- coding: utf-8
local MSG = { { 'Xlat' }, Rus = { 'Xlat: QWERTY-ЙЦУКЕН выделения или слова и смена языка ввода ОС' }, }
local LNG = Far.GetConfig('Language.Help').sub(1, 3); MSG = MSG[LNG] and MSG[LNG] or MSG[1] -- Язык определяется однажды при загрузке макроса.
Macro { key = 'ShiftBS'; area = 'Common'; description = MSG[1]; action = function()
if not Object.Selected then
Keys('SelWord')
end
Keys('Xlat')
mf.xlat('0', 1)
end
}
-- Для предсказуемой работы xlat можно запустить из командной строки far:config и скопировать ограничители слов редактора
-- Editor.WordDiv в соответствующую настройку xlat — XLat.WordDivForXlat, не забыв, правда, оставить пробелы в начале этой настройки xlat.
-- Например, такие знаки (без скобок) [[ ~!%^&*()+|{}:"<>?`-=\[];',./]].
2. Скрипт jr.typographic.lua для замены Юникод мнемоник в тексте и для быстрого ввода употребительных, но сложных для набивки знаков, вроде «» или Σ. Полностью локализуется. Но он уже с моими модулями, недостаточно скопировать один файл скрипта.
3. F5.lua, улучшенная замена одноимённого скрипта Editor.ColorWord.moon из %FARHOME%\Addons. Двуязычный.
4. Моя раскладка клавиш и всякая вкуснота в редакторе. Пока только по-русски. Там работа с Colorer, перестановки строк, работа с колоночным блоком, переходы по слову.
jr.F4.Rus.lua
5. Для тех, кому ничего сложного не надо, своё есть, маленький модуль с усовершенствованиями среды LuaFAR.
-- coding: utf-8; tab 8
--[[debug]]local function bbb(o, t) Menu.Show(mf.serialize(o):gsub('&', '&&'), t and tostring(t) or '') return o end--]]
function aboriginal (p) -- Процедура, которая упрощает синтаксис настроек языка. Без local, return, { } и пр.
local lng = Far.GetConfig('Language.Help'):sub(1, 3) -- Для неописанных возможностей уместнее язык справки. 3 знака!
local f = mf.fsplit(p, 1 + 2 + 4) .. '\\' .. (lng or 'def') -- Если метка языка не даёт файл, то файл def там же.
local fh = io.open(f)
fh = fh or io.open(mf.fsplit(p, 1 + 2 + 4) .. '\\' .. 'def') -- Настройки в файле path(p)\name(p)\lng
if not fh then return end
f = fh:read(99999) fh:close()
f = loadstring(f)
if not f then return end
local r = {} -- Глобальные переменные файла настроек попадут в таблицу r.
setfenv(f, r)
f(lng)
return r end -- aboriginal (p)
function align (s, t, w, x) if type(w) ~= 'number' then return end -- Повторы строки x между строками s и t усечёные до длины w.
if type(s) ~= 'string' then s = s and tostring(s) or '' end -- s и t не усекаются. Если нет x, x = пробелы.
if type(t) ~= 'string' then t = t and tostring(t) or '' end -- Если w < 0, то x повторяется без усечения и хотя бы раз.
local n = math.abs(w) - s:len() - t:len() -- Тогда длина итога ≤ -w: s и x (1 и более раз) и t.
if type(x) ~= 'string' then x = x and tostring(x) or (' '):rep(n) end -- Использовать:
if n <= 0 then return w < 0 and s .. x .. t or s .. t end -- align('AAA', 'bbb', 5) [AAAbbb].
if x:len() ~= n and 0 < x:len() then -- align('AAA', 'bbb', 10) [AAA bbb].
if w < 0 then -- align('AAA', '', 10, '123') [AAA1231231].
x = x:rep(math.floor(n/x:len())) -- align(nil, nil, 10, -123) [-123-123-1].
else x = x:rep(math.ceil(n/x:len())):sub(1, n) -- align('%', '%%', -2, -123) [%-123%%].
end -- align('%', '%%', -10, '123') [%123123%%].
end -- align('', '', -10, true) [truetrue].
return s .. x .. t end -- align('', '', 10, true) [truetruetr].
function pad (s, w, x) if type(w) ~= 'number' then return end -- Добавляю повторы строки x к s, чтобы увеличить общую длину до w.
return w < 0 and align('', s, -w, x) or align(s, '', w, x) end -- Если w положительно, то s слева, отрицательно — справа.
function iformat (how, ...) local argv = { ... } -- Стиль Java. Метки преобразования string.format. Если номер арг. не указан, то как прежде.
local function f(p, i, o) i = tonumber(i) return argv[i] and (p .. o):format(argv[i]) or '' end
return how:gsub('%f[%%](%%)(%d+)$([-+]?%d*%.?%d*[A-Za-z])', f):format(...) end -- Пример: 'Второй аргумент %2$s поставлен перед первым %1s.'
function cliche (how, argt) -- Предпочёл стиль Format C#, так как он сильнее отличается от Regexp.
local function f(k) return (k:match('^(%d+)$') and argt[tonumber(k)]) or argt[k] or '' end
return how:gsub('%f[{]{([%w_]+)}', f):gsub('{{', '{') end -- {{ — экранирование {. Todo: пока тупое экранирование { и нет меток преобразования аргументов.
--Примеры:
--msgbox(iformat('(5): %5$-10.10s, (4): %4$-3.3s, (3): %3$8f, (2): %2$s (1): %1$s.', '1AA', '2bb', math.pi, '4looooooong', '5sht'))
--msgbox(cliche('(5): {5}, (4): {4}, (3): {3}, (2): {2} (1): {1}.', { '1AA', '2bb', math.pi, '4looooooong', '5sht'), })
--msgbox(cliche('{{X}} (E): {{{E}}, (D): {D}, (1): {1}, (B): {B} (A): {A}.', { A = 'AAA', B = 'Bbb', math.pi, D = 'Dlooooooong', E = 'Esht', }))
-- get default metatable for strings:
function nocasepatternof (t)
return t:gsub('.', function (c) local u, l = c:upper(), c:lower() return u == l and c or '['..u..l..']' end) end
--msgbox(NoCasePatternOf('-- Привет!'))
--EOT /16.02.2021 (o) Дмитрий Журко. Я старался. dm.jurko@gmail.com Сбер 4276 2007 2491 8425
Чтобы установить макрос его надо поместить в файл с кодировкой utf-8 и расширением ".lua". Этот файл надо поместить в папку %FARLOCALPROFILE%\Macros\scripts\ и дать команду "macro: load" в командной строке.
Если скрипт ещё и загружает модуль, то файл с текстом модуля надо поместить в папку %FARLOCALPROFILE%\Macros\modules\