/coc-explorer

📁 Explorer for coc.nvim

Primary LanguageTypeScriptMIT LicenseMIT

coc-explorer

Explorer extension for coc.nvim

Note: Still under development, maybe has some breaking changes.

Build Status

Screenshot

image

Requirements

>= vim 8.1.0579 or >= neovim 0.3.1

Usage

  1. Install by coc.nvim command:
    :CocInstall coc-explorer
    
  2. Configuration custom vim mapping
    :nmap <space>e :CocCommand explorer<CR>
    
  3. Open explorer
    <space>e
    
  4. Press ? to show mappings help

Feature

  • Buffer source
    • Highlight visible buffers in real time (neovim only)
  • File tree source
    • Basic actions
      • Open file in select / vsplit / tab explorer.openAction.strategy options:
        • select: Open action use selection UI
        • vsplit: Open action use vsplit
        • split: Open action use split
        • tab: Open action use tab
        • previousBuffer: Open action use last used buffer
        • previousWindow: Open action use last used window
        • sourceWindow: Open action use the window where explorer opened
      • Selection
      • Cut / Copy / Paste
      • Delete action use trash by default
      • Other actions, press ? in explorer to check out the all actions
    • Git status
    • Reveal current file in real time (neovim only)
    • Icons, use nerdfont
    • Search files by Coc-list
    • Preview file attributes by floating window
    • LSP
      • diagnostic
      • file rename
    • Exrename, like defx
    • Archive file (use lsar / unar)
    • SSH
  • Bookmark source (require coc-bookmark)
  • Git source
    • Git actions
  • Show help

Command

:CocCommand explorer [options] [root-uri]

User events

  • CocExplorerOpenPre: triggered before open explorer
  • CocExplorerOpenPost: triggered after open explorer
  • CocExplorerQuitPre: triggered before quit explorer
  • CocExplorerQuitPost: triggered after quit explorer

Example

:CocCommand explorer
    \ --toggle
    \ --sources=buffer+,file+
    \ /root/path

Presets

let g:coc_explorer_global_presets = {
\   '.vim': {
\     'root-uri': '~/.vim',
\   },
\   'tab': {
\     'position': 'tab',
\     'quit-on-open': v:true,
\   },
\   'floating': {
\     'position': 'floating',
\     'open-action-strategy': 'sourceWindow',
\   },
\   'floatingTop': {
\     'position': 'floating',
\     'floating-position': 'center-top',
\     'open-action-strategy': 'sourceWindow',
\   },
\   'floatingLeftside': {
\     'position': 'floating',
\     'floating-position': 'left-center',
\     'floating-width': 50,
\     'open-action-strategy': 'sourceWindow',
\   },
\   'floatingRightside': {
\     'position': 'floating',
\     'floating-position': 'right-center',
\     'floating-width': 50,
\     'open-action-strategy': 'sourceWindow',
\   },
\   'simplify': {
\     'file-child-template': '[selection | clip | 1] [indent][icon | 1] [filename omitCenter 1]'
\   }
\ }

" Use preset argument to open it
nmap <space>ed :CocCommand explorer --preset .vim<CR>
nmap <space>ef :CocCommand explorer --preset floating<CR>

" List all presets
nmap <space>el :CocList explPresets

Options

[root-uri]

Explorer root, default:

  • getcwd() when buftype is nofile
  • workspace.rootPath

--preset <name>

Open explorer use presets

--toggle | --no-toggle

Close the explorer if it exists, default: --toggle

--focus | --no-focus

Focus to explorer when opened, default: --focus

--open-action-strategy <strategy>

Strategy for open action, types: select | vsplit | split | tab | previousBuffer | previousWindow | sourceWindow, default: select

--quit-on-open | --no-quit-on-open

quit explorer when open action, default: --no-quit-on-open

--sources <sources>

Explorer sources, example: buffer+,file+, default: buffer-,file+

              expand
      collapsed │
          ↓     ↓
    buffer-,file+
    └──┬─┘  └─┬┘
buffer source │
          file source

