From 616c9f7a6ba132a2adbfc8d8d5947de3a396b4f8 Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Thu, 5 Jan 2017 14:28:31 +0100 Subject: [PATCH] Improved alignment of functions. --- pretty.lua | 65 ++++++++++++++++++++++++++++---------------- test/test_pretty.lua | 29 ++++++++++++++++++++ 2 files changed, 71 insertions(+), 23 deletions(-) diff --git a/pretty.lua b/pretty.lua index e42d52a..b14c4f9 100644 --- a/pretty.lua +++ b/pretty.lua @@ -245,6 +245,30 @@ local function width_of_strings_in_l (l, start_i, end_i) return width end +local function ignore_alignment_info (l, start_i, stop_i) + for i = start_i or 1, stop_i or #l do + if type(l[i]) == 'table' then + l[i] = '' + end + end +end + +local function fix_alignment (l, start_i, stop_i) + -- Find maximums + local max = {} + for i = start_i or 1, stop_i or #l do + if type(l[i]) == 'table' then + max[ l[i][2] ] = math.max( l[i][1], max[ l[i][2] ] or 0 ) + end + end + + -- Insert the proper whitespace + for i = start_i, stop_i do + if type(l[i]) == 'table' then + l[i] = string.rep(' ', max[ l[i][2] ] - l[i][1]) + end + end +end -------------------------------------------------------------------------------- -- Identifyer stuff @@ -335,7 +359,7 @@ local format_table, format_value local function format_key_and_value_string_map (l, key, value, options, depth) l[#l+1] = key - l[#l+1] = #key + l[#l+1] = { #key, 'key' } l[#l+1] = ' = ' format_value(value, options, depth, l) end @@ -345,7 +369,7 @@ local function format_key_and_value_arbitr_map (l, key, value, options, depth) l[#l+1] = '[' format_value(key, options, 'max', l) l[#l+1] = ']' - l[#l+1] = width_of_strings_in_l(l, index_before_key) + l[#l+1] = { width_of_strings_in_l(l, index_before_key), 'key' } l[#l+1] = ' = ' format_value(value, options, depth, l) end @@ -379,11 +403,7 @@ local function format_single_line_map (t, options, l) end -- Ignore the "width of key"-shit - for i = top_before, #l do - if type(l[i]) == 'number' then - l[i] = '' - end - end + ignore_alignment_info(l, top_before, #l) if l[#l] == ', ' then l[#l] = nil end l[#l+1] = ' }' @@ -396,7 +416,6 @@ local function format_map (t, options, depth, l) local table_type = get_table_type(t) local pair_format_func = TABLE_TYPE_TO_PAIR_FORMAT[table_type] - -- Figure out the max key length l[#l+1] = '{\n' local top_before = #l for _, pair in pairs(key_value_pairs) do @@ -404,20 +423,11 @@ local function format_map (t, options, depth, l) pair_format_func(l, pair[1], pair[2], options, depth + 1) l[#l+1] = ',\n' end - -- Figure out max key len - local max_key_len = 0 - for i = top_before, #l do - if type(l[i]) == 'number' and l[i] > max_key_len then - max_key_len = l[i] - end - end - -- Replace in the proper whitespace - for i = top_before, #l do - if type(l[i]) == 'number' then - l[i] = string.rep(' ', max_key_len - l[i]) - end - end + -- Fix whitespace alignment + fix_alignment(l, top_before, #l) + + -- Fix and cleanup if l[#l] == ',\n' then l[#l] = nil end l[#l+1] = '\n' l[#l+1] = options.indent:rep(depth) @@ -515,12 +525,17 @@ local function format_function (value, options, depth, l) return format_string_defined_function(value, options, depth, l) end - -- Build function signature - if info.builtin then l[#l+1] = 'builtin ' end + -- Include function modifier, and alignment info. + l[#l+1] = info.builtin and 'builtin ' or '' + l[#l+1] = { #l[#l], 'func_mod'} + + -- Build rest of function signature l[#l+1] = 'function (' + local top_before = #l for _, param in ipairs(info.params) do l[#l+1], l[#l+2] = param, ', ' end if l[#l] == ', ' then l[#l] = nil end l[#l+1] = ')' + l[#l+1] = { width_of_strings_in_l(l, top_before), 'func_def' } -- Cleanup and finish if not options.more_function_info or depth ~= 0 then @@ -627,6 +642,10 @@ local function pretty_format (value, options) options.max_depth = options.max_depth or math.huge options.indent = options.indent or '\t' format_value(value, options, 0, l) + + -- If any alignment info still exists, ignore it + ignore_alignment_info(l) + return table.concat(l, '') end diff --git a/test/test_pretty.lua b/test/test_pretty.lua index 8a87b38..7d37ff7 100644 --- a/test/test_pretty.lua +++ b/test/test_pretty.lua @@ -338,6 +338,28 @@ format_test { expect = 'builtin function (s [, i [, j]])\n\t-- string.byte\n\t-- Returns the internal numerical codes of the characters s[i], s[i+1], ..., s[j]. The default value for i is 1; the default value for j is i.\n\t-- Note that numerical codes are not necessarily portable across platforms.\n\n\t...\nend', } +-- Indent functions nicely + +format_test { + -- The tail part should align, letting people focus on the important aspects. + input = { random = math.random, abs = math.abs }, + expect = '{\n\tabs = builtin function (x) ... end,\n\trandom = builtin function ([m [, n]) ... end\n}', +} + +format_test { + -- The function part should align, if some are builtin and some are not. + input = { random = math.random, abs = function (x) return x < 0 and -x or x end }, + expect = '{\n\tabs = function (x) ... end,\n\trandom = builtin function ([m [, n]) ... end\n}', +} + +format_test { + -- No special indent if no special function modifier. + input = { max = function(a, b) return a > b and a or b end, + abs = function (x) return x < 0 and -x or x end + }, + expect = '{\n\tabs = function (x) ... end,\n\tmax = function (a, b) ... end\n}', +} + -------------------------------------------------------------------------------- -- Userdata printing @@ -503,10 +525,17 @@ format_test { } format_test { + -- Proper indent input = { [1] = 1, ['whatever'] = false }, expect = '{\n\t[1] = 1,\n\t[\'whatever\'] = false\n}', } +format_test { + -- Table view, with indent. + input = { { a = 'hello', b = 'hi' }, { a = 'hi', b = 'hello' } }, + expect = '{\n\t{ a = \'hello\', b = \'hi\' },\n\t{ a = \'hi\', b = \'hello\' }\n}', +} + -------------------------------------------------------------------------------- -- CDATA