ignatov / intellij-erlang

Erlang IDE
https://www.jetbrains.com/help/idea/2018.2/getting-started-with-erlang.html
Other
732 stars 121 forks source link

Formatting issue #419

Closed bryanhughes closed 10 years ago

bryanhughes commented 10 years ago

The following code results in a weird formatting issue. For blocks of code that has a string continuation on multiple lines, when you press Option+Command+I, it aligns the beginning of the quoted line at the end of the last quoted line.

    Code3 = "    performance_encode_test(10000, Record, {0, 0, 0, 0, 0}),\n"
            "    performance_decode_test(10000, " ++ Prefix ++ "_" ++ PName ++ ":encode(Record), {0, 0, 0, 0, 0}).\n\n"
            "performance_encode_test(0, _Record, {Cnt, TotalTime, TotalMemory, TotalHeap, TotalStack}) ->\n"
            "    io:format(\"Encode Performance Results for " ++ PName ++ "~n\"),\n"
            "    io:format(\"Total Pass:        ~p~n\", [Cnt]),\n"
            "    io:format(\"Total Time (ms):   ~p~n\", [TotalTime / 1000]),\n"
            "    io:format(\"Avg Time (ms):     ~p~n\", [(TotalTime / Cnt) / 1000]),\n"
            "    io:format(\"Avg Memory (KB):   ~p~n\", [((TotalMemory / Cnt) / 1024)]),\n"
            "    io:format(\"Avg Heap (bytes):  ~p~n\", [(TotalHeap / Cnt)]),\n"
            "    io:format(\"Avg Stack (bytes): ~p~n\", [(TotalStack / Cnt)]);\n"
            "performance_encode_test(Pass, Record, {Cnt, TotalTime, TotalMemory, TotalHeap, TotalStack}) ->\n"
            "    Start = os:timestamp(),\n"
                                                                                                                                                                     "    [{memory, M0}, {heap_size, H0}, {stack_size, S0}] = erlang:process_info(self(), [memory, heap_size, stack_size]),\n"
            "    " ++ Prefix ++ "_" ++ PName ++ ":encode(Record),\n"
            "    Delta = timer:now_diff(os:timestamp(), Start),\n"
            "    [{memory, Memory}, {heap_size, HeapSize}, {stack_size, StackSize}] = erlang:process_info(self(), [memory, heap_size, stack_size]),\n"
            "    performance_encode_test(Pass - 1, Record, {Cnt + 1, TotalTime + Delta, TotalMemory + Memory, TotalHeap + HeapSize, TotalStack + StackSize}).\n\n",
deadok22 commented 10 years ago

@ignatov I checked around what could a possible solution to this issue be and I've noticed you made list concatenation expression right associative in 557b2e70ef538a118dc382904d6b86e5d48195a6. What is the reason for that?

bryanhughes commented 10 years ago

Howdy!

Tested with build 538 and the fixed formatting alignment seems to work with on exception. If the string continuation contains a concatenation operator, moves the starting location of the double quote. The rule should probably have an exception for the ++ operator so that the starting quote position doesnt change to the quote location after the operator.

Formatted code with 538:

    Code3 = "    performance_encode_test(10000, Record, {0, 0, 0, 0, 0}),\n"
            "    performance_decode_test(10000, " ++ Prefix ++ "_" ++ PName ++ ":encode(Record), {0, 0, 0, 0, 0}).\n\n"
                                                                               "performance_encode_test(0, _Record, {Cnt, TotalTime, TotalMemory, TotalHeap, TotalStack}) ->\n"
                                                                               "    io:format(\"Encode Performance Results for " ++ PName ++ "~n\"),\n"
                                                                                                                                             "    io:format(\"Total Pass:        ~p~n\", [Cnt]),\n"
                                                                                                                                             "    io:format(\"Total Time (ms):   ~p~n\", [TotalTime / 1000]),\n"
                                                                                                                                             "    io:format(\"Avg Time (ms):     ~p~n\", [(TotalTime / Cnt) / 1000]),\n"
                                                                                                                                             "    io:format(\"Avg Memory (KB):   ~p~n\", [((TotalMemory / Cnt) / 1024)]),\n"
                                                                                                                                             "    io:format(\"Avg Heap (bytes):  ~p~n\", [(TotalHeap / Cnt)]),\n"
                                                                                                                                             "    io:format(\"Avg Stack (bytes): ~p~n\", [(TotalStack / Cnt)]);\n"
                                                                                                                                             "performance_encode_test(Pass, Record, {Cnt, TotalTime, TotalMemory, TotalHeap, TotalStack}) ->\n"
                                                                                                                                             "    erlang:garbage_collect(),\n"
                                                                                                                                             "    Start = os:timestamp(),\n"
                                                                                                                                             "    [{memory, M0}, {heap_size, H0}, {stack_size, S0}] = erlang:process_info(self(), [memory, heap_size, stack_size]),\n"
                                                                                                                                             "    " ++ Prefix ++ "_" ++ PName ++ ":encode(Record),\n"
    "    [{memory, M1}, {heap_size, H1}, {stack_size, S1}] = erlang:process_info(self(), [memory, heap_size, stack_size]),\n"
    "    Delta = timer:now_diff(os:timestamp(), Start),\n"
    "    performance_encode_test(Pass - 1, Record, {Cnt + 1, TotalTime + Delta, TotalMemory + (M1 - M0), TotalHeap + (H1 - H0), TotalStack + (S1 - S0)}).\n\n",
    ok = file:write(IoDevice, Code3),

Expected:

    Code3 = "    performance_encode_test(10000, Record, {0, 0, 0, 0, 0}),\n"
            "    performance_decode_test(10000, " ++ Prefix ++ "_" ++ PName ++ ":encode(Record), {0, 0, 0, 0, 0}).\n\n"
            "performance_encode_test(0, _Record, {Cnt, TotalTime, TotalMemory, TotalHeap, TotalStack}) ->\n"
            "    io:format(\"Encode Performance Results for " ++ PName ++ "~n\"),\n"
            "    io:format(\"Total Pass:        ~p~n\", [Cnt]),\n"
            "    io:format(\"Total Time (ms):   ~p~n\", [TotalTime / 1000]),\n"
            "    io:format(\"Avg Time (ms):     ~p~n\", [(TotalTime / Cnt) / 1000]),\n"
            "    io:format(\"Avg Memory (KB):   ~p~n\", [((TotalMemory / Cnt) / 1024)]),\n"
            "    io:format(\"Avg Heap (bytes):  ~p~n\", [(TotalHeap / Cnt)]),\n"
            "    io:format(\"Avg Stack (bytes): ~p~n\", [(TotalStack / Cnt)]);\n"
            "performance_encode_test(Pass, Record, {Cnt, TotalTime, TotalMemory, TotalHeap, TotalStack}) ->\n"
            "    erlang:garbage_collect(),\n"
            "    Start = os:timestamp(),\n"
            "    [{memory, M0}, {heap_size, H0}, {stack_size, S0}] = erlang:process_info(self(), [memory, heap_size, stack_size]),\n"
            "    " ++ Prefix ++ "_" ++ PName ++ ":encode(Record),\n"
            "    [{memory, M1}, {heap_size, H1}, {stack_size, S1}] = erlang:process_info(self(), [memory, heap_size, stack_size]),\n"
            "    Delta = timer:now_diff(os:timestamp(), Start),\n"
            "    performance_encode_test(Pass - 1, Record, {Cnt + 1, TotalTime + Delta, TotalMemory + (M1 - M0), TotalHeap + (H1 - H0), TotalStack + (S1 - S0)}).\n\n",
    ok = file:write(IoDevice, Code3),
deadok22 commented 10 years ago

Is it the only case where you'd like to have such formatting style? I mean, would you like to have all types of binary expression chains formatted like that? For example,

%% formatted with Emacs' formatter. 
C =
        b !
        b ! b !
        10 +
        189.

We can make something similar to this.

bryanhughes commented 10 years ago

That makes sense. Any line contuation would format that way. I am assuming it would be an optional setting?

deadok22 commented 10 years ago

Yes, because to do something like this means to change the whole structure of formatting blocks there - it can become a real mess =)

I'm going to put something out next week, stay tuned.

deadok22 commented 10 years ago

Allright, so I've added a formatting option named "Uniform binary expressions style" - @bryanhughes, please give it a try. A new build is available at https://github.com/ignatov/intellij-erlang/releases/tag/%23548

bryanhughes commented 10 years ago

Nice work. Formatting as expected now.