Configuring :smart-indent-selection

81 views
Skip to first unread message

Atamert Ölçgen

unread,
Aug 3, 2015, 5:19:36 AM8/3/15
to light-table...@googlegroups.com
Hi,

:smart-indent-selection seems to understand some forms should be indented with 2 spaces:

(defn f []
  nil)

But all other forms are aligned with the 2nd element:

(fact "x"
      nil)

I couldn't find any resources so I've read the code and found that lt.objs.editor/indent-selection is just calling indentSelection method on codemirror editor.

How does the editor know which forms are special (indent with 2 spaces) and can I add more to the list? If that's possible can it discriminate between a some.ns/my-symbol and any other my-symbol?


--
Kind Regards,
Atamert Ölçgen

◻◼◻
◻◻◼
◼◼◼

www.muhuk.com

Benjamin Van Ryseghem

unread,
Aug 3, 2015, 7:48:25 AM8/3/15
to light-table...@googlegroups.com
I am also interested in that,
as it indent macros with two spaces (core macros)
but usually indent wrongly my own macros

Ben


--
You received this message because you are subscribed to the Google Groups "Light Table Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to light-table-discu...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Magnus Rundberget

unread,
Aug 4, 2015, 10:46:30 AM8/4/15
to Light Table Discussion
You could try to use the clj-light-refactor plugin which has a format command using cljfmt!

Alternatively submit a patch to the codemirror clojure module and then raise an issue on lt github to upgrade codemirror :)

Cheers
Magnus

Atamert Ölçgen

unread,
Jan 21, 2016, 5:19:21 AM1/21/16
to light-table...@googlegroups.com
I think got to the bottom of this. And I think `bottom` is a fitting word to describe the situation.

Here is one way to add more keywords to the indentKeys:

- Copy http://codemirror.net/mode/clojure/clojure.js into your User plugin directory.
- Open clojure.js and add your keywords to the list (making sure there is a space at the end of each string chunk)
- Change the mode name: `CodeMirror.defineMode("clojure", function...`, call it "clojure+" for instance.
- Change the two `CodeMirror.defineMIME` calls at the end of the file to connect clojure related MIMEs to your mode.
- Add `[:app :lt.objs.plugins/load-js ["path/to/clojure.js"]]` to your user.behaviors. (Path is relative to `User` directory.)
- Restart LT. (After the first restart, reloading seems to work)

This is quite an ugly solution I think. Better ways to fix it would be:

- Fix upstream. The only option CodeMirror mode accepts is `indentUnit`. But a lot more can be configured during init. `builtins`, `indentKeys` etc. But they seem to prefer hiding all that, possibly due to JavaScript's mutable nature. I would be happy to try refactoring, but it seems every other plugin is using this approach. Do you have any experience about how CM approaches contributions like this?
- I suppose there are advantages of re-using official mode in Clojure plugin. An obvious advantage is that we don't need to maintain it. Perhaps it is high performance js code. But I think it would be cooler to be able to configure things like which keywords to indent with 2 spaces from within LT. Would the Clojure plugin maintainers be willing to accept a mode written in cljs? I think we all know a thing or two about Clojure, should be enough to maintain a parser.

I just want my frigging `checking`'s to be indented like my `testing`'s.


On Sun, Aug 16, 2015 at 10:26 AM, Atamert Ölçgen <mu...@muhuk.com> wrote:
I've been digging into this and found Clojure's parser:


There's this bit of code:

    var indentKeys = makeKeywords(
        // Built-ins
        "ns fn def defn defmethod bound-fn if if-not case condp when while when-not when-first do future comment doto locking proxy with-open with-precision reify deftype defrecord defprotocol extend extend-protocol extend-type try catch " +

        // Binding forms
        "let letfn binding loop for doseq dotimes when-let if-let " +

        // Data structures
        "defstruct struct-map assoc " +

        // clojure.test
        "testing deftest " +

        // contrib
        "handler-case handle dotrace deftrace");

And it seems one can make a new mode containing more `indentKeys`. Things to figure out yet:

