1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-04-14 07:09:11 +08:00

fix(defx_icons): fix defx_icons colors

close https://github.com/SpaceVim/SpaceVim/issues/4419
This commit is contained in:
wsdjeg 2022-04-11 19:56:49 +08:00
parent 3ebcbf97be
commit 07c31caa6e
3 changed files with 145 additions and 53 deletions

View File

@ -15,10 +15,11 @@ This is the default configuration:
```vimL
let g:defx_icons_enable_syntax_highlight = 1
let g:defx_icons_column_length = 2
let g:defx_icons_column_length = 1
let g:defx_icons_directory_icon = ''
let g:defx_icons_mark_icon = '*'
let g:defx_icons_copy_icon = ''
let g:defx_icons_link_icon = ''
let g:defx_icons_move_icon = ''
let g:defx_icons_parent_icon = ''
let g:defx_icons_default_icon = ''
@ -57,6 +58,7 @@ For directory icons these highlight groups are defined:
```vimL
hi default link DefxIconsMarkIcon Statement
hi default link DefxIconsCopyIcon WarningMsg
hi default link DefxIconsLinkIcon WarningMsg
hi default link DefxIconsMoveIcon ErrorMsg
hi default link DefxIconsDirectory Directory
hi default link DefxIconsParentDirectory Directory

View File

@ -15,6 +15,7 @@ let s:root_opened_tree_icon = get(g:, 'defx_icons_root_opened_tree_icon', '')
let s:nested_closed_tree_icon = get(g: ,'defx_icons_nested_closed_tree_icon', '')
let s:nested_opened_tree_icon = get(g: ,'defx_icons_nested_opened_tree_icon', '')
let s:copy_icon = get(g:, 'defx_icons_copy_icon', '')
let s:link_icon = get(g:, 'defx_icons_link_icon', '')
let s:move_icon = get(g:, 'defx_icons_move_icon', '')
let s:default_color = synIDattr(hlID('Normal'), 'fg')
@ -152,10 +153,28 @@ let s:extensions = extend({
\ 'psd': {'icon': '', 'color': s:gui_colors.darkBlue, 'term_color': s:term_colors.darkBlue},
\ 'psb': {'icon': '', 'color': s:gui_colors.darkBlue, 'term_color': s:term_colors.darkBlue},
\ 'ts': {'icon': '', 'color': s:gui_colors.blue, 'term_color': s:term_colors.blue},
\ 'tsx': {'icon': '', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'tsx': {'icon': '', 'color': s:gui_colors.blue, 'term_color': s:term_colors.blue},
\ 'jl': {'icon': '', 'color': s:gui_colors.purple, 'term_color': s:term_colors.purple},
\ 'pp': {'icon': '', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'vue': {'icon': '﵂', 'color': s:gui_colors.green, 'term_color': s:term_colors.green},
\ 'key': {'icon': '', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'cs': {'icon': '', 'color': s:gui_colors.blue, 'term_color': s:term_colors.blue},
\ 'elm': {'icon': '', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'f#': {'icon': '', 'color': s:gui_colors.darkBlue, 'term_color': s:term_colors.darkBlue},
\ 'gemspec': {'icon': '', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'haml': {'icon': '', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'hh': {'icon': '', 'color': s:gui_colors.blue, 'term_color': s:term_colors.blue},
\ 'leex': {'icon': '', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'mdx': {'icon': '', 'color': s:gui_colors.yellow, 'term_color': s:term_colors.yellow},
\ 'r': {'icon': 'ﳒ', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'rake': {'icon': '', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'rproj': {'icon': '鉶', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'swift': {'icon': '', 'color': s:gui_colors.orange, 'term_color': s:term_colors.orange},
\ 'tex': {'icon': 'ﭨ', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'webmanifest': {'icon': '', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'webp': {'icon': '', 'color': s:gui_colors.aqua, 'term_color': s:term_colors.aqua},
\ 'xcplayground': {'icon': '', 'color': s:gui_colors.orange, 'term_color': s:term_colors.orange},
\ 'svelte': {'icon': '', 'color': s:gui_colors.darkOrange, 'term_color': s:term_colors.darkOrange},
\ }, get(g:, 'defx_icons_extensions', {}))
let s:exact_matches = extend({
@ -183,6 +202,13 @@ let s:exact_matches = extend({
\ 'procfile': {'icon': '', 'color': s:gui_colors.purple, 'term_color': s:term_colors.purple},
\ 'dockerfile': {'icon': '', 'color': s:gui_colors.blue, 'term_color': s:term_colors.blue},
\ 'docker-compose.yml': {'icon': '', 'color': s:gui_colors.yellow, 'term_color': s:term_colors.yellow},
\ 'makefile': {'icon': '', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'gemfile': {'icon': '', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ '.gitlab-ci.yml': {'icon': '', 'color': s:gui_colors.orange, 'term_color': s:term_colors.orange},
\ 'cmakelists.txt': {'icon': '', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'config.ru': {'icon': '', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'mix.lock': {'icon': '', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ 'rakefile': {'icon': '', 'color': s:gui_colors.default, 'term_color': s:term_colors.default},
\ }, get(g:, 'defx_icons_exact_matches', {}))
let s:pattern_matches = extend({
@ -199,6 +225,7 @@ let s:pattern_matches = extend({
hi default link DefxIconsMarkIcon Statement
hi default link DefxIconsCopyIcon WarningMsg
hi default link DefxIconsLinkIcon WarningMsg
hi default link DefxIconsMoveIcon ErrorMsg
hi default link DefxIconsDirectory Directory
hi default link DefxIconsParentDirectory Directory
@ -209,21 +236,26 @@ hi default link DefxIconsClosedTreeIcon Directory
function! defx_icons#get() abort
return {
\ 'extensions': s:extensions,
\ 'exact_matches': s:exact_matches,
\ 'exact_dir_matches': get(g:, 'defx_icon_exact_dir_matches', {}),
\ 'pattern_matches': s:pattern_matches,
\ 'enable_syntax_highlight': s:enable_syntax_highlight,
\ 'column_length': s:column_length,
\ 'parent_icon': s:parent_icon,
\ 'directory_icon': s:directory_icon,
\ 'directory_symlink_icon': s:directory_symlink_icon,
\ 'mark_icon': s:mark_icon,
\ 'default_icon': s:default_icon,
\ 'root_opened_tree_icon': s:root_opened_tree_icon,
\ 'nested_closed_tree_icon': s:nested_closed_tree_icon,
\ 'nested_opened_tree_icon': s:nested_opened_tree_icon,
\ 'copy_icon': s:copy_icon,
\ 'move_icon': s:move_icon,
\ 'icons': {
\ 'extensions': s:extensions,
\ 'exact_matches': s:exact_matches,
\ 'pattern_matches': s:pattern_matches,
\ 'exact_dir_matches': get(g:, 'defx_icon_exact_dir_matches', {}),
\ 'parent_icon': s:parent_icon,
\ 'directory_icon': s:directory_icon,
\ 'directory_symlink_icon': s:directory_symlink_icon,
\ 'mark_icon': s:mark_icon,
\ 'default_icon': s:default_icon,
\ 'root_opened_tree_icon': s:root_opened_tree_icon,
\ 'nested_closed_tree_icon': s:nested_closed_tree_icon,
\ 'nested_opened_tree_icon': s:nested_opened_tree_icon,
\ 'copy_icon': s:copy_icon,
\ 'link_icon': s:link_icon,
\ 'move_icon': s:move_icon,
\ },
\ 'settings': {
\ 'enable_syntax_highlight': s:enable_syntax_highlight,
\ 'column_length': s:column_length,
\ }
\ }
endfunction

View File

@ -7,11 +7,11 @@
import re
import typing
from pathlib import Path
from defx.base.column import Base
from defx.base.column import Base, Highlights
from defx.context import Context
from defx.clipboard import ClipboardAction
from defx.view import View
from neovim import Nvim
from defx.util import Nvim, Candidate, len_bytes
class Column(Base):
@ -19,7 +19,49 @@ class Column(Base):
super().__init__(vim)
self.vim = vim
self.name = 'icons'
self.has_get_with_highlights = True
self.opts = self.vim.call('defx_icons#get')
self.icons = self.opts['icons']
self.settings = self.opts['settings']
self.highlights: typing.Dict[str, typing.Any] = {}
self.generate_highlights_map()
def item_hl(self, name, hi_group) -> None:
icon = format(self.icons[name], f'<{self.settings["column_length"]}')
self.highlights[name] = (
icon,
hi_group,
len_bytes(icon)
)
def list_hl(self, list_name) -> None:
self.highlights[list_name] = {}
for name, opts in self.icons[list_name].items():
text = re.sub('[^A-Za-z]', '', name)
icon = format(opts['icon'], f'<{self.settings["column_length"]}')
self.highlights[list_name][name] = (
icon,
text,
len_bytes(icon)
)
def generate_highlights_map(self) -> None:
self.item_hl('default_icon', '')
self.item_hl('mark_icon', 'DefxIconsMarkIcon')
self.item_hl('copy_icon', 'DefxIconsCopyIcon')
self.item_hl('link_icon', 'DefxIconsLinkIcon')
self.item_hl('move_icon', 'DefxIconsMoveIcon')
self.item_hl('directory_icon', 'DefxIconsDirectory')
self.item_hl('parent_icon', 'DefxIconsParentDirectory')
self.item_hl('directory_symlink_icon', 'DefxIconsSymlinkDirectory')
self.item_hl('root_opened_tree_icon', 'DefxIconsOpenedTreeIcon')
self.item_hl('nested_opened_tree_icon', 'DefxIconsNestedTreeIcon')
self.item_hl('nested_closed_tree_icon', 'DefxIconsClosedTreeIcon')
self.list_hl('pattern_matches')
self.list_hl('exact_matches')
self.list_hl('exact_dir_matches')
self.list_hl('extensions')
def on_init(self, view: View, context: Context) -> None:
self._context = context
@ -29,11 +71,13 @@ class Column(Base):
self._context = context
self._view = view
def get(self, context: Context, candidate: dict) -> str:
def get_with_highlights(
self, context: Context, candidate: Candidate
) -> typing.Tuple[str, Highlights]:
path: Path = candidate['action__path']
filename = path.name
if 'mark' not in context.columns and candidate['is_selected']:
return self.icon(self.opts['mark_icon'])
return self.icon('mark_icon')
if self._view and self._view._clipboard.candidates:
for clipboard_candidate in self._view._clipboard.candidates:
@ -41,85 +85,99 @@ class Column(Base):
return self.clipboard_icon()
if candidate.get('is_root', False):
return self.icon(self.opts['parent_icon'])
return self.icon('parent_icon')
if candidate['is_directory']:
if filename in self.opts['exact_dir_matches']:
return self.icon(self.opts['exact_dir_matches'][filename]['icon'])
if filename in self.icons['exact_dir_matches']:
return self.icon('exact_dir_matches', filename)
if candidate.get('level', 0) > 0:
if candidate.get('is_opened_tree'):
return self.icon(self.opts['nested_opened_tree_icon'])
return self.icon(self.opts['nested_closed_tree_icon'])
return self.icon('nested_opened_tree_icon')
if path.is_symlink():
return self.icon('directory_symlink_icon')
return self.icon('nested_closed_tree_icon')
if candidate.get('is_opened_tree', False):
return self.icon(self.opts['root_opened_tree_icon'])
return self.icon('root_opened_tree_icon')
if path.is_symlink():
return self.icon(self.opts['directory_symlink_icon'])
return self.icon('directory_symlink_icon')
return self.icon(self.opts['directory_icon'])
return self.icon('directory_icon')
filename = filename.lower()
ext = path.suffix[1:].lower()
for pattern, pattern_data in self.opts['pattern_matches'].items():
for pattern, pattern_data in self.icons['pattern_matches'].items():
if re.search(pattern, filename) is not None:
return self.icon(pattern_data['icon'])
return self.icon('pattern_matches', pattern)
if filename in self.opts['exact_matches']:
return self.icon(self.opts['exact_matches'][filename]['icon'])
if filename in self.icons['exact_matches']:
return self.icon('exact_matches', filename)
if ext in self.opts['extensions']:
return self.icon(self.opts['extensions'][ext]['icon'])
if ext in self.icons['extensions']:
return self.icon('extensions', ext)
return self.icon(self.opts['default_icon'])
return self.icon('default_icon')
def icon(
self, icon_name, nested_icon_name = None
) -> typing.Tuple[str, Highlights]:
icon = self.highlights[icon_name]
if nested_icon_name is not None:
icon = icon[nested_icon_name]
hl = f'{self.highlight_name}_{icon[1]}'
else:
hl = icon[1]
return (icon[0], [(hl, self.start, icon[2])])
def length(self, context: Context) -> int:
return self.opts['column_length']
def icon(self, icon: str) -> str:
return format(icon, f'<{self.opts["column_length"]}')
return typing.cast(int, self.settings['column_length'])
def clipboard_icon(self) -> str:
if self._view._clipboard.action == ClipboardAction.COPY:
return self.opts['copy_icon']
return self.icon('copy_icon')
if self._view._clipboard.action == ClipboardAction.LINK:
return self.icon('link_icon')
if self._view._clipboard.action == ClipboardAction.MOVE:
return self.opts['move_icon']
return self.icon('move_icon')
return ''
def syn_item(self, name, opt_name, hi_group_name) -> typing.List[str]:
commands: typing.List[str] = []
commands.append(f'silent! syntax clear {self.syntax_name}_{name}')
commands.append(f'silent! syntax clear {self.highlight_name}_{name}')
commands.append((
'syntax match {0}_{1} /[{2}]/ contained containedin={0}'
).format(self.syntax_name, name, self.opts[opt_name]))
'syntax match {0}_{1} /[{2}]/ contained containedin={3}'
).format(self.highlight_name, name, self.icons[opt_name],
self.syntax_name))
commands.append('highlight default link {0}_{1} {2}'.format(
self.syntax_name, name, hi_group_name
self.highlight_name, name, hi_group_name
))
return commands
def syn_list(self, opt) -> typing.List[str]:
commands: typing.List[str] = []
for name, opts in self.opts[opt].items():
for name, opts in self.icons[opt].items():
text = re.sub('[^A-Za-z]', '', name)
commands.append(f'silent! syntax clear {self.syntax_name}_{text}')
commands.append(f'silent! syntax clear {self.highlight_name}_{text}')
commands.append((
'syntax match {0}_{1} /[{2}]/ contained containedin={0}'
).format(self.syntax_name, text, opts['icon']))
'syntax match {0}_{1} /[{2}]/ contained containedin={3}'
).format(self.highlight_name, text, opts['icon'], self.syntax_name))
commands.append('highlight default {0}_{1} guifg=#{2} ctermfg={3}'.format(
self.syntax_name, text, opts['color'], opts.get('term_color',
self.highlight_name, text, opts['color'], opts.get('term_color',
'NONE')))
return commands
def highlight_commands(self) -> typing.List[str]:
commands: typing.List[str] = []
if not self.opts['enable_syntax_highlight']:
if not self.settings['enable_syntax_highlight']:
return commands
commands += self.syn_item('icon_mark', 'mark_icon', 'DefxIconsMarkIcon')
commands += self.syn_item('icon_copy', 'copy_icon', 'DefxIconsCopyIcon')
commands += self.syn_item('icon_link', 'link_icon', 'DefxIconsLinkIcon')
commands += self.syn_item('icon_move', 'move_icon', 'DefxIconsMoveIcon')
commands += self.syn_item('directory', 'directory_icon', 'DefxIconsDirectory')