--position <position>

Explorer position, supported position: left, right, tab, floating, default: left

--width <number>

Width of Explorer window for open in left or right side, default: 40

--content-width <number>

Content width, default: 0

--content-width-type <type>

Type of content width, types: win-width, vim-width, , default: vim-width

--floating-position <position>

Explorer position for floating window, positions:

  • left-center
  • center
  • right-center
  • center-top
  • <number for left>,<number for top>

default: center

--floating-width <number>

Width of Explorer window when position is floating, use negative value or zero to as width - value, default: 0

--floating-height <number>

Height of Explorer window when position is floating, use negative value or zero to as height - value, default: 0

--floating-content-width <number>

Width of content when position is floating, use negative value or zero to as width - value, default: 0

--buffer-root-template <template>

Template for root node of buffer source

Columns:

  • icon
  • hidden
  • title

default: [icon] [title] [hidden & 1]

--buffer-child-template <template>

Template for child node of buffer source

Columns:

  • selection
  • name
  • bufname
  • modified
  • bufnr
  • readonly
  • fullpath

default: [selection | 1] [bufnr] [name][modified][readonly] [fullpath]

--buffer-child-labeling-template <template>

Labeling template for child node of buffer source, use for preview when previewAction is labeling

Columns: same with --buffer-child-template

default: [name][bufname][fullpath][modified][readonly]

--file-root-template <template>

Template for root node of file source

Columns:

  • icon
  • hidden
  • title
  • root
  • fullpath

default: [icon] [title] [hidden & 1][root] [fullpath]

--file-root-labeling-template <template>

Labeling template for root node of file source, use for preview when previewAction is labeling

Columns: same with --file-root-template

default: [fullpath]

--file-child-template <template>

Template for child node file source

Columns:

  • git
  • selection
  • icon
  • filename
  • linkIcon
  • link
  • fullpath
  • indent
  • clip
  • size
  • readonly
  • modified
  • timeModified
  • timeCreated
  • timeAccessed
  • diagnosticError
  • diagnosticWarning

default: [git | 2] [selection | clip | 1] [indent][icon | 1] [diagnosticError & 1][filename omitCenter 1][modified][readonly] [linkIcon & 1][link growRight 1 omitCenter 5][size]

--file-child-labeling-template <template>

Labeling template for child node of file source, use for preview when previewAction is labeling

Columns: same with --file-child-template

default: [fullpath][link][diagnosticWarning][diagnosticError][size][timeAccessed][timeModified][timeCreated][readonly][modified]

--bookmark-root-template <template>

Template for root node of bookmark source

Columns:

  • icon
  • hidden
  • title

default: [icon] [title] [hidden & 1]

--bookmark-child-template <template>

Template for child node of bookmark source

Columns:

  • selection
  • position
  • filename
  • fullpath
  • line
  • annotation

default: [selection | 1] [filename] [position]

--bookmark-child-labeling-template <template>

Labeling template for child node of bookmark source, use for preview when previewAction is labeling

Columns: same with --bookmark-child-template

default: [filename][fullpath][position][line][annotation]

--reveal <filepath>

Explorer will expand to this filepath, default: current buffer

Template grammar

Example:

[git | 2] [selection | clip | 1] [diagnosticError & 1][filename growRight 1 omitCenter 5]
  • [git]
    • Display git.
  • [git | 2]
    • If git is not empty, display git, otherwise display 2 spaces.
  • [selection | clip | 1]
    • Checking selection and clip in turn, if one is not empty, display it, otherwise display 1 spaces.
  • [diagnosticError & 1]
    • If diagnosticError is empty, display nothing. otherwise display diagnosticError and 1 space.
  • [filename growRight 1 omitCenter 5]
    • Flexible to display filename, grow right column volume is 1, omit center volume is 5

Grammar:

                      block
         ┌──────────────┴───────────────┐
┌────────┴───────────┐ ┌────────────────┴────────────────┐
[selection | clip | 1] [filename growRight 1 omitCenter 5]
                      ↑
                 plain string

            column
     ┌─────────┴───────────┐
     │                     │   volume of modifier
     │         ┌────┬──────│──────────┴────┬────────────┐
 ┌───┴───┐   ┌─┴┐   ↓   ┌──┴───┐           ↓            ↓
[selection | clip | 1] [filename growRight 1 omitCenter 5]
           ↑      ↑              └───┬───┘   └────┬───┘
           └──────┴───────────┬──────┴────────────┘
                           modifier

Configuration

explorer.presets: Explorer presets. type: object
explorer.keyMappingMode: Keymapping mode. type: "none" | "default" Default:
"default"
explorer.keyMappings: Custom keymappings. type: object Default:
{}
explorer.toggle: Close the explorer if it exists. type: boolean Default:
true
explorer.focus: Focus to explorer when opened. type: boolean Default:
true
explorer.position: Explorer position. type: "left" | "right" | "tab" | "floating" Default:
"left"
explorer.width: Width of explorer window for open in left or right side. type: integer Default:
40
explorer.contentWidth: Content width, use negative value or zero to as `width - value`. type: integer Default:
0
explorer.contentWidthType: Type of content width. type: "win-width" | "vim-width" Default:
"vim-width"
explorer.floating.position: Position of Explorer for floating window. type: "left-center" | "right-center" | "center" | "center-top" | integer Default:
"center"
explorer.floating.width: Width of explorer window when position is floating, use negative value or zero to as `width - value`. type: integer Default:
-10
explorer.floating.height: Height of explorer window when position is floating, use negative value or zero to as `height - value`. type: integer Default:
-10
explorer.floating.contentWidth: Width of content when position is floating, use negative value or zero to as `width - value`. type: integer Default:
0
explorer.floating.border.enable: . type: boolean Default:
true
explorer.floating.border.chars: Border chars for floating window, their order is top/right/bottom/left/topleft/topright/botright/botleft. type: string Default:
[
  "─",
  "│",
  "─",
  "│",
  "┌",
  "┐",
  "┘",
  "└"
]
explorer.floating.border.title: . type: string Default:
"coc-explorer"
explorer.floating.hideOnCocList: Hide floating window, when opening CocList. type: boolean Default:
true
explorer.autoExpandMaxDepth: Automatically expand maximum depth of one time. type: integer Default:
20
explorer.autoExpandOptions: Automatically expand options. type: "recursive" | "compact" | "uncompact" | "recursiveSingle" Default:
[
  "compact",
  "uncompact"
]
explorer.autoCollapseOptions: Automatically collapse options. type: "recursive" Default:
[
  "recursive"
]
explorer.activeMode: Render explorer when after open or save buffer. type: boolean Default:
true
explorer.quitOnOpen: quit explorer when open action. type: boolean Default:
false
explorer.previewAction.strategy: Strategy for preview action. type: "labeling" Default:
"labeling"
explorer.previewAction.onHover: Open preview when hovering over on node. type: boolean Default:
true
explorer.openAction.strategy: Strategy for open action. type: "select" | "split" | "split:plain" | "split:intelligent" | "vsplit" | "vsplit:plain" | "vsplit:intelligent" | "tab" | "previousBuffer" | "previousWindow" | "sourceWindow" Default:
"select"
explorer.openAction.select.filterFloatWindows: Filter floating windows in select strategy. type: boolean Default:
true
explorer.openAction.select.filter: Filter windows for select strategy. type: object Default:
{
  "buftypes": [
    "terminal"
  ],
  "filetypes": [
    "vista_kind",
    "qf"
  ],
  "floatingWindows": true
}
explorer.openAction.for.directory: The action when you open a directory of file source. type: string Default:
"cd"
explorer.openAction.relativePath: Use relative path when open a file with openAction. type: boolean Default:
false
explorer.sources: Explorer sources. type: object Default:
[
  {
    "name": "bookmark",
    "expand": false
  },
  {
    "name": "buffer",
    "expand": false
  },
  {
    "name": "file",
    "expand": true
  }
]
explorer.enableFloatinput: Enable integrated with coc-floatinput. type: boolean Default:
true
explorer.icon.enableNerdfont: Enable nerdfont. type: boolean Default:
false
explorer.icon.customIcons: Custom icons and color highlights. type: object Default:
{
  "icons": {},
  "extensions": {},
  "filenames": {},
  "dirnames": {},
  "patternMatches": {},
  "dirPatternMatches": {}
}
explorer.icon.enableVimDevicons: Enable use vim-devicons instead of built-in icon configuration. type: boolean Default:
false
explorer.icon.expanded: Icon for expanded node. type: string Default:
"-"
explorer.icon.collapsed: Icon for collapsed node. type: string Default:
"+"
explorer.icon.selected: Selection selected chars for File source. type: string Default:
"✓"
explorer.icon.hidden: Icon for hidden status. type: string Default:
"‥"
explorer.bookmark.root.template: Template for root node of bookmark source. type: string Default:
"[icon] [title] [hidden & 1]"
explorer.bookmark.child.template: Template for child node of bookmark source. type: string Default:
"[selection | 1] [filename] [position] - [annotation]"
explorer.bookmark.child.labelingTemplate: Labeling template for child node of bookmark source, use for preview when previewAction is labeling. type: string Default:
"[filename][fullpath][position][line][annotation]"
explorer.buffer.showHiddenBuffers: Default show hidden buffers. type: boolean Default:
false
explorer.buffer.tabOnly: Default only show buffers in current tab. type: boolean Default:
false
explorer.buffer.root.template: Template for root node of buffer source. type: string Default:
"[icon] [title] [hidden & 1]"
explorer.buffer.child.template: Template for child node of buffer source. type: string Default:
"[selection | 1] [bufnr] [name][modified][readonly] [fullpath]"
explorer.buffer.child.labelingTemplate: Labeling template for child node of buffer source, use for preview when previewAction is labeling. type: string Default:
"[name][bufname][fullpath][modified][readonly]"
explorer.datetime.format: Explorer datetime format, check out https://date-fns.org/v2.9.0/docs/format. type: string Default:
"yy/MM/dd HH:mm:ss"
explorer.file.autoReveal: Explorer will automatically expand to the current buffer. type: boolean Default:
true
explorer.file.diagnosticCountMax: Maximum count of diagnostic column. type: integer Default:
99
explorer.file.hiddenRules: Custom hidden rules for file. type: object Default:
{
  "extensions": [
    "o",
    "a",
    "obj",
    "pyc"
  ],
  "filenames": [],
  "patternMatches": [
    "^\\."
  ]
}
explorer.file.showHiddenFiles: Default show hidden files. type: boolean Default:
false
explorer.file.root.template: Template for root node of file source. type: string Default:
"[icon] [title] [hidden & 1][root] [fullpath]"
explorer.file.root.labelingTemplate: Labeling template for root node of file source, use for preview when previewAction is labeling. type: string Default:
"[fullpath]"
explorer.file.child.template: Template for child node file source. type: string Default:
"[git | 2] [selection | clip | 1] [indent][icon | 1] [diagnosticError & 1][filename omitCenter 1][modified][readonly] [linkIcon & 1][link growRight 1 omitCenter 5][size]"
explorer.file.child.labelingTemplate: Labeling template for child node of file source, use for preview when previewAction is labeling. type: string Default:
"[fullpath][link][diagnosticWarning][diagnosticError][size][timeAccessed][timeModified][timeCreated][readonly][modified]"
explorer.file.column.git.showIgnored: Show ignored files in git column. type: boolean Default:
false
explorer.file.column.git.icon.mixed: Icon for git mixed status. type: string Default:
"*"
explorer.file.column.git.icon.unmodified: Icon for git unmodified status. type: string Default:
" "
explorer.file.column.git.icon.modified: Icon for git modified status. type: string Default:
"M"
explorer.file.column.git.icon.added: Icon for git added status. type: string Default:
"A"
explorer.file.column.git.icon.deleted: Icon for git removed status. type: string Default:
"D"
explorer.file.column.git.icon.renamed: Icon for git renamed status. type: string Default:
"R"
explorer.file.column.git.icon.copied: Icon for git copied status. type: string Default:
"C"
explorer.file.column.git.icon.unmerged: Icon for git unmerged status. type: string Default:
"U"
explorer.file.column.git.icon.untracked: Icon for git untracked status. type: string Default:
"?"
explorer.file.column.git.icon.ignored: Icon for git ignored status. type: string Default:
"!"
explorer.file.column.clip.copy: Whether the file has been copied. type: string
explorer.file.column.clip.cut: Whether the file has been cut. type: string
explorer.file.column.indent.chars: Indent chars for file source. type: string Default:
"  "
explorer.file.column.indent.indentLine: Whether to display the alignment line. type: boolean
explorer.file.tabCD: Change tab directory when performing the cd action. type: boolean Default:
true
explorer.git.command: Git command. type: string Default:
"git"
explorer.debug: Enable debug. type: boolean Default:
false

