Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Indent dict keys wrongly if the keys are strings #32

Closed
larme opened this issue Jun 2, 2015 · 8 comments
Closed

Indent dict keys wrongly if the keys are strings #32

larme opened this issue Jun 2, 2015 · 8 comments
Labels

Comments

@larme
Copy link

larme commented Jun 2, 2015

I'm not sure if it's just my setup or a universal problem. But my emacs always indent a dict with the second string keys aligned to the first value part. For example:

(def a {"key1" value1
               "key2" value2
               "key3" value3})

From the example above you can see that the third (and later) keys are not affected.

@clemux
Copy link

clemux commented Jan 12, 2016

I have the same problem here. Latest master, no changes to the .el file.

@gilch gilch added the bug label Jul 27, 2017
@gilch
Copy link
Member

gilch commented Jul 27, 2017

This one is a real pain. I have to switch to clojure-mode whenever there's a file containing such a form. I'd call fixing this one a top priority.

@ekaschalk
Copy link
Collaborator

I've found where the bug occurs: parse-partial-sexp.

In particular lines 789-790 in calculate-lisp-indent in lisp-mode.el.

      (while (< (point) indent-point)
        (setq state (parse-partial-sexp (point) indent-point 0)))

Unfortunately this is a C function in src/syntax.c so a non-hackish solution is beyond me.

@gilch
Copy link
Member

gilch commented Jul 31, 2017

I wonder how clojure-mode does it. Maybe we can detect a { or [ and define an indent of 1 in hy-indent-function, the same way we have custom indents for special forms.

@ekaschalk
Copy link
Collaborator

ekaschalk commented Jul 31, 2017

I've got a solution.

Update calculate-lisp-indent at line 789 to now be:

      (while (< (point) indent-point)
        (setq state (parse-partial-sexp (point) indent-point 0))
        (save-excursion
          (goto-char (elt state 1))
          (if (looking-at "\{\"")
              (setcar (nthcdr 2 state) (+ 1 (elt state 1)))))
        )

Indenting is working at various sexp depths.

Now editing lisp-mode's source is clearly not the best approach. I'll see if I can due some advice-add magic to setup a PR for hy-mode.el.

@ekaschalk
Copy link
Collaborator

In the meantime you can find the fix at: https://github.com/ekaschalk/.spacemacs.d/blob/master/layers/langs/local/hy-indent-fix/hy-indent-fix.el

Just load the file in your emacs config.

@ekaschalk
Copy link
Collaborator

https://emacs.stackexchange.com/questions/10230/how-to-indent-keywords-aligned

This is apparantly a known problem, the stackexchange links a robust solution for aligning with colons.

We can see that common lisp's mode defines their own version of calculate-lisp-indent with, among other things, modifications in that same loop I linked earlier including:

              (when (and (null tem)
                         (string-match ":[^:]+" function))

Where it explicitly deals with the colon keyword indentation.

So the solution is to write a modified calculate-lisp-indent mirroring common-lisp-indent-function-1 as a new hy-indent-function.

ekaschalk added a commit that referenced this issue Sep 3, 2017
@ekaschalk
Copy link
Collaborator

Finally fixed, for lists as well. As compared to previous fix, doesn't fail on newlines, nor cause issues with the #@ with-decorator tag macro.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants