Юникод в LuaFAR

Здесь обсуждается всё, что касается макросов.
Shmuel
Posts: 6819
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 528 times

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

Post 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
Max Rusov
Posts: 3651
Joined: Wed 23 Nov, 2005 11:11
Location: Москва-Питер
Has thanked: 2 times
Been thanked: 19 times

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

Post by Max Rusov »

Какая то непоследовательность в работе со строками, не кажется?

Code: Select all

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

Code: Select all

╔══ Привет, мир! ══╗
║ Len=12, index=21 ║
╟──────────────────╢
║      { OK }      ║
╚══════════════════╝
User avatar
Aidar
Posts: 541
Joined: Mon 09 Mar, 2009 22:43
Location: Kazan
Has thanked: 8 times
Been thanked: 7 times
Contact:

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

Post 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("!")
User avatar
Skirda
Posts: 3475
Joined: Wed 16 Mar, 2005 11:01
Been thanked: 8 times

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

Post by Skirda »

Тогда, по аналогии, должно быть clen, а то как то нелогично получается.
We are the Borg. You will be assimilated.
So Say We All!
User avatar
zg
zero-gravity
Posts: 6016
Joined: Tue 15 Mar, 2005 17:36
Location: riga
Been thanked: 185 times
Contact:

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

Post 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()
User avatar
zg
zero-gravity
Posts: 6016
Joined: Tue 15 Mar, 2005 17:36
Location: riga
Been thanked: 185 times
Contact:

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

Post by zg »

Aidar wrote:Нужно использовать функцию cfind
её нет.
User avatar
Aidar
Posts: 541
Joined: Mon 09 Mar, 2009 22:43
Location: Kazan
Has thanked: 8 times
Been thanked: 7 times
Contact:

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

Post by Aidar »

zg wrote:стырено с lua4ed. в автостартующем макросе: ...
Не стоит заменять функцию, т.к. эта замена будет действовать для всех макросов, скриптов и плагинов на Lua.
zg wrote:
Aidar wrote:Нужно использовать функцию cfind
её нет.
Поэтому нужно добавить её, пока Shmuel не добавил официально.
User avatar
Aidar
Posts: 541
Joined: Mon 09 Mar, 2009 22:43
Location: Kazan
Has thanked: 8 times
Been thanked: 7 times
Contact:

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

Post by Aidar »

Skirda wrote:Тогда, по аналогии, должно быть clen, а то как то нелогично получается.
Для получения длины строки в байтах есть string.len(s).
Проблема в том, что cfind медленнее, чем find. Посмотрите как она реализуется: приходится использовать slen, ssub (дважды), ulen и unpack.
Если же нужно просто проверить наличие подстроки в строке, то использование cfind будет неоправданным, хватит и обычной find.
За всё время написания скриптов на Lua cfind понадобился мне только один раз. В остальных случаях использовал sub, match, gsub и gmatch.
Shmuel
Posts: 6819
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 528 times

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

Post by Shmuel »

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

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

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

P.P.S. Добавил cfind.
Max Rusov
Posts: 3651
Joined: Wed 23 Nov, 2005 11:11
Location: Москва-Питер
Has thanked: 2 times
Been thanked: 19 times

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

Post 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. Если не ошибка - то как поправить, чтобы работал?
Shmuel
Posts: 6819
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 528 times

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

Post by Shmuel »

Max Rusov wrote: 1. Это ошибка или так и должно быть?
Это не ошибка. os.execute - не юникодная функция.
Max Rusov wrote: 2. Если не ошибка - то как поправить, чтобы работал?
Либо передавать аргумент в OEM ANSI, либо использовать win.ShellExecute, которая поддерживает юникод.
Max Rusov
Posts: 3651
Joined: Wed 23 Nov, 2005 11:11
Location: Москва-Питер
Has thanked: 2 times
Been thanked: 19 times

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

Post by Max Rusov »

Спасибо, с ShellExecute заработало. А по поводу os.execute - не может ли макродвижек автоматически делать преобразование строки при вызове таких функций?
Shmuel
Posts: 6819
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 528 times

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

Post 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
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

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

Post by John Doe »

Shmuel wrote: Но надо иметь в виду, что эти преобразования всё равно не сделают функцию юникодной
Хочу уточнить: я заводил тот тикет в расчёте, что os.execute в итоге станет юникодной.
Или это проблематично?
Shmuel
Posts: 6819
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 528 times

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

Post by Shmuel »

John Doe wrote: Или это проблематично?
Насколько проблематично, пока не смотрел, т.к. не было надобности в os.execute.
Допустим, она уже юникодная, есть пример применения?
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

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

Post by John Doe »

Применять везде, где требуется запуск консольных утилит в консоли фара (win.ShellExecute не подходит, т.к. умеет запускать только в отдельном окне).

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

Return to “Обсуждение макросов”