everforest.vim 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. " =============================================================================
  2. " URL: https://github.com/sainnhe/everforest
  3. " Filename: autoload/everforest.vim
  4. " Author: sainnhe
  5. " Email: i@sainnhe.dev
  6. " License: MIT License
  7. " =============================================================================
  8. function! everforest#get_configuration() "{{{
  9. return {
  10. \ 'background': get(g:, 'everforest_background', 'medium'),
  11. \ 'transparent_background': get(g:, 'everforest_transparent_background', 0),
  12. \ 'dim_inactive_windows': get(g:, 'everforest_dim_inactive_windows', 0),
  13. \ 'disable_italic_comment': get(g:, 'everforest_disable_italic_comment', 0),
  14. \ 'enable_italic': get(g:, 'everforest_enable_italic', 0),
  15. \ 'cursor': get(g:, 'everforest_cursor', 'auto'),
  16. \ 'sign_column_background': get(g:, 'everforest_sign_column_background', 'none'),
  17. \ 'spell_foreground': get(g:, 'everforest_spell_foreground', 'none'),
  18. \ 'ui_contrast': get(g:, 'everforest_ui_contrast', 'low'),
  19. \ 'show_eob': get(g:, 'everforest_show_eob', 1),
  20. \ 'float_style': get(g:, 'everforest_float_style', 'bright'),
  21. \ 'current_word': get(g:, 'everforest_current_word', get(g:, 'everforest_transparent_background', 0) == 0 ? 'grey background' : 'bold'),
  22. \ 'lightline_disable_bold': get(g:, 'everforest_lightline_disable_bold', 0),
  23. \ 'diagnostic_text_highlight': get(g:, 'everforest_diagnostic_text_highlight', 0),
  24. \ 'diagnostic_line_highlight': get(g:, 'everforest_diagnostic_line_highlight', 0),
  25. \ 'diagnostic_virtual_text': get(g:, 'everforest_diagnostic_virtual_text', 'grey'),
  26. \ 'disable_terminal_colors': get(g:, 'everforest_disable_terminal_colors', 0),
  27. \ 'better_performance': get(g:, 'everforest_better_performance', 0),
  28. \ 'colors_override': get(g:, 'everforest_colors_override', {}),
  29. \ }
  30. endfunction "}}}
  31. function! everforest#get_palette(background, colors_override) "{{{
  32. if a:background ==# 'hard' "{{{
  33. if &background ==# 'dark'
  34. let palette1 = {
  35. \ 'bg_dim': ['#1e2326', '233'],
  36. \ 'bg0': ['#272e33', '235'],
  37. \ 'bg1': ['#2e383c', '236'],
  38. \ 'bg2': ['#374145', '237'],
  39. \ 'bg3': ['#414b50', '238'],
  40. \ 'bg4': ['#495156', '239'],
  41. \ 'bg5': ['#4f5b58', '240'],
  42. \ 'bg_visual': ['#4c3743', '52'],
  43. \ 'bg_red': ['#493b40', '52'],
  44. \ 'bg_green': ['#3c4841', '22'],
  45. \ 'bg_blue': ['#384b55', '17'],
  46. \ 'bg_yellow': ['#45443c', '136'],
  47. \ }
  48. else
  49. let palette1 = {
  50. \ 'bg_dim': ['#f2efdf', '223'],
  51. \ 'bg0': ['#fffbef', '230'],
  52. \ 'bg1': ['#f8f5e4', '228'],
  53. \ 'bg2': ['#f2efdf', '223'],
  54. \ 'bg3': ['#edeada', '223'],
  55. \ 'bg4': ['#e8e5d5', '223'],
  56. \ 'bg5': ['#bec5b2', '223'],
  57. \ 'bg_visual': ['#f0f2d4', '194'],
  58. \ 'bg_red': ['#ffe7de', '217'],
  59. \ 'bg_green': ['#f3f5d9', '194'],
  60. \ 'bg_blue': ['#ecf5ed', '117'],
  61. \ 'bg_yellow': ['#fef2d5', '226'],
  62. \ }
  63. endif "}}}
  64. elseif a:background ==# 'medium' "{{{
  65. if &background ==# 'dark'
  66. let palette1 = {
  67. \ 'bg_dim': ['#232a2e', '233'],
  68. \ 'bg0': ['#2d353b', '235'],
  69. \ 'bg1': ['#343f44', '236'],
  70. \ 'bg2': ['#3d484d', '237'],
  71. \ 'bg3': ['#475258', '238'],
  72. \ 'bg4': ['#4f585e', '239'],
  73. \ 'bg5': ['#56635f', '240'],
  74. \ 'bg_visual': ['#543a48', '52'],
  75. \ 'bg_red': ['#514045', '52'],
  76. \ 'bg_green': ['#425047', '22'],
  77. \ 'bg_blue': ['#3a515d', '17'],
  78. \ 'bg_yellow': ['#4d4c43', '136'],
  79. \ }
  80. else
  81. let palette1 = {
  82. \ 'bg_dim': ['#efebd4', '223'],
  83. \ 'bg0': ['#fdf6e3', '230'],
  84. \ 'bg1': ['#f4f0d9', '228'],
  85. \ 'bg2': ['#efebd4', '223'],
  86. \ 'bg3': ['#e6e2cc', '223'],
  87. \ 'bg4': ['#e0dcc7', '223'],
  88. \ 'bg5': ['#bdc3af', '223'],
  89. \ 'bg_visual': ['#eaedc8', '194'],
  90. \ 'bg_red': ['#fbe3da', '217'],
  91. \ 'bg_green': ['#f0f1d2', '194'],
  92. \ 'bg_blue': ['#e9f0e9', '117'],
  93. \ 'bg_yellow': ['#faedcd', '226'],
  94. \ }
  95. endif "}}}
  96. else "{{{
  97. if &background ==# 'dark'
  98. let palette1 = {
  99. \ 'bg_dim': ['#293136', '233'],
  100. \ 'bg0': ['#333c43', '235'],
  101. \ 'bg1': ['#3a464c', '236'],
  102. \ 'bg2': ['#434f55', '237'],
  103. \ 'bg3': ['#4d5960', '238'],
  104. \ 'bg4': ['#555f66', '239'],
  105. \ 'bg5': ['#5d6b66', '240'],
  106. \ 'bg_visual': ['#5c3f4f', '52'],
  107. \ 'bg_red': ['#59464c', '52'],
  108. \ 'bg_green': ['#48584e', '22'],
  109. \ 'bg_blue': ['#3f5865', '17'],
  110. \ 'bg_yellow': ['#55544a', '136'],
  111. \ }
  112. else
  113. let palette1 = {
  114. \ 'bg_dim': ['#e5dfc5', '223'],
  115. \ 'bg0': ['#f3ead3', '230'],
  116. \ 'bg1': ['#eae4ca', '228'],
  117. \ 'bg2': ['#e5dfc5', '223'],
  118. \ 'bg3': ['#ddd8be', '223'],
  119. \ 'bg4': ['#d8d3ba', '223'],
  120. \ 'bg5': ['#b9c0ab', '223'],
  121. \ 'bg_visual': ['#e1e4bd', '194'],
  122. \ 'bg_red': ['#f4dbd0', '217'],
  123. \ 'bg_green': ['#e5e6c5', '194'],
  124. \ 'bg_blue': ['#e1e7dd', '117'],
  125. \ 'bg_yellow': ['#f1e4c5', '226'],
  126. \ }
  127. endif
  128. endif "}}}
  129. if &background ==# 'dark' "{{{
  130. let palette2 = {
  131. \ 'fg': ['#d3c6aa', '223'],
  132. \ 'red': ['#e67e80', '167'],
  133. \ 'orange': ['#e69875', '208'],
  134. \ 'yellow': ['#dbbc7f', '214'],
  135. \ 'green': ['#a7c080', '142'],
  136. \ 'aqua': ['#83c092', '108'],
  137. \ 'blue': ['#7fbbb3', '109'],
  138. \ 'purple': ['#d699b6', '175'],
  139. \ 'grey0': ['#7a8478', '243'],
  140. \ 'grey1': ['#859289', '245'],
  141. \ 'grey2': ['#9da9a0', '247'],
  142. \ 'statusline1':['#a7c080', '142'],
  143. \ 'statusline2':['#d3c6aa', '223'],
  144. \ 'statusline3':['#e67e80', '167'],
  145. \ 'none': ['NONE', 'NONE']
  146. \ } "}}}
  147. else "{{{
  148. let palette2 = {
  149. \ 'fg': ['#5c6a72', '242'],
  150. \ 'red': ['#f85552', '160'],
  151. \ 'orange': ['#f57d26', '116'],
  152. \ 'yellow': ['#dfa000', '136'],
  153. \ 'green': ['#8da101', '106'],
  154. \ 'aqua': ['#35a77c', '37'],
  155. \ 'blue': ['#3a94c5', '32'],
  156. \ 'purple': ['#df69ba', '162'],
  157. \ 'grey0': ['#a6b0a0', '247'],
  158. \ 'grey1': ['#939f91', '247'],
  159. \ 'grey2': ['#829181', '247'],
  160. \ 'statusline1':['#93b259', '106'],
  161. \ 'statusline2':['#708089', '242'],
  162. \ 'statusline3':['#e66868', '160'],
  163. \ 'none': ['NONE', 'NONE']
  164. \ }
  165. endif "}}}
  166. return extend(extend(palette1, palette2), a:colors_override)
  167. endfunction "}}}
  168. function! everforest#highlight(group, fg, bg, ...) "{{{
  169. execute 'highlight' a:group
  170. \ 'guifg=' . a:fg[0]
  171. \ 'guibg=' . a:bg[0]
  172. \ 'ctermfg=' . a:fg[1]
  173. \ 'ctermbg=' . a:bg[1]
  174. \ 'gui=' . (a:0 >= 1 ?
  175. \ a:1 :
  176. \ 'NONE')
  177. \ 'cterm=' . (a:0 >= 1 ?
  178. \ a:1 :
  179. \ 'NONE')
  180. \ 'guisp=' . (a:0 >= 2 ?
  181. \ a:2[0] :
  182. \ 'NONE')
  183. endfunction "}}}
  184. function! everforest#syn_gen(path, last_modified, msg) "{{{
  185. " Generate the `after/syntax` directory.
  186. let full_content = join(readfile(a:path), "\n") " Get the content of `colors/everforest.vim`
  187. let syn_conent = []
  188. let rootpath = everforest#syn_rootpath(a:path) " Get the path to place the `after/syntax` directory.
  189. call substitute(full_content, '" syn_begin.\{-}syn_end', '\=add(syn_conent, submatch(0))', 'g') " Search for 'syn_begin.\{-}syn_end' (non-greedy) and put all the search results into a list.
  190. for content in syn_conent
  191. let syn_list = []
  192. call substitute(matchstr(matchstr(content, 'syn_begin:.\{-}{{{'), ':.\{-}{{{'), '\(\w\|-\)\+', '\=add(syn_list, submatch(0))', 'g') " Get the file types. }}}}}}
  193. for syn in syn_list
  194. call everforest#syn_write(rootpath, syn, content) " Write the content.
  195. endfor
  196. endfor
  197. call everforest#syn_write(rootpath, 'text', "let g:everforest_last_modified = '" . a:last_modified . "'") " Write the last modified time to `after/syntax/text/everforest.vim`
  198. let syntax_relative_path = has('win32') ? '\after\syntax' : '/after/syntax'
  199. if a:msg ==# 'update'
  200. echohl WarningMsg | echom '[everforest] Updated ' . rootpath . syntax_relative_path | echohl None
  201. call everforest#ftplugin_detect(a:path)
  202. else
  203. echohl WarningMsg | echom '[everforest] Generated ' . rootpath . syntax_relative_path | echohl None
  204. execute 'set runtimepath+=' . fnamemodify(rootpath, ':p') . 'after'
  205. endif
  206. endfunction "}}}
  207. function! everforest#syn_write(rootpath, syn, content) "{{{
  208. " Write the content.
  209. let syn_path = a:rootpath . '/after/syntax/' . a:syn . '/everforest.vim' " The path of a syntax file.
  210. " create a new file if it doesn't exist
  211. if !filereadable(syn_path)
  212. call mkdir(a:rootpath . '/after/syntax/' . a:syn, 'p')
  213. call writefile([
  214. \ "if !exists('g:colors_name') || g:colors_name !=# 'everforest'",
  215. \ ' finish',
  216. \ 'endif'
  217. \ ], syn_path, 'a') " Abort if the current color scheme is not everforest.
  218. call writefile([
  219. \ "if index(g:everforest_loaded_file_types, '" . a:syn . "') ==# -1",
  220. \ " call add(g:everforest_loaded_file_types, '" . a:syn . "')",
  221. \ 'else',
  222. \ ' finish',
  223. \ 'endif'
  224. \ ], syn_path, 'a') " Abort if this file type has already been loaded.
  225. endif
  226. " If there is something like `call everforest#highlight()`, then add
  227. " code to initialize the palette and configuration.
  228. if matchstr(a:content, 'everforest#highlight') !=# ''
  229. call writefile([
  230. \ 'let s:configuration = everforest#get_configuration()',
  231. \ 'let s:palette = everforest#get_palette(s:configuration.background, s:configuration.colors_override)'
  232. \ ], syn_path, 'a')
  233. endif
  234. " Append the content.
  235. call writefile(split(a:content, "\n"), syn_path, 'a')
  236. " Add modeline.
  237. call writefile(['" vim: set sw=2 ts=2 sts=2 et tw=80 ft=vim fdm=marker fmr={{{,}}}:'], syn_path, 'a')
  238. endfunction "}}}
  239. function! everforest#syn_rootpath(path) "{{{
  240. " Get the directory where `after/syntax` is generated.
  241. if (matchstr(a:path, '^/usr/share') ==# '') " Return the plugin directory. The `after/syntax` directory should never be generated in `/usr/share`, even if you are a root user.
  242. return fnamemodify(a:path, ':p:h:h')
  243. else " Use vim home directory.
  244. if has('nvim')
  245. return stdpath('config')
  246. else
  247. return expand('~') . '/.vim'
  248. endif
  249. endif
  250. endfunction "}}}
  251. function! everforest#syn_newest(path, last_modified) "{{{
  252. " Determine whether the current syntax files are up to date by comparing the last modified time in `colors/everforest.vim` and `after/syntax/text/everforest.vim`.
  253. let rootpath = everforest#syn_rootpath(a:path)
  254. execute 'source ' . rootpath . '/after/syntax/text/everforest.vim'
  255. return a:last_modified ==# g:everforest_last_modified ? 1 : 0
  256. endfunction "}}}
  257. function! everforest#syn_clean(path, msg) "{{{
  258. " Clean the `after/syntax` directory.
  259. let rootpath = everforest#syn_rootpath(a:path)
  260. " Remove `after/syntax/**/everforest.vim`.
  261. let file_list = split(globpath(rootpath, 'after/syntax/**/everforest.vim'), "\n")
  262. for file in file_list
  263. call delete(file)
  264. endfor
  265. " Remove empty directories.
  266. let dir_list = split(globpath(rootpath, 'after/syntax/*'), "\n")
  267. for dir in dir_list
  268. if globpath(dir, '*') ==# ''
  269. call delete(dir, 'd')
  270. endif
  271. endfor
  272. if globpath(rootpath . '/after/syntax', '*') ==# ''
  273. call delete(rootpath . '/after/syntax', 'd')
  274. endif
  275. if globpath(rootpath . '/after', '*') ==# ''
  276. call delete(rootpath . '/after', 'd')
  277. endif
  278. if a:msg
  279. let syntax_relative_path = has('win32') ? '\after\syntax' : '/after/syntax'
  280. echohl WarningMsg | echom '[everforest] Cleaned ' . rootpath . syntax_relative_path | echohl None
  281. endif
  282. endfunction "}}}
  283. function! everforest#syn_exists(path) "{{{
  284. return filereadable(everforest#syn_rootpath(a:path) . '/after/syntax/text/everforest.vim')
  285. endfunction "}}}
  286. function! everforest#ftplugin_detect(path) "{{{
  287. " Check if /after/ftplugin exists.
  288. " This directory is generated in earlier versions, users may need to manually clean it.
  289. let rootpath = everforest#syn_rootpath(a:path)
  290. if filereadable(everforest#syn_rootpath(a:path) . '/after/ftplugin/text/everforest.vim')
  291. let ftplugin_relative_path = has('win32') ? '\after\ftplugin' : '/after/ftplugin'
  292. echohl WarningMsg | echom '[everforest] Detected ' . rootpath . ftplugin_relative_path | echohl None
  293. echohl WarningMsg | echom '[everforest] This directory is no longer used, you may need to manually delete it.' | echohl None
  294. endif
  295. endfunction "}}}
  296. " vim: set sw=2 ts=2 sts=2 et tw=80 ft=vim fdm=marker fmr={{{,}}}: