*UNDER CONSTRUCTION*

vis-korea-ime 포팅하기 P2

created:
updated:
<a>

vis-korea-ime 포팅하기(이전 아티클)

Info

알려진 문제

문제가 있다면.. vis에서는 입력 모드 (INSERT, NORMAL, etc.)를 명령 입력 모달에서도 적용하는지라, 자꾸 :w 대신 :ㅈ 을 입력해 버린다든가 하는 마이너한(아님) 문제가 있습니다…. ㅎㅎ
해결하려고 vis API를 뒤져보고 있습니다만…. 아직은 잘 모르겠네요….

해결 방식?

하나 생각해 낸 방식은 입력 영역이 Window[↗] 로 구분되기 때문에, 아래와 같이 window의 테이블 아이디를 받아와 window마다 모드를 저장하는 방식입니다. n

M.mode = {}

local function get_win_mode()
    if M.mode[tostring(vis.win)] == nil then
        M.mode[tostring(vis.win)] = "en"
    end
    return M.mode[tostring(vis.win)]
end

local function set_win_mode(mode)
    M.mode[tostring(vis.win)] = mode
end

하지만 문제는, 명령 입력 영역은 : 를 누를 때마다 새로 생성되기 때문에, 계속해서 테이블이 커지는 것이 문제입니다.

주기적으로 현재 window를 제외한 M.mode 테이블을 리셋한다면, 한 번에 여러 window가 열려있을 때 나머지가 리셋되는 문제가 생깁니다.

문제

첫 번째 포스팅에서 한글 입력이 명령 입력 영역에서도 유지되어 원하는 커맨드를 작성하지 못하게 되는 뭊제가 있헜고, 그걸 창마다 IM을 분리하는 방식으로 해결하려고 했습니다.

그러나 명령 입력 영여역의 window는 매번 새로 생성되기에, 이것을 table에 저장한다면 찌꺼기가 계속 남을 것이라는 문제가 있습니다.

일정 시간/이벤트 마다 table을 리셋한다면, 한번에 두개 이상의 윈도우가 열려있을떄 다릉ㄴ 윈도우의 IM이 ㄹ이셋되는 문제가 생겼습니다.

해결 방법

그렇게 vis api를 읽고, 여러 이벤트나 명령을 테스트 하던 와중, win_open/win_close 이벤트가 며열ㅇ 입력 영역의 window에 대해서는 발생하지 않는다는 것을 알아냈습니다.

윈도우마다 IM를 저장하고, win_open/win_close를 이용해 열려있는 window를 추적하고 일정 이벤트마다 추적된 열려있는 window를 제외한 window의 IM을 지우는 방법을 택했습니다.


local window_list = {}
M.mode = {}

local function refresh_win_modes()
    local new_mode = {}
    for k,v in pairs(M.mode) do
        if has_value(window_list, k) then
            new_mode[k] = v
        end
    end
    M.mode = new_mode
end

...

vis.events.subscribe(vis.events.WIN_OPEN, function(win)
    if not has_value(window_list, tostring(win)) then
        table.insert(window_list, tostring(win))
    end
end)
vis.events.subscribe(vis.events.WIN_CLOSE, function(win)
    array_remove(window_list, tostring(win))
end)

현재 집중된 window가 변화할 때 마다 새로고침을 하도록 하였습니다.

local last_pos
local last_win
local last_mode = vis.mode
vis.events.subscribe(vis.events.UI_DRAW, function()
    local win = vis.win

    if last_win ~= tostring(win) then -- Win Moved
        last_win = tostring(win)

        refresh_win_modes()
    end
...

Status Bar

아래같은 방식으로 statusbar에 현재 상태를 나타낼 수 있습니다.

local ime = "[EN]"
if korea_ime.get_mode(win) == "en" then
    ime = "[EN]"
elseif korea_ime.get_mode(win) == "ko" then
    ime = "[KO]"
end

...

win:status(..., ... ime ...)
Figure 1: 분리된 window에 개별적으로 설정된 IM

Figure 1: 분리된 window에 개별적으로 설정된 IM

Webmentions(?)

Q. Why isn't my webmention not appearing?

A. I deploy this site not so often and this site is static site. So don't expect your webmention to appear instantly. Thanks for the webmention and sorry for the inconvenience.
last deployed: see footer