aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua/cmake/actions.lua19
-rw-r--r--lua/cmake/commands.lua6
-rw-r--r--lua/cmake/config.lua16
-rw-r--r--lua/cmake/constants.lua3
-rw-r--r--lua/cmake/fileapi.lua2
-rw-r--r--lua/cmake/lazy.lua21
-rw-r--r--lua/cmake/lyaml.lua1038
-rw-r--r--lua/cmake/project.lua44
-rw-r--r--lua/cmake/terminal.lua2
-rw-r--r--lua/cmake/test.lua11
-rw-r--r--lua/cmake/variants.lua3
11 files changed, 601 insertions, 564 deletions
diff --git a/lua/cmake/actions.lua b/lua/cmake/actions.lua
index ff64f95..3c09d93 100644
--- a/lua/cmake/actions.lua
+++ b/lua/cmake/actions.lua
@@ -1,6 +1,8 @@
local pr = require("cmake.project")
local config = require("cmake.config")
local t = require("cmake.terminal")
+local utils = require("cmake.utils")
+local constants = require("cmake.constants")
local Path = require("plenary.path")
local M = {}
@@ -121,4 +123,21 @@ M.toggle = function()
t.cmake_toggle()
end
+M.edit_variants = function()
+ utils.file_exists(constants.variants_yaml_filename, function(variants_exists)
+ if variants_exists then
+ vim.schedule(function()
+ vim.cmd(string.format("e %s", constants.variants_yaml_filename))
+ end)
+ else
+ local default_yaml = require("cmake.lyaml").dump(config.cmake.variants)
+ utils.write_file(constants.variants_yaml_filename, default_yaml, function()
+ vim.schedule(function()
+ vim.cmd(string.format("e %s", constants.variants_yaml_filename))
+ end)
+ end)
+ end
+ end)
+end
+
return M
diff --git a/lua/cmake/commands.lua b/lua/cmake/commands.lua
index f754b1c..c2f6e75 100644
--- a/lua/cmake/commands.lua
+++ b/lua/cmake/commands.lua
@@ -29,7 +29,11 @@ M.register_commands = function()
cmd("CMakeToggle", function()
require("cmake.actions").toggle()
- end, { desc = "Toggle CMake terminal" })
+ end, { desc = "Toggle terminal with cmake command" })
+
+ cmd("CMakeEditVariants", function()
+ require("cmake.actions").edit_variants()
+ end, { desc = "Edit variants" })
end
return M
diff --git a/lua/cmake/config.lua b/lua/cmake/config.lua
index 0e3a641..5a4cb75 100644
--- a/lua/cmake/config.lua
+++ b/lua/cmake/config.lua
@@ -9,12 +9,14 @@ local default_config = {
build_tool_args = {},
generator = nil,
variants = {
- {
+ buildType = {
default = "debug",
description = "Build type",
choices = {
- debug = { short = "Debug", long = "Long debug", buildType = "Debug" },
- release = { short = "Release", long = "Long release", buildType = "Release" },
+ debug = { short = "Debug", buildType = "Debug" },
+ release = { short = "Release", buildType = "Release" },
+ relWithDebInfo = { short = "Release with debug info", buildType = "RelWithDebInfo" },
+ minSizeRel = { short = "Minimal size releaze", buildType = "MinSizeRel" },
},
},
},
@@ -23,7 +25,7 @@ local default_config = {
source_directory = "${workspaceFolder}",
},
terminal = {
- direction = "horizontal",
+ direction = "vertical",
display_name = "CMake",
close_on_exit = "success",
hidden = false,
@@ -31,7 +33,7 @@ local default_config = {
focus = false,
},
runner_terminal = {
- direction = "horizontal",
+ direction = "vertical",
close_on_exit = false,
hidden = false,
clear_env = false,
@@ -41,8 +43,8 @@ local default_config = {
after = "success",
},
variants_display = {
- short = { sep = " × " },
- long = { sep = " ❄ " },
+ short = { sep = " × ", show = true },
+ long = { sep = " ❄ ", show = false },
},
}
diff --git a/lua/cmake/constants.lua b/lua/cmake/constants.lua
new file mode 100644
index 0000000..fcbfea3
--- /dev/null
+++ b/lua/cmake/constants.lua
@@ -0,0 +1,3 @@
+return {
+ variants_yaml_filename = "cmake-variants.yaml",
+}
diff --git a/lua/cmake/fileapi.lua b/lua/cmake/fileapi.lua
index 2f61677..47a7459 100644
--- a/lua/cmake/fileapi.lua
+++ b/lua/cmake/fileapi.lua
@@ -47,6 +47,8 @@ function FileApi.read_reply(path, callback)
if object.kind == "codemodel" then
utils.read_file(Path:new(reply_dir, object.jsonFile):absolute(), function(codemodel_data)
local codemodel = vim.json.decode(codemodel_data)
+ --FIX: this loop does not read all files if codemodel contains many targets. This is because libuv (or some external settings) forbids to open files
+ -- in async mode more than some limit number. Seems like the solution is to queue these calls and limit max number for opened files per time
for _, target in ipairs(codemodel.configurations[1].targets) do
utils.read_file(
Path:new(reply_dir, target.jsonFile):absolute(),
diff --git a/lua/cmake/lazy.lua b/lua/cmake/lazy.lua
new file mode 100644
index 0000000..7669dcd
--- /dev/null
+++ b/lua/cmake/lazy.lua
@@ -0,0 +1,21 @@
+local lazy = {}
+
+--- Require on index.
+---
+--- Will only require the module after the first index of a module.
+--- Only works for modules that export a table.
+---@param require_path string
+---@return table
+lazy.require = function(require_path)
+ return setmetatable({}, {
+ __index = function(_, key)
+ return require(require_path)[key]
+ end,
+
+ __newindex = function(_, key, value)
+ require(require_path)[key] = value
+ end,
+ })
+end
+
+return lazy
diff --git a/lua/cmake/lyaml.lua b/lua/cmake/lyaml.lua
index 9555a75..3a17cc1 100644
--- a/lua/cmake/lyaml.lua
+++ b/lua/cmake/lyaml.lua
@@ -1,519 +1,495 @@
---[[
-(The MIT License)
-
-Copyright (c) 2017 Dominic Letz dominicletz@exosite.com
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the 'Software'), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
-OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---]]
+-- (The MIT License)
+--
+-- Copyright (c) 2017 Dominic Letz dominicletz@exosite.com
+--
+-- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+-- documentation files (the 'Software'), to deal in the Software without restriction, including without limitation
+-- the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
+-- and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+--
+-- The above copyright notice and this permission notice shall be included in all copies or substantial portions
+-- of the Software.
+--
+-- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+-- TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+-- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+-- CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+-- DEALINGS IN THE SOFTWARE.
local table_print_value
table_print_value = function(value, indent, done)
- indent = indent or 0
- done = done or {}
- if type(value) == "table" and not done[value] then
- done[value] = true
-
- local list = {}
- for key in pairs(value) do
- list[#list + 1] = key
- end
- table.sort(list, function(a, b)
- return tostring(a) < tostring(b)
- end)
- local last = list[#list]
-
- local rep = "{\n"
- local comma
- for _, key in ipairs(list) do
- if key == last then
- comma = ""
- else
- comma = ","
- end
- local keyRep
- if type(key) == "number" then
- keyRep = key
- else
- keyRep = string.format("%q", tostring(key))
- end
- rep = rep
- .. string.format(
- "%s[%s] = %s%s\n",
- string.rep(" ", indent + 2),
- keyRep,
- table_print_value(value[key], indent + 2, done),
- comma
- )
- end
-
- rep = rep .. string.rep(" ", indent) -- indent it
- rep = rep .. "}"
-
- done[value] = false
- return rep
- elseif type(value) == "string" then
- return string.format("%q", value)
- else
- return tostring(value)
- end
+ indent = indent or 0
+ done = done or {}
+ if type(value) == "table" then
+ -- done[value] = true
+
+ local rep = "\n"
+ for key, val in pairs(value) do
+ local keyRep
+ if type(key) == "number" then
+ keyRep = "-"
+ else
+ keyRep = string.format("%s:", tostring(key))
+ end
+ local child_indent = indent + 2
+ rep = rep
+ .. string
+ .format("%s%s %s\n", string.rep(" ", indent), keyRep, table_print_value(val, child_indent, done))
+ :gsub("\n\n", "\n")
+ end
+
+ -- rep = rep .. string.rep(" ", indent) -- indent it
+
+ -- done[value] = false
+ return rep
+ elseif type(value) == "string" then
+ return string.format("%q", value)
+ else
+ return tostring(value)
+ end
end
local table_print = function(tt)
- print("return " .. table_print_value(tt))
+ return vim.trim(table_print_value(tt))
end
local table_clone = function(t)
- local clone = {}
- for k, v in pairs(t) do
- clone[k] = v
- end
- return clone
+ local clone = {}
+ for k, v in pairs(t) do
+ clone[k] = v
+ end
+ return clone
end
local string_trim = function(s, what)
- what = what or " "
- return s:gsub("^[" .. what .. "]*(.-)[" .. what .. "]*$", "%1")
+ what = what or " "
+ return s:gsub("^[" .. what .. "]*(.-)[" .. what .. "]*$", "%1")
end
local push = function(stack, item)
- stack[#stack + 1] = item
+ stack[#stack + 1] = item
end
local pop = function(stack)
- local item = stack[#stack]
- stack[#stack] = nil
- return item
+ local item = stack[#stack]
+ stack[#stack] = nil
+ return item
end
local context = function(str)
- if type(str) ~= "string" then
- return ""
- end
+ if type(str) ~= "string" then
+ return ""
+ end
- str = str:sub(0, 25):gsub("\n", "\\n"):gsub('"', '\\"')
- return ', near "' .. str .. '"'
+ str = str:sub(0, 25):gsub("\n", "\\n"):gsub('"', '\\"')
+ return ', near "' .. str .. '"'
end
local Parser = {}
function Parser.new(self, tokens)
- self.tokens = tokens
- self.parse_stack = {}
- self.refs = {}
- self.current = 0
- return self
+ self.tokens = tokens
+ self.parse_stack = {}
+ self.refs = {}
+ self.current = 0
+ return self
end
local exports = { version = "1.2" }
local word = function(w)
- return "^(" .. w .. ")([%s$%c])"
+ return "^(" .. w .. ")([%s$%c])"
end
local tokens = {
- { "comment", "^#[^\n]*" },
- { "indent", "^\n( *)" },
- { "space", "^ +" },
- {
- "true",
- word("enabled"),
- const = true,
- value = true,
- },
- {
- "true",
- word("true"),
- const = true,
- value = true,
- },
- {
- "true",
- word("yes"),
- const = true,
- value = true,
- },
- {
- "true",
- word("on"),
- const = true,
- value = true,
- },
- {
- "false",
- word("disabled"),
- const = true,
- value = false,
- },
- {
- "false",
- word("false"),
- const = true,
- value = false,
- },
- {
- "false",
- word("no"),
- const = true,
- value = false,
- },
- {
- "false",
- word("off"),
- const = true,
- value = false,
- },
- {
- "null",
- word("null"),
- const = true,
- value = nil,
- },
- {
- "null",
- word("Null"),
- const = true,
- value = nil,
- },
- {
- "null",
- word("NULL"),
- const = true,
- value = nil,
- },
- {
- "null",
- word("~"),
- const = true,
- value = nil,
- },
- { "id", '^"([^"]-)" *(:[%s%c])' },
- { "id", "^'([^']-)' *(:[%s%c])" },
- { "string", '^"([^"]-)"', force_text = true },
- { "string", "^'([^']-)'", force_text = true },
- { "timestamp", "^(%d%d%d%d)-(%d%d?)-(%d%d?)%s+(%d%d?):(%d%d):(%d%d)%s+(%-?%d%d?):(%d%d)" },
- { "timestamp", "^(%d%d%d%d)-(%d%d?)-(%d%d?)%s+(%d%d?):(%d%d):(%d%d)%s+(%-?%d%d?)" },
- { "timestamp", "^(%d%d%d%d)-(%d%d?)-(%d%d?)%s+(%d%d?):(%d%d):(%d%d)" },
- { "timestamp", "^(%d%d%d%d)-(%d%d?)-(%d%d?)%s+(%d%d?):(%d%d)" },
- { "timestamp", "^(%d%d%d%d)-(%d%d?)-(%d%d?)%s+(%d%d?)" },
- { "timestamp", "^(%d%d%d%d)-(%d%d?)-(%d%d?)" },
- { "doc", "^%-%-%-[^%c]*" },
- { ",", "^," },
- { "string", "^%b{} *[^,%c]+", noinline = true },
- { "{", "^{" },
- { "}", "^}" },
- { "string", "^%b[] *[^,%c]+", noinline = true },
- { "[", "^%[" },
- { "]", "^%]" },
- { "-", "^%-", noinline = true },
- { ":", "^:" },
- { "pipe", "^(|)(%d*[+%-]?)", sep = "\n" },
- { "pipe", "^(>)(%d*[+%-]?)", sep = " " },
- { "id", "^([%w][%w %-_]*)(:[%s%c])" },
- { "string", "^[^%c]+", noinline = true },
- { "string", "^[^,%]}%c ]+" },
+ { "comment", "^#[^\n]*" },
+ { "indent", "^\n( *)" },
+ { "space", "^ +" },
+ {
+ "true",
+ word("enabled"),
+ const = true,
+ value = true,
+ },
+ {
+ "true",
+ word("true"),
+ const = true,
+ value = true,
+ },
+ {
+ "true",
+ word("yes"),
+ const = true,
+ value = true,
+ },
+ {
+ "true",
+ word("on"),
+ const = true,
+ value = true,
+ },
+ {
+ "false",
+ word("disabled"),
+ const = true,
+ value = false,
+ },
+ {
+ "false",
+ word("false"),
+ const = true,
+ value = false,
+ },
+ {
+ "false",
+ word("no"),
+ const = true,
+ value = false,
+ },
+ {
+ "false",
+ word("off"),
+ const = true,
+ value = false,
+ },
+ {
+ "null",
+ word("null"),
+ const = true,
+ value = nil,
+ },
+ {
+ "null",
+ word("Null"),
+ const = true,
+ value = nil,
+ },
+ {
+ "null",
+ word("NULL"),
+ const = true,
+ value = nil,
+ },
+ {
+ "null",
+ word("~"),
+ const = true,
+ value = nil,
+ },
+ { "id", '^"([^"]-)" *(:[%s%c])' },
+ { "id", "^'([^']-)' *(:[%s%c])" },
+ { "string", '^"([^"]-)"', force_text = true },
+ { "string", "^'([^']-)'", force_text = true },
+ { "timestamp", "^(%d%d%d%d)-(%d%d?)-(%d%d?)%s+(%d%d?):(%d%d):(%d%d)%s+(%-?%d%d?):(%d%d)" },
+ { "timestamp", "^(%d%d%d%d)-(%d%d?)-(%d%d?)%s+(%d%d?):(%d%d):(%d%d)%s+(%-?%d%d?)" },
+ { "timestamp", "^(%d%d%d%d)-(%d%d?)-(%d%d?)%s+(%d%d?):(%d%d):(%d%d)" },
+ { "timestamp", "^(%d%d%d%d)-(%d%d?)-(%d%d?)%s+(%d%d?):(%d%d)" },
+ { "timestamp", "^(%d%d%d%d)-(%d%d?)-(%d%d?)%s+(%d%d?)" },
+ { "timestamp", "^(%d%d%d%d)-(%d%d?)-(%d%d?)" },
+ { "doc", "^%-%-%-[^%c]*" },
+ { ",", "^," },
+ { "string", "^%b{} *[^,%c]+", noinline = true },
+ { "{", "^{" },
+ { "}", "^}" },
+ { "string", "^%b[] *[^,%c]+", noinline = true },
+ { "[", "^%[" },
+ { "]", "^%]" },
+ { "-", "^%-", noinline = true },
+ { ":", "^:" },
+ { "pipe", "^(|)(%d*[+%-]?)", sep = "\n" },
+ { "pipe", "^(>)(%d*[+%-]?)", sep = " " },
+ { "id", "^([%w][%w %-_]*)(:[%s%c])" },
+ { "string", "^[^%c]+", noinline = true },
+ { "string", "^[^,%]}%c ]+" },
}
exports.tokenize = function(str)
- local token
- local row = 0
- local ignore
- local indents = 0
- local lastIndents
- local stack = {}
- local indentAmount = 0
- local inline = false
- str = str:gsub("\r\n", "\010")
-
- while #str > 0 do
- for i in ipairs(tokens) do
- local captures = {}
- if not inline or tokens[i].noinline == nil then
- captures = { str:match(tokens[i][2]) }
- end
-
- if #captures > 0 then
- captures.input = str:sub(0, 25)
- token = table_clone(tokens[i])
- token[2] = captures
- local str2 = str:gsub(tokens[i][2], "", 1)
- token.raw = str:sub(1, #str - #str2)
- str = str2
-
- if token[1] == "{" or token[1] == "[" then
- inline = true
- elseif token.const then
- -- Since word pattern contains last char we're re-adding it
- str = token[2][2] .. str
- token.raw = token.raw:sub(1, #token.raw - #token[2][2])
- elseif token[1] == "id" then
- -- Since id pattern contains last semi-colon we're re-adding it
- str = token[2][2] .. str
- token.raw = token.raw:sub(1, #token.raw - #token[2][2])
- -- Trim
- token[2][1] = string_trim(token[2][1])
- elseif token[1] == "string" then
- -- Finding numbers
- local snip = token[2][1]
- if not token.force_text then
- if snip:match("^(-?%d+%.%d+)$") or snip:match("^(-?%d+)$") then
- token[1] = "number"
- end
- end
- elseif token[1] == "comment" then
- ignore = true
- elseif token[1] == "indent" then
- row = row + 1
- inline = false
- lastIndents = indents
- if indentAmount == 0 then
- indentAmount = #token[2][1]
- end
-
- if indentAmount ~= 0 then
- indents = (#token[2][1] / indentAmount)
- else
- indents = 0
- end
-
- if indents == lastIndents then
- ignore = true
- elseif indents > lastIndents + 2 then
- error(
- "SyntaxError: invalid indentation, got "
- .. tostring(indents)
- .. " instead of "
- .. tostring(lastIndents)
- .. context(token[2].input)
- )
- elseif indents > lastIndents + 1 then
- push(stack, token)
- elseif indents < lastIndents then
- local input = token[2].input
- token = { "dedent", { "", input = "" } }
- token.input = input
- while lastIndents > indents + 1 do
- lastIndents = lastIndents - 1
- push(stack, token)
- end
- end
- end -- if token[1] == XXX
- token.row = row
- break
- end -- if #captures > 0
- end
-
- if not ignore then
- if token then
- push(stack, token)
- token = nil
- else
- error("SyntaxError " .. context(str))
- end
- end
-
- ignore = false
- end
-
- return stack
+ local token
+ local row = 0
+ local ignore
+ local indents = 0
+ local lastIndents
+ local stack = {}
+ local indentAmount = 0
+ local inline = false
+ str = str:gsub("\r\n", "\010")
+
+ while #str > 0 do
+ for i in ipairs(tokens) do
+ local captures = {}
+ if not inline or tokens[i].noinline == nil then
+ captures = { str:match(tokens[i][2]) }
+ end
+
+ if #captures > 0 then
+ captures.input = str:sub(0, 25)
+ token = table_clone(tokens[i])
+ token[2] = captures
+ local str2 = str:gsub(tokens[i][2], "", 1)
+ token.raw = str:sub(1, #str - #str2)
+ str = str2
+
+ if token[1] == "{" or token[1] == "[" then
+ inline = true
+ elseif token.const then
+ -- Since word pattern contains last char we're re-adding it
+ str = token[2][2] .. str
+ token.raw = token.raw:sub(1, #token.raw - #token[2][2])
+ elseif token[1] == "id" then
+ -- Since id pattern contains last semi-colon we're re-adding it
+ str = token[2][2] .. str
+ token.raw = token.raw:sub(1, #token.raw - #token[2][2])
+ -- Trim
+ token[2][1] = string_trim(token[2][1])
+ elseif token[1] == "string" then
+ -- Finding numbers
+ local snip = token[2][1]
+ if not token.force_text then
+ if snip:match("^(-?%d+%.%d+)$") or snip:match("^(-?%d+)$") then
+ token[1] = "number"
+ end
+ end
+ elseif token[1] == "comment" then
+ ignore = true
+ elseif token[1] == "indent" then
+ row = row + 1
+ inline = false
+ lastIndents = indents
+ if indentAmount == 0 then
+ indentAmount = #token[2][1]
+ end
+
+ if indentAmount ~= 0 then
+ indents = (#token[2][1] / indentAmount)
+ else
+ indents = 0
+ end
+
+ if indents == lastIndents then
+ ignore = true
+ elseif indents > lastIndents + 2 then
+ error(
+ "SyntaxError: invalid indentation, got "
+ .. tostring(indents)
+ .. " instead of "
+ .. tostring(lastIndents)
+ .. context(token[2].input)
+ )
+ elseif indents > lastIndents + 1 then
+ push(stack, token)
+ elseif indents < lastIndents then
+ local input = token[2].input
+ token = { "dedent", { "", input = "" } }
+ token.input = input
+ while lastIndents > indents + 1 do
+ lastIndents = lastIndents - 1
+ push(stack, token)
+ end
+ end
+ end -- if token[1] == XXX
+ token.row = row
+ break
+ end -- if #captures > 0
+ end
+
+ if not ignore then
+ if token then
+ push(stack, token)
+ token = nil
+ else
+ error("SyntaxError " .. context(str))
+ end
+ end
+
+ ignore = false
+ end
+
+ return stack
end
Parser.peek = function(self, offset)
- offset = offset or 1
- return self.tokens[offset + self.current]
+ offset = offset or 1
+ return self.tokens[offset + self.current]
end
Parser.advance = function(self)
- self.current = self.current + 1
- return self.tokens[self.current]
+ self.current = self.current + 1
+ return self.tokens[self.current]
end
Parser.advanceValue = function(self)
- return self:advance()[2][1]
+ return self:advance()[2][1]
end
Parser.accept = function(self, type)
- if self:peekType(type) then
- return self:advance()
- end
+ if self:peekType(type) then
+ return self:advance()
+ end
end
Parser.expect = function(self, type, msg)
- return self:accept(type) or error(msg .. context(self:peek()[1].input))
+ return self:accept(type) or error(msg .. context(self:peek()[1].input))
end
Parser.expectDedent = function(self, msg)
- return self:accept("dedent") or (self:peek() == nil) or error(msg .. context(self:peek()[2].input))
+ return self:accept("dedent") or (self:peek() == nil) or error(msg .. context(self:peek()[2].input))
end
Parser.peekType = function(self, val, offset)
- return self:peek(offset) and self:peek(offset)[1] == val
+ return self:peek(offset) and self:peek(offset)[1] == val
end
Parser.ignore = function(self, items)
- local advanced
- repeat
- advanced = false
- for _, v in pairs(items) do
- if self:peekType(v) then
- self:advance()
- advanced = true
- end
- end
- until advanced == false
+ local advanced
+ repeat
+ advanced = false
+ for _, v in pairs(items) do
+ if self:peekType(v) then
+ self:advance()
+ advanced = true
+ end
+ end
+ until advanced == false
end
Parser.ignoreSpace = function(self)
- self:ignore({ "space" })
+ self:ignore({ "space" })
end
Parser.ignoreWhitespace = function(self)
- self:ignore({ "space", "indent", "dedent" })
+ self:ignore({ "space", "indent", "dedent" })
end
Parser.parse = function(self)
- local ref = nil
- if self:peekType("string") and not self:peek().force_text then
- local char = self:peek()[2][1]:sub(1, 1)
- if char == "&" then
- ref = self:peek()[2][1]:sub(2)
- self:advanceValue()
- self:ignoreSpace()
- elseif char == "*" then
- ref = self:peek()[2][1]:sub(2)
- return self.refs[ref]
- end
- end
-
- local result
- local c = {
- indent = self:accept("indent") and 1 or 0,
- token = self:peek(),
- }
- push(self.parse_stack, c)
-
- if c.token[1] == "doc" then
- result = self:parseDoc()
- elseif c.token[1] == "-" then
- result = self:parseList()
- elseif c.token[1] == "{" then
- result = self:parseInlineHash()
- elseif c.token[1] == "[" then
- result = self:parseInlineList()
- elseif c.token[1] == "id" then
- result = self:parseHash()
- elseif c.token[1] == "string" then
- result = self:parseString("\n")
- elseif c.token[1] == "timestamp" then
- result = self:parseTimestamp()
- elseif c.token[1] == "number" then
- result = tonumber(self:advanceValue())
- elseif c.token[1] == "pipe" then
- result = self:parsePipe()
- elseif c.token.const == true then
- self:advanceValue()
- result = c.token.value
- else
- error("ParseError: unexpected token '" .. c.token[1] .. "'" .. context(c.token.input))
- end
-
- pop(self.parse_stack)
- while c.indent > 0 do
- c.indent = c.indent - 1
- local term = "term " .. c.token[1] .. ": '" .. c.token[2][1] .. "'"
- self:expectDedent("last " .. term .. " is not properly dedented")
- end
-
- if ref then
- self.refs[ref] = result
- end
- return result
+ local ref = nil
+ if self:peekType("string") and not self:peek().force_text then
+ local char = self:peek()[2][1]:sub(1, 1)
+ if char == "&" then
+ ref = self:peek()[2][1]:sub(2)
+ self:advanceValue()
+ self:ignoreSpace()
+ elseif char == "*" then
+ ref = self:peek()[2][1]:sub(2)
+ return self.refs[ref]
+ end
+ end
+
+ local result
+ local c = {
+ indent = self:accept("indent") and 1 or 0,
+ token = self:peek(),
+ }
+ push(self.parse_stack, c)
+
+ if c.token[1] == "doc" then
+ result = self:parseDoc()
+ elseif c.token[1] == "-" then
+ result = self:parseList()
+ elseif c.token[1] == "{" then
+ result = self:parseInlineHash()
+ elseif c.token[1] == "[" then
+ result = self:parseInlineList()
+ elseif c.token[1] == "id" then
+ result = self:parseHash()
+ elseif c.token[1] == "string" then
+ result = self:parseString("\n")
+ elseif c.token[1] == "timestamp" then
+ result = self:parseTimestamp()
+ elseif c.token[1] == "number" then
+ result = tonumber(self:advanceValue())
+ elseif c.token[1] == "pipe" then
+ result = self:parsePipe()
+ elseif c.token.const == true then
+ self:advanceValue()
+ result = c.token.value
+ else
+ error("ParseError: unexpected token '" .. c.token[1] .. "'" .. context(c.token.input))
+ end
+
+ pop(self.parse_stack)
+ while c.indent > 0 do
+ c.indent = c.indent - 1
+ local term = "term " .. c.token[1] .. ": '" .. c.token[2][1] .. "'"
+ self:expectDedent("last " .. term .. " is not properly dedented")
+ end
+
+ if ref then
+ self.refs[ref] = result
+ end
+ return result
end
Parser.parseDoc = function(self)
- self:accept("doc")
- return self:parse()
+ self:accept("doc")
+ return self:parse()
end
Parser.inline = function(self)
- local current = self:peek(0)
- if not current then
- return {}, 0
- end
+ local current = self:peek(0)
+ if not current then
+ return {}, 0
+ end
- local inline = {}
- local i = 0
+ local inline = {}
+ local i = 0
- while self:peek(i) and not self:peekType("indent", i) and current.row == self:peek(i).row do
- inline[self:peek(i)[1]] = true
- i = i - 1
- end
- return inline, -i
+ while self:peek(i) and not self:peekType("indent", i) and current.row == self:peek(i).row do
+ inline[self:peek(i)[1]] = true
+ i = i - 1
+ end
+ return inline, -i
end
Parser.isInline = function(self)
- local _, i = self:inline()
- return i > 0
+ local _, i = self:inline()
+ return i > 0
end
Parser.parent = function(self, level)
- level = level or 1
- return self.parse_stack[#self.parse_stack - level]
+ level = level or 1
+ return self.parse_stack[#self.parse_stack - level]
end
Parser.parentType = function(self, type, level)
- return self:parent(level) and self:parent(level).token[1] == type
+ return self:parent(level) and self:parent(level).token[1] == type
end
Parser.parseString = function(self)
- if self:isInline() then
- local result = self:advanceValue()
+ if self:isInline() then
+ local result = self:advanceValue()
- --[[
+ --[[
- a: this looks
flowing: but is
no: string
--]]
- local types = self:inline()
- if types["id"] and types["-"] then
- if not self:peekType("indent") or not self:peekType("indent", 2) then
- return result
- end
- end
-
- --[[
+ local types = self:inline()
+ if types["id"] and types["-"] then
+ if not self:peekType("indent") or not self:peekType("indent", 2) then
+ return result
+ end
+ end
+
+ --[[
a: 1
b: this is
a flowing string
example
c: 3
--]]
- if self:peekType("indent") then
- self:expect("indent", "text block needs to start with indent")
- local addtl = self:accept("indent")
-
- result = result .. "\n" .. self:parseTextBlock("\n")
-
- self:expectDedent("text block ending dedent missing")
- if addtl then
- self:expectDedent("text block ending dedent missing")
- end
- end
- return result
- else
- --[[
+ if self:peekType("indent") then
+ self:expect("indent", "text block needs to start with indent")
+ local addtl = self:accept("indent")
+
+ result = result .. "\n" .. self:parseTextBlock("\n")
+
+ self:expectDedent("text block ending dedent missing")
+ if addtl then
+ self:expectDedent("text block ending dedent missing")
+ end
+ end
+ return result
+ else
+ --[[
a: 1
b:
this is also
@@ -521,149 +497,149 @@ Parser.parseString = function(self)
example
c: 3
--]]
- return self:parseTextBlock("\n")
- end
+ return self:parseTextBlock("\n")
+ end
end
Parser.parsePipe = function(self)
- local pipe = self:expect("pipe")
- self:expect("indent", "text block needs to start with indent")
- local result = self:parseTextBlock(pipe.sep)
- self:expectDedent("text block ending dedent missing")
- return result
+ local pipe = self:expect("pipe")
+ self:expect("indent", "text block needs to start with indent")
+ local result = self:parseTextBlock(pipe.sep)
+ self:expectDedent("text block ending dedent missing")
+ return result
end
Parser.parseTextBlock = function(self, sep)
- local token = self:advance()
- local result = string_trim(token.raw, "\n")
- local indents = 0
- while self:peek() ~= nil and (indents > 0 or not self:peekType("dedent")) do
- local newtoken = self:advance()
- while token.row < newtoken.row do
- result = result .. sep
- token.row = token.row + 1
- end
- if newtoken[1] == "indent" then
- indents = indents + 1
- elseif newtoken[1] == "dedent" then
- indents = indents - 1
- else
- result = result .. string_trim(newtoken.raw, "\n")
- end
- end
- return result
+ local token = self:advance()
+ local result = string_trim(token.raw, "\n")
+ local indents = 0
+ while self:peek() ~= nil and (indents > 0 or not self:peekType("dedent")) do
+ local newtoken = self:advance()
+ while token.row < newtoken.row do
+ result = result .. sep
+ token.row = token.row + 1
+ end
+ if newtoken[1] == "indent" then
+ indents = indents + 1
+ elseif newtoken[1] == "dedent" then
+ indents = indents - 1
+ else
+ result = result .. string_trim(newtoken.raw, "\n")
+ end
+ end
+ return result
end
Parser.parseHash = function(self, hash)
- hash = hash or {}
- local indents = 0
-
- if self:isInline() then
- local id = self:advanceValue()
- self:expect(":", "expected semi-colon after id")
- self:ignoreSpace()
- if self:accept("indent") then
- indents = indents + 1
- hash[id] = self:parse()
- else
- hash[id] = self:parse()
- if self:accept("indent") then
- indents = indents + 1
- end
- end
- self:ignoreSpace()
- end
-
- while self:peekType("id") do
- local id = self:advanceValue()
- self:expect(":", "expected semi-colon after id")
- self:ignoreSpace()
- hash[id] = self:parse()
- self:ignoreSpace()
- end
-
- while indents > 0 do
- self:expectDedent("expected dedent")
- indents = indents - 1
- end
-
- return hash
+ hash = hash or {}
+ local indents = 0
+
+ if self:isInline() then
+ local id = self:advanceValue()
+ self:expect(":", "expected semi-colon after id")
+ self:ignoreSpace()
+ if self:accept("indent") then
+ indents = indents + 1
+ hash[id] = self:parse()
+ else
+ hash[id] = self:parse()
+ if self:accept("indent") then
+ indents = indents + 1
+ end
+ end
+ self:ignoreSpace()
+ end
+
+ while self:peekType("id") do
+ local id = self:advanceValue()
+ self:expect(":", "expected semi-colon after id")
+ self:ignoreSpace()
+ hash[id] = self:parse()
+ self:ignoreSpace()
+ end
+
+ while indents > 0 do
+ self:expectDedent("expected dedent")
+ indents = indents - 1
+ end
+
+ return hash
end
Parser.parseInlineHash = function(self)
- local id
- local hash = {}
- local i = 0
-
- self:accept("{")
- while not self:accept("}") do
- self:ignoreSpace()
- if i > 0 then
- self:expect(",", "expected comma")
- end
-
- self:ignoreWhitespace()
- if self:peekType("id") then
- id = self:advanceValue()
- if id then
- self:expect(":", "expected semi-colon after id")
- self:ignoreSpace()
- hash[id] = self:parse()
- self:ignoreWhitespace()
- end
- end
-
- i = i + 1
- end
- return hash
+ local id
+ local hash = {}
+ local i = 0
+
+ self:accept("{")
+ while not self:accept("}") do
+ self:ignoreSpace()
+ if i > 0 then
+ self:expect(",", "expected comma")
+ end
+
+ self:ignoreWhitespace()
+ if self:peekType("id") then
+ id = self:advanceValue()
+ if id then
+ self:expect(":", "expected semi-colon after id")
+ self:ignoreSpace()
+ hash[id] = self:parse()
+ self:ignoreWhitespace()
+ end
+ end
+
+ i = i + 1
+ end
+ return hash
end
Parser.parseList = function(self)
- local list = {}
- while self:accept("-") do
- self:ignoreSpace()
- list[#list + 1] = self:parse()
+ local list = {}
+ while self:accept("-") do
+ self:ignoreSpace()
+ list[#list + 1] = self:parse()
- self:ignoreSpace()
- end
- return list
+ self:ignoreSpace()
+ end
+ return list
end
Parser.parseInlineList = function(self)
- local list = {}
- local i = 0
- self:accept("[")
- while not self:accept("]") do
- self:ignoreSpace()
- if i > 0 then
- self:expect(",", "expected comma")
- end
+ local list = {}
+ local i = 0
+ self:accept("[")
+ while not self:accept("]") do
+ self:ignoreSpace()
+ if i > 0 then
+ self:expect(",", "expected comma")
+ end
- self:ignoreSpace()
- list[#list + 1] = self:parse()
- self:ignoreSpace()
- i = i + 1
- end
+ self:ignoreSpace()
+ list[#list + 1] = self:parse()
+ self:ignoreSpace()
+ i = i + 1
+ end
- return list
+ return list
end
Parser.parseTimestamp = function(self)
- local capture = self:advance()[2]
+ local capture = self:advance()[2]
- return os.time({
- year = capture[1],
- month = capture[2],
- day = capture[3],
- hour = capture[4] or 0,
- min = capture[5] or 0,
- sec = capture[6] or 0,
- isdst = false,
- }) - os.time({ year = 1970, month = 1, day = 1, hour = 8 })
+ return os.time({
+ year = capture[1],
+ month = capture[2],
+ day = capture[3],
+ hour = capture[4] or 0,
+ min = capture[5] or 0,
+ sec = capture[6] or 0,
+ isdst = false,
+ }) - os.time({ year = 1970, month = 1, day = 1, hour = 8 })
end
exports.eval = function(str)
- return Parser:new(exports.tokenize(str)):parse()
+ return Parser:new(exports.tokenize(str)):parse()
end
exports.dump = table_print
diff --git a/lua/cmake/project.lua b/lua/cmake/project.lua
index f98b82a..ad713e3 100644
--- a/lua/cmake/project.lua
+++ b/lua/cmake/project.lua
@@ -1,9 +1,9 @@
local config = require("cmake.config")
local VariantConfig = require("cmake.variants")
local FileApi = require("cmake.fileapi")
-local lyaml = require("cmake.lyaml")
local utils = require("cmake.utils")
-local scan = require("plenary.scandir")
+local constants = require("cmake.constants")
+local uv = vim.uv or vim.loop
local Project = {}
@@ -52,7 +52,16 @@ end
-- TODO: validate yaml and fallback to config's variants if not valid
function Project.from_variants(variants)
- for var, is_default in VariantConfig.cartesian_product(variants) do
+ local list_variants = {}
+ for k, v in pairs(variants) do
+ table.insert(list_variants, v)
+ list_variants[#list_variants]._name = k
+ end
+ table.sort(list_variants, function(a, b)
+ vim.notify(a._name .. " " .. b._name)
+ return a._name < b._name
+ end)
+ for var, is_default in VariantConfig.cartesian_product(list_variants) do
var.current_build = 1
table.insert(configs, var)
current_config = not current_config and is_default and #configs or current_config
@@ -157,7 +166,7 @@ function Project.create_fileapi_query(opts, callback)
path = configs[opts.idx].directory
elseif type(opts.path) == "string" then
path = opts.path
- --TODO: compare getmetatable(opts.config) with VariantConfig (and PresetsConfig in future)
+ --TODO: compare getmetatable(opts.config) with VariantConfig (and PresetsConfig in future)
elseif type(opts.config) == "table" then
path = opts.config.directory
else
@@ -176,22 +185,17 @@ end
function Project.setup(opts)
opts = opts or {}
- scan.scan_dir_async(".", {
- depth = 0,
- hidden = true,
- silent = true,
- search_pattern = ".variants.yaml",
- on_exit = function(variants_results)
- if #variants_results ~= 0 then
- utils.read_file(variants_results[1], function(variants_data)
- local yaml = lyaml.eval(variants_data)
- Project.from_variants(yaml)
- end)
- else
- Project.from_variants(config.cmake.variants)
- end
- end,
- })
+ local variants_path = vim.fs.joinpath(uv.cwd(), constants.variants_yaml_filename)
+ utils.file_exists(variants_path, function(variants_exists)
+ if variants_exists then
+ utils.read_file(variants_path, function(variants_data)
+ local yaml = require("cmake.lyaml").eval(variants_data)
+ Project.from_variants(yaml)
+ end)
+ else
+ Project.from_variants(config.cmake.variants)
+ end
+ end)
end
return Project
diff --git a/lua/cmake/terminal.lua b/lua/cmake/terminal.lua
index 9ba8cb1..358d731 100644
--- a/lua/cmake/terminal.lua
+++ b/lua/cmake/terminal.lua
@@ -35,7 +35,6 @@ M.cmake_execute = function(command, opts)
)
end
elseif config.notification.after == "failure" or config.notification.after == true then
- vim.notify(vim.inspect("failure "))
local msg = "CMake failed. Code " .. tostring(code)
local opt_msg = vim.tbl_get(opts, "notify", "err_message")
if type(opt_msg) == "string" then
@@ -82,7 +81,6 @@ M.target_execute = function(command, opts)
if not runnable:is_open() then
runnable:open()
end
- vim.notify(vim.inspect(command), vim.log.levels.INFO)
if command.cmd then
runnable:send(command.cmd, not config.runner_terminal.focus)
end
diff --git a/lua/cmake/test.lua b/lua/cmake/test.lua
new file mode 100644
index 0000000..d5fbab9
--- /dev/null
+++ b/lua/cmake/test.lua
@@ -0,0 +1,11 @@
+local lyaml = require("cmake.lyaml")
+lyaml.dump({ { foo = "bar" } })
+--> ---
+--> foo: bar
+--> ...
+
+lyaml.dump({ "one", "two" })
+--> --- one
+--> ...
+--> --- two
+--> ...
diff --git a/lua/cmake/variants.lua b/lua/cmake/variants.lua
index 50254c8..289d0e4 100644
--- a/lua/cmake/variants.lua
+++ b/lua/cmake/variants.lua
@@ -97,9 +97,7 @@ function VariantConfig:new(source)
end
function VariantConfig.cartesian_product(sets)
- -- vim.notify("cartesian_product", vim.log.levels.INFO)
local function collapse_result(res)
- -- vim.notify("collapse_result", vim.log.levels.INFO)
local ret = {
short = {},
long = {},
@@ -130,7 +128,6 @@ function VariantConfig.cartesian_product(sets)
ret.env[ename] = eres
end
end
- -- vim.notify(vim.inspect(ret), vim.log.levels.INFO)
return VariantConfig:new(ret), is_default
end
local result = {}