1using JuliaFormatter, CSTParser, Tokenize 2 3for name in names(JuliaFormatter, all=true) 4 if name != :include && name != :eval 5 @eval import JuliaFormatter: $name 6 end 7end 8 9# Same as DefaultStyle, but no space in between operators with precedence CSTParser.TimesOp 10struct CeedStyle <: AbstractStyle end 11 12getstyle(s::CeedStyle) = s 13 14function p_binaryopcall( 15 style::CeedStyle, 16 cst::CSTParser.EXPR, 17 s::State; 18 nonest=false, 19 nospace=false, 20) 21 t = FST(cst, nspaces(s)) 22 op = cst[2] 23 nonest = nonest || op.kind === Tokens.COLON 24 if cst.parent.typ === CSTParser.Curly && 25 op.kind in (Tokens.ISSUBTYPE, Tokens.ISSUPERTYPE) && 26 !s.opts.whitespace_typedefs 27 nospace = true 28 elseif op.kind === Tokens.COLON 29 nospace = true 30 end 31 nospace_args = s.opts.whitespace_ops_in_indices ? false : nospace 32 33 if is_opcall(cst[1]) 34 n = pretty(style, cst[1], s, nonest=nonest, nospace=nospace_args) 35 else 36 n = pretty(style, cst[1], s) 37 end 38 39 if op.kind === Tokens.COLON && 40 s.opts.whitespace_ops_in_indices && 41 !is_leaf(cst[1]) && 42 !is_iterable(cst[1]) 43 paren = FST(CSTParser.PUNCTUATION, -1, n.startline, n.startline, "(") 44 add_node!(t, paren, s) 45 add_node!(t, n, s, join_lines=true) 46 paren = FST(CSTParser.PUNCTUATION, -1, n.startline, n.startline, ")") 47 add_node!(t, paren, s, join_lines=true) 48 else 49 add_node!(t, n, s) 50 end 51 52 nrhs = nest_rhs(cst) 53 nrhs && (t.nest_behavior = AlwaysNest) 54 nest = (nestable(style, cst) && !nonest) || nrhs 55 56 if op.fullspan == 0 57 # Do nothing - represents a binary op with no textual representation. 58 # For example: `2a`, which is equivalent to `2 * a`. 59 elseif op.kind === Tokens.EX_OR 60 add_node!(t, Whitespace(1), s) 61 add_node!(t, pretty(style, op, s), s, join_lines=true) 62 elseif (is_number(cst[1]) || op.kind === Tokens.CIRCUMFLEX_ACCENT) && op.dot 63 add_node!(t, Whitespace(1), s) 64 add_node!(t, pretty(style, op, s), s, join_lines=true) 65 nest ? add_node!(t, Placeholder(1), s) : add_node!(t, Whitespace(1), s) 66 elseif op.kind !== Tokens.IN && ( 67 nospace || ( 68 op.kind !== Tokens.ANON_FUNC && CSTParser.precedence(op) in ( 69 CSTParser.ColonOp, 70 CSTParser.PowerOp, 71 CSTParser.DeclarationOp, 72 CSTParser.DotOp, 73 CSTParser.TimesOp, 74 ) 75 ) 76 ) 77 add_node!(t, pretty(style, op, s), s, join_lines=true) 78 else 79 add_node!(t, Whitespace(1), s) 80 add_node!(t, pretty(style, op, s), s, join_lines=true) 81 nest ? add_node!(t, Placeholder(1), s) : add_node!(t, Whitespace(1), s) 82 end 83 84 if is_opcall(cst[3]) 85 n = pretty(style, cst[3], s, nonest=nonest, nospace=nospace_args) 86 else 87 n = pretty(style, cst[3], s) 88 end 89 90 if op.kind === Tokens.COLON && 91 s.opts.whitespace_ops_in_indices && 92 !is_leaf(cst[3]) && 93 !is_iterable(cst[3]) 94 paren = FST(CSTParser.PUNCTUATION, -1, n.startline, n.startline, "(") 95 add_node!(t, paren, s, join_lines=true) 96 add_node!(t, n, s, join_lines=true) 97 paren = FST(CSTParser.PUNCTUATION, -1, n.startline, n.startline, ")") 98 add_node!(t, paren, s, join_lines=true) 99 else 100 add_node!(t, n, s, join_lines=true) 101 end 102 103 if nest 104 # for indent, will be converted to `indent` if needed 105 insert!(t.nodes, length(t.nodes), Placeholder(0)) 106 end 107 108 t 109end 110 111function p_chainopcall( 112 style::CeedStyle, 113 cst::CSTParser.EXPR, 114 s::State; 115 nonest=false, 116 nospace=false, 117) 118 t = FST(cst, nspaces(s)) 119 120 # Check if there's a number literal on the LHS of a dot operator. 121 # In this case we need to surround the dot operator with whitespace 122 # in order to avoid ambiguity. 123 for (i, a) in enumerate(cst) 124 if a.typ === CSTParser.OPERATOR && a.dot && is_number(cst[i-1]) 125 nospace = false 126 break 127 end 128 end 129 130 nws = nospace ? 0 : 1 131 for (i, a) in enumerate(cst) 132 if a.typ === CSTParser.OPERATOR 133 nws_op = (CSTParser.precedence(a) == CSTParser.TimesOp) ? 0 : nws 134 add_node!(t, Whitespace(nws_op), s) 135 add_node!(t, pretty(style, a, s), s, join_lines=true) 136 if nonest 137 add_node!(t, Whitespace(nws_op), s) 138 else 139 add_node!(t, Placeholder(nws_op), s) 140 end 141 elseif is_opcall(a) 142 add_node!( 143 t, 144 pretty(style, a, s, nospace=nospace, nonest=nonest), 145 s, 146 join_lines=true, 147 ) 148 elseif i == length(cst) - 1 && is_punc(a) && is_punc(cst[i+1]) 149 add_node!(t, pretty(style, a, s), s, join_lines=true) 150 else 151 add_node!(t, pretty(style, a, s), s, join_lines=true) 152 end 153 end 154 t 155end 156 157prefix_path(fname) = joinpath(@__DIR__, "..", fname) 158format( 159 prefix_path.(["src", "test", "examples", ".style"]), 160 style=CeedStyle(), 161 indent=4, 162 margin=92, 163 remove_extra_newlines=true, 164 whitespace_in_kwargs=false, 165) 166