[erlang-patches] [PATCH] Fix indentation of record fields in Emacs
Tomas Abrahamsson
tomas.abrahamsson@REDACTED
Tue Jun 12 16:18:53 CEST 2012
No problems, thanks for including the patch.
BRs
Tomas
On Tue, Jun 12, 2012 at 11:41 AM, Henrik Nord <henrik@REDACTED> wrote:
> Hi Tomas
>
> Yes this is probably my bad that it is not included.
>
> It has already been reviewed and approved and marked as answered so the only
> thing missing is the Email notification for you and the list, and the merger
> itself.
>
> I will run it through the tests real fast.
>
> Apologies for the wait, and thank you for the contribution!
>
> /Henrik
>
>
> On 06/11/2012 03:54 PM, Tomas Abrahamsson wrote:
>>
>> Hi,
>>
>> I never received any feedback on the patch to the emacs
>> record indentation, it was not included in pu and not the R15B01.
>> Was it good? Bad? Ugly? Or just forgotten?
>>
>> We've been using it extensively in a project with lots
>> of records, and folks seem happy with it. We haven't
>> seen any bad cases of indentation due to it.
>>
>> BRs
>> Tomas
>>
>> On Sat, Feb 11, 2012 at 9:55 PM, Tomas Abrahamsson
>> <tomas.abrahamsson@REDACTED> wrote:
>>>
>>> In some situations, the indentation of record fields in Emacs was
>>> strange. This example below shows how Emacs previously would indent
>>> two similar pieces of code very differently:
>>>
>>> some_function_with_a_very_long_name() ->
>>> #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
>>> field1=a,
>>> field2=b}.
>>>
>>> x() ->
>>> #some_record_name{
>>> field1=a,
>>> field2=b}.
>>>
>>> This changes the indentation to be like below for both cases:
>>>
>>> some_function() ->
>>> #some_record{
>>> field1=a,
>>> field2=b}.
>>> ---
>>> lib/tools/emacs/erlang.el | 58
>>> +++++++++++++++++++++++++++++-------
>>> lib/tools/emacs/test.erl.indented | 38 ++++++++++++++++++++++++
>>> lib/tools/emacs/test.erl.orig | 38 ++++++++++++++++++++++++
>>> 3 files changed, 122 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
>>> index bc7a190..2f6c7f5 100644
>>> --- a/lib/tools/emacs/erlang.el
>>> +++ b/lib/tools/emacs/erlang.el
>>> @@ -2986,18 +2986,52 @@ This assumes that the preceding expression is
>>> either simple
>>> (forward-sexp (- arg))
>>> (let ((col (current-column)))
>>> (skip-chars-backward " \t")
>>> - ;; Needed to match the colon in "'foo':'bar'".
>>> - (if (not (memq (preceding-char) '(?# ?:)))
>>> - col
>>> - ;; Special hack to handle: (note line break)
>>> - ;; [#myrecord{
>>> - ;; foo = foo}]
>>> - (or
>>> - (ignore-errors
>>> - (backward-char 1)
>>> - (forward-sexp -1)
>>> - (current-column))
>>> - col)))))
>>> + ;; Special hack to handle: (note line break)
>>> + ;; [#myrecord{
>>> + ;; foo = foo}]
>>> + ;; where the call (forward-sexp -1) will fail when point is at the
>>> `#'.
>>> + (or
>>> + (ignore-errors
>>> + ;; Needed to match the colon in "'foo':'bar'".
>>> + (cond ((eq (preceding-char) ?:)
>>> + (backward-char 1)
>>> + (forward-sexp -1)
>>> + (current-column))
>>> + ((eq (preceding-char) ?#)
>>> + ;; We may now be at:
>>> + ;; - either a construction of a new record
>>> + ;; - or update of a record, in which case we want
>>> + ;; the column of the expression to be updated.
>>> + ;;
>>> + ;; To see which of the two cases we are at, we first
>>> + ;; move an expression backwards, check for keywords,
>>> + ;; then immediately an expression forwards. Moving
>>> + ;; backwards skips past tokens like `,' or `->', but
>>> + ;; when moving forwards again, we won't skip past such
>>> + ;; tokens. We use this: if, after having moved
>>> + ;; forwards, we're back where we started, then it was
>>> + ;; a record update.
>>> + ;; The check for keywords is to detect cases like:
>>> + ;; case Something of #record_construction{...}
>>> + (backward-char 1)
>>> + (let ((record-start (point))
>>> + (record-start-col (current-column)))
>>> + (forward-sexp -1)
>>> + (let ((preceding-expr-col (current-column))
>>> + ;; white space definition according to erl_scan
>>> + (white-space "\000-\040\200-\240"))
>>> + (if (erlang-at-keyword)
>>> + ;; The (forward-sexp -1) call moved past a
>>> keyword
>>> + (1+ record-start-col)
>>> + (forward-sexp 1)
>>> + (skip-chars-forward white-space record-start)
>>> + ;; Are we back where we started? If so, it was an
>>> update.
>>> + (if (= (point) record-start)
>>> + preceding-expr-col
>>> + (goto-char record-start)
>>> + (1+ (current-column)))))))
>>> + (t col)))
>>> + col))))
>>>
>>> (defun erlang-indent-parenthesis (stack-position)
>>> (let ((previous (erlang-indent-find-preceding-expr)))
>>> diff --git a/lib/tools/emacs/test.erl.indented
>>> b/lib/tools/emacs/test.erl.indented
>>> index 2948ccf..e0593c6 100644
>>> --- a/lib/tools/emacs/test.erl.indented
>>> +++ b/lib/tools/emacs/test.erl.indented
>>> @@ -657,3 +657,41 @@ indent_comprehensions() ->
>>> foo() ->
>>> [#foo{
>>> foo = foo}].
>>> +
>>> +%% Record indentation
>>> +some_function_with_a_very_long_name() ->
>>> + #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
>>> + field1=a,
>>> + field2=b},
>>> + case dummy_function_with_a_very_very_long_name(x) of
>>> + #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
>>> + field1=a,
>>> + field2=b} ->
>>> + ok;
>>> + Var =
>>> #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
>>> + field1=a,
>>> + field2=b} ->
>>> +
>>> Var#'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
>>> + field1=a,
>>> + field2=b};
>>> + #xyz{
>>> + a=1,
>>> + b=2} ->
>>> + ok
>>> + end.
>>> +
>>> +another_function_with_a_very_very_long_name() ->
>>> + #rec{
>>> + field1=1,
>>> + field2=1}.
>>> +
>>> +some_function_name_xyz(xyzzy, #some_record{
>>> + field1=Field1,
>>> + field2=Field2}) ->
>>> + SomeVariable = f(#'Some-long-record-name'{
>>> + field_a = 1,
>>> + 'inter-xyz-parameters' =
>>> + #'Some-other-very-long-record-name'{
>>> + field2 = Field1,
>>> + field2 = Field2}}),
>>> + {ok, SomeVariable}.
>>> diff --git a/lib/tools/emacs/test.erl.orig
>>> b/lib/tools/emacs/test.erl.orig
>>> index 1221c56..69356ac 100644
>>> --- a/lib/tools/emacs/test.erl.orig
>>> +++ b/lib/tools/emacs/test.erl.orig
>>> @@ -657,3 +657,41 @@ ok.
>>> foo() ->
>>> [#foo{
>>> foo = foo}].
>>> +
>>> +%% Record indentation
>>> +some_function_with_a_very_long_name() ->
>>> + #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
>>> + field1=a,
>>> + field2=b},
>>> + case dummy_function_with_a_very_very_long_name(x) of
>>> + #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
>>> + field1=a,
>>> + field2=b} ->
>>> + ok;
>>> + Var = #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
>>> + field1=a,
>>> + field2=b} ->
>>> + Var#'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
>>> + field1=a,
>>> + field2=b};
>>> + #xyz{
>>> + a=1,
>>> + b=2} ->
>>> + ok
>>> + end.
>>> +
>>> +another_function_with_a_very_very_long_name() ->
>>> + #rec{
>>> + field1=1,
>>> + field2=1}.
>>> +
>>> +some_function_name_xyz(xyzzy, #some_record{
>>> + field1=Field1,
>>> + field2=Field2}) ->
>>> + SomeVariable = f(#'Some-long-record-name'{
>>> + field_a = 1,
>>> + 'inter-xyz-parameters' =
>>> + #'Some-other-very-long-record-name'{
>>> + field2 = Field1,
>>> + field2 = Field2}}),
>>> + {ok, SomeVariable}.
>>> --
>>> 1.7.5.4
>>>
>> _______________________________________________
>> erlang-patches mailing list
>> erlang-patches@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-patches
>
>
> --
> /Henrik Nord Erlang/OTP
>
More information about the erlang-patches
mailing list