/rplugin/python3/denite/common.py

https://github.com/autozimu/LanguageClient-neovim · Python · 159 lines · 135 code · 24 blank · 0 comment · 17 complexity · 586f4c19104e01b0f6172e1cee0e3a17 MD5 · raw file

  1. from typing import List, Dict
  2. from os.path import dirname, relpath
  3. from urllib import request, parse
  4. import sys
  5. from collections import namedtuple
  6. from denite.source.base import Base
  7. sys.path.insert(0, dirname(__file__))
  8. from lsp.protocol import SymbolKind # isort:skip # noqa: I100 E402
  9. MAX_FNAME_LEN = 30
  10. _HighlightDefinition = namedtuple("HighlightDefinition", (
  11. "name",
  12. 're',
  13. "contained",
  14. "contains",
  15. "nextgroup",
  16. 'link',
  17. ))
  18. def HighlightDefinition(name,
  19. re,
  20. contained=False,
  21. contains=None,
  22. nextgroup=None,
  23. link=None):
  24. return _HighlightDefinition(name,
  25. re,
  26. contained,
  27. contains,
  28. nextgroup,
  29. link)
  30. SYMBOL_CANDIDATE_HIGHLIGHT_SYNTAX = [
  31. HighlightDefinition(
  32. name='location',
  33. contains=('colon', 'number', 'path'),
  34. nextgroup='kind',
  35. re=r'\([^:]\+:\)\?\d\+:\d\+',
  36. ),
  37. HighlightDefinition(
  38. name='path',
  39. contained=True,
  40. re=r'[^:]\+',
  41. link='String',
  42. ),
  43. HighlightDefinition(
  44. name='colon',
  45. contained=True,
  46. re=r':',
  47. link='Comment',
  48. ),
  49. HighlightDefinition(
  50. name='number',
  51. contained=True,
  52. re=r'\d\+',
  53. link='Number',
  54. ),
  55. HighlightDefinition(
  56. name='kind',
  57. contained=True,
  58. nextgroup='name',
  59. re=r'\s\+\[\(\w\|\s\)*\]',
  60. link='Type',
  61. ),
  62. ]
  63. def uri_to_path(uri: str) -> str:
  64. return request.url2pathname(parse.urlparse(uri).path)
  65. def highlight_setup(source: Base, syntax: List[HighlightDefinition]) -> None:
  66. def mangle_name(name: str) -> str:
  67. if name in ("TOP", "NONE"):
  68. return name
  69. if name.startswith("@"):
  70. return name
  71. return "{}_{}".format(source.syntax_name, name)
  72. for hl_def in syntax:
  73. match = [
  74. mangle_name(hl_def.name),
  75. '/{}/'.format(hl_def.re),
  76. 'contained']
  77. if hl_def.contains:
  78. match.append("contains=" + ','.join(
  79. mangle_name(i) for i in hl_def.contains
  80. ))
  81. elif hl_def.contains is None:
  82. match.append("contains=NONE")
  83. if hl_def.nextgroup is not None:
  84. match.append("nextgroup=" + mangle_name(hl_def.nextgroup))
  85. if not hl_def.contained:
  86. match.append("containedin=" + source.syntax_name)
  87. source.vim.command('syntax match ' + ' '.join(match))
  88. if hl_def.link is not None:
  89. source.vim.command(
  90. 'highlight default link {0}_{1} {2}'.format(
  91. source.syntax_name, hl_def.name, hl_def.link))
  92. def convert_symbols_to_candidates(symbols: List[Dict],
  93. bufname: str = None,
  94. pwd: str = None) -> List[Dict]:
  95. candidates = []
  96. paths = []
  97. kinds = []
  98. max_path_len = 0
  99. max_kind_len = 0
  100. for symbol in symbols:
  101. name = symbol["name"]
  102. start = symbol["location"]["range"]["start"]
  103. line = start["line"] + 1
  104. character = start["character"] + 1
  105. kinds.append(SymbolKind(symbol.get("kind", 0)).describe())
  106. if not bufname:
  107. filepath = uri_to_path(symbol["location"]["uri"])
  108. if pwd:
  109. rpath = relpath(filepath, pwd)
  110. if len(rpath) < len(filepath):
  111. filepath = rpath
  112. disp_path = filepath
  113. if len(disp_path) > MAX_FNAME_LEN:
  114. disp_path = "..." + disp_path[-MAX_FNAME_LEN - 3:]
  115. paths.append("{}:{}:{}".format(disp_path, line, character))
  116. else:
  117. filepath = bufname
  118. paths.append("{}:{}".format(line, character))
  119. max_path_len = max(max_path_len, len(paths[-1]))
  120. max_kind_len = max(max_kind_len, len(kinds[-1]))
  121. candidates.append({
  122. "word": name,
  123. "action__path": filepath,
  124. "action__line": line,
  125. "action__col": character,
  126. })
  127. for candidate, path, kind in zip(candidates, paths, kinds):
  128. candidate["abbr"] = "{:<{}} [{:^{}}] {}".format(
  129. path,
  130. max_path_len,
  131. kind,
  132. max_kind_len,
  133. candidate["word"],
  134. )
  135. return candidates