Pop Out Panel of Custom user mode
- For vim user: VimL version code (see README.VimL.md or old branch) is still kept and disabled for Neovim by default.
 
Popc is to display a panel and handle all input keys inside an usermode.
Install:
-- e.g. with lazy.nvim:
{
    'yehuohan/popc',
    config = function()
        require('popc').setup(opts)
    end,
    event = 'VeryLazy'
},Default options:
opts = {
    debug = false,
    data_path = vim.fn.stdpath('data'),
    auto_setup_highlights = true, -- Add ColorScheme event for highlights
    root_marker = { '.git' }, -- Detect root path for tabuf and workspace panel
    icons = {
        -- Require a nerd font by default
        popc = '',
        tabuf = '',
        bookmark = '',
        workspace = '',
        focus = '▪',
        win = '▫',
        tab = '',
        tab_scope = { '(', '╭', '│', '╰' },
        tab_focus = { '[', '┏', '┃', '┗' },
        tlbuf = '', -- Tabline buffer icon
        tltab = '', -- Tabline tabpage icon
        pointer = '',
        select = '',
        dots = '…',
        pads = { '', '' },
        nums = { '⁰', '¹', '²', '³', '⁴', '⁵', '⁶', '⁷', '⁸', '⁹' },
    },
    usermode = {
        input = nil, -- Support: 'snacks'
        win = {
            zindex = 1000,
            border = vim.o.winborder, -- Support: 'none', 'single', 'double', 'rounded'
            number = true,
        },
        -- Usermode's keys is the first priority handler
        keys_number = 'jump', -- Jump to the pressed number item (disable with false)
        keys_panels = { -- Jump between panels (only support 'tabuf', 'bookmark', 'workspace')
            -- Set false to disable key
            ['h'] = 'tabuf',
            ['b'] = 'bookmark',
            ['w'] = 'workspace',
        },
        keys = {
            -- Set false to disable key
            ['<Esc>'] = 'quit',
            ['q'] = 'back',
            ['?'] = 'help',
            ['j'] = 'next', -- Goto next line
            ['k'] = 'prev', -- Goto Previous line
            ['<M-j>'] = 'next_page', -- Goto next page
            ['<M-k>'] = 'prev_page', -- Goto previous page
            ['J'] = 'bottom', -- Goto bottom line
            ['K'] = 'top', -- Goto top line
        },
    },
    tabuf = { ... }, -- See `Tabuf` section
    workspace = { ... }, -- See `Workspace` section
    bookmark = { ... }, -- See `Bookmark` section
    selection = { ... }, -- See `Selection` section
}Highlights for usermode:
PopcFloat: Floating window normalPopcFloatBorder: Floating window borderPopcFloatTitle: Floating window titlePopcFloatTitleBar: Floating window title bar for panel namePopcFloatTitleBarSep: Highlight between floating title and barPopcFloatTitleBarPad: Highlight between floating title and borderPopcFloatSelect: Floating selection indicator
Tabuf panel can track all buffers and tabpages automatically. And display hierarchical buffers and tabpages to floating panel and tabline.
Tabuf commands:
PopcTabuf: Pop outTabufpanelPopcTabufResetTabline: Reset tabline ofTabufpanelPopcBufferSwitchLeft: Switch to left buffer of current tabpage (works withopts.tabuf.tabline = true)PopcBufferSwitchRight: Switch to right buffer of current tabpage (works withopts.tabuf.tabline = true)PopcBufferSwitchLeftandPopcBufferSwitchRightsupportv:count1, e.g.:3PopcBufferSwitchLeftwill switch to the 3th left bufferPopcBufferSwitchLeftandPopcBufferSwitchRightsupport bang, e.g.:PopcBufferSwitchLeft!will switch the last accessed window's buffer to left buffer
PopcBufferJumpPrev: Jump to previous jumplist location of current bufferPopcBufferJumpNext: Jump to next jumplist location of current bufferPopcBufferJumpPrevandPopcBufferJumpNextsupportv:count1, e.g.:3PopcBufferJumpPrev!will jump to 3th previous jumplist location
PopcBufferClose: Close current buffer with window kept
Default options:
opts.tabuf = {
    enable = true,
    tabline = true,
    exclude_buffer = function(bid)
        if vim.tbl_contains({ 'Popc', 'qf' }, vim.fn.getbufvar(bid, '&filetype')) then
            return true
        end
    end,
    keys = {
        -- Set false to disable key
        ['h'] = 'pop_buffers',
        ['l'] = 'pop_tabpages',
        ['a'] = 'pop_tabpage_buffers',
        ['<CR>'] = 'load_buffer_or_tabpage_quit', -- Load buffer into current window of current tabpage, then quit panel
        ['<Space>'] = 'load_buffer_or_tabpage',
        ['<S-CR>'] = 'goto_buffer_or_tabpage_quit', -- Goto buffer of corresponding window and tabpage, then quit panel
        ['<S-Space>'] = 'goto_buffer_or_tabpage',
        ['f'] = 'focus_on_window',
        ['s'] = 'split_buffer_quit',
        ['S'] = 'split_buffer',
        ['v'] = 'vsplit_buffer_quit',
        ['V'] = 'vsplit_buffer',
        ['t'] = 'tabnew_buffer_quit',
        ['T'] = 'tabnew_buffer',
        ['c'] = 'close_buffer_or_tabpage', -- Keep windows layout
        ['C'] = 'close_all_buffers_or_tabpages', -- Keep windows layout
        ['d'] = 'close_window', -- Only close window
        ['D'] = 'close_window_and_buffer', -- Also close window along with buffer
        ['i'] = 'switch_to_prev_tabpage',
        ['o'] = 'switch_to_next_tabpage',
        ['I'] = 'move_buffer_or_tabpage_to_prev', -- Move buffer or tabpage to previous (the selected item index follows buffer)
        ['O'] = 'move_buffer_or_tabpage_to_next',
        ['<M-i>'] = 'move_out_buffer_or_tabpage_to_prev', -- Move buffer or tabpage to previous (the selected item index keeps unchanged)
        ['<M-o>'] = 'move_out_buffer_or_tabpage_to_next',
        ['n'] = 'set_tabpage_label', -- Set tabpage label (also show at tabline, input empty string means delete label)
        ['r'] = 'set_tabpage_dir', -- Set tabpage directory (input empty string means delete dir, support expand environment variables)
        ['p'] = 'toggle_fullpath',
    },
}Highlights for Tabuf tabline:
PopcTlBar: Bar to indicate tabpage or bufferPopcTlNormal: Normal tabpage or bufferPopcTlCurrent: Current tabpage or bufferPopcTlModified: Tabpage or buffer has modificationPopcTlCurrentModified: Current tabpage or buffer has modificationPopcTl<XXX>Pad: Padding for bar/tabpage/buffer
Workspace panel is mainly for saving/loading vim sessions along with user data.
Workspace commands:
PopcWorkspace: Pop outWorkspacepanel
Default options:
opts.workspace = {
    enable = true,
    keys = {
        -- Set false to disable key
        ['<CR>'] = 'open_workspace', -- Open workspace: drop all original tabpages and buffers
        ['t'] = 'load_workspace', -- Load workspace: keep original tabpages and buffers
        ['a'] = 'append_workspace', -- Append a new workspace
        ['d'] = 'delete_workspace', -- Delete the seleted  workspace
        ['s'] = 'save_workspace', -- Override the same workspace
        ['S'] = 'save_workspace_forcely', -- Override the seleted workspace forcely
        ['n'] = 'set_workspace_name',
        ['r'] = 'set_workspace_root',
        ['g'] = 'sort_workspace',
    },
}Save/load user data:
vim.api.nvim_create_augroup('MyWks', { clear = true })
vim.api.nvim_create_autocmd('User', {
    group = 'MyWks',
    pattern = 'PopcWorkspaceSavePre',
    callback = function()
        require('popc.panel.workspace').cmd_set_userdata({
            -- Save user data here
        })
    end,
})
vim.api.nvim_create_autocmd('User', {
    group = 'MyWks',
    pattern = 'PopcWorkspaceLoaded',
    callback = function()
        -- Load user data here
        local userdata = require('popc.panel.workspace').cmd_get_userdata()
    end,
})Bookmark panel is a convenient container of bookmark files.
Bookmark commands:
PopcBookmark: Pop outBookmarkpanel
Default options:
opts.Bookmark = {
    enable = true,
    keys = {
        -- Set false to disable key
        ['<CR>'] = 'load_bookmark_quit',
        ['<Space>'] = 'load_bookmark',
        ['s'] = 'split_bookmark_quit',
        ['S'] = 'split_bookmark',
        ['v'] = 'vsplit_bookmark_quit',
        ['V'] = 'vsplit_bookmark',
        ['t'] = 'tabnew_bookmark_quit',
        ['T'] = 'tabnew_bookmark',
        ['a'] = 'append_bookmark', -- Append current buffer as bookmark
        ['d'] = 'delete_bookmark',
        ['g'] = 'sort_bookmark',
    },
}
Selectionis a replacement of popset
Selection panel is to provide selections for setting vim options, executing function with args and so on.
(Selection panel is disabled by default and enable with opts.selection.enable = true)
Selection functions:
require(popc).pop_selection([PopSelection])
--- @class PopSelection
--- @field opt nil|string|fun():string
---        Option name
--- @field dic nil|table<string,string|PopSelection>|fun(opt:string):table<string,string|PopSelection>
---        * table<string, string>       : 'lst' desctiption
---        * table<string, PopSelection> : sub-selection
--- @field lst nil|any[]|fun(opt:string):any[]
---        * any[]    : Selection item list
---        * string[] : Key index list of 'dic'
--- @field dsr nil|string|fun(opt:string):string
---        'opt' description
--- @field cpl nil|string|fun(opt:string):string
---        'completion' of `input()` to modify selection value
--- @field cmd nil|fun(opt:string, sel)
---        Command executed with selected item of 'lst'
--- @field get nil|fun(opt:string):any
---        Get the selected item of 'opt'
--- @field evt nil|fun(event:string)
---        Selection event callback
---        * 'onCR'   : called at `pkeys.confirm` (called after executed 'cmd')
---        * 'onQuit' : called at `pctx.on_quit`
--- @field sub nil|table<string,any|fun(...):any>|fun(opt:string):table<string,any|fun(...):any>
---        Shared 'lst', 'dsr', 'cpl', 'cmd', 'get' for 'dic' sub-selectionAn example to setup configs with pop_selection:
Selection commands:
PopcSet: Pop out selection panel to setup vim options
Default options:
selection = {
    enable = false,
    collect_builtin_colorscheme = true, -- `PopcSet` collects neovim builtin colorschemes or not
    keys = {
        -- Set false to disable key
        ['<CR>'] = 'execute_confirm', -- Execute 'cmd' then confirm with 'evt' callback
        ['<S-CR>'] = 'confirm', -- Confirm with 'evt' callback
        ['<Space>'] = 'execute', -- Execute 'cmd' or open/fold sub-selection
        ['<S-Space>'] = 'enter', -- Enter sub-selection or execute 'cmd'
        ['u'] = 'leave', -- Leave sub-selection and go back base selection
        ['f'] = 'fold_or_open', -- Fold or open sub-selection
        ['F'] = 'fold_always', -- Fold sub-selection always
        ['n'] = 'next_lst_item', -- Execute 'cmd' with next 'lst' item
        ['p'] = 'prev_lst_item', -- Execute 'cmd' with previous 'lst' item
        ['m'] = 'modify', -- Modify the selection value from `input()`
        ['M'] = 'modify_current', -- Modify the selection value from `input({ default = <current selection value> })`
    },
},