Custom mappings example

You can use ? to view all actions of current source

// coc-settings.json
{
  "explorer.keyMappings": {
    "i": false, // cancel default mapkey

    "gk": "expandablePrev",
    "gj": "expandableNext",

    "*": "toggleSelection",
    "<tab>": "actionMenu",

    "h": "collapse",
    "l": ["expandable?", "expand", "open"],
    "J": ["toggleSelection", "nodeNext"],
    "K": ["toggleSelection", "nodePrev"],
    "gl": "expandRecursive",
    "gh": "collapseRecursive",
    "<2-LeftMouse>": [
      "expandable?",
      ["expanded?", "collapse", "expand"],
      "open"
    ],
    "o": ["expanded?", "collapse", "expand"],
    "<cr>": ["expandable?", "cd", "open"],
    "e": "open",
    "s": "open:split",
    "S": "open:split:plain",
    "E": "open:vsplit",
    "t": "open:tab",
    "<bs>": "gotoParent",
    "gp": "preview:labeling",

    "y": "copyFilepath",
    "Y": "copyFilename",
    "c": "copyFile",
    "x": "cutFile",
    "p": "pasteFile",
    "d": "delete",
    "D": "deleteForever",

    "a": "addFile",
    "A": "addDirectory",
    "r": "rename",

    ".": "toggleHidden",
    "R": "refresh",

    "?": "help",
    "q": "quit",
    "<esc>": "esc",
    "X": "systemExecute",
    "gd": "listDrive",

    "f": "search",
    "F": "searchRecursive",

    "gf": "gotoSource:file",
    "gb": "gotoSource:buffer",

    "[[": "sourcePrev",
    "]]": "sourceNext",

    "[d": "diagnosticPrev",
    "]d": "diagnosticNext",

    "[c": "gitPrev",
    "]c": "gitNext",
    "<<": "gitStage",
    ">>": "gitUnstage"
  }
}

Example by Vim API and event hooks

function! s:coc_list_current_dir(args)
  let node_info = CocAction('runCommand', 'explorer.getNodeInfo', 0)
  execute 'cd ' . fnamemodify(node_info['fullpath'], ':h')
  execute 'CocList ' . a:args
endfunction

function! s:init_explorer(bufnr)
  set winblend=50
  nmap <buffer> <Leader>fg :call <SID>coc_list_current_dir('-I grep')<CR>
  nmap <buffer> <Leader>fG :call <SID>coc_list_current_dir('-I grep -regex')<CR>
  nmap <buffer> <C-p> :call <SID>coc_list_current_dir('files')<CR>
endfunction

function! s:enter_explorer()
  if &filetype == 'coc-explorer'
    " statusline
    setl statusline=coc-explorer
  endif
endfunction

augroup CocExplorerCustom
  autocmd!
  autocmd BufEnter * call <SID>enter_explorer()
  autocmd FileType coc-explorer call <SID>init_explorer()
augroup END

more API: https://github.com/weirongxu/coc-explorer/wiki/Vim-API

Inspired by