better multi-line printing based on resulting length This patch adds new `line-length` option to fennelview options table. This option triggers multi-line output for tables, which single-line representation at given indentation level will result in a greater number, than one specified with the option. Tables are no longer printed multi-line only because they contain nested tables. It also inverts the behavior of `__fennelview` second return value, now it will be used to force multi-line output instead of forcing single-line, which plays much nicer with introduced `line-length` option. The check is now automated, so `__fennelview` can return just table of lines most of the time, and `fennelview` will produce multi-line output when needed.
3 files changed, 168 insertions(+), 139 deletions(-) M fennelview.fnl M fennelview.lua M test/core.fnl
M fennelview.fnl => fennelview.fnl +69 -62
@@ 90,24 90,22 @@ (fn concat-table-lines [elements options multiline? indent table-type prefix] (.. (or prefix "") (if (= :seq table-type) "[" "{") (table.concat elements (if (and (not options.one-line?) (or multiline? (> (length elements) (if (= table-type :seq) options.sequential-length options.associative-length)) (> indent 40))) (.. "\n" (string.rep " " indent)) " ")) (if (= :seq table-type) "]" "}"))) (let [indent-str (.. "\n" (string.rep " " indent)) open (.. (or prefix "") (if (= :seq table-type) "[" "{")) close (if (= :seq table-type) "]" "}") oneline (.. open (table.concat elements " ") close)] (if (and (not options.one-line?) (or multiline? (> (length elements) (if (= table-type :seq) options.sequential-length options.associative-length)) (> (+ indent (length oneline)) options.line-length))) (.. open (table.concat elements indent-str) close) oneline))) (fn pp-associative [t kv options indent key?] (var multiline? false) (let [elements [] id (. options.seen t)] (let [id (. options.seen t)] (if (>= options.level options.depth) "{...}" (and id options.detect-cycles?) (.. "@" id "{...}") @@ (let [visible-cycle? (visible-cycle? t options) 115,52 113,53 @@ indent (table-indent t indent id) slength (or (and options.utf8? (-?> (rawget _G :utf8) (. :len))) #(length $)) prefix (if visible-cycle? (.. "@" id) "")] (each [i [k v] (pairs kv)] (when (or (= (type k) :table) (= (type v) :table)) (set multiline? true)) (let [k (pp.pp k options (+ indent 1) true) v (pp.pp v options (+ indent (slength k) 1))] (table.insert elements (.. k " " v)))) prefix (if visible-cycle? (.. "@" id) "") elements (icollect [_ [k v] (pairs kv)] (let [k (pp.pp k options (+ indent 1) true) v (pp.pp v options (+ indent (slength k) 1))] (set multiline? (or multiline? (k:find "\n") (v:find "\n"))) (.. k " " v)))] (concat-table-lines elements options multiline? indent :table prefix))))) (fn pp-sequence [t kv options indent] (var multiline? false) (let [elements [] id (. options.seen t)] (let [id (. options.seen t)] (if (>= options.level options.depth) "[...]" (and id options.detect-cycles?) (.. "@" id "[...]") (let [visible-cycle? (visible-cycle? t options) id (and visible-cycle? (. options.seen t)) indent (table-indent t indent id) prefix (if visible-cycle? (.. "@" id) "")] (each [_ [_ v] (pairs kv)] (when (= (type v) :table) (set multiline? true)) (table.insert elements (pp.pp v options indent))) prefix (if visible-cycle? (.. "@" id) "") elements (icollect [_ [_ v] (pairs kv)] (let [v (pp.pp v options indent)] (set multiline? (or multiline? (v:find "\n"))) v))] (concat-table-lines elements options multiline? indent :seq prefix))))) (fn concat-lines [lines options indent one-line?] (fn concat-lines [lines options indent force-multi-line?] (if (= (length lines) 0) (if options.empty-as-sequence? "[]" "{}") (if (and (not options.one-line?) (not one-line?)) (table.concat lines (.. "\n" (string.rep " " indent))) (-> (icollect [_ line (ipairs lines)] (line:gsub "^%s+" " ")) table.concat)))) (let [oneline (-> (icollect [_ line (ipairs lines)] (line:gsub "^%s+" "")) (table.concat " "))] (if (and (not options.one-line?) (or force-multi-line? (oneline:find "\n") (> (+ indent (length oneline)) options.line-length))) (table.concat lines (.. "\n" (string.rep " " indent))) oneline)))) (fn pp-metamethod [t metamethod options indent] (if (>= options.level options.depth) (if options.empty-as-sequence? "[...]" "{...}") (let [_ (set options.visible-cycle? #(visible-cycle? $ options)) (lines force-one-line?) (metamethod t pp.pp options indent)] (lines force-multi-line?) (metamethod t pp.pp options indent)] (set options.visible-cycle? nil) (match (type lines) :string lines ;; assuming that it is already single line :table (concat-lines lines options indent force-one-line?) :string lines ;; TODO: assuming that result is already a single line. Maybe warn? :table (concat-lines lines options indent force-multi-line?) _ (error "Error: __fennelview metamethod must return a table of lines"))))) @@ (fn pp-table [x options indent] 196,6 195,7 @@ (let [;; defaults are used when options are not provided defaults {:sequential-length 10 :associative-length 4 :line-length 80 :one-line? false :depth 128 @@ :detect-cycles? true 241,15 241,17 @@ Can take an options table with these keys: * :metamethod? (boolean: default: true) use the __fennelview metamethod if found * :empty-as-sequence? (boolean, default: false) render empty tables as [] * :sequential-length (number, default: 10) amount of elements at which multi-line sequence ouptut is produced. multi-line sequence ouptut is produced * :associative-length (number, default: 4) amount of elements at which multi-line table ouptut is produced. multi-line table ouptut is produced * :line-length (number, default: 80) length of the line at which multi-line output for tables is forced * :utf8? (boolean, default true) whether to use utf8 module to compute string lengths The __fennelview metamethod should take the table being serialized as its first argument, a function as its second argument, options table as third argument, and current amount of indentation as its last argument: The `__fennelview` metamethod should take the table being serialized as its first argument, a function as its second argument, options table as third argument, and current amount of indentation as its last argument: (fn [t view inspector indent] ...) @@ 260,15 262,21 @@ amount of addition indentation you've introduced. `inspector` table contains options described above, and also `visible-cycle?` function, that takes a table being serialized, detects and saves information about possible reachable cycle. Should be used in __fennelview to implement about possible reachable cycle. Should be used in `__fennelview` to implement cycle detection. `__fennelview` metamethod should always return a table of correctly indented lines when producing multi-line output, or a string when returning single-line item. If single-line representation is needed in some cases, there's no need to concatenate table manually, instead `__fennelview` should return two values - a table of lines, and a boolean indicating if one-line representation should be forced. lines when producing multi-line output, or a string when always returning single-line item. `fennelview` will transform your data structure to correct multi-line representation when needed. There's no need to concatenate table manually ever - `fennelview` will apply general rules for your data structure, depending on current options. By default multiline output is produced only when inner data structures contains newlines, or when returning table of lines as single line results in width greater than `line-size` option. Multi-line representation can be forced by returning two values from `__fennelview` - a table of indented lines as first value, and `true` as second value, indicating that multi-line representation should be forced. There's no need to incorporate indentation beyond needed to correctly align @@ elements within the printed representation of your data structure. For example, 278,19 286,19 @@ if you want to print a multi-line table, like this: 2 3] __fennelview should return a sequence of lines: `__fennelview` should return a sequence of lines: [\"@my-table[1\" \" 2\" \" 3]\"] Note, since we've introduced inner indent string of length 10, when calling `view` function from within __fennelview metamethod, in order to keep inner `view` function from within `__fennelview` metamethod, in order to keep inner tables indented correctly, `indent` must be increased by this amount of extra indentation. `view` function also accepts additional boolean argument, which controls if strings should be printed as a colon-strings when possible. Set it to `true` strings should be printed as a colon-strings when possible. Set it to `true` when `view` is being called on the key of a table. @@ Here's an implementation of such pretty-printer for an arbitrary sequential 305,19 313,18 @@ table: (tset 1 (.. \"@my-table[\" (or (. lines 1) \"\"))) (tset (length lines) (.. (. lines (length lines)) \"]\"))))) Setting table's __fennelview metamethod to this function will provide correct Setting table's `__fennelview` metamethod to this function will provide correct results regardless of nesting: >> {:my-table (setmetatable [{:a {} :b [[1] [2]]} 3] >> {:my-table (setmetatable [[1 2 3 4 5] {:smalls [6 7 8 9 10 11 12] :bigs [500 1000 2000 3000 4000]}] {:__fennelview pp-doc-example}) :normal-table [{:c [1 2 3] :d :some-data} 4]} {:my-table @my-table[{:a {} :b [[1] [2]]} 3] :normal-table [{:c [1 2 3] :d \"some-data\"} 4]} {:my-table @my-table[[1 2 3 4 5] {:bigs [500 1000 2000 3000 4000] :smalls [6 7 8 9 10 11 12]}] :normal-table [{:c [1 2 3] :d \"some-data\"} 4]} Note that even though we've only indented inner elements of our table with 10 spaces, the result is correctly indented in terms of outer table, and inner
M fennelview.lua => fennelview.lua +66 -50
@@ 96,6 96,8 @@ local function table_indent(t, indent, id) end local pp = {} local function concat_table_lines(elements, options, multiline_3f, indent, table_type, prefix) local indent_str = ("\n" .. string.rep(" ", indent)) local open = nil local function _2_() if ("seq" == table_type) then @@ return "[" 103,31 105,28 @@ local function concat_table_lines(elements, options, multiline_3f, indent, table return "{" end end local function _3_() local _3_ if (table_type == "seq") then _3_ = options["sequential-length"] else _3_ = options["associative-length"] end if (not options["one-line?"] and (multiline_3f or (#elements > _3_) or (indent > 40))) then return ("\n" .. string.rep(" ", indent)) else return " " end open = ((prefix or "") .. _2_()) local close = nil if ("seq" == table_type) then close = "]" else close = "}" end local function _4_() if ("seq" == table_type) then return "]" else return "}" end local oneline = (open .. table.concat(elements, " ") .. close) local _4_ if (table_type == "seq") then _4_ = options["sequential-length"] else _4_ = options["associative-length"] end if (not options["one-line?"] and (multiline_3f or (#elements > _4_) or ((indent + #oneline) > options["line-length"]))) then return (open .. table.concat(elements, indent_str) .. close) else return oneline end return ((prefix or "") .. _2_() .. table.concat(elements, _3_()) .. _4_()) end local function pp_associative(t, kv, options, indent, key_3f) local multiline_3f = false local elements = {} local id = options.seen[t] if (options.level >= options.depth) then @@ return "{...}" 156,23 155,29 @@ local function pp_associative(t, kv, options, indent, key_3f) else prefix = "" end for i, _6_0 in pairs(kv) do local _7_ = _6_0 local k = _7_[1] local v = _7_[2] if ((type(k) == "table") or (type(v) == "table")) then multiline_3f = true local elements = nil do local tbl_0_ = {} for _, _6_0 in pairs(kv) do local _7_ = _6_0 local k = _7_[1] local v = _7_[2] local _8_ do local k0 = pp.pp(k, options, (indent0 + 1), true) local v0 = pp.pp(v, options, (indent0 + slength(k0) + 1)) multiline_3f = (multiline_3f or k0:find("\n") or v0:find("\n")) _8_ = (k0 .. " " .. v0) end tbl_0_[(#tbl_0_ + 1)] = _8_ end local k0 = pp.pp(k, options, (indent0 + 1), true) local v0 = pp.pp(v, options, (indent0 + slength(k0) + 1)) table.insert(elements, (k0 .. " " .. v0)) elements = tbl_0_ end return concat_table_lines(elements, options, multiline_3f, indent0, "table", prefix) end end local function pp_sequence(t, kv, options, indent) local multiline_3f = false local elements = {} local id = options.seen[t] if (options.level >= options.depth) then @@ return "[...]" 188,19 193,27 @@ local function pp_sequence(t, kv, options, indent) else prefix = "" end for _, _3_0 in pairs(kv) do local _4_ = _3_0 local _0 = _4_[1] local v = _4_[2] if (type(v) == "table") then multiline_3f = true local elements = nil do local tbl_0_ = {} for _, _3_0 in pairs(kv) do local _4_ = _3_0 local _0 = _4_[1] local v = _4_[2] local _5_ do local v0 = pp.pp(v, options, indent0) multiline_3f = (multiline_3f or v0:find("\n")) _5_ = v0 end tbl_0_[(#tbl_0_ + 1)] = _5_ end table.insert(elements, pp.pp(v, options, indent0)) elements = tbl_0_ end return concat_table_lines(elements, options, multiline_3f, indent0, "seq", prefix) end end local function concat_lines(lines, options, indent, one_line_3f) local function concat_lines(lines, options, indent, force_multi_line_3f) if (#lines == 0) then if options["empty-as-sequence?"] then @@ return "[]" 208,17 221,20 @@ local function concat_lines(lines, options, indent, one_line_3f) return "{}" end else if (not options["one-line?"] and not one_line_3f) then local oneline = nil local _2_ do local tbl_0_ = {} for _, line in ipairs(lines) do tbl_0_[(#tbl_0_ + 1)] = line:gsub("^%s+", "") end _2_ = tbl_0_ end oneline = table.concat(_2_, " ") if (not options["one-line?"] and (force_multi_line_3f or oneline:find("\n") or ((indent + #oneline) > options["line-length"]))) then return table.concat(lines, ("\n" .. string.rep(" ", indent))) else local function _2_() local tbl_0_ = {} for _, line in ipairs(lines) do tbl_0_[(#tbl_0_ + 1)] = line:gsub("^%s+", " ") end return tbl_0_ end return table.concat(_2_()) return oneline end end @@ end 236,13 252,13 @@ local function pp_metamethod(t, metamethod, options, indent) end options["visible-cycle?"] = _2_ _ = nil local lines, force_one_line_3f = metamethod(t, pp.pp, options, indent) local lines, force_multi_line_3f = metamethod(t, pp.pp, options, indent) options["visible-cycle?"] = nil local _3_0 = type(lines) if (_3_0 == "string") then return lines elseif (_3_0 == "table") then return concat_lines(lines, options, indent, force_one_line_3f) return concat_lines(lines, options, indent, force_multi_line_3f) else local _0 = _3_0 @@ return error("Error: __fennelview metamethod must return a table of lines") 321,7 337,7 @@ local function colon_string_3f(s) return s:find("^[-%w?\\^_!$%&*+./@:|<=>]+$") end local function make_options(t, options) local defaults = {["associative-length"] = 4, ["detect-cycles?"] = true, ["empty-as-sequence?"] = false, ["metamethod?"] = true, ["one-line?"] = false, ["sequential-length"] = 10, ["utf8?"] = true, depth = 128} local defaults = {["associative-length"] = 4, ["detect-cycles?"] = true, ["empty-as-sequence?"] = false, ["line-length"] = 80, ["metamethod?"] = true, ["one-line?"] = false, ["sequential-length"] = 10, ["utf8?"] = true, depth = 128} local overrides = {appearances = count_table_appearances(t, {}), level = 0, seen = {len = 0}} for k, v in pairs((options or {})) do defaults[k] = v
M test/core.fnl => test/core.fnl +33 -27
@@ 349,32 349,38 @@ "{:a 1 :b 5}" ;; nesting "((require :fennelview) (let [t {}] [t t]) {:detect-cycles? false})" "[{}\n {}]" "[{} {}]" "((require :fennelview) (let [t {}] [t t]))" "[{}\n {}]" "[{} {}]" "((require :fennelview) [{}])" "[{}]" "((require :fennelview) {[{}] []})" "{[{}] {}}" "((require :fennelview) {[[]] {[[]] [[[]]]}} {:empty-as-sequence? true})" "{[[]] {[[]] [[[]]]}}" "((require :fennelview) [1 2 [3 4]])" "((require :fennelview) [1 2 [3 4]] {:sequential-length 2})" "[1\n 2\n [3 4]]" "((require :fennelview) {[1] [2 [3]] :data {4 {:data 5} 6 [0 1 2 3]}} {:sequential-length 3})" "{:data [{:data 5}\n [0\n 1\n 2\n 3]]\n [1] [2\n [3]]}" "{:data [{:data 5}\n [0\n 1\n 2\n 3]]\n [1] [2 [3]]}" "((require :fennelview) {{:b 2} {:c 3 :d 4} {:a 1} {:b 2 :c 3}})" "{{:a 1} {:b 2 :c 3}\n {:b 2} {:c 3 :d 4}}" "{{:a 1} {:b 2 :c 3} {:b 2} {:c 3 :d 4}}" "((require :fennelview) [{:aaa [1 2 3]}] {:sequential-length 2})" "[{:aaa [1\n 2\n 3]}]" "((require :fennelview) {:a [1 2 3 4 5 6 7] :b [1 2 3 4 5 6 7] :c [1 2 3 4 5 6 7] :d [1 2 3 4 5 6 7]})" "{:a [1 2 3 4 5 6 7] :b [1 2 3 4 5 6 7] :c [1 2 3 4 5 6 7] :d [1 2 3 4 5 6 7]}" "((require :fennelview) {:a [1 2] :b [1 2] :c [1 2] :d [1 2]} {:line-length 3})" "{:a [1\n 2]\n :b [1\n 2]\n :c [1\n 2]\n :d [1\n 2]}" "((require :fennelview) {:a [1 2 3 4 5 6 7 8] :b [1 2 3 4 5 6 7 8] :c [1 2 3 4 5 6 7 8] :d [1 2 3 4 5 6 7 8]})" "{:a [1 2 3 4 5 6 7 8]\n :b [1 2 3 4 5 6 7 8]\n :c [1 2 3 4 5 6 7 8]\n :d [1 2 3 4 5 6 7 8]}" ;; Unicode "((require :fennelview) \"ваыв\")" "\"ваыв\"" "((require :fennelview) {[1] [2 [3]] :ваыв {4 {:ваыв 5} 6 [0 1 2 3]}} {:sequential-length 3})" (if _G.utf8 "{\"ваыв\" [{\"ваыв\" 5}\n [0\n 1\n 2\n 3]]\n [1] [2\n [3]]}" "{\"ваыв\" [{\"ваыв\" 5}\n [0\n 1\n 2\n 3]]\n [1] [2\n [3]]}") "{\"ваыв\" [{\"ваыв\" 5}\n [0\n 1\n 2\n 3]]\n [1] [2 [3]]}" "{\"ваыв\" [{\"ваыв\" 5}\n [0\n 1\n 2\n 3]]\n [1] [2 [3]]}") ;; the next one may look incorrect in some editors, but is actually correct "((require :fennelview) {:ǍǍǍ {} :ƁƁƁ {:ǍǍǍ {} :ƁƁƁ {}}})" "((require :fennelview) {:ǍǍǍ {} :ƁƁƁ {:ǍǍǍ {} :ƁƁƁ {}}} {:associative-length 1})" (if _G.utf8 ; older versions of Lua can't indent this correctly "{\"ƁƁƁ\" {\"ƁƁƁ\" {}\n \"ǍǍǍ\" {}}\n \"ǍǍǍ\" {}}" @@ "{\"ƁƁƁ\" {\"ƁƁƁ\" {}\n \"ǍǍǍ\" {}}\n \"ǍǍǍ\" {}}") 387,9 393,9 @@ "@1[@1[...]]" "(local t1 {}) (local t2 {:t1 t1}) (tset t1 :t2 t2) ((require :fennelview) t1)" "@1{:t2 {:t1 @1{...}}}" "(local t1 {:a 1 :c 2}) (local v1 [1 2 3]) (tset t1 :b v1) (table.insert v1 2 t1) ((require :fennelview) t1)" "(local t1 {:a 1 :c 2}) (local v1 [1 2 3]) (tset t1 :b v1) (table.insert v1 2 t1) ((require :fennelview) t1 {:sequential-length 1})" "@1{:a 1\n :b [1\n @1{...}\n 2\n 3]\n :c 2}" "(local v1 [1 2 3]) (local v2 [1 2 v1]) (local v3 [1 2 v2]) (table.insert v1 v2) (table.insert v1 v3) ((require :fennelview) v1)" "(local v1 [1 2 3]) (local v2 [1 2 v1]) (local v3 [1 2 v2]) (table.insert v1 v2) (table.insert v1 v3) ((require :fennelview) v1 {:sequential-length 1})" "@1[1\n 2\n 3\n @2[1\n 2\n @1[...]]\n [1\n 2\n @2[...]]]" "(local v1 []) (table.insert v1 v1) ((require :fennelview) v1 {:detect-cycles? false :one-line? true :depth 10})" @@ "[[[[[[[[[[...]]]]]]]]]]" 397,39 403,39 @@ "{{{{...} {...}} {{...} {...}}} {{{...} {...}} {{...} {...}}}}" ;; sorry :) "(local v1 []) (local v2 [v1]) (local v3 [v1 v2]) (local v4 [v2 v3]) (local v5 [v3 v4]) (local v6 [v4 v5]) (local v7 [v5 v6]) (local v8 [v6 v7]) (local v9 [v7 v8]) (local v10 [v8 v9]) (local v11 [v9 v10]) (table.insert v1 v2) (table.insert v1 v3) (table.insert v1 v4) (table.insert v1 v5) (table.insert v1 v6) (table.insert v1 v7) (table.insert v1 v8) (table.insert v1 v9) (table.insert v1 v10) (table.insert v1 v11) ((require :fennelview) v1)" "@1[@2[@1[...]]\n @3[@1[...]\n @2[...]]\n @4[@2[...]\n @3[...]]\n @5[@3[...]\n @4[...]]\n @6[@4[...]\n @5[...]]\n @7[@5[...]\n @6[...]]\n @8[@6[...]\n @7[...]]\n @9[@7[...]\n @8[...]]\n @10[@8[...]\n @9[...]]\n [@9[...]\n @10[...]]]" "@1[@2[@1[...]]\n @3[@1[...] @2[...]]\n @4[@2[...] @3[...]]\n @5[@3[...] @4[...]]\n @6[@4[...] @5[...]]\n @7[@5[...] @6[...]]\n @8[@6[...] @7[...]]\n @9[@7[...] @8[...]]\n @10[@8[...] @9[...]]\n [@9[...] @10[...]]]" "(local v1 []) (local v2 [v1]) (local v3 [v1 v2]) (local v4 [v2 v3]) (local v5 [v3 v4]) (local v6 [v4 v5]) (local v7 [v5 v6]) (local v8 [v6 v7]) (local v9 [v7 v8]) (local v10 [v8 v9]) (local v11 [v9 v10]) (table.insert v1 v2) (table.insert v1 v3) (table.insert v1 v4) (table.insert v1 v5) (table.insert v1 v6) (table.insert v1 v7) (table.insert v1 v8) (table.insert v1 v9) (table.insert v1 v10) (table.insert v1 v11) (table.insert v2 v11) ((require :fennelview) v1)" "@1[@2[@1[...]\n @3[@4[@5[@6[@7[@1[...]\n @2[...]]\n @8[@2[...]\n @7[...]]]\n @9[@8[...]\n @6[...]]]\n @10[@9[...]\n @5[...]]]\n @11[@10[...]\n @4[...]]]]\n @7[...]\n @8[...]\n @6[...]\n @9[...]\n @5[...]\n @10[...]\n @4[...]\n @11[...]\n @3[...]]" "@1[@2[@1[...]\n @3[@4[@5[@6[@7[@1[...] @2[...]] @8[@2[...] @7[...]]]\n @9[@8[...] @6[...]]]\n @10[@9[...] @5[...]]]\n @11[@10[...] @4[...]]]]\n @7[...]\n @8[...]\n @6[...]\n @9[...]\n @5[...]\n @10[...]\n @4[...]\n @11[...]\n @3[...]]" ;; __fennelview metamethod test "(fn pp-list [x pp opts indent] (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) l1)" "(fn pp-list [x pp opts indent] (values (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (values (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) true)) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) l1)" "(1\n 2\n 3)" "(fn pp-list [x pp opts indent] (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) [l1])" "(fn pp-list [x pp opts indent] (values (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (values (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) true)) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) [l1])" "[(1\n 2\n 3)]" "(fn pp-list [x pp opts indent] (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) [1 l1 2])" "(fn pp-list [x pp opts indent] (values (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (values (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) true)) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) [1 l1 2])" "[1\n (1\n 2\n 3)\n 2]" "(fn pp-list [x pp opts indent] (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) [[1 l1 2]])" "(fn pp-list [x pp opts indent] (values (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (values (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) true)) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) [[1 l1 2]])" "[[1\n (1\n 2\n 3)\n 2]]" "(fn pp-list [x pp opts indent] (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) {:abc [l1]})" "(fn pp-list [x pp opts indent] (values (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (values (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) true)) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) {:abc [l1]})" "{:abc [(1\n 2\n 3)]}" "(fn pp-list [x pp opts indent] (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) l1 {:one-line? true})" "(fn pp-list [x pp opts indent] (values (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (values (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) true)) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) l1 {:one-line? true})" "(1 2 3)" "(fn pp-list [x pp opts indent] (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) [l1] {:one-line? true})" "(fn pp-list [x pp opts indent] (values (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (values (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) true)) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) [l1] {:one-line? true})" "[(1 2 3)]" "(fn pp-list [x pp opts indent] (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) {:abc [l1]} {:one-line? true})" "(fn pp-list [x pp opts indent] (values (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (values (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) true)) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) ((require :fennelview) {:abc [l1]} {:one-line? true})" "{:abc [(1 2 3)]}" "(fn pp-list [x pp opts indent] (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) (local l2 (setmetatable [\"a\" \"a b\" [1 2 3] {:a l1 :b []}] {:__fennelview pp-list})) ((require :fennelview) l2)" "(fn pp-list [x pp opts indent] (values (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (values (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) true)) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) (local l2 (setmetatable [\"a\" \"a b\" [1 2 3] {:a l1 :b []}] {:__fennelview pp-list})) ((require :fennelview) l2)" "(:a\n \"a b\"\n [1 2 3]\n {:a (1\n 2\n 3)\n :b {}})" "(fn pp-list [x pp opts indent] (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) (local l2 (setmetatable [\"a\" \"a b\" [1 2 3] {:a l1 :b []}] {:__fennelview pp-list})) ((require :fennelview) {:list l2})" "(fn pp-list [x pp opts indent] (values (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (values (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) true)) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) (local l2 (setmetatable [\"a\" \"a b\" [1 2 3] {:a l1 :b []}] {:__fennelview pp-list})) ((require :fennelview) {:list l2})" "{:list (:a\n \"a b\"\n [1 2 3]\n {:a (1\n 2\n 3)\n :b {}})}" "(fn pp-list [x pp opts indent] (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) (local l2 (setmetatable [\"a\" \"a b\" [1 2 3] {:a l1 :b []}] {:__fennelview pp-list})) ((require :fennelview) [l2])" "(fn pp-list [x pp opts indent] (values (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (values (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) true)) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) (local l2 (setmetatable [\"a\" \"a b\" [1 2 3] {:a l1 :b []}] {:__fennelview pp-list})) ((require :fennelview) [l2])" "[(:a\n \"a b\"\n [1 2 3]\n {:a (1\n 2\n 3)\n :b {}})]" "(fn pp-list [x pp opts indent] (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) (local l2 (setmetatable [\"a\" \"a b\" [1 2 3] {:a l1 :b []}] {:__fennelview pp-list})) ((require :fennelview) {:abc [l1]})" "(fn pp-list [x pp opts indent] (values (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (values (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) true)) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) (local l2 (setmetatable [\"a\" \"a b\" [1 2 3] {:a l1 :b []}] {:__fennelview pp-list})) ((require :fennelview) {:abc [l1]})" "{:abc [(1\n 2\n 3)]}" "(fn pp-list [x pp opts indent] (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) (local l2 (setmetatable [\"a\" \"a b\" [1 2 3] {:a l1 :b []}] {:__fennelview pp-list})) ((require :fennelview) l1 {:one-line? true})" "(fn pp-list [x pp opts indent] (values (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (values (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) true)) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) (local l2 (setmetatable [\"a\" \"a b\" [1 2 3] {:a l1 :b []}] {:__fennelview pp-list})) ((require :fennelview) l1 {:one-line? true})" "(1 2 3)" "(fn pp-list [x pp opts indent] (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) (local l2 (setmetatable [\"a\" \"a b\" [1 2 3] {:a l1 :b []}] {:__fennelview pp-list})) ((require :fennelview) [l1] {:one-line? true})" "(fn pp-list [x pp opts indent] (values (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (values (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) true)) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) (local l2 (setmetatable [\"a\" \"a b\" [1 2 3] {:a l1 :b []}] {:__fennelview pp-list})) ((require :fennelview) [l1] {:one-line? true})" "[(1 2 3)]" "(fn pp-list [x pp opts indent] (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) (local l2 (setmetatable [\"a\" \"a b\" [1 2 3] {:a l1 :b []}] {:__fennelview pp-list})) ((require :fennelview) {:abc [l1]} {:one-line? true})" "(fn pp-list [x pp opts indent] (values (icollect [i v (ipairs x)] (let [v (pp v opts (+ 1 indent) true)] (values (if (= i 1) (.. \"(\" v) (= i (length x)) (.. \" \" v \")\") (.. \" \" v))))) true)) (local l1 (setmetatable [1 2 3] {:__fennelview pp-list})) (local l2 (setmetatable [\"a\" \"a b\" [1 2 3] {:a l1 :b []}] {:__fennelview pp-list})) ((require :fennelview) {:abc [l1]} {:one-line? true})" "{:abc [(1 2 3)]}" ;; ensure it works on lists/syms inside compiler "(eval-compiler