Skip to content
This repository has been archived by the owner on Oct 21, 2022. It is now read-only.

Smart-indent not outdenting correctly with Python #41

Open
kenny-evitt opened this issue Jan 6, 2016 · 9 comments
Open

Smart-indent not outdenting correctly with Python #41

kenny-evitt opened this issue Jan 6, 2016 · 9 comments

Comments

@kenny-evitt
Copy link

Copied from the original comment on LightTable/LightTable#1627:

I'm running into a roadblock using Light Table with python because the smart-indent feature isn't out-denting when it should after functions or classes.

Ex. before smart-indent:

class Dog:
    kind = 'canine'
    def __init__(self, name):
        self.name = name

class Cat:
    kind = 'feline'
    def __init__(self, name):
        self.name = name

After smart-indent:

class Dog:
  kind = 'canine'
  def __init__(self, name):
    self.name = name

    class Cat:
      kind = 'feline'
      def __init__(self, name):
        self.name = name

Not only did it reduce the tabs down to 2 spaces, it also didn't pickup on when to outdent causing the sibling classes to become nested.

This is a major blocker for polyglot Light Table users who use python.

LightTable 0.6.7

@kenny-evitt
Copy link
Author

I just confirmed that the CodeMirror Python demo (Light Table uses CodeMirror) also suffers from this problem.

@MortalCatalyst
Copy link

@kenny-evitt so does that mean that if the next release of LightTable has updated codemirror as was mentioned in the blog that it would still suffer this problem?

@kenny-evitt
Copy link
Author

@MortalCatalyst Yes. We should submit a fix for this, if it's possible, upstream to CodeMirror and then pull in the new version to LT. Would you mind checking for an existing issue for CodeMirror that covers this?

@MortalCatalyst
Copy link

@kenny-evitt is this a codemirror error or do we need to define the indentation, I found this answer on SO http://stackoverflow.com/a/15969118/461887

If you want your mode to provide smart indentation (through the indentLine method and the indentAuto and newlineAndIndent commands, to which keys can be bound), you must define an indent(state, textAfter) method on your mode object.
After applying a mode that defines indent(state, textAfter), and assuming smartIndent is set to true (which is the default value), auto indentation should be provided transparently, no extra effort on your side.

If a mode does not support smart indentation out of the box, you can always implement it yourself. See the section on writing CodeMirror modes in the docs.

@MortalCatalyst
Copy link

This is the mode in codemirror http://codemirror.net/mode/python/python.js are the extra codemirror settings defined in LT?

http://codemirror.net/doc/manual.html#indentLine

@kenny-evitt
Copy link
Author

@MortalCatalyst Interesting – thanks for looking into this. If extra settings are required by CodeMirror, e.g. for Python, I'm confused why their Python demo doesn't provide them.

More generally, is it even possible to indent Python code correctly for these scenarios? Is there some way to know, apart from existing indentation or other scoping info, that a subsequent class defined in a file is or is not nested inside the former class? Or, in other words, why is this failing at all?

@MortalCatalyst
Copy link

Well indentation works perfectly in LT when typing the code, except for if/else, a lot of editors get that wrong though. It's actually only when running the smart indent does the error occur, so the error likely occurs only in its version.

@MortalCatalyst
Copy link

As a test I loaded the latest pyhon.js from https://github.com/codemirror/CodeMirror/edit/master/mode/python/python.js into LT 0.8.0 . Still works fine on indent but smart indent a fail. It's like smart indent keeps resetting what it thinks column 0 is and adds 2 over and over again.

@MortalCatalyst
Copy link

@kenny-evitt I did post in the gitter tonight no one around currently. It seems that in pool.cljs the trigger to subtract indentation for line is not met in python and so the continual add.

This is the code I am referring to

(cmd/command {:command :indent-selection
              :desc "Editor: Indent line(s)"
              :exec (fn []
                      (when-let [cur (last-active)]
                        (let [line (-> cur (editor/->cursor "start") :line)]
                          (if (editor/selection? cur)
                            (editor/indent-selection cur "add")
                            (editor/indent-line cur line "add")))))})

(cmd/command {:command :unindent-selection
              :desc "Editor: Unindent line(s)"
              :exec (fn []
                      (when-let [cur (last-active)]
                        (let [line (-> cur (editor/->cursor "start") :line)]
                          (if (editor/selection? cur)
                            (editor/indent-selection cur "subtract")
                            (editor/indent-line cur line "subtract")))))})

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

No branches or pull requests

2 participants