15 changed files with 2356 additions and 4 deletions
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
nvim-colorizer.lua is the fastest colorizer for neovim |
||||
Copyright © 2019 Ashkan Kiani |
||||
|
||||
This program is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
@ -0,0 +1,154 @@
@@ -0,0 +1,154 @@
|
||||
# colorizer.lua |
||||
|
||||
[](https://norcalli.github.io/luadoc/nvim-colorizer.lua/modules/colorizer.html) |
||||
|
||||
A high-performance color highlighter for Neovim which has **no external dependencies**! Written in performant Luajit. |
||||
|
||||
 |
||||
|
||||
 |
||||
|
||||
## Installation and Usage |
||||
|
||||
Requires Neovim >= 0.4.0 and `set termguicolors` (I'm looking into relaxing |
||||
these constraints). If you don't have true color for your terminal or are |
||||
unsure, [read this excellent guide](https://github.com/termstandard/colors). |
||||
|
||||
Use your plugin manager or clone directly into your `runtimepath`. |
||||
|
||||
```vim |
||||
Plug 'norcalli/nvim-colorizer.lua' |
||||
``` |
||||
|
||||
As long as you have `malloc()` and `free()` on your system, this will work. |
||||
Which includes Linux, OSX, and Windows. |
||||
|
||||
One line setup. This will create an `autocmd` for `FileType *` to highlight |
||||
every filetype. |
||||
|
||||
```vim |
||||
lua require'colorizer'.setup() |
||||
``` |
||||
|
||||
### Why another highlighter? |
||||
|
||||
Mostly, **RAW SPEED**. |
||||
|
||||
This has no external dependencies, which means you install it and **it just |
||||
works**. Other colorizers typically were synchronous and slow, as well. Being |
||||
written with performance in mind and leveraging the excellent LuaJIT and a |
||||
handwritten parser, updates can be done in real time. There are plugins such as |
||||
[hexokinase](https://github.com/RRethy/vim-hexokinase) which have good |
||||
performance, but it has some difficulty with becoming out of sync. The downside |
||||
is that *this only works for Neovim*, and that will never change. |
||||
|
||||
Additionally, having a Lua API that's available means users can use this as a |
||||
library to do custom highlighting themselves. |
||||
|
||||
### Customization |
||||
|
||||
```lua |
||||
DEFAULT_OPTIONS = { |
||||
RGB = true; -- #RGB hex codes |
||||
RRGGBB = true; -- #RRGGBB hex codes |
||||
names = true; -- "Name" codes like Blue |
||||
RRGGBBAA = false; -- #RRGGBBAA hex codes |
||||
rgb_fn = false; -- CSS rgb() and rgba() functions |
||||
hsl_fn = false; -- CSS hsl() and hsla() functions |
||||
css = false; -- Enable all CSS features: rgb_fn, hsl_fn, names, RGB, RRGGBB |
||||
css_fn = false; -- Enable all CSS *functions*: rgb_fn, hsl_fn |
||||
-- Available modes: foreground, background |
||||
mode = 'background'; -- Set the display mode. |
||||
} |
||||
``` |
||||
|
||||
MODES: |
||||
- `foreground`: sets the foreground text color. |
||||
- `background`: sets the background text color. |
||||
|
||||
For basic setup, you can use a command like the following. |
||||
|
||||
```lua |
||||
-- Attaches to every FileType mode |
||||
require 'colorizer'.setup() |
||||
|
||||
-- Attach to certain Filetypes, add special configuration for `html` |
||||
-- Use `background` for everything else. |
||||
require 'colorizer'.setup { |
||||
'css'; |
||||
'javascript'; |
||||
html = { |
||||
mode = 'foreground'; |
||||
} |
||||
} |
||||
|
||||
-- Use the `default_options` as the second parameter, which uses |
||||
-- `foreground` for every mode. This is the inverse of the previous |
||||
-- setup configuration. |
||||
require 'colorizer'.setup({ |
||||
'css'; |
||||
'javascript'; |
||||
html = { mode = 'background' }; |
||||
}, { mode = 'foreground' }) |
||||
|
||||
-- Use the `default_options` as the second parameter, which uses |
||||
-- `foreground` for every mode. This is the inverse of the previous |
||||
-- setup configuration. |
||||
require 'colorizer'.setup { |
||||
'*'; -- Highlight all files, but customize some others. |
||||
css = { rgb_fn = true; }; -- Enable parsing rgb(...) functions in css. |
||||
html = { names = false; } -- Disable parsing "names" like Blue or Gray |
||||
} |
||||
|
||||
-- Exclude some filetypes from highlighting by using `!` |
||||
require 'colorizer'.setup { |
||||
'*'; -- Highlight all files, but customize some others. |
||||
'!vim'; -- Exclude vim from highlighting. |
||||
-- Exclusion Only makes sense if '*' is specified! |
||||
} |
||||
``` |
||||
|
||||
|
||||
For lower level interface, see the [LuaDocs for API details](https://norcalli.github.io/luadoc/nvim-colorizer.lua/modules/colorizer.html) or use `:h colorizer.lua` once installed. |
||||
|
||||
## Commands |
||||
|
||||
```help |
||||
|:ColorizerAttachToBuffer| |
||||
|
||||
Attach to the current buffer and start highlighting with the settings as |
||||
specified in setup (or the defaults). |
||||
|
||||
If the buffer was already attached (i.e. being highlighted), the settings will |
||||
be reloaded with the ones from setup. This is useful for reloading settings |
||||
for just one buffer. |
||||
|
||||
|:ColorizerDetachFromBuffer| |
||||
|
||||
Stop highlighting the current buffer (detach). |
||||
|
||||
|:ColorizerReloadAllBuffers| |
||||
|
||||
Reload all buffers that are being highlighted with new settings from the setup |
||||
settings (or the defaults). Shortcut for ColorizerAttachToBuffer on every |
||||
buffer. |
||||
|
||||
|:ColorizerToggle| |
||||
|
||||
Toggle highlighting of the current buffer. |
||||
``` |
||||
|
||||
|
||||
## Caveats |
||||
|
||||
If the file you are editing has no filetype, the plugin won't be attached, as |
||||
it relies on AutoCmd to do so. You can still make it work by running the |
||||
following command: `:ColorizerAttachToBuffer` |
||||
|
||||
See [this comment](https://github.com/norcalli/nvim-colorizer.lua/issues/9#issuecomment-543742619) for more information. |
||||
|
||||
## TODO |
||||
|
||||
- [ ] Add more display modes? |
||||
- [ ] Use a more space efficient trie implementation. |
||||
- [ ] Create a COMMON_SETUP which does obvious things like enable `rgb_fn` for css |
@ -0,0 +1,160 @@
@@ -0,0 +1,160 @@
|
||||
*colorizer.lua* Highlight color codes like #RRGGBB and others. |
||||
|
||||
Minimum version of neovim: 0.4.0 |
||||
|
||||
Author: Ashkan Kiani <from-nvim-colorizer.lua@kiani.io> |
||||
|
||||
============================================================================== |
||||
INTRODUCTION *colorizer-lua-introduction* |
||||
|
||||
============================================================================== |
||||
QUICK START *colorizer-lua-quickstart* |
||||
|
||||
Establish the an autocmd to highlight all filetypes. |
||||
> |
||||
lua require 'colorizer'.setup() |
||||
|
||||
" Highlight using all available possible highlight modes in every filetype |
||||
lua require 'colorizer'.setup(nil, { css = true; }) |
||||
< |
||||
|
||||
============================================================================== |
||||
COMMANDS *colorizer-commands* |
||||
|
||||
|:ColorizerAttachToBuffer| *:ColorizerAttachToBuffer* |
||||
|
||||
Attach to the current buffer and start highlighting with the settings as |
||||
specified in setup (or the defaults). |
||||
|
||||
If the buffer was already attached (i.e. being highlighted), the settings will |
||||
be reloaded with the ones from setup. This is useful for reloading settings |
||||
for just one buffer. |
||||
|
||||
|
||||
|:ColorizerDetachFromBuffer| *:ColorizerDetachFromBuffer* |
||||
|
||||
Stop highlighting the current buffer (detach). |
||||
|
||||
|:ColorizerReloadAllBuffers| *:ColorizerReloadAllBuffers* |
||||
|
||||
Reload all buffers that are being highlighted with new settings from the setup |
||||
settings (or the defaults). Shortcut for ColorizerAttachToBuffer on every |
||||
buffer. |
||||
|
||||
:ColorizerToggle :ColorizerToggle |
||||
|
||||
Toggle highlighting of the current buffer. |
||||
|
||||
============================================================================== |
||||
LUA API DEFINITION *colorizer-lua-api* |
||||
|
||||
Assumes the module is imported as `colorizer` |
||||
|
||||
|colorizer-options| *colorizer-options* |
||||
|
||||
> |
||||
DEFAULT_OPTIONS = { |
||||
RGB = true; -- #RGB hex codes |
||||
RRGGBB = true; -- #RRGGBB hex codes |
||||
names = true; -- "Name" codes like Blue |
||||
RRGGBBAA = false; -- #RRGGBBAA hex codes |
||||
rgb_fn = false; -- CSS rgb() and rgba() functions |
||||
hsl_fn = false; -- CSS hsl() and hsla() functions |
||||
css = false; -- Enable all CSS features: rgb_fn, hsl_fn, names, RGB, RRGGBB |
||||
css_fn = false; -- Enable all CSS *functions*: rgb_fn, hsl_fn |
||||
-- Available modes: foreground, background |
||||
mode = 'background'; -- Set the display mode. |
||||
} |
||||
< |
||||
|
||||
MODES: |
||||
- 'foreground': sets the foreground text color. |
||||
- 'background': sets the background text color. |
||||
|
||||
|
||||
|colorizer.setup| *colorizer.setup* |
||||
|
||||
Easy to use function if you want the full setup without fine grained control. |
||||
Establishes an autocmd for `FileType`s . |
||||
|
||||
PARAMETERS: |
||||
`filetypes` (optional) filetypes to enable. see examples below |
||||
`default_options` (optional) |colorizer-options| |
||||
> |
||||
colorizer.setup([filetypes=nil], [default_options={}]) |
||||
|
||||
" In your VIMRC |
||||
lua require'colorizer'.setup() |
||||
|
||||
-- From lua |
||||
-- Attaches to every FileType mode |
||||
require 'colorizer'.setup() |
||||
|
||||
-- Attach to certain Filetypes, add special configuration for `html` |
||||
-- Use `background` for everything else. |
||||
require 'colorizer'.setup { |
||||
'css'; |
||||
'javascript'; |
||||
html = { |
||||
mode = 'foreground'; |
||||
} |
||||
} |
||||
|
||||
-- Use the `default_options` as the second parameter, which uses |
||||
-- `foreground` for every mode. This is the inverse of the previous |
||||
-- setup configuration. |
||||
require 'colorizer'.setup({ |
||||
'css'; |
||||
'javascript'; |
||||
html = { mode = 'background' }; |
||||
}, { mode = 'foreground' }) |
||||
|
||||
-- Use the `default_options` as the second parameter, which uses |
||||
-- `foreground` for every mode. This is the inverse of the previous |
||||
-- setup configuration. |
||||
require 'colorizer'.setup { |
||||
'*'; -- Highlight all files, but customize some others. |
||||
css = { rgb_fn = true; }; -- Enable parsing rgb(...) functions in css. |
||||
html = { names = false; } -- Disable parsing "names" like Blue or Gray |
||||
} |
||||
|
||||
-- Exclude some filetypes from highlighting by using `!` |
||||
require 'colorizer'.setup { |
||||
'*'; -- Highlight all files, but customize some others. |
||||
'!vim'; -- Exclude vim from highlighting. |
||||
-- Exclusion Only makes sense if '*' is specified! |
||||
} |
||||
< |
||||
|
||||
|colorizer.highlight_buffer| *colorizer.highlight_buffer* |
||||
|
||||
Highlight starting from `line_start` (0-indexed) for each line described by `lines` in the |
||||
buffer `buf` and attach it to the namespace `ns`. |
||||
|
||||
PARAMETERS: |
||||
`buf` buffer id. |
||||
`ns` the namespace id. Create it with `vim.api.create_namespace` |
||||
`lines` the lines to highlight from the buffer. |
||||
`line_start` should be 0-indexed |
||||
`options` |colorizer-options| to set. REQUIRED! |
||||
> |
||||
colorizer.highlight_buffer(buf[, ns=DEFAULT_NAMESPACE], |
||||
lines, line_start, options) |
||||
< |
||||
|
||||
|colorizer.attach_to_buffer| *colorizer.attach_to_buffer* |
||||
|
||||
Attach to a buffer and continuously highlight changes. |
||||
|
||||
If you don't specify `options`, it will be set from the setup options if |
||||
specified or the default in |colorizer-options|. |
||||
|
||||
PARAMETERS: |
||||
`buf` A value of 0 implies the current buffer. |
||||
`options` (optional) |colorizer-options| to set. |
||||
> |
||||
colorizer.attach_to_buffer(buf[, options={}]) |
||||
< |
||||
|
||||
vim:tw=78:ts=8:noet:ft=help:norl: |
||||
|
@ -0,0 +1,70 @@
@@ -0,0 +1,70 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
||||
<html> |
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> |
||||
<head> |
||||
<title>Reference</title> |
||||
<link rel="stylesheet" href="ldoc.css" type="text/css" /> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="container"> |
||||
|
||||
<div id="product"> |
||||
<div id="product_logo"></div> |
||||
<div id="product_name"><big><b></b></big></div> |
||||
<div id="product_description"></div> |
||||
</div> <!-- id="product" --> |
||||
|
||||
|
||||
<div id="main"> |
||||
|
||||
|
||||
<!-- Menu --> |
||||
|
||||
<div id="navigation"> |
||||
<br/> |
||||
<h1>ldoc</h1> |
||||
|
||||
|
||||
|
||||
|
||||
<h2>Modules</h2> |
||||
<ul class="nowrap"> |
||||
<li><a href="modules/colorizer.html">colorizer</a></li> |
||||
<li><a href="modules/nvim.html">nvim</a></li> |
||||
<li><a href="modules/trie.html">trie</a></li> |
||||
</ul> |
||||
|
||||
</div> |
||||
|
||||
<div id="content"> |
||||
|
||||
|
||||
|
||||
<h2>Modules</h2> |
||||
<table class="module_list"> |
||||
<tr> |
||||
<td class="name" nowrap><a href="modules/colorizer.html">colorizer</a></td> |
||||
<td class="summary">Highlights terminal CSI ANSI color codes.</td> |
||||
</tr> |
||||
<tr> |
||||
<td class="name" nowrap><a href="modules/nvim.html">nvim</a></td> |
||||
<td class="summary">Module of magic functions for nvim</td> |
||||
</tr> |
||||
<tr> |
||||
<td class="name" nowrap><a href="modules/trie.html">trie</a></td> |
||||
<td class="summary">Trie implementation in luajit |
||||
Copyright © 2019 Ashkan Kiani</td> |
||||
</tr> |
||||
</table> |
||||
|
||||
</div> <!-- id="content" --> |
||||
</div> <!-- id="main" --> |
||||
<div id="about"> |
||||
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> |
||||
<i style="float:right;">Last updated 2019-10-18 09:40:19 </i> |
||||
</div> <!-- id="about" --> |
||||
</div> <!-- id="container" --> |
||||
</body> |
||||
</html> |
@ -0,0 +1,303 @@
@@ -0,0 +1,303 @@
|
||||
/* BEGIN RESET |
||||
|
||||
Copyright (c) 2010, Yahoo! Inc. All rights reserved. |
||||
Code licensed under the BSD License: |
||||
http://developer.yahoo.com/yui/license.html |
||||
version: 2.8.2r1 |
||||
*/ |
||||
html { |
||||
color: #000; |
||||
background: #FFF; |
||||
} |
||||
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td { |
||||
margin: 0; |
||||
padding: 0; |
||||
} |
||||
table { |
||||
border-collapse: collapse; |
||||
border-spacing: 0; |
||||
} |
||||
fieldset,img { |
||||
border: 0; |
||||
} |
||||
address,caption,cite,code,dfn,em,strong,th,var,optgroup { |
||||
font-style: inherit; |
||||
font-weight: inherit; |
||||
} |
||||
del,ins { |
||||
text-decoration: none; |
||||
} |
||||
li { |
||||
margin-left: 20px; |
||||
} |
||||
caption,th { |
||||
text-align: left; |
||||
} |
||||
h1,h2,h3,h4,h5,h6 { |
||||
font-size: 100%; |
||||
font-weight: bold; |
||||
} |
||||
q:before,q:after { |
||||
content: ''; |
||||
} |
||||
abbr,acronym { |
||||
border: 0; |
||||
font-variant: normal; |
||||
} |
||||
sup { |
||||
vertical-align: baseline; |
||||
} |
||||
sub { |
||||
vertical-align: baseline; |
||||
} |
||||
legend { |
||||
color: #000; |
||||
} |
||||
input,button,textarea,select,optgroup,option { |
||||
font-family: inherit; |
||||
font-size: inherit; |
||||
font-style: inherit; |
||||
font-weight: inherit; |
||||
} |
||||
input,button,textarea,select {*font-size:100%; |
||||
} |
||||
/* END RESET */ |
||||
|
||||
body { |
||||
margin-left: 1em; |
||||
margin-right: 1em; |
||||
font-family: arial, helvetica, geneva, sans-serif; |
||||
background-color: #ffffff; margin: 0px; |
||||
} |
||||
|
||||
code, tt { font-family: monospace; font-size: 1.1em; } |
||||
span.parameter { font-family:monospace; } |
||||
span.parameter:after { content:":"; } |
||||
span.types:before { content:"("; } |
||||
span.types:after { content:")"; } |
||||
.type { font-weight: bold; font-style:italic } |
||||
|
||||
body, p, td, th { font-size: .95em; line-height: 1.2em;} |
||||
|
||||
p, ul { margin: 10px 0 0 0px;} |
||||
|
||||
strong { font-weight: bold;} |
||||
|
||||
em { font-style: italic;} |
||||
|
||||
h1 { |
||||
font-size: 1.5em; |
||||
margin: 20px 0 20px 0; |
||||
} |
||||
h2, h3, h4 { margin: 15px 0 10px 0; } |
||||
h2 { font-size: 1.25em; } |
||||
h3 { font-size: 1.15em; } |
||||
h4 { font-size: 1.06em; } |
||||
|
||||
a:link { font-weight: bold; color: #004080; text-decoration: none; } |
||||
a:visited { font-weight: bold; color: #006699; text-decoration: none; } |
||||
a:link:hover { text-decoration: underline; } |
||||
|
||||
hr { |
||||
color:#cccccc; |
||||
background: #00007f; |
||||
height: 1px; |
||||
} |
||||
|
||||
blockquote { margin-left: 3em; } |
||||
|
||||
ul { list-style-type: disc; } |
||||
|
||||
p.name { |
||||
font-family: "Andale Mono", monospace; |
||||
padding-top: 1em; |
||||
} |
||||
|
||||
pre { |
||||
background-color: rgb(245, 245, 245); |
||||
border: 1px solid #C0C0C0; /* silver */ |
||||
padding: 10px; |
||||
margin: 10px 0 10px 0; |
||||
overflow: auto; |
||||
font-family: "Andale Mono", monospace; |
||||
} |
||||
|
||||
pre.example { |
||||
font-size: .85em; |
||||
} |
||||
|
||||
table.index { border: 1px #00007f; } |
||||
table.index td { text-align: left; vertical-align: top; } |
||||
|
||||
#container { |
||||
margin-left: 1em; |
||||
margin-right: 1em; |
||||
background-color: #f0f0f0; |
||||
} |
||||
|
||||
#product { |
||||
text-align: center; |
||||
border-bottom: 1px solid #cccccc; |
||||
background-color: #ffffff; |
||||
} |
||||
|
||||
#product big { |
||||
font-size: 2em; |
||||
} |
||||
|
||||
#main { |
||||
background-color: #f0f0f0; |
||||
border-left: 2px solid #cccccc; |
||||
} |
||||
|
||||
#navigation { |
||||
float: left; |
||||
width: 14em; |
||||
vertical-align: top; |
||||
background-color: #f0f0f0; |
||||
overflow: visible; |
||||
} |
||||
|
||||
#navigation h2 { |
||||
background-color:#e7e7e7; |
||||
font-size:1.1em; |
||||
color:#000000; |
||||
text-align: left; |
||||
padding:0.2em; |
||||
border-top:1px solid #dddddd; |
||||
border-bottom:1px solid #dddddd; |
||||
} |
||||
|
||||
#navigation ul |
||||
{ |
||||
font-size:1em; |
||||
list-style-type: none; |
||||
margin: 1px 1px 10px 1px; |
||||
} |
||||
|
||||
#navigation li { |
||||
text-indent: -1em; |
||||
display: block; |
||||
margin: 3px 0px 0px 22px; |
||||
} |
||||
|
||||
#navigation li li a { |
||||
margin: 0px 3px 0px -1em; |
||||
} |
||||
|
||||
#content { |
||||
margin-left: 14em; |
||||
padding: 1em; |
||||
width: 700px; |
||||
border-left: 2px solid #cccccc; |
||||
border-right: 2px solid #cccccc; |
||||
background-color: #ffffff; |
||||
} |
||||
|
||||
#about { |
||||
clear: both; |
||||
padding: 5px; |
||||
border-top: 2px solid #cccccc; |
||||
background-color: #ffffff; |
||||
} |
||||
|
||||
@media print { |
||||
body { |
||||
font: 12pt "Times New Roman", "TimeNR", Times, serif; |
||||
} |
||||
a { font-weight: bold; color: #004080; text-decoration: underline; } |
||||
|
||||
#main { |
||||
background-color: #ffffff; |
||||
border-left: 0px; |
||||
} |
||||
|
||||
#container { |
||||
margin-left: 2%; |
||||
margin-right: 2%; |
||||
background-color: #ffffff; |
||||
} |
||||
|
||||
#content { |
||||
padding: 1em; |
||||
background-color: #ffffff; |
||||
} |
||||
|
||||
#navigation { |
||||
display: none; |
||||
} |
||||
pre.example { |
||||
font-family: "Andale Mono", monospace; |
||||
font-size: 10pt; |
||||
page-break-inside: avoid; |
||||
} |
||||
} |
||||
|
||||
table.module_list { |
||||
border-width: 1px; |
||||
border-style: solid; |
||||
border-color: #cccccc; |
||||
border-collapse: collapse; |
||||
} |
||||
table.module_list td { |
||||
border-width: 1px; |
||||
padding: 3px; |
||||
border-style: solid; |
||||
border-color: #cccccc; |
||||
} |
||||
table.module_list td.name { background-color: #f0f0f0; min-width: 200px; } |
||||
table.module_list td.summary { width: 100%; } |
||||
|
||||
|
||||
table.function_list { |
||||
border-width: 1px; |
||||
border-style: solid; |
||||
border-color: #cccccc; |
||||
border-collapse: collapse; |
||||
} |
||||
table.function_list td { |
||||
border-width: 1px; |
||||
padding: 3px; |
||||
border-style: solid; |
||||
border-color: #cccccc; |
||||
} |
||||
table.function_list td.name { background-color: #f0f0f0; min-width: 200px; } |
||||
table.function_list td.summary { width: 100%; } |
||||
|
||||
ul.nowrap { |
||||
overflow:auto; |
||||
white-space:nowrap; |
||||
} |
||||
|
||||
dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} |
||||
dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;} |
||||
dl.table h3, dl.function h3 {font-size: .95em;} |
||||
|
||||
/* stop sublists from having initial vertical space */ |
||||
ul ul { margin-top: 0px; } |
||||
ol ul { margin-top: 0px; } |
||||
ol ol { margin-top: 0px; } |
||||
ul ol { margin-top: 0px; } |
||||
|
||||
/* make the target distinct; helps when we're navigating to a function */ |
||||
a:target + * { |
||||
background-color: #FF9; |
||||
} |
||||
|
||||
|
||||
/* styles for prettification of source */ |
||||
pre .comment { color: #558817; } |
||||
pre .constant { color: #a8660d; } |
||||
pre .escape { color: #844631; } |
||||
pre .keyword { color: #aa5050; font-weight: bold; } |
||||
pre .library { color: #0e7c6b; } |
||||
pre .marker { color: #512b1e; background: #fedc56; font-weight: bold; } |
||||
pre .string { color: #8080ff; } |
||||
pre .number { color: #f8660d; } |
||||
pre .operator { color: #2239a8; font-weight: bold; } |
||||
pre .preprocessor, pre .prepro { color: #a33243; } |
||||
pre .global { color: #800080; } |
||||
pre .user-keyword { color: #800080; } |
||||
pre .prompt { color: #558817; } |
||||
pre .url { color: #272fc2; text-decoration: underline; } |
||||
|
@ -0,0 +1,312 @@
@@ -0,0 +1,312 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
||||
<html> |
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> |
||||
<head> |
||||
<title>Reference</title> |
||||
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="container"> |
||||
|
||||
<div id="product"> |
||||
<div id="product_logo"></div> |
||||
<div id="product_name"><big><b></b></big></div> |
||||
<div id="product_description"></div> |
||||
</div> <!-- id="product" --> |
||||
|
||||
|
||||
<div id="main"> |
||||
|
||||
|
||||
<!-- Menu --> |
||||
|
||||
<div id="navigation"> |
||||
<br/> |
||||
<h1>ldoc</h1> |
||||
|
||||
<ul> |
||||
<li><a href="../index.html">Index</a></li> |
||||
</ul> |
||||
|
||||
<h2>Contents</h2> |
||||
<ul> |
||||
<li><a href="#Functions">Functions</a></li> |
||||
<li><a href="#Fields">Fields</a></li> |
||||
</ul> |
||||
|
||||
|
||||
<h2>Modules</h2> |
||||
<ul class="nowrap"> |
||||
<li><strong>colorizer</strong></li> |
||||
<li><a href="../modules/nvim.html">nvim</a></li> |
||||
<li><a href="../modules/trie.html">trie</a></li> |
||||
</ul> |
||||
|
||||
</div> |
||||
|
||||
<div id="content"> |
||||
|
||||
<h1>Module <code>colorizer</code></h1> |
||||
<p>Highlights terminal CSI ANSI color codes.</p> |
||||
<p></p> |
||||
|
||||
|
||||
<h2><a href="#Functions">Functions</a></h2> |
||||
<table class="function_list"> |
||||
<tr> |
||||
<td class="name" nowrap><a href="#highlight_buffer">highlight_buffer (buf[, ns=DEFAULT_NAMESPACE], lines, line_start, options)</a></td> |
||||
<td class="summary">Highlight the buffer region.</td> |
||||
</tr> |
||||
<tr> |
||||
<td class="name" nowrap><a href="#attach_to_buffer">attach_to_buffer ([buf=0|nil[, options]])</a></td> |
||||
<td class="summary">Attach to a buffer and continuously highlight changes.</td> |
||||
</tr> |
||||
<tr> |
||||
<td class="name" nowrap><a href="#detach_from_buffer">detach_from_buffer ([buf=0|nil[, ns=DEFAULT_NAMESPACE]])</a></td> |
||||
<td class="summary">Stop highlighting the current buffer.</td> |
||||
</tr> |
||||
<tr> |
||||
<td class="name" nowrap><a href="#setup">setup ([filetypes={'*'}[, default_options]])</a></td> |
||||
<td class="summary">Easy to use function if you want the full setup without fine grained control.</td> |
||||
</tr> |
||||
<tr> |
||||
<td class="name" nowrap><a href="#reload_all_buffers">reload_all_buffers ()</a></td> |
||||
<td class="summary">Reload all of the currently active highlighted buffers.</td> |
||||
</tr> |
||||
<tr> |
||||
<td class="name" nowrap><a href="#get_buffer_options">get_buffer_options ([buf=0|nil])</a></td> |
||||
<td class="summary">Return the currently active buffer options.</td> |
||||
</tr> |
||||
</table> |
||||
<h2><a href="#Fields">Fields</a></h2> |
||||
<table class="function_list"> |
||||
<tr> |
||||
<td class="name" nowrap><a href="#DEFAULT_NAMESPACE">DEFAULT_NAMESPACE</a></td> |
||||
<td class="summary">Default namespace used in `highlight_buffer` and `attach_to_buffer`.</td> |
||||
</tr> |
||||
</table> |
||||
|
||||
<br/> |
||||
<br/> |
||||
|
||||
|
||||
<h2 class="section-header "><a name="Functions"></a>Functions</h2> |
||||
|
||||
<dl class="function"> |
||||
<dt> |
||||
<a name = "highlight_buffer"></a> |
||||
<strong>highlight_buffer (buf[, ns=DEFAULT_NAMESPACE], lines, line_start, options)</strong> |
||||
</dt> |
||||
<dd> |
||||
Highlight the buffer region. |
||||
Highlight starting from `line_start` (0-indexed) for each line described by `lines` in the |
||||
buffer `buf` and attach it to the namespace `ns`. |
||||
|
||||
|
||||
|
||||
<h3>Parameters:</h3> |
||||
<ul> |
||||
<li><span class="parameter">buf</span> |
||||
<span class="types"><span class="type">integer</span></span> |
||||
buffer id. |
||||
</li> |
||||
<li><span class="parameter">ns</span> |
||||
<span class="types"><span class="type">integer</span></span> |
||||
the namespace id. Create it with `vim.api.create_namespace` |
||||
(<em>default</em> DEFAULT_NAMESPACE) |
||||
</li> |
||||
<li><span class="parameter">lines</span> |
||||
<span class="types"><a class="type" href="https://www.lua.org/manual/5.3/manual.html#6.4">{string,...}</a></span> |
||||
the lines to highlight from the buffer. |
||||
</li> |
||||
<li><span class="parameter">line_start</span> |
||||
<span class="types"><span class="type">integer</span></span> |
||||
should be 0-indexed |
||||
</li> |
||||
<li><span class="parameter">options</span> |
||||
Configuration options as described in `setup` |
||||
</li> |
||||
</ul> |
||||
|
||||
|
||||
|
||||
<h3>See also:</h3> |
||||
<ul> |
||||
<a href="../modules/colorizer.html#setup">setup</a> |
||||
</ul> |
||||
|
||||
|
||||
</dd> |
||||
<dt> |
||||
<a name = "attach_to_buffer"></a> |
||||
<strong>attach_to_buffer ([buf=0|nil[, options]])</strong> |
||||
</dt> |
||||
<dd> |
||||
Attach to a buffer and continuously highlight changes. |
||||
|
||||
|
||||
<h3>Parameters:</h3> |
||||
<ul> |
||||
<li><span class="parameter">buf</span> |
||||
<span class="types"><span class="type">integer</span></span> |
||||
A value of 0 implies the current buffer. |
||||
(<em>default</em> 0|nil) |
||||
</li> |
||||
<li><span class="parameter">options</span> |
||||
Configuration options as described in `setup` |
||||
(<em>optional</em>) |
||||
</li> |
||||
</ul> |
||||
|
||||
|
||||
|
||||
<h3>See also:</h3> |
||||
<ul> |
||||
<a href="../modules/colorizer.html#setup">setup</a> |
||||
</ul> |
||||
|
||||
|
||||
</dd> |
||||
<dt> |
||||
<a name = "detach_from_buffer"></a> |
||||
<strong>detach_from_buffer ([buf=0|nil[, ns=DEFAULT_NAMESPACE]])</strong> |
||||
</dt> |
||||
<dd> |
||||
Stop highlighting the current buffer. |
||||
|
||||
|
||||
<h3>Parameters:</h3> |
||||
<ul> |
||||
<li><span class="parameter">buf</span> |
||||
<span class="types"><span class="type">integer</span></span> |
||||
A value of 0 or nil implies the current buffer. |
||||
(<em>default</em> 0|nil) |
||||
</li> |
||||
<li><span class="parameter">ns</span> |
||||
<span class="types"><span class="type">integer</span></span> |
||||
the namespace id. |
||||
(<em>default</em> DEFAULT_NAMESPACE) |
||||
</li> |
||||
</ul> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd> |
||||
<dt> |
||||
<a name = "setup"></a> |
||||
<strong>setup ([filetypes={'*'}[, default_options]])</strong> |
||||
</dt> |
||||
<dd> |
||||
Easy to use function if you want the full setup without fine grained control. |
||||
Setup an autocmd which enables colorizing for the filetypes and options specified. |
||||
<p> By default highlights all FileTypes. |
||||
<p> Example config: |
||||
``` |
||||
{ 'scss', 'html', css = { rgb_fn = true; }, javascript = { no_names = true } } |
||||
``` |
||||
<p> You can combine an array and more specific options. |
||||
Possible options: |
||||
- `no_names`: Don't highlight names like Blue |
||||
- `rgb_fn`: Highlight `rgb(...)` functions. |
||||
- `mode`: Highlight mode. Valid options: `foreground`,`background` |
||||
|
||||
|
||||
|
||||
<h3>Parameters:</h3> |
||||
<ul> |
||||
<li><span class="parameter">filetypes</span> |
||||
A table/array of filetypes to selectively enable and/or customize. By default, enables all filetypes. |
||||
(<em>default</em> {'*'}) |
||||
</li> |
||||
<li><span class="parameter">default_options</span> |
||||
<span class="types"><a class="type" href="https://www.lua.org/manual/5.3/manual.html#6.4">{[string]=string}</a></span> |
||||
Default options to apply for the filetypes enable. |
||||
(<em>optional</em>) |
||||
</li> |
||||
</ul> |
||||
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3> |
||||
<ul> |
||||
<pre class="example"><span class="global">require</span><span class="string">'colorizer'</span>.setup()</pre> |
||||
</ul> |
||||
|
||||
</dd> |
||||
<dt> |
||||
<a name = "reload_all_buffers"></a> |
||||
<strong>reload_all_buffers ()</strong> |
||||
</dt> |
||||
<dd> |
||||
Reload all of the currently active highlighted buffers. |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd> |
||||
<dt> |
||||
<a name = "get_buffer_options"></a> |
||||
<strong>get_buffer_options ([buf=0|nil])</strong> |
||||
</dt> |
||||
<dd> |
||||
Return the currently active buffer options. |
||||
|
||||
|
||||
<h3>Parameters:</h3> |
||||
<ul> |
||||
<li><span class="parameter">buf</span> |
||||
<span class="types"><span class="type">integer</span></span> |
||||
A value of 0 or nil implies the current buffer. |
||||
(<em>default</em> 0|nil) |
||||
</li> |
||||
</ul> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd> |
||||
</dl> |
||||
<h2 class="section-header "><a name="Fields"></a>Fields</h2> |
||||
|
||||
<dl class="function"> |
||||
<dt> |
||||
<a name = "DEFAULT_NAMESPACE"></a> |
||||
<strong>DEFAULT_NAMESPACE</strong> |
||||
</dt> |
||||
<dd> |
||||
Default namespace used in `highlight_buffer` and `attach_to_buffer`. |
||||
The name is "terminal_highlight" |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>See also:</h3> |
||||
<ul> |
||||
<li><a href="../modules/colorizer.html#highlight_buffer">highlight_buffer</a></li> |
||||
<li><a href="../modules/colorizer.html#attach_to_buffer">attach_to_buffer</a></li> |
||||
</ul> |
||||
|
||||
|
||||
</dd> |
||||
</dl> |
||||
|
||||
|
||||
</div> <!-- id="content" --> |
||||
</div> <!-- id="main" --> |
||||
<div id="about"> |
||||
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> |
||||
<i style="float:right;">Last updated 2019-10-18 09:40:19 </i> |
||||
</div> <!-- id="about" --> |
||||
</div> <!-- id="container" --> |
||||
</body> |
||||
</html> |
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
||||
<html> |
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> |
||||
<head> |
||||
<title>Reference</title> |
||||
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="container"> |
||||
|
||||
<div id="product"> |
||||
<div id="product_logo"></div> |
||||
<div id="product_name"><big><b></b></big></div> |
||||
<div id="product_description"></div> |
||||
</div> <!-- id="product" --> |
||||
|
||||
|
||||
<div id="main"> |
||||
|
||||
|
||||
<!-- Menu --> |
||||
|
||||
<div id="navigation"> |
||||
<br/> |
||||
<h1>ldoc</h1> |
||||
|
||||
<ul> |
||||
<li><a href="../index.html">Index</a></li> |
||||
</ul> |
||||
|
||||
|
||||
|
||||
<h2>Modules</h2> |
||||
<ul class="nowrap"> |
||||
<li><a href="../modules/colorizer.html">colorizer</a></li> |
||||
<li><strong>nvim</strong></li> |
||||
<li><a href="../modules/trie.html">trie</a></li> |
||||
</ul> |
||||
|
||||
</div> |
||||
|
||||
<div id="content"> |
||||
|
||||
<h1>Module <code>nvim</code></h1> |
||||
<p>Module of magic functions for nvim</p> |
||||
<p></p> |
||||
|
||||
|
||||
|
||||
<br/> |
||||
<br/> |
||||
|
||||
|
||||
|
||||
|
||||
</div> <!-- id="content" --> |
||||
</div> <!-- id="main" --> |
||||
<div id="about"> |
||||
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> |
||||
<i style="float:right;">Last updated 2019-10-18 09:40:19 </i> |
||||
</div> <!-- id="about" --> |
||||
</div> <!-- id="container" --> |
||||
</body> |
||||
</html> |
@ -0,0 +1,67 @@
@@ -0,0 +1,67 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
||||
<html> |
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> |
||||
<head> |
||||
<title>Reference</title> |
||||
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> |
||||
</head> |
||||
<body> |
||||
|
||||
<div id="container"> |
||||
|
||||
<div id="product"> |
||||
<div id="product_logo"></div> |
||||
<div id="product_name"><big><b></b></big></div> |
||||
<div id="product_description"></div> |
||||
</div> <!-- id="product" --> |
||||
|
||||
|
||||
<div id="main"> |
||||
|
||||
|
||||
<!-- Menu --> |
||||
|
||||
<div id="navigation"> |
||||
<br/> |
||||
<h1>ldoc</h1> |
||||
|
||||
<ul> |
||||
<li><a href="../index.html">Index</a></li> |
||||
</ul> |
||||
|
||||
|
||||
|
||||
<h2>Modules</h2> |
||||
<ul class="nowrap"> |
||||
<li><a href="../modules/colorizer.html">colorizer</a></li> |
||||
<li><a href="../modules/nvim.html">nvim</a></li> |
||||
<li><strong>trie</strong></li> |
||||
</ul> |
||||
|
||||
</div> |
||||
|
||||
<div id="content"> |
||||
|
||||
<h1>Module <code>trie</code></h1> |
||||
<p>Trie implementation in luajit |
||||
Copyright © 2019 Ashkan Kiani</p> |
||||
<p></p> |
||||
|
||||
|
||||
|
||||
<br/> |
||||
<br/> |
||||
|
||||
|
||||
|
||||
|
||||
</div> <!-- id="content" --> |
||||
</div> <!-- id="main" --> |
||||
<div id="about"> |
||||
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> |
||||
<i style="float:right;">Last updated 2019-10-18 09:40:19 </i> |
||||
</div> <!-- id="about" --> |
||||
</div> <!-- id="container" --> |
||||
</body> |
||||
</html> |
@ -0,0 +1,647 @@
@@ -0,0 +1,647 @@
|
||||
--- Highlights terminal CSI ANSI color codes. |
||||
-- @module colorizer |
||||
local nvim = require 'colorizer/nvim' |
||||
local Trie = require 'colorizer/trie' |
||||
local bit = require 'bit' |
||||
local ffi = require 'ffi' |
||||
|
||||
local nvim_buf_add_highlight = vim.api.nvim_buf_add_highlight |
||||
local nvim_buf_clear_namespace = vim.api.nvim_buf_clear_namespace |
||||
local nvim_buf_get_lines = vim.api.nvim_buf_get_lines |
||||
local nvim_get_current_buf = vim.api.nvim_get_current_buf |
||||
local band, lshift, bor, tohex = bit.band, bit.lshift, bit.bor, bit.tohex |
||||
local rshift = bit.rshift |
||||
local floor, min, max = math.floor, math.min, math.max |
||||
|
||||
local COLOR_MAP |
||||
local COLOR_TRIE |
||||
local COLOR_NAME_MINLEN, COLOR_NAME_MAXLEN |
||||
local COLOR_NAME_SETTINGS = { |
||||
lowercase = false; |
||||
strip_digits = false; |
||||
} |
||||
|
||||
--- Setup the COLOR_MAP and COLOR_TRIE |
||||
local function initialize_trie() |
||||
if not COLOR_TRIE then |
||||
COLOR_MAP = {} |
||||
COLOR_TRIE = Trie() |
||||
for k, v in pairs(nvim.get_color_map()) do |
||||
if not (COLOR_NAME_SETTINGS.strip_digits and k:match("%d+$")) then |
||||
COLOR_NAME_MINLEN = COLOR_NAME_MINLEN and min(#k, COLOR_NAME_MINLEN) or #k |
||||
COLOR_NAME_MAXLEN = COLOR_NAME_MAXLEN and max(#k, COLOR_NAME_MAXLEN) or #k |
||||
local rgb_hex = tohex(v, 6) |
||||
COLOR_MAP[k] = rgb_hex |
||||
COLOR_TRIE:insert(k) |
||||
if COLOR_NAME_SETTINGS.lowercase then |
||||
local lowercase = k:lower() |
||||
COLOR_MAP[lowercase] = rgb_hex |
||||
COLOR_TRIE:insert(lowercase) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
local function merge(...) |
||||
local res = {} |
||||
for i = 1,select("#", ...) do |
||||
local o = select(i, ...) |
||||
for k,v in pairs(o) do |
||||
res[k] = v |
||||
end |
||||
end |
||||
return res |
||||
end |
||||
|
||||
local DEFAULT_OPTIONS = { |
||||
RGB = true; -- #RGB hex codes |
||||
RRGGBB = true; -- #RRGGBB hex codes |
||||
names = true; -- "Name" codes like Blue |
||||
RRGGBBAA = false; -- #RRGGBBAA hex codes |
||||
rgb_fn = false; -- CSS rgb() and rgba() functions |
||||
hsl_fn = false; -- CSS hsl() and hsla() functions |
||||
css = false; -- Enable all CSS features: rgb_fn, hsl_fn, names, RGB, RRGGBB |
||||
css_fn = false; -- Enable all CSS *functions*: rgb_fn, hsl_fn |
||||
-- Available modes: foreground, background |
||||
mode = 'background'; -- Set the display mode. |
||||
} |
||||
|
||||
-- -- TODO use rgb as the return value from the matcher functions |
||||
-- -- instead of the rgb_hex. Can be the highlight key as well |
||||
-- -- when you shift it left 8 bits. Use the lower 8 bits for |
||||
-- -- indicating which highlight mode to use. |
||||
-- ffi.cdef [[ |
||||
-- typedef struct { uint8_t r, g, b; } colorizer_rgb; |
||||
-- ]] |
||||
-- local rgb_t = ffi.typeof 'colorizer_rgb' |
||||
|
||||
-- Create a lookup table where the bottom 4 bits are used to indicate the |
||||
-- category and the top 4 bits are the hex value of the ASCII byte. |
||||
local BYTE_CATEGORY = ffi.new 'uint8_t[256]' |
||||
local CATEGORY_DIGIT = lshift(1, 0); |
||||
local CATEGORY_ALPHA = lshift(1, 1); |
||||
local CATEGORY_HEX = lshift(1, 2); |
||||
local CATEGORY_ALPHANUM = bor(CATEGORY_ALPHA, CATEGORY_DIGIT) |
||||
do |
||||
local b = string.byte |
||||
for i = 0, 255 do |
||||
local v = 0 |
||||
-- Digit is bit 1 |
||||
if i >= b'0' and i <= b'9' then |
||||
v = bor(v, lshift(1, 0)) |
||||
v = bor(v, lshift(1, 2)) |
||||
v = bor(v, lshift(i - b'0', 4)) |
||||
end |
||||
local lowercase = bor(i, 0x20) |
||||
-- Alpha is bit 2 |
||||
if lowercase >= b'a' and lowercase <= b'z' then |
||||
v = bor(v, lshift(1, 1)) |
||||
if lowercase <= b'f' then |
||||
v = bor(v, lshift(1, 2)) |
||||
v = bor(v, lshift(lowercase - b'a'+10, 4)) |
||||
end |
||||
end |
||||
BYTE_CATEGORY[i] = v |
||||
end |
||||
end |
||||
|
||||
local function byte_is_hex(byte) |
||||
return band(BYTE_CATEGORY[byte], CATEGORY_HEX) ~= 0 |
||||
end |
||||
|
||||
local function byte_is_alphanumeric(byte) |
||||
local category = BYTE_CATEGORY[byte] |
||||
return band(category, CATEGORY_ALPHANUM) ~= 0 |
||||
end |
||||
|
||||
local function parse_hex(b) |
||||
return rshift(BYTE_CATEGORY[b], 4) |
||||
end |
||||
|
||||
local function percent_or_hex(v) |
||||
if v:sub(-1,-1) == "%" then |
||||
return tonumber(v:sub(1,-2))/100*255 |
||||
end |
||||
local x = tonumber(v) |
||||
if x > 255 then return end |
||||
return x |
||||
end |
||||
|
||||
--- Determine whether to use black or white text |
||||
-- Ref: https://stackoverflow.com/a/1855903/837964 |
||||
-- https://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color |
||||
local function color_is_bright(r, g, b) |
||||
-- Counting the perceptive luminance - human eye favors green color |
||||
local luminance = (0.299*r + 0.587*g + 0.114*b)/255 |
||||
if luminance > 0.5 then |
||||
return true -- Bright colors, black font |
||||
else |
||||
return false -- Dark colors, white font |
||||
end |
||||
end |
||||
|
||||
-- https://gist.github.com/mjackson/5311256 |
||||
local function hue_to_rgb(p, q, t) |
||||
if t < 0 then t = t + 1 end |
||||
if t > 1 then t = t - 1 end |
||||
if t < 1/6 then return p + (q - p) * 6 * t end |
||||
if t < 1/2 then return q end |
||||
if t < 2/3 then return p + (q - p) * (2/3 - t) * 6 end |
||||
return p |
||||
end |
||||
|
||||
local function hsl_to_rgb(h, s, l) |
||||
if h > 1 or s > 1 or l > 1 then return end |
||||
if s == 0 then |
||||
local r = l * 255 |
||||
return r, r, r |
||||
end |
||||
local q |
||||
if l < 0.5 then |
||||
q = l * (1 + s) |
||||
else |
||||
q = l + s - l * s |
||||
end |
||||
local p = 2 * l - q |
||||
return 255*hue_to_rgb(p, q, h + 1/3), 255*hue_to_rgb(p, q, h), 255*hue_to_rgb(p, q, h - 1/3) |
||||
end |
||||
|
||||
local function color_name_parser(line, i) |
||||
if i > 1 and byte_is_alphanumeric(line:byte(i-1)) then |
||||
return |
||||
end |
||||
if #line < i + COLOR_NAME_MINLEN - 1 then return end |
||||
local prefix = COLOR_TRIE:longest_prefix(line, i) |
||||
if prefix then |
||||
-- Check if there is a letter here so as to disallow matching here. |
||||
-- Take the Blue out of Blueberry |
||||
-- Line end or non-letter. |
||||
local next_byte_index = i + #prefix |
||||
if #line >= next_byte_index and byte_is_alphanumeric(line:byte(next_byte_index)) then |
||||
return |
||||
end |
||||
return #prefix, COLOR_MAP[prefix] |
||||
end |
||||
end |
||||
|
||||
local b_hash = ("#"):byte() |
||||
local function rgb_hex_parser(line, i, minlen, maxlen) |
||||
if i > 1 and byte_is_alphanumeric(line:byte(i-1)) then |
||||
return |
||||
end |
||||
if line:byte(i) ~= b_hash then |
||||
return |
||||
end |
||||
local j = i + 1 |
||||
if #line < j + minlen - 1 then return end |
||||
local n = j + maxlen |
||||
local alpha |
||||
local v = 0 |
||||
while j <= min(n, #line) do |
||||
local b = line:byte(j) |
||||
if not byte_is_hex(b) then break end |
||||
if j - i >= 7 then |
||||
alpha = parse_hex(b) + lshift(alpha or 0, 4) |
||||
else |
||||
v = parse_hex(b) + lshift(v, 4) |
||||
end |
||||
j = j + 1 |
||||
end |
||||
if #line >= j and byte_is_alphanumeric(line:byte(j)) then |
||||
return |
||||
end |
||||
local length = j - i |
||||
if length ~= 4 and length ~= 7 and length ~= 9 then return end |
||||
if alpha then |
||||
alpha = tonumber(alpha)/255 |
||||
local r = floor(band(v, 0xFF)*alpha) |
||||
local g = floor(band(rshift(v, 8), 0xFF)*alpha) |
||||
local b = floor(band(rshift(v, 16), 0xFF)*alpha) |
||||
v = bor(lshift(r, 16), lshift(g, 8), b) |
||||
return 9, tohex(v, 6) |
||||
end |
||||
return length, line:sub(i+1, i+length-1) |
||||
end |
||||
|
||||
-- TODO consider removing the regexes here |
||||
-- TODO this might not be the best approach to alpha channel. |
||||
-- Things like pumblend might be useful here. |
||||
local css_fn = {} |
||||
do |
||||
local CSS_RGB_FN_MINIMUM_LENGTH = #'rgb(0,0,0)' - 1 |
||||
local CSS_RGBA_FN_MINIMUM_LENGTH = #'rgba(0,0,0,0)' - 1 |
||||
local CSS_HSL_FN_MINIMUM_LENGTH = #'hsl(0,0%,0%)' - 1 |
||||
local CSS_HSLA_FN_MINIMUM_LENGTH = #'hsla(0,0%,0%,0)' - 1 |
||||
function css_fn.rgb(line, i) |
||||
if #line < i + CSS_RGB_FN_MINIMUM_LENGTH then return end |
||||
local r, g, b, match_end = line:sub(i):match("^rgb%(%s*(%d+%%?)%s*,%s*(%d+%%?)%s*,%s*(%d+%%?)%s*%)()") |
||||
if not match_end then return end |
||||
r = percent_or_hex(r) if not r then return end |
||||
g = percent_or_hex(g) if not g then return end |
||||
b = percent_or_hex(b) if not b then return end |
||||
local rgb_hex = tohex(bor(lshift(r, 16), lshift(g, 8), b), 6) |
||||
return match_end - 1, rgb_hex |
||||
end |
||||
function css_fn.hsl(line, i) |
||||
if #line < i + CSS_HSL_FN_MINIMUM_LENGTH then return end |
||||
local h, s, l, match_end = line:sub(i):match("^hsl%(%s*(%d+)%s*,%s*(%d+)%%%s*,%s*(%d+)%%%s*%)()") |
||||
if not match_end then return end |
||||
h = tonumber(h) if h > 360 then return end |
||||
s = tonumber(s) if s > 100 then return end |
||||
l = tonumber(l) if l > 100 then return end |
||||
local r, g, b = hsl_to_rgb(h/360, s/100, l/100) |
||||
if r == nil or g == nil or b == nil then return end |
||||
local rgb_hex = tohex(bor(lshift(floor(r), 16), lshift(floor(g), 8), floor(b)), 6) |
||||
return match_end - 1, rgb_hex |
||||
end |
||||
function css_fn.rgba(line, i) |
||||
if #line < i + CSS_RGBA_FN_MINIMUM_LENGTH then return end |
||||
local r, g, b, a, match_end = line:sub(i):match("^rgba%(%s*(%d+%%?)%s*,%s*(%d+%%?)%s*,%s*(%d+%%?)%s*,%s*([.%d]+)%s*%)()") |
||||
if not match_end then return end |
||||
a = tonumber(a) if not a or a > 1 then return end |
||||
r = percent_or_hex(r) if not r then return end |
||||
g = percent_or_hex(g) if not g then return end |
||||
b = percent_or_hex(b) if not b then return end |
||||
local rgb_hex = tohex(bor(lshift(floor(r*a), 16), lshift(floor(g*a), 8), floor(b*a)), 6) |
||||
return match_end - 1, rgb_hex |
||||
end |
||||
function css_fn.hsla(line, i) |
||||
if #line < i + CSS_HSLA_FN_MINIMUM_LENGTH then return end |
||||
local h, s, l, a, match_end = line:sub(i):match("^hsla%(%s*(%d+)%s*,%s*(%d+)%%%s*,%s*(%d+)%%%s*,%s*([.%d]+)%s*%)()") |
||||
if not match_end then return end |
||||
a = tonumber(a) if not a or a > 1 then return end |
||||
h = tonumber(h) if h > 360 then return end |
||||
s = tonumber(s) if s > 100 then return end |
||||
l = tonumber(l) if l > 100 then return end |
||||
local r, g, b = hsl_to_rgb(h/360, s/100, l/100) |
||||
if r == nil or g == nil or b == nil then return end |
||||
local rgb_hex = tohex(bor(lshift(floor(r*a), 16), lshift(floor(g*a), 8), floor(b*a)), 6) |
||||
return match_end - 1, rgb_hex |
||||
end |
||||
end |
||||
local css_function_parser, rgb_function_parser, hsl_function_parser |
||||
do |
||||
local CSS_FUNCTION_TRIE = Trie {'rgb', 'rgba', 'hsl', 'hsla'} |
||||
local RGB_FUNCTION_TRIE = Trie {'rgb', 'rgba'} |
||||
local HSL_FUNCTION_TRIE = Trie {'hsl', 'hsla'} |
||||
css_function_parser = function(line, i) |
||||
local prefix = CSS_FUNCTION_TRIE:longest_prefix(line:sub(i)) |
||||
if prefix then |
||||
return css_fn[prefix](line, i) |
||||
end |
||||
end |
||||
rgb_function_parser = function(line, i) |
||||
local prefix = RGB_FUNCTION_TRIE:longest_prefix(line:sub(i)) |
||||
if prefix then |
||||
return css_fn[prefix](line, i) |
||||
end |
||||
end |
||||
hsl_function_parser = function(line, i) |
||||
local prefix = HSL_FUNCTION_TRIE:longest_prefix(line:sub(i)) |
||||
if prefix then |
||||
return css_fn[prefix](line, i) |
||||
end |
||||
end |
||||
end |
||||
|
||||
local function compile_matcher(matchers) |
||||
local parse_fn = matchers[1] |
||||
for j = 2, #matchers do |
||||
local old_parse_fn = parse_fn |
||||
local new_parse_fn = matchers[j] |
||||
parse_fn = function(line, i) |
||||
local length, rgb_hex = new_parse_fn(line, i) |
||||
if length then return length, rgb_hex end |
||||
return old_parse_fn(line, i) |
||||
end |
||||
end |
||||
return parse_fn |
||||
end |
||||
|
||||
--- Default namespace used in `highlight_buffer` and `attach_to_buffer`. |
||||
-- The name is "terminal_highlight" |
||||
-- @see highlight_buffer |
||||
-- @see attach_to_buffer |
||||
local DEFAULT_NAMESPACE = nvim.create_namespace "colorizer" |
||||
local HIGHLIGHT_NAME_PREFIX = "colorizer" |
||||
local HIGHLIGHT_MODE_NAMES = { |
||||
background = "mb"; |
||||
foreground = "mf"; |
||||
} |
||||
local HIGHLIGHT_CACHE = {} |
||||
|
||||
--- Make a deterministic name for a highlight given these attributes |
||||
local function make_highlight_name(rgb, mode) |
||||
return table.concat({HIGHLIGHT_NAME_PREFIX, HIGHLIGHT_MODE_NAMES[mode], rgb}, '_') |
||||
end |
||||
|
||||
local function create_highlight(rgb_hex, options) |
||||
local mode = options.mode or 'background' |
||||
-- TODO validate rgb format? |
||||
rgb_hex = rgb_hex:lower() |
||||
local cache_key = table.concat({HIGHLIGHT_MODE_NAMES[mode], rgb_hex}, "_") |
||||
local highlight_name = HIGHLIGHT_CACHE[cache_key] |
||||
-- Look up in our cache. |
||||
if not highlight_name then |
||||
if #rgb_hex == 3 then |
||||
rgb_hex = table.concat { |
||||
rgb_hex:sub(1,1):rep(2); |
||||
rgb_hex:sub(2,2):rep(2); |
||||
rgb_hex:sub(3,3):rep(2); |
||||
} |
||||
end |
||||
-- Create the highlight |
||||
highlight_name = make_highlight_name(rgb_hex, mode) |
||||
if mode == 'foreground' then |
||||
nvim.ex.highlight(highlight_name, "guifg=#"..rgb_hex) |
||||
else |
||||
local r, g, b = rgb_hex:sub(1,2), rgb_hex:sub(3,4), rgb_hex:sub(5,6) |
||||
r, g, b = tonumber(r,16), tonumber(g,16), tonumber(b,16) |
||||
local fg_color |
||||
if color_is_bright(r,g,b) then |
||||
fg_color = "Black" |
||||
else |
||||
fg_color = "White" |
||||
end |
||||
nvim.ex.highlight(highlight_name, "guifg="..fg_color, "guibg=#"..rgb_hex) |
||||
end |
||||
HIGHLIGHT_CACHE[cache_key] = highlight_name |
||||
end |
||||
return highlight_name |
||||
end |
||||
|
||||
local MATCHER_CACHE = {} |
||||
local function make_matcher(options) |
||||
local enable_names = options.css or options.names |
||||
local enable_RGB = options.css or options.RGB |
||||
local enable_RRGGBB = options.css or options.RRGGBB |
||||
local enable_RRGGBBAA = options.css or options.RRGGBBAA |
||||
local enable_rgb = options.css or options.css_fns or options.rgb_fn |
||||
local enable_hsl = options.css or options.css_fns or options.hsl_fn |
||||
|
||||
local matcher_key = bor( |
||||
lshift(enable_names and 1 or 0, 0), |
||||
lshift(enable_RGB and 1 or 0, 1), |
||||
lshift(enable_RRGGBB and 1 or 0, 2), |
||||
lshift(enable_RRGGBBAA and 1 or 0, 3), |
||||
lshift(enable_rgb and 1 or 0, 4), |
||||
lshift(enable_hsl and 1 or 0, 5)) |
||||
|
||||
if matcher_key == 0 then return end |
||||
|
||||
local loop_parse_fn = MATCHER_CACHE[matcher_key] |
||||
if loop_parse_fn then |
||||
return loop_parse_fn |
||||
end |
||||
|
||||
local loop_matchers = {} |
||||
if enable_names then |
||||
table.insert(loop_matchers, color_name_parser) |
||||
end |
||||
do |
||||
local valid_lengths = {[3] = enable_RGB, [6] = enable_RRGGBB, [8] = enable_RRGGBBAA} |
||||
local minlen, maxlen |
||||
for k, v in pairs(valid_lengths) do |
||||
if v then |
||||
minlen = minlen and min(k, minlen) or k |
||||
maxlen = maxlen and max(k, maxlen) or k |
||||
end |
||||
end |
||||
if minlen then |
||||
table.insert(loop_matchers, function(line, i) |
||||
local length, rgb_hex = rgb_hex_parser(line, i, minlen, maxlen) |
||||
if length and valid_lengths[length-1] then |
||||
return length, rgb_hex |
||||
end |
||||
end) |
||||
end |
||||
end |
||||
if enable_rgb and enable_hsl then |
||||
table.insert(loop_matchers, css_function_parser) |
||||
elseif enable_rgb then |
||||
table.insert(loop_matchers, rgb_function_parser) |
||||
elseif enable_hsl then |
||||
table.insert(loop_matchers, hsl_function_parser) |
||||
end |
||||
loop_parse_fn = compile_matcher(loop_matchers) |
||||
MATCHER_CACHE[matcher_key] = loop_parse_fn |
||||
return loop_parse_fn |
||||
end |
||||
|
||||
--[[-- Highlight the buffer region. |
||||
Highlight starting from `line_start` (0-indexed) for each line described by `lines` in the |
||||
buffer `buf` and attach it to the namespace `ns`. |
||||
|
||||
@tparam integer buf buffer id. |
||||
@tparam[opt=DEFAULT_NAMESPACE] integer ns the namespace id. Create it with `vim.api.create_namespace` |
||||
@tparam {string,...} lines the lines to highlight from the buffer. |
||||
@tparam integer line_start should be 0-indexed |
||||
@param options Configuration options as described in `setup` |
||||
@see setup |
||||
]] |
||||
local function highlight_buffer(buf, ns, lines, line_start, options) |
||||
-- TODO do I have to put this here? |
||||
initialize_trie() |
||||
ns = ns or DEFAULT_NAMESPACE |
||||
local loop_parse_fn = make_matcher(options) |
||||
for current_linenum, line in ipairs(lines) do |
||||
current_linenum = current_linenum - 1 + line_start |
||||
-- Upvalues are options and current_linenum |
||||
local i = 1 |
||||
while i < #line do |
||||
local length, rgb_hex = loop_parse_fn(line, i) |
||||
if length then |
||||
local highlight_name = create_highlight(rgb_hex, options) |
||||
nvim_buf_add_highlight(buf, ns, highlight_name, current_linenum, i-1, i+length-1) |
||||
i = i + length |
||||
else |
||||
i = i + 1 |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
--- |
||||
-- USER FACING FUNCTIONALITY |
||||
--- |
||||
|
||||
local SETUP_SETTINGS = { |
||||
exclusions = {}; |
||||
default_options = DEFAULT_OPTIONS; |
||||
} |
||||
local BUFFER_OPTIONS = {} |
||||
local FILETYPE_OPTIONS = {} |
||||
|
||||
local function rehighlight_buffer(buf, options) |
||||
local ns = DEFAULT_NAMESPACE |
||||
if buf == 0 or buf == nil then |
||||
buf = nvim_get_current_buf() |
||||
end |
||||
assert(options) |
||||
nvim_buf_clear_namespace(buf, ns, 0, -1) |
||||
local lines = nvim_buf_get_lines(buf, 0, -1, true) |
||||
highlight_buffer(buf, ns, lines, 0, options) |
||||
end |
||||
|
||||
local function new_buffer_options(buf) |
||||
local filetype = nvim.buf_get_option(buf, 'filetype') |
||||
return FILETYPE_OPTIONS[filetype] or SETUP_SETTINGS.default_options |
||||
end |
||||
|
||||
--- Check if attached to a buffer. |
||||
-- @tparam[opt=0|nil] integer buf A value of 0 implies the current buffer. |
||||
-- @return true if attached to the buffer, false otherwise. |
||||
local function is_buffer_attached(buf) |
||||
if buf == 0 or buf == nil then |
||||
buf = nvim_get_current_buf() |
||||
end |
||||
return BUFFER_OPTIONS[buf] ~= nil |
||||
end |
||||
|
||||
--- Attach to a buffer and continuously highlight changes. |
||||
-- @tparam[opt=0|nil] integer buf A value of 0 implies the current buffer. |
||||
-- @param[opt] options Configuration options as described in `setup` |
||||
-- @see setup |
||||
local function attach_to_buffer(buf, options) |
||||
if buf == 0 or buf == nil then |
||||
buf = nvim_get_current_buf() |
||||
end |
||||
local already_attached = BUFFER_OPTIONS[buf] ~= nil |
||||
local ns = DEFAULT_NAMESPACE |
||||
if not options then |
||||
options = new_buffer_options(buf) |
||||
end |
||||
BUFFER_OPTIONS[buf] = options |
||||
rehighlight_buffer(buf, options) |
||||
if already_attached then |
||||
return |
||||
end |
||||
-- send_buffer: true doesn't actually do anything in Lua (yet) |
||||
nvim.buf_attach(buf, false, { |
||||
on_lines = function(event_type, buf, changed_tick, firstline, lastline, new_lastline) |
||||
-- This is used to signal stopping the handler highlights |
||||
if not BUFFER_OPTIONS[buf] then |
||||
return true |
||||
end |
||||
nvim_buf_clear_namespace(buf, ns, firstline, new_lastline) |
||||
local lines = nvim_buf_get_lines(buf, firstline, new_lastline, false) |
||||
highlight_buffer(buf, ns, lines, firstline, BUFFER_OPTIONS[buf]) |
||||
end; |
||||
on_detach = function() |
||||
BUFFER_OPTIONS[buf] = nil |
||||
end; |
||||
}) |
||||
end |
||||
|
||||
--- Stop highlighting the current buffer. |
||||
-- @tparam[opt=0|nil] integer buf A value of 0 or nil implies the current buffer. |
||||
-- @tparam[opt=DEFAULT_NAMESPACE] integer ns the namespace id. |
||||
local function detach_from_buffer(buf, ns) |
||||
if buf == 0 or buf == nil then |
||||
buf = nvim_get_current_buf() |
||||
end |
||||
nvim_buf_clear_namespace(buf, ns or DEFAULT_NAMESPACE, 0, -1) |
||||
BUFFER_OPTIONS[buf] = nil |
||||
end |
||||
|
||||
|
||||
--- Easy to use function if you want the full setup without fine grained control. |
||||
-- Setup an autocmd which enables colorizing for the filetypes and options specified. |
||||
-- |
||||
-- By default highlights all FileTypes. |
||||
-- |
||||
-- Example config: |
||||
-- ``` |
||||
-- { 'scss', 'html', css = { rgb_fn = true; }, javascript = { no_names = true } } |
||||
-- ``` |
||||
-- |
||||
-- You can combine an array and more specific options. |
||||
-- Possible options: |
||||
-- - `no_names`: Don't highlight names like Blue |
||||
-- - `rgb_fn`: Highlight `rgb(...)` functions. |
||||
-- - `mode`: Highlight mode. Valid options: `foreground`,`background` |
||||
-- |
||||
-- @param[opt={'*'}] filetypes A table/array of filetypes to selectively enable and/or customize. By default, enables all filetypes. |
||||
-- @tparam[opt] {[string]=string} default_options Default options to apply for the filetypes enable. |
||||
-- @usage require'colorizer'.setup() |
||||
local function setup(filetypes, user_default_options) |
||||
if not nvim.o.termguicolors then |
||||
nvim.err_writeln("&termguicolors must be set") |
||||
return |
||||
end |
||||
FILETYPE_OPTIONS = {} |
||||
SETUP_SETTINGS = { |
||||
exclusions = {}; |
||||
default_options = merge(DEFAULT_OPTIONS, user_default_options or {}); |
||||
} |
||||
-- Initialize this AFTER setting COLOR_NAME_SETTINGS |
||||
initialize_trie() |
||||
function COLORIZER_SETUP_HOOK() |
||||
local filetype = nvim.bo.filetype |
||||
if SETUP_SETTINGS.exclusions[filetype] then |
||||
return |
||||
end |
||||
local options = FILETYPE_OPTIONS[filetype] or SETUP_SETTINGS.default_options |
||||
attach_to_buffer(nvim_get_current_buf(), options) |
||||
end |
||||
nvim.ex.augroup("ColorizerSetup") |
||||
nvim.ex.autocmd_() |
||||
if not filetypes then |
||||
nvim.ex.autocmd("FileType * lua COLORIZER_SETUP_HOOK()") |
||||
else |
||||
for k, v in pairs(filetypes) do |
||||
local filetype |
||||
local options = SETUP_SETTINGS.default_options |
||||
if type(k) == 'string' then |
||||
filetype = k |
||||
if type(v) ~= 'table' then |
||||
nvim.err_writeln("colorizer: Invalid option type for filetype "..filetype) |
||||
else |
||||
options = merge(SETUP_SETTINGS.default_options, v) |
||||
assert(HIGHLIGHT_MODE_NAMES[options.mode or 'background'], "colorizer: Invalid mode: "..tostring(options.mode)) |
||||
end |
||||
else |
||||
filetype = v |
||||
end |
||||
-- Exclude |
||||
if filetype:sub(1,1) == '!' then |
||||
SETUP_SETTINGS.exclusions[filetype:sub(2)] = true |
||||
else |
||||
FILETYPE_OPTIONS[filetype] = options |
||||
-- TODO What's the right mode for this? BufEnter? |
||||
nvim.ex.autocmd("FileType", filetype, "lua COLORIZER_SETUP_HOOK()") |
||||
end |
||||
end |
||||
end |
||||
nvim.ex.augroup("END") |
||||
end |
||||
|
||||
--- Reload all of the currently active highlighted buffers. |
||||
local function reload_all_buffers() |
||||
for buf, buffer_options in pairs(BUFFER_OPTIONS) do |
||||
attach_to_buffer(buf) |
||||
end |
||||
end |
||||
|
||||
--- Return the currently active buffer options. |
||||
-- @tparam[opt=0|nil] integer buf A value of 0 or nil implies the current buffer. |
||||
local function get_buffer_options(buf) |
||||
if buf == 0 or buf == nil then |
||||
buf = nvim_get_current_buf() |
||||
end |
||||
return merge({}, BUFFER_OPTIONS[buf]) |
||||
end |
||||
|
||||
--- @export |
||||
return { |
||||
DEFAULT_NAMESPACE = DEFAULT_NAMESPACE; |
||||
setup = setup; |
||||
is_buffer_attached = is_buffer_attached; |
||||
attach_to_buffer = attach_to_buffer; |
||||
detach_from_buffer = detach_from_buffer; |
||||
highlight_buffer = highlight_buffer; |
||||
reload_all_buffers = reload_all_buffers; |
||||
get_buffer_options = get_buffer_options; |
||||
} |
||||
|
@ -0,0 +1,193 @@
@@ -0,0 +1,193 @@
|
||||
--- Module of magic functions for nvim |
||||
-- @module nvim |
||||
|
||||
-- Equivalent to `echo vim.inspect(...)` |
||||
local function nvim_print(...) |
||||
if select("#", ...) == 1 then |
||||
vim.api.nvim_out_write(vim.inspect((...))) |
||||
else |
||||
vim.api.nvim_out_write(vim.inspect {...}) |
||||
end |
||||
vim.api.nvim_out_write("\n") |
||||
end |
||||
|
||||
--- Equivalent to `echo` EX command |
||||
local function nvim_echo(...) |
||||
for i = 1, select("#", ...) do |
||||
local part = select(i, ...) |
||||
vim.api.nvim_out_write(tostring(part)) |
||||
-- vim.api.nvim_out_write("\n") |
||||
vim.api.nvim_out_write(" ") |
||||
end |
||||
vim.api.nvim_out_write("\n") |
||||
end |
||||
|
||||
local window_options = { |
||||
arab = true; arabic = true; breakindent = true; breakindentopt = true; |
||||
bri = true; briopt = true; cc = true; cocu = true; |
||||
cole = true; colorcolumn = true; concealcursor = true; conceallevel = true; |
||||
crb = true; cuc = true; cul = true; cursorbind = true; |
||||
cursorcolumn = true; cursorline = true; diff = true; fcs = true; |
||||
fdc = true; fde = true; fdi = true; fdl = true; |
||||
fdm = true; fdn = true; fdt = true; fen = true; |
||||
fillchars = true; fml = true; fmr = true; foldcolumn = true; |
||||
foldenable = true; foldexpr = true; foldignore = true; foldlevel = true; |
||||
foldmarker = true; foldmethod = true; foldminlines = true; foldnestmax = true; |
||||
foldtext = true; lbr = true; lcs = true; linebreak = true; |
||||
list = true; listchars = true; nu = true; number = true; |
||||
numberwidth = true; nuw = true; previewwindow = true; pvw = true; |
||||
relativenumber = true; rightleft = true; rightleftcmd = true; rl = true; |
||||
rlc = true; rnu = true; scb = true; scl = true; |
||||
scr = true; scroll = true; scrollbind = true; signcolumn = true; |
||||
spell = true; statusline = true; stl = true; wfh = true; |
||||
wfw = true; winbl = true; winblend = true; winfixheight = true; |
||||
winfixwidth = true; winhighlight = true; winhl = true; wrap = true; |
||||
} |
||||
|
||||
-- `nvim.$method(...)` redirects to `nvim.api.nvim_$method(...)` |
||||
-- `nvim.fn.$method(...)` redirects to `vim.api.nvim_call_function($method, {...})` |
||||
-- TODO `nvim.ex.$command(...)` is approximately `:$command {...}.join(" ")` |
||||
-- `nvim.print(...)` is approximately `echo vim.inspect(...)` |
||||
-- `nvim.echo(...)` is approximately `echo table.concat({...}, '\n')` |
||||
-- Both methods cache the inital lookup in the metatable, but there is a small overhead regardless. |
||||
return setmetatable({ |
||||
print = nvim_print; |
||||
echo = nvim_echo; |
||||
fn = setmetatable({}, { |
||||
__index = function(self, k) |
||||
local mt = getmetatable(self) |
||||
local x = mt[k] |
||||
if x ~= nil then |
||||
return x |
||||
end |
||||
local f = function(...) return vim.api.nvim_call_function(k, {...}) end |
||||
mt[k] = f |
||||
return f |
||||
end |
||||
}); |
||||
buf = setmetatable({ |
||||
}, { |
||||
__index = function(self, k) |
||||
local mt = getmetatable(self) |
||||
local x = mt[k] |
||||
if x ~= nil then return x end |
||||
local f |
||||
if k == 'line' then |
||||
f = function() |
||||
local pos = vim.api.nvim_win_get_cursor(0) |
||||
return vim.api.nvim_buf_get_lines(0, pos[1]-1, pos[1], 'line')[1] |
||||
end |
||||
elseif k == 'nr' then |
||||
f = vim.api.nvim_get_current_buf |
||||
end |
||||
mt[k] = f |
||||
return f |
||||
end |
||||
}); |
||||
ex = setmetatable({}, { |
||||
__index = function(self, k) |
||||
local mt = getmetatable(self) |
||||
local x = mt[k] |
||||
if x ~= nil then |
||||
return x |
||||
end |
||||
local command = k:gsub("_$", "!") |
||||
local f = function(...) |
||||
return vim.api.nvim_command(table.concat(vim.tbl_flatten {command, ...}, " ")) |
||||
end |
||||
mt[k] = f |
||||
return f |
||||
end |
||||
}); |
||||
g = setmetatable({}, { |
||||
__index = function(_, k) |
||||
return vim.api.nvim_get_var(k) |
||||
end; |
||||
__newindex = function(_, k, v) |
||||
if v == nil then |
||||
return vim.api.nvim_del_var(k) |
||||
else |
||||
return vim.api.nvim_set_var(k, v) |
||||
end |
||||
end; |
||||
}); |
||||
v = setmetatable({}, { |
||||
__index = function(_, k) |
||||
return vim.api.nvim_get_vvar(k) |
||||
end; |
||||
__newindex = function(_, k, v) |
||||
return vim.api.nvim_set_vvar(k, v) |
||||
end |
||||
}); |
||||
b = setmetatable({}, { |
||||
__index = function(_, k) |
||||
return vim.api.nvim_buf_get_var(0, k) |
||||
end; |
||||
__newindex = function(_, k, v) |
||||
if v == nil then |
||||
return vim.api.nvim_buf_del_var(0, k) |
||||
else |
||||
return vim.api.nvim_buf_set_var(0, k, v) |
||||
end |
||||
end |
||||
}); |
||||
w = setmetatable({}, { |
||||
__index = function(_, k) |
||||
return vim.api.nvim_win_get_var(0, k) |
||||
end; |
||||
__newindex = function(_, k, v) |
||||
if v == nil then |
||||
return vim.api.nvim_win_del_var(0, k) |
||||
else |
||||
return vim.api.nvim_win_set_var(0, k, v) |
||||
end |
||||
end |
||||
}); |
||||
o = setmetatable({}, { |
||||
__index = function(_, k) |
||||
return vim.api.nvim_get_option(k) |
||||
end; |
||||
__newindex = function(_, k, v) |
||||
return vim.api.nvim_set_option(k, v) |
||||
end |
||||
}); |
||||
-- TODO add warning if you try to use a window option here? |
||||
bo = setmetatable({}, { |
||||
__index = function(_, k) |
||||
return vim.api.nvim_buf_get_option(0, k) |
||||
end; |
||||
__newindex = function(_, k, v) |
||||
return vim.api.nvim_buf_set_option(0, k, v) |
||||
end |
||||
}); |
||||
wo = setmetatable({}, { |
||||
__index = function(_, k) |
||||
return vim.api.nvim_win_get_option(0, k) |
||||
end; |
||||
__newindex = function(_, k, v) |
||||
-- passing v == nil will clear the value, just like above. |
||||
return vim.api.nvim_win_set_option(0, k, v) |
||||
end |
||||
}); |
||||
env = setmetatable({}, { |
||||
__index = function(_, k) |
||||
return vim.api.nvim_call_function('getenv', {k}) |
||||
end; |
||||
__newindex = function(_, k, v) |
||||
return vim.api.nvim_call_function('setenv', {k, v}) |
||||
end |
||||
}); |
||||
}, { |
||||
__index = function(self, k) |
||||
local mt = getmetatable(self) |
||||
local x = mt[k] |
||||
if x ~= nil then |
||||
return x |
||||
end |
||||
local f = vim.api['nvim_'..k] |
||||
mt[k] = f |
||||
return f |
||||
end |
||||
}) |
||||
|
||||
|
@ -0,0 +1,242 @@
@@ -0,0 +1,242 @@
|
||||
--- Trie implementation in luajit |
||||
-- Copyright © 2019 Ashkan Kiani |
||||
|
||||
-- This program is free software: you can redistribute it and/or modify |
||||
-- it under the terms of the GNU General Public License as published by |
||||
-- the Free Software Foundation, either version 3 of the License, or |
||||
-- (at your option) any later version. |
||||
|
||||
-- This program is distributed in the hope that it will be useful, |
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
-- GNU General Public License for more details. |
||||
|
||||
-- You should have received a copy of the GNU General Public License |
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
local ffi = require 'ffi' |
||||
|
||||
ffi.cdef [[ |
||||
struct Trie { |
||||
bool is_leaf; |
||||
struct Trie* character[62]; |
||||
}; |
||||
void *malloc(size_t size); |
||||
void free(void *ptr); |
||||
]] |
||||
|
||||
local Trie_t = ffi.typeof('struct Trie') |
||||
local Trie_ptr_t = ffi.typeof('$ *', Trie_t) |
||||
local Trie_size = ffi.sizeof(Trie_t) |
||||
|
||||
local function trie_create() |
||||
local ptr = ffi.C.malloc(Trie_size) |
||||
ffi.fill(ptr, Trie_size) |
||||
return ffi.cast(Trie_ptr_t, ptr) |
||||
end |
||||
|
||||
local function trie_destroy(trie) |
||||
if trie == nil then |
||||
return |
||||
end |
||||
for i = 0, 61 do |
||||
local child = trie.character[i] |
||||
if child ~= nil then |
||||
trie_destroy(child) |
||||
end |
||||
end |
||||
ffi.C.free(trie) |
||||
end |
||||
|
||||
local INDEX_LOOKUP_TABLE = ffi.new 'uint8_t[256]' |
||||
local CHAR_LOOKUP_TABLE = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' |
||||
do |
||||
local b = string.byte |
||||
for i = 0, 255 do |
||||
if i >= b'0' and i <= b'9' then |
||||
INDEX_LOOKUP_TABLE[i] = i - b'0' |
||||
elseif i >= b'A' and i <= b'Z' then |
||||
INDEX_LOOKUP_TABLE[i] = i - b'A' + 10 |
||||
elseif i >= b'a' and i <= b'z' then |
||||
INDEX_LOOKUP_TABLE[i] = i - b'a' + 10 + 26 |
||||
else |
||||
INDEX_LOOKUP_TABLE[i] = 255 |
||||
end |
||||
end |
||||
end |
||||
|
||||
local function trie_insert(trie, value) |
||||
if trie == nil then return false end |
||||
local node = trie |
||||
for i = 1, #value do |
||||
local index = INDEX_LOOKUP_TABLE[value:byte(i)] |
||||
if index == 255 then |
||||
return false |
||||
end |
||||
if node.character[index] == nil then |
||||
node.character[index] = trie_create() |
||||
end |
||||
node = node.character[index] |
||||
end |
||||
node.is_leaf = true |
||||
return node, trie |
||||
end |
||||
|
||||
local function trie_search(trie, value, start) |
||||
if trie == nil then return false end |
||||
local node = trie |
||||
for i = (start or 1), #value do |
||||
local index = INDEX_LOOKUP_TABLE[value:byte(i)] |
||||
if index == 255 then |
||||
return |
||||
end |
||||
local child = node.character[index] |
||||
if child == nil then |
||||
return false |
||||
end |
||||
node = child |
||||
end |
||||
return node.is_leaf |
||||
end |
||||
|
||||
local function trie_longest_prefix(trie, value, start) |
||||
if trie == nil then return false end |
||||
-- insensitive = insensitive and 0x20 or 0 |
||||
start = start or 1 |
||||
local node = trie |
||||
local last_i = nil |
||||
for i = start, #value do |
||||
local index = INDEX_LOOKUP_TABLE[value:byte(i)] |
||||
-- local index = INDEX_LOOKUP_TABLE[bor(insensitive, value:byte(i))] |
||||
if index == 255 then |
||||
break |
||||
end |
||||
local child = node.character[index] |
||||
if child == nil then |
||||
break |
||||
end |
||||
if child.is_leaf then |
||||
last_i = i |
||||
end |
||||
node = child |
||||
end |
||||
if last_i then |
||||
-- Avoid a copy if the whole string is a match. |
||||
if start == 1 and last_i == #value then |
||||
return value |
||||
else |
||||
return value:sub(start, last_i) |
||||
end |
||||
end |
||||
end |
||||
|
||||
local function trie_extend(trie, t) |
||||
assert(type(t) == 'table') |
||||
for _, v in ipairs(t) do |
||||
trie_insert(trie, v) |
||||
end |
||||
end |
||||
|
||||
--- Printing utilities |
||||
|
||||
local function index_to_char(index) |
||||
if index < 0 or index > 61 then return end |
||||
return CHAR_LOOKUP_TABLE:sub(index+1, index+1) |
||||
end |
||||
|
||||
local function trie_as_table(trie) |
||||
if trie == nil then |
||||
return nil |
||||
end |
||||
local children = {} |
||||
for i = 0, 61 do |
||||
local child = trie.character[i] |
||||
if child ~= nil then |
||||
local child_table = trie_as_table(child) |
||||
child_table.c = index_to_char(i) |
||||
table.insert(children, child_table) |
||||
end |
||||
end |
||||
return { |
||||
is_leaf = trie.is_leaf; |
||||
children = children; |
||||
} |
||||
end |
||||
|
||||
local function print_trie_table(s) |
||||
local mark |
||||
if not s then |
||||
return {'nil'} |
||||
end |
||||
if s.c then |
||||
if s.is_leaf then |
||||
mark = s.c.."*" |
||||
else |
||||
mark = s.c.."─" |
||||
end |
||||
else |
||||
mark = "├─" |
||||
end |
||||
if #s.children == 0 then |
||||
return {mark} |
||||
end |
||||
local lines = {} |
||||
for _, child in ipairs(s.children) do |
||||
local child_lines = print_trie_table(child, thicc) |
||||
for _, child_line in ipairs(child_lines) do |
||||
table.insert(lines, child_line) |
||||
end |
||||
end |
||||
local child_count = 0 |
||||
for i, line in ipairs(lines) do |
||||
local line_parts = {} |
||||
if line:match("^%w") then |
||||
child_count = child_count + 1 |
||||
if i == 1 then |
||||
line_parts = {mark} |
||||
elseif i == #lines or child_count == #s.children then |
||||
line_parts = {"└─"} |
||||
else |
||||
line_parts = {"├─"} |
||||
end |
||||
else |
||||
if i == 1 then |
||||
line_parts = {mark} |
||||
elseif #s.children > 1 and child_count ~= #s.children then |
||||
line_parts = {"│ "} |
||||
else |
||||
line_parts = {" "} |
||||
end |
||||
end |
||||
table.insert(line_parts, line) |
||||
lines[i] = table.concat(line_parts) |
||||
end |
||||
return lines |
||||
end |
||||
|
||||
local function trie_to_string(trie) |
||||
if trie == nil then |
||||
return 'nil' |
||||
end |
||||
local as_table = trie_as_table(trie) |
||||
return table.concat(print_trie_table(as_table), '\n') |
||||
end |
||||
|
||||
local Trie_mt = { |
||||
__new = function(_, init) |
||||
local trie = trie_create() |
||||
if type(init) == 'table' then |
||||
trie_extend(trie, init) |
||||
end |
||||
return trie |
||||
end; |
||||
__index = { |
||||
insert = trie_insert; |
||||
search = trie_search; |
||||
longest_prefix = trie_longest_prefix; |
||||
extend = trie_extend; |
||||
}; |
||||
__tostring = trie_to_string; |
||||
__gc = trie_destroy; |
||||
} |
||||
|
||||
return ffi.metatype('struct Trie', Trie_mt) |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
if exists('g:loaded_colorizer') |
||||
finish |
||||
endif |
||||
|
||||
command! ColorizerAttachToBuffer lua require'colorizer'.attach_to_buffer(0) |
||||
command! ColorizerDetachFromBuffer lua require'colorizer'.detach_from_buffer(0) |
||||
command! ColorizerReloadAllBuffers lua require'colorizer'.reload_all_buffers() |
||||
command! ColorizerToggle lua local c = require'colorizer' |
||||
\ if c.is_buffer_attached(0) then c.detach_from_buffer(0) else |
||||
\ c.attach_to_buffer(0) end |
||||
|
||||
let g:loaded_colorizer = 1 |
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
-- vim:ft=lua |
||||
require'colorizer'.attach_to_buffer(0, {css=true}) |
||||
|
||||
--[[ SUCCESS |
||||
#F0F |
||||
#FF00FF |
||||
#FFF00F8F |
||||
#F0F |
||||
#FF00FF |
||||
#FFF00F8F |
||||
#F0F #F00 |
||||
#FF00FF #F00 |
||||
#FFF00F8F #F00 |
||||
Blue Gray LightBlue Gray100 White |
||||
White |
||||
#def |
||||
#deadbeef |
||||
rgba(0,0,0,0) |
||||
rgb(0,0,0) |
||||
rgb(10, 100 , 100) |
||||
hsl(300,50%,50%) |
||||
hsla(300,50%,50%,0.5) |
||||
hsla(300,50%,50%,1.0000000000000001) |
||||
hsla(360,50%,50%,1.0000000000000001) |
||||
blue gray lightblue gray100 white gold blue |
||||
]] |
||||
|
||||
--[[ FAIL |
||||
#F0FF |
||||
#F0FFF |
||||
#F0FFF0F |
||||
#F0FFF0FFF |
||||
Blueberry Gray1000 BlueGree BlueGray |
||||
#define |
||||
#def0 |
||||
matcher#add |
||||
rgb(10,256,100) |
||||
rgb (10,255,100) |
||||
rgb(10, 1 00 , 100) |
||||
hsla(300,50%,50%,05) |
||||
hsla(300,50%,50%,1.000000000000001) |
||||
hsla(300,50%,50,1.0000000000000001) |
||||
hsla(300,50,50,1.0000000000000001) |
||||
hsla(361,50,50,1.0000000000000001) |
||||
]] |
||||
|
@ -0,0 +1,62 @@
@@ -0,0 +1,62 @@
|
||||
-- TODO this is kinda shitty |
||||
local function dirname(str,sep) |
||||
sep=sep or'/' |
||||
return str:match("(.*"..sep..")") |
||||
end |
||||
|
||||
local script_dir = dirname(arg[0]) |
||||
package.path = script_dir.."/../lua/?.lua;"..package.path |
||||
|
||||
local Trie = require 'trie' |
||||
local nvim = require 'nvim' |
||||
|
||||
local function print_color_trie() |
||||
local tohex = bit.tohex |
||||
local min, max = math.min, math.max |
||||
|
||||
local COLOR_NAME_SETTINGS = { |
||||
lowercase = false; |
||||
strip_digits = true; |
||||
} |
||||
local COLOR_MAP = {} |
||||
local COLOR_TRIE = Trie() |
||||
for k, v in pairs(nvim.get_color_map()) do |
||||
if not (COLOR_NAME_SETTINGS.strip_digits and k:match("%d+$")) then |
||||
COLOR_NAME_MINLEN = COLOR_NAME_MINLEN and min(#k, COLOR_NAME_MINLEN) or #k |
||||
COLOR_NAME_MAXLEN = COLOR_NAME_MAXLEN and max(#k, COLOR_NAME_MAXLEN) or #k |
||||
COLOR_MAP[k] = tohex(v, 6) |
||||
COLOR_TRIE:insert(k) |
||||
if COLOR_NAME_SETTINGS.lowercase then |
||||
local lowercase = k:lower() |
||||
COLOR_MAP[lowercase] = tohex(v, 6) |
||||
COLOR_TRIE:insert(lowercase) |
||||
end |
||||
end |
||||
end |
||||
print(COLOR_TRIE) |
||||
end |
||||
|
||||
local trie = Trie { |
||||
"cat"; |
||||
"car"; |
||||
"celtic"; |
||||
"carb"; |
||||
"carb0"; |
||||
"CART0"; |
||||
"CaRT0"; |
||||
"Cart0"; |
||||
"931"; |
||||
"191"; |
||||
"121"; |
||||
"cardio"; |
||||
"call"; |
||||
"calcium"; |
||||
"calciur"; |
||||
"carry"; |
||||
"dog"; |
||||
"catdog"; |
||||
} |
||||
|
||||
print(trie) |
||||
print("catdo", trie:longest_prefix("catdo")) |
||||
print("catastrophic", trie:longest_prefix("catastrophic")) |
Loading…
Reference in new issue