- How to replace default clojure mode with my custom mode in LightTable.
- How to get custom keywords to indent with 2 spaces from Leiningen.

One thing I don't like too much is, if I manage to do all this I'll have to be connected. I don't want custom indentation to be a user setting, it should be a project setting.

Gabriel Horner

unread,
Jan 22, 2016, 5:14:13 AM1/22/16
to light-table...@googlegroups.com
On Thu, Jan 21, 2016 at 5:18 AM, Atamert Ölçgen <mu...@muhuk.com> wrote:
I think got to the bottom of this. And I think `bottom` is a fitting word to describe the situation.

Here is one way to add more keywords to the indentKeys:

- Copy http://codemirror.net/mode/clojure/clojure.js into your User plugin directory.
- Open clojure.js and add your keywords to the list (making sure there is a space at the end of each string chunk)
- Change the mode name: `CodeMirror.defineMode("clojure", function...`, call it "clojure+" for instance.
- Change the two `CodeMirror.defineMIME` calls at the end of the file to connect clojure related MIMEs to your mode.
- Add `[:app :lt.objs.plugins/load-js ["path/to/clojure.js"]]` to your user.behaviors. (Path is relative to `User` directory.)
- Restart LT. (After the first restart, reloading seems to work)

If you want to modify a plugin there is a much easier way: git clone a forked version of a plugin and make your modifications. Instructions on this FAQ
 

This is quite an ugly solution I think. Better ways to fix it would be:

- Fix upstream. The only option CodeMirror mode accepts is `indentUnit`. But a lot more can be configured during init. `builtins`, `indentKeys` etc. But they seem to prefer hiding all that, possibly due to JavaScript's mutable nature. I would be happy to try refactoring, but it seems every other plugin is using this approach. Do you have any experience about how CM approaches contributions like this?

Having just got 3 pull requests merged, they are pretty reasonable. Making indentKeys configurable as an option is one approach. You'd have to decide if you want make that an append option or not. If it's not that's going to be a _long_ option in your behaviors file. You could also make block_indent an option. I'd recommend trying both, figure out which one you like and then open an issue (or friendly PR) explaining what you would like to do (or did) and why
 
- I suppose there are advantages of re-using official mode in Clojure plugin. An obvious advantage is that we don't need to maintain it. Perhaps it is high performance js code. But I think it would be cooler to be able to configure things like which keywords to indent with 2 spaces from within LT. Would the Clojure plugin maintainers be willing to accept a mode written in cljs? I think we all know a thing or two about Clojure, should be enough to maintain a parser.

We already have plenty of cool cljs to maintain :) Seriously though, it's easier to maintain and better for us if we re-use the official mode. I would rather focus our cljs efforts on fixing non-mode issues and adding enhancements. If you're just interested in helping, there are the Clojure issues or a few beginner issues

Cheers,
Gabriel

--

Atamert Ölçgen

unread,
Jan 22, 2016, 7:15:44 AM1/22/16
to light-table...@googlegroups.com
Hi Gabriel,

Thanks for the response.

On Fri, Jan 22, 2016 at 12:14 PM, Gabriel Horner <gabriel...@gmail.com> wrote:


On Thu, Jan 21, 2016 at 5:18 AM, Atamert Ölçgen <mu...@muhuk.com> wrote:
I think got to the bottom of this. And I think `bottom` is a fitting word to describe the situation.

Here is one way to add more keywords to the indentKeys:

- Copy http://codemirror.net/mode/clojure/clojure.js into your User plugin directory.
- Open clojure.js and add your keywords to the list (making sure there is a space at the end of each string chunk)
- Change the mode name: `CodeMirror.defineMode("clojure", function...`, call it "clojure+" for instance.
- Change the two `CodeMirror.defineMIME` calls at the end of the file to connect clojure related MIMEs to your mode.
- Add `[:app :lt.objs.plugins/load-js ["path/to/clojure.js"]]` to your user.behaviors. (Path is relative to `User` directory.)
- Restart LT. (After the first restart, reloading seems to work)

If you want to modify a plugin there is a much easier way: git clone a forked version of a plugin and make your modifications. Instructions on this FAQ
 

This is quite an ugly solution I think. Better ways to fix it would be:

- Fix upstream. The only option CodeMirror mode accepts is `indentUnit`. But a lot more can be configured during init. `builtins`, `indentKeys` etc. But they seem to prefer hiding all that, possibly due to JavaScript's mutable nature. I would be happy to try refactoring, but it seems every other plugin is using this approach. Do you have any experience about how CM approaches contributions like this?

Having just got 3 pull requests merged, they are pretty reasonable.

Good news. Thanks.
 
Making indentKeys configurable as an option is one approach. You'd have to decide if you want make that an append option or not. If it's not that's going to be a _long_ option in your behaviors file.

I would add an indentKeysExtra to be appended to the existing list. So, yes, you are right.
 
You could also make block_indent an option. I'd recommend trying both, figure out which one you like and then open an issue (or friendly PR) explaining what you would like to do (or did) and why

That's how with* forms work right! Cool.
 
 
- I suppose there are advantages of re-using official mode in Clojure plugin. An obvious advantage is that we don't need to maintain it. Perhaps it is high performance js code. But I think it would be cooler to be able to configure things like which keywords to indent with 2 spaces from within LT. Would the Clojure plugin maintainers be willing to accept a mode written in cljs? I think we all know a thing or two about Clojure, should be enough to maintain a parser.

We already have plenty of cool cljs to maintain :) Seriously though, it's easier to maintain and better for us if we re-use the official mode. I would rather focus our cljs efforts on fixing non-mode issues and adding enhancements. If you're just interested in helping, there are the Clojure issues or a few beginner issues


Fair point.

Now that I have given this more thought; I think none of the options we've discussed above is ideal. What I am looking for is a more context-aware formatter. Something that can standardize formatting (clojure-style-guide?). Perhaps I should give cljfmt another try.

Regarding contributions, as I tinker with LT, TUTF increases. Still not super psyched about the amount of JavaScript involved.

TUTF: time until table flip

Atamert Ölçgen

unread,
Jan 22, 2016, 7:23:20 AM1/22/16
to light-table...@googlegroups.com
If anyone else is interested, getting `defn` like formatting can be achieved like this:

;; This is how it formats by default:
(checking "will it format right"
          (is (= 3 4)))

;; Move the 1st parameter down, smart-indent:
(checking 
  "will it format right"
  (is (= 3 4)))

;; Move it back up:
(checking "will it format right"
  (is (= 3 4)))

;; Do this again and again and again


(I know 2nd param should be a number...)

Magnus Rundberget

unread,
Jan 26, 2016, 5:13:01 AM1/26/16
to Light Table Discussion
Not that it's any consolation in the short term....

But there is a cljs port of cljformat underway:
https://github.com/comamitc/cljsfmt

so once clojurescript is upped in LT (planned for 0.9), I think we should be able to provide very powerful customizable formatting. Maybe as a separate plugin.
Time will tell

cheers
Magnus
Hi Gabriel,

Thanks for the response.



 
Cheers,
Gabriel

--
To unsubscribe from this group and stop receiving emails from it, send an email to light-table-discussion+unsub...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Light Table Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to light-table-discussion+unsub...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Kind Regards,
Atamert Ölçgen

◻◼◻
◻◻◼
◼◼◼

www.muhuk.com

Atamert Ölçgen

unread,
Jan 26, 2016, 5:39:08 AM1/26/16
to light-table...@googlegroups.com
Thanks Magnus. That's good news. For now, I'm using cljfmt. It's a bit of more work, but it's ok.

Hi Gabriel,

Thanks for the response.



 
Cheers,
Gabriel

--
To unsubscribe from this group and stop receiving emails from it, send an email to light-table-discu...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Light Table Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to light-table-discu...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Kind Regards,
Atamert Ölçgen

◻◼◻
◻◻◼
◼◼◼

www.muhuk.com



--
Kind Regards,
Atamert Ölçgen

◻◼◻
◻◻◼
◼◼◼

www.muhuk.com

--
You received this message because you are subscribed to the Google Groups "Light Table Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to light-table-discu...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages