diff options
| author | Opportunity <[email protected]> | 2020-01-16 00:35:46 +0800 |
|---|---|---|
| committer | Opportunity <[email protected]> | 2020-01-16 00:35:46 +0800 |
| commit | d72f0495c5a8b860e7abed729f0d874542653066 (patch) | |
| tree | 634eab84b3f7188ee278d202fa09299cb97e3a8b | |
| parent | b18e975c2791c308499371173da11cbfa5297650 (diff) | |
show
| -rw-r--r-- | xmake/core/base/cli.lua | 72 | ||||
| -rw-r--r-- | xmake/core/base/colors.lua | 19 | ||||
| -rw-r--r-- | xmake/core/base/option.lua | 83 |
3 files changed, 117 insertions, 57 deletions
diff --git a/xmake/core/base/cli.lua b/xmake/core/base/cli.lua index 310335fd4..9ce43500b 100644 --- a/xmake/core/base/cli.lua +++ b/xmake/core/base/cli.lua @@ -117,6 +117,78 @@ function cli.parsev(argv, flags) return parsed end +-- @see https://unicode.org/reports/tr14/ +function cli._lastwbr(str, width, wordbreak) + + -- check + assert(#str >= width) + + if wordbreak == "breakall" then + -- To prevent overflow, word may be broken at any character + return width + else + + if str:sub(width + 1, width + 1):find("[%s]") then + -- exact break + return width + end + + local range = str:sub(1, width) + local poss = range:reverse():find("[%s-]") + if poss then + return #range - poss + 1 + end + + -- not found in range, try afterwards + poss = str:find("[%s-]", width + 1) + if poss then + return poss + end + + -- not found in all str + return #str + end +end + +-- break lines +function cli.wordwrap(str, width, opt) + + opt = opt or {} + + -- split to lines + if type(str) == 'table' then + str = table.concat(str, '\n') + end + local lines = tostring(str):split('\n', {plain = true, strict = true}) + + local result = {} + -- handle lines + for _, v in ipairs(lines) do + + -- remove tailing spaces, include '\r', which will be produced by `('l1\r\nl2'):split(...)` + v = v:rtrim() + while #v > width do + + -- find word break chance + local wbr = cli._lastwbr(v, width, opt.wordbreak) + + -- break line + local line = v:sub(1, wbr):rtrim() + table.insert(result, line) + v = v:sub(wbr + 1):ltrim() + + -- prevent empty line + if #v == 0 then v = nil end + end + + -- put remaining parts + table.insert(result, v) + end + + -- ok + return result +end + cli._segment = segment -- return module return cli diff --git a/xmake/core/base/colors.lua b/xmake/core/base/colors.lua index 3dff114b5..de66a9414 100644 --- a/xmake/core/base/colors.lua +++ b/xmake/core/base/colors.lua @@ -139,7 +139,7 @@ colors._keys24 = } -- the escape string -colors._escape = string.char(27) .. '[%sm' +colors._escape = '\x1b[%sm' -- get colorterm setting -- @@ -453,17 +453,20 @@ function colors.table(data, opt) assert(data) - local opt = opt or {} + -- init options + opt = opt or {} if opt.sep == nil then opt.sep = ' | ' end opt.patch_reset = true opt.ignore_unknown = true local sep = colors.translate(opt.sep, opt) + -- formartted cells local tab = {} local col_width = {} -- 'l' 'r' 'c' local col_align = {} + -- load column options if opt.colunms then for i = 1, table.maxn(opt.colunms or {}) do local v = opt.colunms[i] or {} @@ -472,6 +475,7 @@ function colors.table(data, opt) end end + -- format cells for i, row in ipairs(data) do tab[i] = {} for j, cell in ipairs(row) do @@ -483,25 +487,34 @@ function colors.table(data, opt) end end + -- render cells local empty_cell = { str = "", len = 0 } local rows = {} for i, row in ipairs(tab) do local cells = {} for j = 1, #col_width do + + -- use empty cell if not defined local cell = row[j] or empty_cell + if col_align[j] == 'r' then + -- right align cells[j] = string.rep(' ', col_width[j] - cell.len) .. cell.str elseif col_align[j] == 'c' then + -- centered local padding = col_width[j] - cell.len local lp = math.floor(padding / 2) local rp = math.ceil(padding / 2) cells[j] = string.rep(' ', lp) .. cell.str .. string.rep(' ', rp) else - cells[j] = cell.str .. string.rep(' ', col_width[j] - cell.len) + --left align, emit tailing spaces for last colunm + cells[j] = cell.str .. ((j == #col_width) and "" or string.rep(' ', col_width[j] - cell.len)) end end rows[i] = table.concat(cells, sep) end + + -- concat rendered rows rows[#rows + 1] = "" return table.concat(rows, '\n') end diff --git a/xmake/core/base/option.lua b/xmake/core/base/option.lua index a1f628cdb..a862a2d40 100644 --- a/xmake/core/base/option.lua +++ b/xmake/core/base/option.lua @@ -147,18 +147,10 @@ end -- the command line function option.cmdline() - -- make command - local line = "xmake" - local argv = xmake._ARGV - for _, arg in ipairs(argv) do - if arg:find("%s") then - arg = "\"" .. arg .. "\"" - end - line = line .. " " .. arg + if not xmake._ARGS then + xmake._ARGS = os.args(xmake._ARGV) end - - -- ok? - return line + return "xmake " .. xmake._ARGS end -- init the option @@ -693,79 +685,62 @@ function option.show_main() end -- the category task - local categorytask = categories[categoryname] or {} - categories[categoryname] = categorytask + local category = categories[categoryname] or { name = categoryname, tasks = {} } + categories[categoryname] = category -- add task to the category - categorytask[taskname] = taskinfo + category.tasks[taskname] = taskinfo end -- sort categories - local categories_sorted = {} - for categoryname, categorytask in pairs(categories) do - if categoryname == "action" then - table.insert(categories_sorted, 1, {categoryname, categorytask}) - else - table.insert(categories_sorted, {categoryname, categorytask}) + categories = table.values(categories) + table.sort(categories, function (a, b) + if a.name == 'action' then + return true end - end + return a.name < b.name + end) -- dump tasks by categories - for _, categoryinfo in ipairs(categories_sorted) do + local tablecontent = {} + for _, category in ipairs(categories) do -- the category name and task - local categoryname = categoryinfo[1] - local categorytask = categoryinfo[2] - assert(categoryname and categorytask) + assert(category.name and category.tasks) -- print category name - io.print("") - io.print(colors.translate(string.format("${bright}%s%ss: ", string.sub(categoryname, 1, 1):upper(), string.sub(categoryname, 2)))) + table.insert(tablecontent, {}) + table.insert(tablecontent, {string.format("${bright}%s%ss: ", string.sub(category.name, 1, 1):upper(), string.sub(category.name, 2))}) -- the padding spaces local padding = 42 - -- get width of console - local console_width = math.max(os.getwinsize().width, 80) + -- get width of right colunm + local right_width = math.max(os.getwinsize().width, 60) - 41 -- print tasks - for taskname, taskinfo in pairs(categorytask) do + for taskname, taskinfo in pairs(category.tasks) do -- init the task line - local taskline = " " - if taskinfo.shortname then - taskline = taskline .. taskinfo.shortname .. ", " - else - taskline = taskline .. " " - end + local taskline = string.format("${color.menu.main.task.name} %s%s", + taskinfo.shortname and (taskinfo.shortname .. ", ") or " ", + taskname) - -- append the task name - taskline = taskline .. taskname - - -- append spaces - for i = (#taskline), padding do - taskline = taskline .. " " - end - - -- append color - taskline = colors.translate("${color.menu.main.task.name}" .. taskline .. "${clear}") - - -- append the task description - if taskinfo.description then - taskline = option._inwidth_append(taskline, taskinfo.description, padding + 1 - 18, console_width, console_width - padding - 1 + 18) + local taskdesc = cli.wordwrap(taskinfo.description or "", right_width) + table.insert(tablecontent, {taskline, taskdesc[1]}) + for i = 2, #taskdesc do + table.insert(tablecontent, {"", taskdesc[i]}) end - - -- print task line - io.print(colors.translate(taskline)) end end + io.write(colors.table(tablecontent, {sep = " ", colunms = {{min_width=40}, {}}})) end -- print options if main.options then option.show_options(main.options, "build") end -end +end -- show the options menu function option.show_options(options, taskname) |
