Page 2 of 4

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Wed 10 Oct, 2012 20:30
by Shmuel

Latest post of the previous page:

SUSim wrote:я спрашивал не про строки а про библиотеку string.
Библиотека string - не юникодная.
Если пользоваться двоеточием вместо точки - будут использоваться функции из unicode.utf8.

Примеры:

Code: Select all

string.sub(text,5,10) -- получить подстроку от 5 до 10 байта (длина = 6 байт)
text:sub(5,10)        -- получить подстроку от 5 до 10 символа (длина = 6 символов)
text = "Привет"
print(#text)            --> 12
print(string.len(text)) --> 12
print(text:len())       --> 6

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Sun 14 Oct, 2012 19:10
by Max Rusov
Какая то непоследовательность в работе со строками, не кажется?

Code: Select all

s = "Привет, мир!"
msgbox(s, "Len=" .. s:len() .. ", index=" .. s:find("!"))

Code: Select all

╔══ Привет, мир! ══╗
║ Len=12, index=21 ║
╟──────────────────╢
║      { OK }      ║
╚══════════════════╝

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Sun 14 Oct, 2012 19:23
by Aidar
Max Rusov wrote:Какая то непоследовательность в работе со строками, не кажется?

Code: Select all

s = "Привет, мир!"
msgbox(s, "Len=" .. s:len() .. ", index=" .. s:find("!"))

Code: Select all

╔══ Привет, мир! ══╗
║ Len=12, index=21 ║
╟──────────────────╢
║      { OK }      ║
╚══════════════════╝
Функция find возвращает позицию в байтах.
Это сделано намеренно, т.к. часто интересует не позиция подстроки, а её наличие в строке. Нужно использовать функцию cfind:

Code: Select all

s:cfind("!")

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Sun 14 Oct, 2012 19:26
by Skirda
Тогда, по аналогии, должно быть clen, а то как то нелогично получается.

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Sun 14 Oct, 2012 19:28
by zg
стырено с lua4ed. в автостартующем макросе:

Code: Select all

local function FixFindFunction()
  local usub, ssub = unicode.utf8.sub, string.sub
  local ulen, slen = unicode.utf8.len, string.len
  local ufind = unicode.utf8.find
  unicode.utf8.find = function(s, patt, init, plain)
    init = init and slen(usub(s, 1, init-1)) + 1
    local t = { ufind(s, patt, init, plain) }
    if t[1] == nil then return nil end
    return ulen(ssub(s, 1, t[1]-1)) + 1, ulen(ssub(s, 1, t[2])), unpack(t, 3)
  end
end
FixFindFunction()

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Sun 14 Oct, 2012 19:30
by zg
Aidar wrote:Нужно использовать функцию cfind
её нет.

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Sun 14 Oct, 2012 19:45
by Aidar
zg wrote:стырено с lua4ed. в автостартующем макросе: ...
Не стоит заменять функцию, т.к. эта замена будет действовать для всех макросов, скриптов и плагинов на Lua.
zg wrote:
Aidar wrote:Нужно использовать функцию cfind
её нет.
Поэтому нужно добавить её, пока Shmuel не добавил официально.

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Sun 14 Oct, 2012 19:50
by Aidar
Skirda wrote:Тогда, по аналогии, должно быть clen, а то как то нелогично получается.
Для получения длины строки в байтах есть string.len(s).
Проблема в том, что cfind медленнее, чем find. Посмотрите как она реализуется: приходится использовать slen, ssub (дважды), ulen и unpack.
Если же нужно просто проверить наличие подстроки в строке, то использование cfind будет неоправданным, хватит и обычной find.
За всё время написания скриптов на Lua cfind понадобился мне только один раз. В остальных случаях использовал sub, match, gsub и gmatch.

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Sun 14 Oct, 2012 19:51
by Shmuel
Max Rusov wrote:Какая то непоследовательность в работе со строками, не кажется?
Есть такое дело, так устроена функция unicode.utf8.find, которая неявно вызывается - она возвращает смещения в байтах. Вышеупомянутая cfind есть в плагине LuaFAR for Editor - наверное есть смысл её и в LuaMacro скопировать, тогда она будет сразу "из коробки", это лучше, чем автостартующий макрос, наверное.

Есть ещё вариант: использовать функцию regex.find - она уже "в коробке", только иметь в виду, что синтаксис другой, а именно, такой как в F7 в редакторе.

P.S. Как уже сказал Aidar, надобность получать эти смещения возникает крайне редко.

P.P.S. Добавил cfind.

Почему не работает макрос c os.execute

Posted: Wed 28 Jan, 2015 12:30
by Max Rusov

Code: Select all

Macro 
{ 
  description="Open explorer..."; area="Shell Tree"; key="AltEnter";

  action=function()
    os.execute( "explorer /select," .. APanel.Path .. "\\" .. APanel.Current )
  end;
}
Макрос не работает на файлах с русскими именами.
1. Это ошибка или так и должно быть?
2. Если не ошибка - то как поправить, чтобы работал?

Почему не работает макрос c os.execute

Posted: Wed 28 Jan, 2015 12:46
by Shmuel
Max Rusov wrote: 1. Это ошибка или так и должно быть?
Это не ошибка. os.execute - не юникодная функция.
Max Rusov wrote: 2. Если не ошибка - то как поправить, чтобы работал?
Либо передавать аргумент в OEM ANSI, либо использовать win.ShellExecute, которая поддерживает юникод.

Почему не работает макрос c os.execute

Posted: Wed 28 Jan, 2015 13:02
by Max Rusov
Спасибо, с ShellExecute заработало. А по поводу os.execute - не может ли макродвижек автоматически делать преобразование строки при вызове таких функций?

Почему не работает макрос c os.execute

Posted: Wed 28 Jan, 2015 13:37
by Shmuel
Max Rusov wrote: по поводу os.execute - не может ли макродвижек автоматически делать преобразование строки при вызове таких функций?
Есть уже виш на мантисе по поводу os.execute. Но надо иметь в виду, что эти преобразования всё равно не сделают функцию юникодной, в случае русских букв будет работать, а вот, к примеру, широкое тире или какой-нибудь иероглиф правильно не преобразуются.

Сейчас проверил - всё-таки надо ANSI, а не OEM:

Code: Select all

function os.myexecute(s)
  s = win.Utf8ToUtf16(s)
  s = win.WideCharToMultiByte(s, win.GetACP())
  return os.execute(s)
end

Почему не работает макрос c os.execute

Posted: Wed 28 Jan, 2015 16:34
by John Doe
Shmuel wrote: Но надо иметь в виду, что эти преобразования всё равно не сделают функцию юникодной
Хочу уточнить: я заводил тот тикет в расчёте, что os.execute в итоге станет юникодной.
Или это проблематично?

Почему не работает макрос c os.execute

Posted: Wed 28 Jan, 2015 16:44
by Shmuel
John Doe wrote: Или это проблематично?
Насколько проблематично, пока не смотрел, т.к. не было надобности в os.execute.
Допустим, она уже юникодная, есть пример применения?

Почему не работает макрос c os.execute

Posted: Wed 28 Jan, 2015 17:14
by John Doe
Применять везде, где требуется запуск консольных утилит в консоли фара (win.ShellExecute не подходит, т.к. умеет запускать только в отдельном окне).

Например http://forum.farmanager.com/viewtopic.php?f=60&t=8546

Почему не работает макрос c os.execute

Posted: Wed 28 Jan, 2015 18:22
by Shmuel
Добавлена функция win.system.