Lua에서 neovim 플러그인용 UI를 만드는 방법
이전 문서article를 읽지 않았다면 이 문서를 읽을 것을 적극 권장합니다. 이 문서는 이전 문서의 아이디어를 확장하고 비교할 때 새로운 내용으로 가득 차 있기 때문입니다.
플러그인 창
좋습니다.
oldfiles
목록이 표시될 첫 번째 창을 만드는 함수를 작성하는 것으로 시작해야 합니다. 그러나 먼저 스크립트의 기본 범위에서 탐색 창과 버퍼 참조를 포함하는 buf
및 win
와 탐색을 연 위치를 기억하는 start_win
의 세 가지 변수를 선언합니다. 플러그인 기능에서 자주 사용할 것입니다.-- It's our main starting function. For now we will only creating navigation window here.
local function oldfiles()
create_win()
end
local function create_win()
-- We save handle to window from which we open the navigation
start_win = vim.api.nvim_get_current_win()
vim.api.nvim_command('botright vnew') -- We open a new vertical window at the far right
win = vim.api.nvim_get_current_win() -- We save our navigation window handle...
buf = vim.api.nvim_get_current_buf() -- ...and it's buffer handle.
-- We should name our buffer. All buffers in vim must have unique names.
-- The easiest solution will be adding buffer handle to it
-- because it is already unique and it's just a number.
vim.api.nvim_buf_set_name(buf, 'Oldfiles #' .. buf)
-- Now we set some options for our buffer.
-- nofile prevent mark buffer as modified so we never get warnings about not saved changes.
-- Also some plugins treat nofile buffers different.
-- For example coc.nvim don't triggers aoutcompletation for these.
vim.api.nvim_buf_set_option(buf, 'buftype', 'nofile')
-- We do not need swapfile for this buffer.
vim.api.nvim_buf_set_option(buf, 'swapfile', false)
-- And we would rather prefer that this buffer will be destroyed when hide.
vim.api.nvim_buf_set_option(buf, 'bufhidden', 'wipe')
-- It's not necessary but it is good practice to set custom filetype.
-- This allows users to create their own autocommand or colorschemes on filetype.
-- and prevent collisions with other plugins.
vim.api.nvim_buf_set_option(buf, 'filetype', 'nvim-oldfile')
-- For better UX we will turn off line wrap and turn on current line highlight.
vim.api.nvim_win_set_option(win, 'wrap', false)
vim.api.nvim_win_set_option(win, 'cursorline', true)
set_mappings() -- At end we will set mappings for our navigation.
end
그리기 기능
좋습니다. 창이 생겼으니 이제 표시할 항목이 필요합니다. 이전에 연 파일의 경로를 저장하는 vim
oldfiles
특수 변수를 사용합니다. 스크롤하지 않고 표시할 수 있는 만큼 항목을 가져오지만 물론 스크립트에서 원하는 만큼 가져올 수 있습니다. 탐색 콘텐츠를 새로 고치는 데 사용할 수 있으므로 이 함수redraw
를 호출합니다. 파일 경로는 길 수 있으므로 작업 디렉토리에 상대적으로 만들려고 합니다.local function redraw()
-- First we allow introduce new changes to buffer. We will block that at end.
vim.api.nvim_buf_set_option(buf, 'modifiable', true)
local items_count = vim.api.nvim_win_get_height(win) - 1 -- get the window height
local list = {}
-- If you using nightly build you can get oldfiles like this
local oldfiles = vim.v.oldfiles
-- In stable version works only that
local oldfiles = vim.api.nvim_get_vvar('oldfiles')
-- Now we populate our list with X last items form oldfiles
for i = #oldfiles, #oldfiles - items_count, -1 do
-- We use build-in vim function fnamemodify to make path relative
-- In nightly we can call vim function like that
local path = vim.fn.fnamemodify(oldfiles[i], ':.')
-- and this is stable version:
local path = vim.api.nvim_call_function('fnamemodify', {oldfiles[i], ':.'})
-- We iterate form end to start, so we should insert items
-- at the end of results list to preserve order
table.insert(list, #list + 1, path)
end
-- We apply results to buffer
vim.api.nvim_buf_set_lines(buf, 0, -1, false, list)
-- And turn off editing
vim.api.nvim_buf_set_option(buf, 'modifiable', false)
end
이제 주요 기능을 업데이트할 수 있습니다. 또한 여러 탐색 창을 여는 것을 방지하는 코드를 추가할 것입니다. 이를 위해 플러그인 창이 이미 존재하는지 확인하는
nvim_win_is_valid
를 사용할 수 있습니다.local function oldfiles()
if win and vim.api.nvim_win_is_valid(win) then
vim.api.nvim_set_current_win(win)
else
create_win()
end
redraw()
end
파일 열기
이제 오래된 파일을 볼 수 있지만 열 수 있다면 훨씬 더 편리할 것입니다. 사용자가 5가지 방법으로 파일을 열 수 있습니다! 새 탭, 가로 또는 세로 분할, 현재 창 및 탐색에 초점을 맞추는 미리보기 모드에서.
현재 창에서 파일을 열어 시작하겠습니다. 두 가지 시나리오를 준비해야 합니다.
local function open()
-- We get path from line which user push enter on
local path = vim.api.nvim_get_current_line()
-- if the starting window exists
if vim.api.nvim_win_is_valid(start_win) then
-- we move to it
vim.api.nvim_set_current_win(start_win)
-- and edit chosen file
vim.api.nvim_command('edit ' .. path)
else
-- if there is no starting window we create new from lest side
vim.api.nvim_command('leftabove vsplit ' .. path)
-- and set it as our new starting window
start_win = vim.api.nvim_get_current_win()
end
end
-- After opening desired file user no longer need our navigation
-- so we should create function to closing it.
local function close()
if win and vim.api.nvim_win_is_valid(win) then
vim.api.nvim_win_close(win, true)
end
end
-- Ok. Now we are ready to making two first opening functions
local function open_and_close()
open() -- We open new file
close() -- and close navigation
end
local function preview()
open() -- WE open new file
-- but in preview instead of closing navigation
-- we focus back to it
vim.api.nvim_set_current_win(win)
end
-- To making splits we need only one function
local function split(axis)
local path = vim.api.nvim_get_current_line()
-- We still need to handle two scenarios
if vim.api.nvim_win_is_valid(start_win) then
vim.api.nvim_set_current_win(start_win)
-- We pass v in axis argument if we want vertical split
-- or nothing/empty string otherwise.
vim.api.nvim_command(axis ..'split ' .. path)
else
-- if there is no starting window we make new on left
vim.api.nvim_command('leftabove ' .. axis..'split ' .. path)
-- but in this case we do not need to set new starting window
-- because splits always close navigation
end
close()
end
그리고 결국 새 탭에서 가장 간단한 열기.
local function open_in_tab()
local path = vim.api.nvim_get_current_line()
vim.api.nvim_command('tabnew ' .. path)
close()
end
모든 것이 작동하려면 키 매핑을 추가하고 모든 공용 기능을 내보내고 탐색을 트리거하는 명령을 추가해야 합니다.
local function set_mappings()
local mappings = {
q = 'close()',
['<cr>'] = 'open_and_close()',
v = 'split("v")',
s = 'split("")',
p = 'preview()',
t = 'open_in_tab()'
}
for k,v in pairs(mappings) do
-- let's assume that our script is in lua/nvim-oldfile.lua file.
vim.api.nvim_buf_set_keymap(buf, 'n', k, ':lua require"nvim-oldfile".'..v..'<cr>', {
nowait = true, noremap = true, silent = true
})
end
end
-- at file end
return {
oldfiles = oldfiles,
close = close,
open_and_close = open_and_close,
preview = preview,
open_in_tab = open_in_tab,
split = split
}
command! Oldfiles lua require'nvim-oldfile'.oldfiles()
그리고 그게 다야! 재미있게 놀고 화격자 물건을 만드십시오!
전체 플러그인
local buf, win, start_win
local function open()
local path = vim.api.nvim_get_current_line()
if vim.api.nvim_win_is_valid(start_win) then
vim.api.nvim_set_current_win(start_win)
vim.api.nvim_command('edit ' .. path)
else
vim.api.nvim_command('leftabove vsplit ' .. path)
start_win = vim.api.nvim_get_current_win()
end
end
local function close()
if win and vim.api.nvim_win_is_valid(win) then
vim.api.nvim_win_close(win, true)
end
end
local function open_and_close()
open()
close()
end
local function preview()
open()
vim.api.nvim_set_current_win(win)
end
local function split(axis)
local path = vim.api.nvim_get_current_line()
if vim.api.nvim_win_is_valid(start_win) then
vim.api.nvim_set_current_win(start_win)
vim.api.nvim_command(axis ..'split ' .. path)
else
vim.api.nvim_command('leftabove ' .. axis..'split ' .. path)
end
close()
end
local function open_in_tab()
local path = vim.api.nvim_get_current_line()
vim.api.nvim_command('tabnew ' .. path)
close()
end
local function redraw()
vim.api.nvim_buf_set_option(buf, 'modifiable', true)
local items_count = vim.api.nvim_win_get_height(win) - 1
local list = {}
local oldfiles = vim.api.nvim_get_vvar('oldfiles')
for i = #oldfiles, #oldfiles - items_count, -1 do
pcall(function()
local path = vim.api.nvim_call_function('fnamemodify', {oldfiles[i], ':.'})
table.insert(list, #list + 1, path)
end)
end
vim.api.nvim_buf_set_lines(buf, 0, -1, false, list)
vim.api.nvim_buf_set_option(buf, 'modifiable', false)
end
local function set_mappings()
local mappings = {
q = 'close()',
['<cr>'] = 'open_and_close()',
v = 'split("v")',
s = 'split("")',
p = 'preview()',
t = 'open_in_tab()'
}
for k,v in pairs(mappings) do
vim.api.nvim_buf_set_keymap(buf, 'n', k, ':lua require"nvim-oldfile".'..v..'<cr>', {
nowait = true, noremap = true, silent = true
})
end
end
local function create_win()
start_win = vim.api.nvim_get_current_win()
vim.api.nvim_command('botright vnew')
win = vim.api.nvim_get_current_win()
buf = vim.api.nvim_get_current_buf()
vim.api.nvim_buf_set_name(0, 'Oldfiles #' .. buf)
vim.api.nvim_buf_set_option(0, 'buftype', 'nofile')
vim.api.nvim_buf_set_option(0, 'swapfile', false)
vim.api.nvim_buf_set_option(0, 'filetype', 'nvim-oldfile')
vim.api.nvim_buf_set_option(0, 'bufhidden', 'wipe')
vim.api.nvim_command('setlocal nowrap')
vim.api.nvim_command('setlocal cursorline')
set_mappings()
end
local function oldfiles()
if win and vim.api.nvim_win_is_valid(win) then
vim.api.nvim_set_current_win(win)
else
create_win()
end
redraw()
end
return {
oldfiles = oldfiles,
close = close,
open_and_close = open_and_close,
preview = preview,
open_in_tab = open_in_tab,
split = split
}
Reference
이 문제에 관하여(Lua에서 neovim 플러그인용 UI를 만드는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/2nit/how-to-make-ui-for-neovim-plugins-in-lua-3b6e텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)