diff options
-rw-r--r-- | doc/colorizer.txt | 118 | ||||
-rw-r--r-- | doc/index.html | 5 | ||||
-rw-r--r-- | doc/modules/colorizer.buffer_utils.html | 1 | ||||
-rw-r--r-- | doc/modules/colorizer.color_utils.html | 111 | ||||
-rw-r--r-- | doc/modules/colorizer.html | 1 | ||||
-rw-r--r-- | doc/modules/colorizer.matcher_utils.html | 1 | ||||
-rw-r--r-- | doc/modules/colorizer.sass.html | 188 | ||||
-rw-r--r-- | doc/modules/colorizer.trie.html | 1 | ||||
-rw-r--r-- | doc/modules/utils.html | 1 | ||||
-rw-r--r-- | lua/colorizer/buffer_utils.lua | 6 | ||||
-rw-r--r-- | lua/colorizer/color_utils.lua | 305 | ||||
-rw-r--r-- | lua/colorizer/matcher_utils.lua | 4 | ||||
-rw-r--r-- | lua/colorizer/sass.lua | 316 |
13 files changed, 585 insertions, 473 deletions
diff --git a/doc/colorizer.txt b/doc/colorizer.txt index 87a3a90..2cc2d6e 100644 --- a/doc/colorizer.txt +++ b/doc/colorizer.txt @@ -351,14 +351,6 @@ Functions: ~ |color_name_parser| - Grab all the colour values from `vim.api.nvim_get_color_map` and create a lookup table. - |sass_cleanup| - Cleanup sass variables - - |sass_update_variables| - Parse the given lines for sass variabled and add - to SASS[buf].DEFINITIONS_ALL. - - |sass_name_parser| - Parse the given line for sass color names - check for value in SASS[buf].DEFINITIONS_ALL - |rgb_function_parser| - Parse for rgb() css function and return rgb hex. |rgba_function_parser| - Parse for rgba() css function and return rgb hex. @@ -401,53 +393,6 @@ color_name_parser({line}, {i}, {opts}) *colorizer.color_utils.color_name_parser* -sass_cleanup({buf}) *colorizer.color_utils.sass_cleanup* - Cleanup sass variables - - Parameters: ~ - {buf} - number - - - - - *colorizer.color_utils.sass_update_variables* -sass_update_variables({buf}, {line_start}, {line_end}, {lines}, {color_parser}, -{options}, {options_local}) - Parse the given lines for sass variabled and add to - SASS[buf].DEFINITIONS_ALL. - - which is then used in |sass_name_parser| - If lines are not given, then fetch the lines with line_start and line_end - - - Parameters: ~ - {buf} - number - {line_start} - number - {line_end} - number - {lines} - table|nil - {color_parser} - function|boolean - {options} - table: Buffer options - {options_local} - table|nil: Buffer local variables - - returns:~ - boolean - - - -sass_name_parser({line}, {i}, {buf}) *colorizer.color_utils.sass_name_parser* - Parse the given line for sass color names - check for value in SASS[buf].DEFINITIONS_ALL - - Parameters: ~ - {line} - string: Line to parse - {i} - number: Index of line from where to start parsing - {buf} - number - - returns:~ - number or nil, string or nil - - - rgb_function_parser({line}, {i}) *colorizer.color_utils.rgb_function_parser* Parse for rgb() css function and return rgb hex. @@ -569,6 +514,69 @@ make_matcher({options}) *colorizer.matcher_utils.make_matcher* ============================================================================== +SASS *colorizer.sass-introduction* + +Helper functions to parse sass color variables + + +============================================================================== +LUA API *colorizer.sass-lua-api* + +Functions: ~ + |sass_cleanup| - Cleanup sass variables and watch handlers + + |sass_name_parser| - Parse the given line for sass color names + check for value in SASS[buf].DEFINITIONS_ALL + + |sass_update_variables| - Parse the given lines for sass variabled and add + to SASS[buf].DEFINITIONS_ALL. + + +sass_cleanup({buf}) *colorizer.sass.sass_cleanup* + Cleanup sass variables and watch handlers + + Parameters: ~ + {buf} - number + + + +sass_name_parser({line}, {i}, {buf}) *colorizer.sass.sass_name_parser* + Parse the given line for sass color names + check for value in SASS[buf].DEFINITIONS_ALL + + Parameters: ~ + {line} - string: Line to parse + {i} - number: Index of line from where to start parsing + {buf} - number + + returns:~ + number or nil, string or nil + + + + + *colorizer.sass.sass_update_variables* +sass_update_variables({buf}, {line_start}, {line_end}, {lines}, {color_parser}, +{options}, {options_local}) + Parse the given lines for sass variabled and add to + SASS[buf].DEFINITIONS_ALL. + + which is then used in |sass_name_parser| + If lines are not given, then fetch the lines with line_start and line_end + + + Parameters: ~ + {buf} - number + {line_start} - number + {line_end} - number + {lines} - table|nil + {color_parser} - function|boolean + {options} - table: Buffer options + {options_local} - table|nil: Buffer local variables + + + +============================================================================== TRIE *colorizer.trie-introduction* Trie implementation in luajit. diff --git a/doc/index.html b/doc/index.html index 6042cb2..2b3efa5 100644 --- a/doc/index.html +++ b/doc/index.html @@ -35,6 +35,7 @@ <li><a href="modules/colorizer.buffer_utils.html">buffer_utils</a></li> <li><a href="modules/colorizer.color_utils.html">color_utils</a></li> <li><a href="modules/colorizer.matcher_utils.html">matcher_utils</a></li> + <li><a href="modules/colorizer.sass.html">sass</a></li> <li><a href="modules/colorizer.trie.html">trie</a></li> <li><a href="modules/utils.html">utils</a></li> </ul> @@ -64,6 +65,10 @@ <td class="summary">Helper functions for colorizer to enable required parsers</td> </tr> <tr> + <td class="name" nowrap><a href="modules/colorizer.sass.html">colorizer.sass</a></td> + <td class="summary">Helper functions to parse sass color variables</td> + </tr> + <tr> <td class="name" nowrap><a href="modules/colorizer.trie.html">colorizer.trie</a></td> <td class="summary">Trie implementation in luajit.</td> </tr> diff --git a/doc/modules/colorizer.buffer_utils.html b/doc/modules/colorizer.buffer_utils.html index 8d7beaa..e433609 100644 --- a/doc/modules/colorizer.buffer_utils.html +++ b/doc/modules/colorizer.buffer_utils.html @@ -44,6 +44,7 @@ <li><strong>buffer_utils</strong></li> <li><a href="../modules/colorizer.color_utils.html">color_utils</a></li> <li><a href="../modules/colorizer.matcher_utils.html">matcher_utils</a></li> + <li><a href="../modules/colorizer.sass.html">sass</a></li> <li><a href="../modules/colorizer.trie.html">trie</a></li> <li><a href="../modules/utils.html">utils</a></li> </ul> diff --git a/doc/modules/colorizer.color_utils.html b/doc/modules/colorizer.color_utils.html index 6e26961..f685731 100644 --- a/doc/modules/colorizer.color_utils.html +++ b/doc/modules/colorizer.color_utils.html @@ -42,6 +42,7 @@ <li><a href="../modules/colorizer.buffer_utils.html">buffer_utils</a></li> <li><strong>color_utils</strong></li> <li><a href="../modules/colorizer.matcher_utils.html">matcher_utils</a></li> + <li><a href="../modules/colorizer.sass.html">sass</a></li> <li><a href="../modules/colorizer.trie.html">trie</a></li> <li><a href="../modules/utils.html">utils</a></li> </ul> @@ -68,19 +69,6 @@ <td class="summary">Grab all the colour values from <code>vim.api.nvim_get_color_map</code> and create a lookup table.</td> </tr> <tr> - <td class="name" nowrap><a href="#sass_cleanup">sass_cleanup (buf)</a></td> - <td class="summary">Cleanup sass variables</td> - </tr> - <tr> - <td class="name" nowrap><a href="#sass_update_variables">sass_update_variables (buf, line_start, line_end, lines, color_parser, options, options_local)</a></td> - <td class="summary">Parse the given lines for sass variabled and add to SASS[buf].DEFINITIONS_ALL.</td> - </tr> - <tr> - <td class="name" nowrap><a href="#sass_name_parser">sass_name_parser (line, i, buf)</a></td> - <td class="summary">Parse the given line for sass color names - check for value in SASS[buf].DEFINITIONS_ALL</td> - </tr> - <tr> <td class="name" nowrap><a href="#rgb_function_parser">rgb_function_parser (line, i)</a></td> <td class="summary">Parse for rgb() css function and return rgb hex.</td> </tr> @@ -170,103 +158,6 @@ </dd> <dt> - <a name = "sass_cleanup"></a> - <strong>sass_cleanup (buf)</strong> - </dt> - <dd> - Cleanup sass variables - - - <h3>Parameters:</h3> - <ul> - <li><span class="parameter">buf</span> - number - </li> - </ul> - - - - - -</dd> - <dt> - <a name = "sass_update_variables"></a> - <strong>sass_update_variables (buf, line_start, line_end, lines, color_parser, options, options_local)</strong> - </dt> - <dd> - Parse the given lines for sass variabled and add to SASS[buf].DEFINITIONS<em>ALL. - which is then used in |sass</em>name<em>parser| - If lines are not given, then fetch the lines with line</em>start and line_end - - - <h3>Parameters:</h3> - <ul> - <li><span class="parameter">buf</span> - number - </li> - <li><span class="parameter">line_start</span> - number - </li> - <li><span class="parameter">line_end</span> - number - </li> - <li><span class="parameter">lines</span> - table|nil - </li> - <li><span class="parameter">color_parser</span> - function|boolean - </li> - <li><span class="parameter">options</span> - table: Buffer options - </li> - <li><span class="parameter">options_local</span> - table|nil: Buffer local variables - </li> - </ul> - - <h3>Returns:</h3> - <ol> - - boolean - </ol> - - - - -</dd> - <dt> - <a name = "sass_name_parser"></a> - <strong>sass_name_parser (line, i, buf)</strong> - </dt> - <dd> - Parse the given line for sass color names - check for value in SASS[buf].DEFINITIONS_ALL - - - <h3>Parameters:</h3> - <ul> - <li><span class="parameter">line</span> - string: Line to parse - </li> - <li><span class="parameter">i</span> - number: Index of line from where to start parsing - </li> - <li><span class="parameter">buf</span> - number - </li> - </ul> - - <h3>Returns:</h3> - <ol> - - number|nil, string|nil - </ol> - - - - -</dd> - <dt> <a name = "rgb_function_parser"></a> <strong>rgb_function_parser (line, i)</strong> </dt> diff --git a/doc/modules/colorizer.html b/doc/modules/colorizer.html index edc06db..14b976f 100644 --- a/doc/modules/colorizer.html +++ b/doc/modules/colorizer.html @@ -44,6 +44,7 @@ <li><a href="../modules/colorizer.buffer_utils.html">buffer_utils</a></li> <li><a href="../modules/colorizer.color_utils.html">color_utils</a></li> <li><a href="../modules/colorizer.matcher_utils.html">matcher_utils</a></li> + <li><a href="../modules/colorizer.sass.html">sass</a></li> <li><a href="../modules/colorizer.trie.html">trie</a></li> <li><a href="../modules/utils.html">utils</a></li> </ul> diff --git a/doc/modules/colorizer.matcher_utils.html b/doc/modules/colorizer.matcher_utils.html index 5a5514f..bdf0188 100644 --- a/doc/modules/colorizer.matcher_utils.html +++ b/doc/modules/colorizer.matcher_utils.html @@ -42,6 +42,7 @@ <li><a href="../modules/colorizer.buffer_utils.html">buffer_utils</a></li> <li><a href="../modules/colorizer.color_utils.html">color_utils</a></li> <li><strong>matcher_utils</strong></li> + <li><a href="../modules/colorizer.sass.html">sass</a></li> <li><a href="../modules/colorizer.trie.html">trie</a></li> <li><a href="../modules/utils.html">utils</a></li> </ul> diff --git a/doc/modules/colorizer.sass.html b/doc/modules/colorizer.sass.html new file mode 100644 index 0000000..45ec0d8 --- /dev/null +++ b/doc/modules/colorizer.sass.html @@ -0,0 +1,188 @@ +<!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>colorizer Docs</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>colorizer</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Modules</h2> +<ul class="nowrap"> + <li><a href="../modules/colorizer.html">colorizer</a></li> + <li><a href="../modules/colorizer.buffer_utils.html">buffer_utils</a></li> + <li><a href="../modules/colorizer.color_utils.html">color_utils</a></li> + <li><a href="../modules/colorizer.matcher_utils.html">matcher_utils</a></li> + <li><strong>sass</strong></li> + <li><a href="../modules/colorizer.trie.html">trie</a></li> + <li><a href="../modules/utils.html">utils</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>colorizer.sass</code></h1> +<p>Helper functions to parse sass color variables</p> +<p> + +</p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#sass_cleanup">sass_cleanup (buf)</a></td> + <td class="summary">Cleanup sass variables and watch handlers</td> + </tr> + <tr> + <td class="name" nowrap><a href="#sass_name_parser">sass_name_parser (line, i, buf)</a></td> + <td class="summary">Parse the given line for sass color names + check for value in SASS[buf].DEFINITIONS_ALL</td> + </tr> + <tr> + <td class="name" nowrap><a href="#sass_update_variables">sass_update_variables (buf, line_start, line_end, lines, color_parser, options, options_local)</a></td> + <td class="summary">Parse the given lines for sass variabled and add to SASS[buf].DEFINITIONS_ALL.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "sass_cleanup"></a> + <strong>sass_cleanup (buf)</strong> + </dt> + <dd> + Cleanup sass variables and watch handlers + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">buf</span> + number + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "sass_name_parser"></a> + <strong>sass_name_parser (line, i, buf)</strong> + </dt> + <dd> + Parse the given line for sass color names + check for value in SASS[buf].DEFINITIONS_ALL + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">line</span> + string: Line to parse + </li> + <li><span class="parameter">i</span> + number: Index of line from where to start parsing + </li> + <li><span class="parameter">buf</span> + number + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + number|nil, string|nil + </ol> + + + + +</dd> + <dt> + <a name = "sass_update_variables"></a> + <strong>sass_update_variables (buf, line_start, line_end, lines, color_parser, options, options_local)</strong> + </dt> + <dd> + Parse the given lines for sass variabled and add to SASS[buf].DEFINITIONS<em>ALL. + which is then used in |sass</em>name<em>parser| + If lines are not given, then fetch the lines with line</em>start and line_end + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">buf</span> + number + </li> + <li><span class="parameter">line_start</span> + number + </li> + <li><span class="parameter">line_end</span> + number + </li> + <li><span class="parameter">lines</span> + table|nil + </li> + <li><span class="parameter">color_parser</span> + function|boolean + </li> + <li><span class="parameter">options</span> + table: Buffer options + </li> + <li><span class="parameter">options_local</span> + table|nil: Buffer local variables + </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 - September </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/doc/modules/colorizer.trie.html b/doc/modules/colorizer.trie.html index e5fc981..25cd3cb 100644 --- a/doc/modules/colorizer.trie.html +++ b/doc/modules/colorizer.trie.html @@ -38,6 +38,7 @@ <li><a href="../modules/colorizer.buffer_utils.html">buffer_utils</a></li> <li><a href="../modules/colorizer.color_utils.html">color_utils</a></li> <li><a href="../modules/colorizer.matcher_utils.html">matcher_utils</a></li> + <li><a href="../modules/colorizer.sass.html">sass</a></li> <li><strong>trie</strong></li> <li><a href="../modules/utils.html">utils</a></li> </ul> diff --git a/doc/modules/utils.html b/doc/modules/utils.html index 3e6fb0a..8a5479a 100644 --- a/doc/modules/utils.html +++ b/doc/modules/utils.html @@ -42,6 +42,7 @@ <li><a href="../modules/colorizer.buffer_utils.html">buffer_utils</a></li> <li><a href="../modules/colorizer.color_utils.html">color_utils</a></li> <li><a href="../modules/colorizer.matcher_utils.html">matcher_utils</a></li> + <li><a href="../modules/colorizer.sass.html">sass</a></li> <li><a href="../modules/colorizer.trie.html">trie</a></li> <li><strong>utils</strong></li> </ul> diff --git a/lua/colorizer/buffer_utils.lua b/lua/colorizer/buffer_utils.lua index 9a48043..97e8918 100644 --- a/lua/colorizer/buffer_utils.lua +++ b/lua/colorizer/buffer_utils.lua @@ -9,8 +9,10 @@ local set_highlight = api.nvim_set_hl local color_utils = require "colorizer.color_utils" local color_is_bright = color_utils.color_is_bright -local sass_update_variables = color_utils.sass_update_variables -local sass_cleanup = color_utils.sass_cleanup + +local sass = require "colorizer.sass" +local sass_update_variables = sass.sass_update_variables +local sass_cleanup = sass.sass_cleanup local make_matcher = require("colorizer.matcher_utils").make_matcher diff --git a/lua/colorizer/color_utils.lua b/lua/colorizer/color_utils.lua index adb3f19..2a7e7ab 100644 --- a/lua/colorizer/color_utils.lua +++ b/lua/colorizer/color_utils.lua @@ -7,10 +7,6 @@ local byte_is_alphanumeric = utils.byte_is_alphanumeric local byte_is_hex = utils.byte_is_hex local parse_hex = utils.parse_hex local percent_or_hex = utils.percent_or_hex -local get_last_modified = utils.get_last_modified -local watch_file = utils.watch_file - -local uv = vim.loop local bit = require "bit" local floor, min, max = math.floor, math.min, math.max @@ -128,304 +124,6 @@ local function color_name_parser(line, i, opts) end end -local SASS = {} ---- Cleanup sass variables ----@param buf number -local function sass_cleanup(buf) - SASS[buf] = nil -end - -local dollar_hash = ("$"):byte() -local at_hash = ("@"):byte() -local colon_hash = (";"):byte() - --- Helper function for sass_update_variables -local function sass_parse_lines(buf, line_start, content, name) - SASS[buf].DEFINITIONS_ALL = SASS[buf].DEFINITIONS_ALL or {} - SASS[buf].DEFINITIONS_RECURSIVE_CURRENT = SASS[buf].DEFINITIONS_RECURSIVE_CURRENT or {} - SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE = SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE or {} - - SASS[buf].DEFINITIONS_LINEWISE[name] = SASS[buf].DEFINITIONS_LINEWISE[name] or {} - SASS[buf].DEFINITIONS[name] = SASS[buf].DEFINITIONS[name] or {} - SASS[buf].IMPORTS[name] = SASS[buf].IMPORTS[name] or {} - SASS[buf].WATCH_IMPORTS[name] = SASS[buf].WATCH_IMPORTS[name] or {} - SASS[buf].CURRENT_IMPORTS[name] = {} - - local import_find_colon = false - for i, line in ipairs(content) do - local linenum = i - 1 + line_start - -- Invalidate any existing definitions for the lines we are processing. - if not vim.tbl_isempty(SASS[buf].DEFINITIONS_LINEWISE[name][linenum] or {}) then - for v, _ in pairs(SASS[buf].DEFINITIONS_LINEWISE[name][linenum]) do - SASS[buf].DEFINITIONS[name][v] = nil - end - SASS[buf].DEFINITIONS_LINEWISE[name][linenum] = {} - else - SASS[buf].DEFINITIONS_LINEWISE[name][linenum] = {} - end - - local index = 1 - while index < #line do - -- ignore comments - if line:match("^//", index) then - index = #line - -- line starting with variables $var - elseif not import_find_colon and line:byte(index) == dollar_hash then - local variable_name, variable_value = line:match("^%$([%w_-]+)%s*:%s*(.+)%s*", index) - -- Check if we got a variable definition - if variable_name and variable_value then - -- Check for a recursive variable definition. - if variable_value:byte() == dollar_hash then - local target_variable_name, len = variable_value:match "^%$([%w_-]+)()" - if target_variable_name then - -- Update the value. - SASS[buf].DEFINITIONS_RECURSIVE_CURRENT[variable_name] = target_variable_name - SASS[buf].DEFINITIONS_LINEWISE[name][linenum][variable_name] = true - index = index + len - end - index = index + 1 - else - -- Check for a recursive variable definition. - -- If it's not recursive, then just update the value. - if SASS[buf].COLOR_PARSER then - local length, rgb_hex = SASS[buf].COLOR_PARSER(variable_value, 1) - if length and rgb_hex then - SASS[buf].DEFINITIONS[name][variable_name] = rgb_hex - SASS[buf].DEFINITIONS_RECURSIVE_CURRENT[variable_name] = rgb_hex - SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE[variable_name] = rgb_hex - SASS[buf].DEFINITIONS_LINEWISE[name][linenum][variable_name] = true - -- added 3 because the color parsers returns 3 less - -- todo: need to fix - index = index + length + 3 - end - end - end - index = index + #variable_name - end - -- color ( ; ) found - elseif import_find_colon and line:byte(index) == colon_hash then - import_find_colon, index = false, index + 1 - -- imports @import 'somefile' - elseif line:byte(index) == at_hash or import_find_colon then - local variable_value, colon, import_kw - if import_find_colon then - variable_value, colon = line:match("%s*(.*[^;])%s*([;]?)", index) - else - import_kw, variable_value, colon = line:match("@(%a+)%s+(.+[^;])%s*([;]?)", index) - import_kw = (import_kw == "import" or import_kw == "use") - end - - if not colon or colon == "" then - -- now loop until ; is found - import_find_colon = true - else - import_find_colon = false - end - - -- if import/use key word is found along with file name - if import_kw and variable_value then - local files = {} - -- grab files to be imported - for s, a in variable_value:gmatch "['\"](.-)()['\"]" do - local folder_path, file_name = vim.fn.fnamemodify(s, ":h"), vim.fn.fnamemodify(s, ":t") - if file_name ~= "" then - -- get the root directory of the file - local parent_dir = vim.fn.fnamemodify(name, ":h") - parent_dir = (parent_dir ~= "") and parent_dir .. "/" or "" - folder_path = vim.fn.fnamemodify(parent_dir .. folder_path, ":p") - file_name = file_name - files = { - folder_path .. file_name .. ".scss", - folder_path .. "_" .. file_name .. ".scss", - folder_path .. file_name .. ".sass", - folder_path .. "_" .. file_name .. ".sass", - } - end - -- why 2 * a ? I don't know - index = index + 2 * a - end - - -- process imported files - for _, v in ipairs(files) do - -- parse the sass files - local last_modified = get_last_modified(v) - if last_modified then - -- grab the full path - v = uv.fs_realpath(v) - SASS[buf].CURRENT_IMPORTS[name][v] = true - - if not SASS[buf].WATCH_IMPORTS[name][v] then - SASS[buf].IMPORTS[name][v] = last_modified - local c, ind = {}, 0 - for l in io.lines(v) do - ind = ind + 1 - c[ind] = l - end - sass_parse_lines(buf, 0, c, v) - c = nil - - local function watch_callback() - local dimen = vim.api.nvim_buf_call(buf, function() - return { vim.fn.line "w0", vim.fn.line "w$", vim.fn.line "$", vim.api.nvim_win_get_height(0) } - end) - -- todo: Improve this to only refresh highlight for visible lines - -- can't find out how to get visible rows from another window - -- probably a neovim bug, it is returning 1 and 1 or 1 and 5 - if - dimen[1] ~= dimen[2] - and ((dimen[3] > dimen[4] and dimen[2] > dimen[4]) or (dimen[2] >= dimen[3])) - then - SASS[buf].LOCAL_OPTIONS.__startline = dimen[1] - SASS[buf].LOCAL_OPTIONS.__endline = dimen[2] - end - SASS[buf].LOCAL_OPTIONS.__event = "" - - local lastm = get_last_modified(v) - if lastm then - SASS[buf].IMPORTS[name][v] = lastm - local cc, inde = {}, 0 - for l in io.lines(v) do - inde = inde + 1 - cc[inde] = l - end - sass_parse_lines(buf, 0, cc, v) - cc = nil - end - - require("colorizer.buffer_utils").rehighlight_buffer( - buf, - SASS[buf].OPTIONS, - SASS[buf].LOCAL_OPTIONS, - true - ) - end - SASS[buf].WATCH_IMPORTS[name][v] = watch_file(v, watch_callback) - end - else - -- if file does not exists then remove related variables - SASS[buf].IMPORTS[name][v] = nil - pcall(uv.fs_event_stop, SASS[buf].WATCH_IMPORTS[name][v]) - SASS[buf].WATCH_IMPORTS[name][v] = nil - end - end -- process imported files - end - end -- parse lines - index = index + 1 - end -- while loop end - end -- for loop end - - local function remove_unused_imports(import_name) - if type(SASS[buf].IMPORTS[import_name]) == "table" then - for file, _ in pairs(SASS[buf].IMPORTS[import_name]) do - remove_unused_imports(file) - end - end - SASS[buf].DEFINITIONS[import_name] = nil - SASS[buf].DEFINITIONS_LINEWISE[import_name] = nil - SASS[buf].IMPORTS[import_name] = nil - -- stop the watch handler - pcall(uv.fs_event_stop, SASS[buf].WATCH_IMPORTS[import_name]) - SASS[buf].WATCH_IMPORTS[import_name] = nil - end - - -- remove definitions of files which are not imported now - for file, _ in pairs(SASS[buf].IMPORTS[name]) do - if not SASS[buf].CURRENT_IMPORTS[name][file] then - remove_unused_imports(name) - end - end -end -- sass_parse_lines end - ---- Parse the given lines for sass variabled and add to SASS[buf].DEFINITIONS_ALL. --- which is then used in |sass_name_parser| --- If lines are not given, then fetch the lines with line_start and line_end ----@param buf number ----@param line_start number ----@param line_end number ----@param lines table|nil ----@param color_parser function|boolean ----@param options table: Buffer options ----@param options_local table|nil: Buffer local variables -local function sass_update_variables(buf, line_start, line_end, lines, color_parser, options, options_local) - lines = lines or vim.api.nvim_buf_get_lines(buf, line_start, line_end, false) - - if not SASS[buf] then - SASS[buf] = { - DEFINITIONS_ALL = {}, - DEFINITIONS = {}, - IMPORTS = {}, - WATCH_IMPORTS = {}, - CURRENT_IMPORTS = {}, - DEFINITIONS_LINEWISE = {}, - OPTIONS = options, - LOCAL_OPTIONS = options_local, - } - end - - SASS[buf].COLOR_PARSER = color_parser - SASS[buf].DEFINITIONS_ALL = {} - SASS[buf].DEFINITIONS_RECURSIVE_CURRENT = {} - SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE = {} - - sass_parse_lines(buf, line_start, lines, api.nvim_buf_get_name(buf)) - - -- add non-recursive def to DEFINITIONS_ALL - for _, color_table in pairs(SASS[buf].DEFINITIONS) do - for color_name, color in pairs(color_table) do - SASS[buf].DEFINITIONS_ALL[color_name] = color - end - end - - -- normally this is just a wasted step as all the values here are - -- already present in SASS[buf].DEFINITIONS - -- but when undoing a pasted text, it acts as a backup - for name, color in pairs(SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE) do - SASS[buf].DEFINITIONS_ALL[name] = color - end - - -- try to find the absolute color value for the given name - -- use tail call recursion - -- https://www.lua.org/pil/6.3.html - local function find_absolute_value(name, color_name) - return SASS[buf].DEFINITIONS_ALL[color_name] - or ( - SASS[buf].DEFINITIONS_RECURSIVE_CURRENT[color_name] - and find_absolute_value(name, SASS[buf].DEFINITIONS_RECURSIVE_CURRENT[color_name]) - ) - end - - local function set_color_value(name, color_name) - local value = find_absolute_value(name, color_name) - if value then - SASS[buf].DEFINITIONS_ALL[name] = value - end - SASS[buf].DEFINITIONS_RECURSIVE_CURRENT[name] = nil - end - - for name, color_name in pairs(SASS[buf].DEFINITIONS_RECURSIVE_CURRENT) do - set_color_value(name, color_name) - end - - SASS[buf].DEFINITIONS_RECURSIVE_CURRENT = nil - SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE = nil -end - ---- Parse the given line for sass color names --- check for value in SASS[buf].DEFINITIONS_ALL ----@param line string: Line to parse ----@param i number: Index of line from where to start parsing ----@param buf number ----@return number|nil, string|nil -local function sass_name_parser(line, i, buf) - local variable_name = line:sub(i):match "^%$([%w_-]+)" - if variable_name then - local rgb_hex = SASS[buf].DEFINITIONS_ALL[variable_name] - if rgb_hex then - return #variable_name + 1, rgb_hex - end - end -end - --- Converts an HSL color value to RGB. ---@param h number: Hue ---@param s number: Saturation @@ -710,7 +408,4 @@ return { rgba_function_parser = rgba_function_parser, hsl_function_parser = hsl_function_parser, hsla_function_parser = hsla_function_parser, - sass_name_parser = sass_name_parser, - sass_cleanup = sass_cleanup, - sass_update_variables = sass_update_variables, } diff --git a/lua/colorizer/matcher_utils.lua b/lua/colorizer/matcher_utils.lua index 7803eac..3f8047a 100644 --- a/lua/colorizer/matcher_utils.lua +++ b/lua/colorizer/matcher_utils.lua @@ -5,9 +5,11 @@ local min, max = math.min, math.max local color_utils = require "colorizer.color_utils" local color_name_parser = color_utils.color_name_parser -local sass_name_parser = color_utils.sass_name_parser local rgba_hex_parser = color_utils.rgba_hex_parser +local sass = require "colorizer.sass" +local sass_name_parser = sass.sass_name_parser + local parser = {} parser["_0x"] = color_utils.argb_hex_parser parser["_rgb"] = color_utils.rgb_function_parser diff --git a/lua/colorizer/sass.lua b/lua/colorizer/sass.lua new file mode 100644 index 0000000..a003624 --- /dev/null +++ b/lua/colorizer/sass.lua @@ -0,0 +1,316 @@ +---Helper functions to parse sass color variables +--@module colorizer.sass +local api = vim.api +local uv = vim.loop + +local utils = require "colorizer.utils" +local get_last_modified = utils.get_last_modified +local watch_file = utils.watch_file + +local DOLLAR_HASH = ("$"):byte() +local AT_HASH = ("@"):byte() +local COLON_HASH = (";"):byte() + +local SASS = {} + +local function remove_unused_imports(buf, import_name) + if type(SASS[buf].IMPORTS[import_name]) == "table" then + for file, _ in pairs(SASS[buf].IMPORTS[import_name]) do + remove_unused_imports(buf, file) + end + end + SASS[buf].DEFINITIONS[import_name] = nil + SASS[buf].DEFINITIONS_LINEWISE[import_name] = nil + SASS[buf].IMPORTS[import_name] = nil + -- stop the watch handler + pcall(uv.fs_event_stop, SASS[buf].WATCH_IMPORTS[import_name]) + SASS[buf].WATCH_IMPORTS[import_name] = nil +end + +--- Cleanup sass variables and watch handlers +---@param buf number +local function sass_cleanup(buf) + remove_unused_imports(buf, api.nvim_buf_get_name(buf)) + SASS[buf] = nil +end + +--- Parse the given line for sass color names +-- check for value in SASS[buf].DEFINITIONS_ALL +---@param line string: Line to parse +---@param i number: Index of line from where to start parsing +---@param buf number +---@return number|nil, string|nil +local function sass_name_parser(line, i, buf) + local variable_name = line:sub(i):match "^%$([%w_-]+)" + if variable_name then + local rgb_hex = SASS[buf].DEFINITIONS_ALL[variable_name] + if rgb_hex then + return #variable_name + 1, rgb_hex + end + end +end + +-- Helper function for sass_update_variables +local function sass_parse_lines(buf, line_start, content, name) + SASS[buf].DEFINITIONS_ALL = SASS[buf].DEFINITIONS_ALL or {} + SASS[buf].DEFINITIONS_RECURSIVE_CURRENT = SASS[buf].DEFINITIONS_RECURSIVE_CURRENT or {} + SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE = SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE or {} + + SASS[buf].DEFINITIONS_LINEWISE[name] = SASS[buf].DEFINITIONS_LINEWISE[name] or {} + SASS[buf].DEFINITIONS[name] = SASS[buf].DEFINITIONS[name] or {} + SASS[buf].IMPORTS[name] = SASS[buf].IMPORTS[name] or {} + SASS[buf].WATCH_IMPORTS[name] = SASS[buf].WATCH_IMPORTS[name] or {} + SASS[buf].CURRENT_IMPORTS[name] = {} + + local import_find_colon = false + for i, line in ipairs(content) do + local linenum = i - 1 + line_start + -- Invalidate any existing definitions for the lines we are processing. + if not vim.tbl_isempty(SASS[buf].DEFINITIONS_LINEWISE[name][linenum] or {}) then + for v, _ in pairs(SASS[buf].DEFINITIONS_LINEWISE[name][linenum]) do + SASS[buf].DEFINITIONS[name][v] = nil + end + SASS[buf].DEFINITIONS_LINEWISE[name][linenum] = {} + else + SASS[buf].DEFINITIONS_LINEWISE[name][linenum] = {} + end + + local index = 1 + while index < #line do + -- ignore comments + if line:sub(index, index + 1) == "//" then + index = #line + -- line starting with variables $var + elseif not import_find_colon and line:byte(index) == DOLLAR_HASH then + local variable_name, variable_value = line:match("^%$([%w_-]+)%s*:%s*(.+)%s*", index) + -- Check if we got a variable definition + if variable_name and variable_value then + -- Check for a recursive variable definition. + if variable_value:byte() == DOLLAR_HASH then + local target_variable_name, len = variable_value:match "^%$([%w_-]+)()" + if target_variable_name then + -- Update the value. + SASS[buf].DEFINITIONS_RECURSIVE_CURRENT[variable_name] = target_variable_name + SASS[buf].DEFINITIONS_LINEWISE[name][linenum][variable_name] = true + index = index + len + end + index = index + 1 + else + -- Check for a recursive variable definition. + -- If it's not recursive, then just update the value. + if SASS[buf].COLOR_PARSER then + local length, rgb_hex = SASS[buf].COLOR_PARSER(variable_value, 1) + if length and rgb_hex then + SASS[buf].DEFINITIONS[name][variable_name] = rgb_hex + SASS[buf].DEFINITIONS_RECURSIVE_CURRENT[variable_name] = rgb_hex + SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE[variable_name] = rgb_hex + SASS[buf].DEFINITIONS_LINEWISE[name][linenum][variable_name] = true + -- added 3 because the color parsers returns 3 less + -- todo: need to fix + index = index + length + 3 + end + end + end + index = index + #variable_name + end + -- color ( ; ) found + elseif import_find_colon and line:byte(index) == COLON_HASH then + import_find_colon, index = false, index + 1 + -- imports @import 'somefile' + elseif line:byte(index) == AT_HASH or import_find_colon then + local variable_value, colon, import_kw + if import_find_colon then + variable_value, colon = line:match("%s*(.*[^;])%s*([;]?)", index) + else + import_kw, variable_value, colon = line:match("@(%a+)%s+(.+[^;])%s*([;]?)", index) + import_kw = (import_kw == "import" or import_kw == "use") + end + + if not colon or colon == "" then + -- now loop until ; is found + import_find_colon = true + else + import_find_colon = false + end + + -- if import/use key word is found along with file name + if import_kw and variable_value then + local files = {} + -- grab files to be imported + for s, a in variable_value:gmatch "['\"](.-)()['\"]" do + local folder_path, file_name = vim.fn.fnamemodify(s, ":h"), vim.fn.fnamemodify(s, ":t") + if file_name ~= "" then + -- get the root directory of the file + local parent_dir = vim.fn.fnamemodify(name, ":h") + parent_dir = (parent_dir ~= "") and parent_dir .. "/" or "" + folder_path = vim.fn.fnamemodify(parent_dir .. folder_path, ":p") + file_name = file_name + files = { + folder_path .. file_name .. ".scss", + folder_path .. "_" .. file_name .. ".scss", + folder_path .. file_name .. ".sass", + folder_path .. "_" .. file_name .. ".sass", + } + end + -- why 2 * a ? I don't know + index = index + 2 * a + end + + -- process imported files + for _, v in ipairs(files) do + -- parse the sass files + local last_modified = get_last_modified(v) + if last_modified then + -- grab the full path + v = uv.fs_realpath(v) + SASS[buf].CURRENT_IMPORTS[name][v] = true + + if not SASS[buf].WATCH_IMPORTS[name][v] then + SASS[buf].IMPORTS[name][v] = last_modified + local c, ind = {}, 0 + for l in io.lines(v) do + ind = ind + 1 + c[ind] = l + end + sass_parse_lines(buf, 0, c, v) + c = nil + + local function watch_callback() + local dimen = vim.api.nvim_buf_call(buf, function() + return { vim.fn.line "w0", vim.fn.line "w$", vim.fn.line "$", vim.api.nvim_win_get_height(0) } + end) + -- todo: Improve this to only refresh highlight for visible lines + -- can't find out how to get visible rows from another window + -- probably a neovim bug, it is returning 1 and 1 or 1 and 5 + if + SASS[buf].LOCAL_OPTIONS + and dimen[1] ~= dimen[2] + and ((dimen[3] > dimen[4] and dimen[2] > dimen[4]) or (dimen[2] >= dimen[3])) + then + SASS[buf].LOCAL_OPTIONS.__startline = dimen[1] + SASS[buf].LOCAL_OPTIONS.__endline = dimen[2] + end + SASS[buf].LOCAL_OPTIONS.__event = "" + + local lastm = get_last_modified(v) + if lastm then + SASS[buf].IMPORTS[name][v] = lastm + local cc, inde = {}, 0 + for l in io.lines(v) do + inde = inde + 1 + cc[inde] = l + end + sass_parse_lines(buf, 0, cc, v) + cc = nil + end + + require("colorizer.buffer_utils").rehighlight_buffer( + buf, + SASS[buf].OPTIONS, + SASS[buf].LOCAL_OPTIONS, + true + ) + end + SASS[buf].WATCH_IMPORTS[name][v] = watch_file(v, watch_callback) + end + else + -- if file does not exists then remove related variables + SASS[buf].IMPORTS[name][v] = nil + pcall(uv.fs_event_stop, SASS[buf].WATCH_IMPORTS[name][v]) + SASS[buf].WATCH_IMPORTS[name][v] = nil + end + end -- process imported files + end + end -- parse lines + index = index + 1 + end -- while loop end + end -- for loop end + + -- remove definitions of files which are not imported now + for file, _ in pairs(SASS[buf].IMPORTS[name]) do + if not SASS[buf].CURRENT_IMPORTS[name][file] then + remove_unused_imports(buf, name) + end + end +end -- sass_parse_lines end + +--- Parse the given lines for sass variabled and add to SASS[buf].DEFINITIONS_ALL. +-- which is then used in |sass_name_parser| +-- If lines are not given, then fetch the lines with line_start and line_end +---@param buf number +---@param line_start number +---@param line_end number +---@param lines table|nil +---@param color_parser function|boolean +---@param options table: Buffer options +---@param options_local table|nil: Buffer local variables +local function sass_update_variables(buf, line_start, line_end, lines, color_parser, options, options_local) + lines = lines or vim.api.nvim_buf_get_lines(buf, line_start, line_end, false) + + if not SASS[buf] then + SASS[buf] = { + DEFINITIONS_ALL = {}, + DEFINITIONS = {}, + IMPORTS = {}, + WATCH_IMPORTS = {}, + CURRENT_IMPORTS = {}, + DEFINITIONS_LINEWISE = {}, + OPTIONS = options, + LOCAL_OPTIONS = options_local, + } + end + + SASS[buf].COLOR_PARSER = color_parser + SASS[buf].DEFINITIONS_ALL = {} + SASS[buf].DEFINITIONS_RECURSIVE_CURRENT = {} + SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE = {} + + sass_parse_lines(buf, line_start, lines, api.nvim_buf_get_name(buf)) + + -- add non-recursive def to DEFINITIONS_ALL + for _, color_table in pairs(SASS[buf].DEFINITIONS) do + for color_name, color in pairs(color_table) do + SASS[buf].DEFINITIONS_ALL[color_name] = color + end + end + + -- normally this is just a wasted step as all the values here are + -- already present in SASS[buf].DEFINITIONS + -- but when undoing a pasted text, it acts as a backup + for name, color in pairs(SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE) do + SASS[buf].DEFINITIONS_ALL[name] = color + end + + -- try to find the absolute color value for the given name + -- use tail call recursion + -- https://www.lua.org/pil/6.3.html + local function find_absolute_value(name, color_name) + return SASS[buf].DEFINITIONS_ALL[color_name] + or ( + SASS[buf].DEFINITIONS_RECURSIVE_CURRENT[color_name] + and find_absolute_value(name, SASS[buf].DEFINITIONS_RECURSIVE_CURRENT[color_name]) + ) + end + + local function set_color_value(name, color_name) + local value = find_absolute_value(name, color_name) + if value then + SASS[buf].DEFINITIONS_ALL[name] = value + end + SASS[buf].DEFINITIONS_RECURSIVE_CURRENT[name] = nil + end + + for name, color_name in pairs(SASS[buf].DEFINITIONS_RECURSIVE_CURRENT) do + set_color_value(name, color_name) + end + + SASS[buf].DEFINITIONS_RECURSIVE_CURRENT = nil + SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE = nil +end + +--- @export +return { + sass_cleanup = sass_cleanup, + sass_name_parser = sass_name_parser, + sass_update_variables = sass_update_variables, +} |