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

julia-mode.el: hitting return at top level is very slow #9254

Closed
JeffBezanson opened this issue Dec 5, 2014 · 4 comments · Fixed by #9308
Closed

julia-mode.el: hitting return at top level is very slow #9254

JeffBezanson opened this issue Dec 5, 2014 · 4 comments · Fixed by #9308
Labels
kind:regression Regression in behavior compared to a previous version performance Must go faster

Comments

@JeffBezanson
Copy link
Sponsor Member

There is a significant delay when hitting the return key with the cursor at the top level of a file (outside any function or block). The farther in to the file you are, the longer the delay. For example put the cursor at the very end of test/core.jl and hit return. For me there is a full 3 second delay, which is unbearable.

This seems to have been introduced fairly recently.

@JeffBezanson JeffBezanson added performance Must go faster kind:regression Regression in behavior compared to a previous version julia-mode labels Dec 5, 2014
@JeffBezanson
Copy link
Sponsor Member Author

cc @Wilfred

@Wilfred
Copy link
Contributor

Wilfred commented Dec 6, 2014

Ouch, sorry about this. This is the pathological case with our current indent logic.

As currently written, our indent logic is O(N) time where N is the line number that the cursor is on. When we indent, we search back through the buffer in order to find the last unclosed block.

# then we end up searching back to this line:
function foo()
    if bar()
        baz()
    end

    # if point is here and we press indent:
    |quux()

This generally gives correct results, but it scales awfully when point is outside a top-level expression.

I think the best solution would be to only consider the last non-empty line:

    foo()
    # indent bar to the same depth of foo, regardless of 
    # how appropriately foo is indented.
    |bar()

c-mode and ruby-mode seem to do this (js2-mode and python-mode do something smarter, I haven't investigated how). This would be much much faster.

It would break on the following case (I can't think of any other corner cases):

export
    Foo,
    Bar

# Indenting here would indent `import` by four spaces
|import Base:
    Baz

However, we don't currently indent this correctly, and I think peeking backwards by one more line would be sufficient to handle this.

I'll work on a patch.

@JeffBezanson
Copy link
Sponsor Member Author

I don't think c-mode does that. For example in julia.h there is an extern "C" { at the top, and because of it emacs wants to indent every line in the file, regardless of the line right above. Hitting tab instantly indents 4 spaces. It must be doing the search faster somehow.

Wilfred added a commit to Wilfred/julia that referenced this issue Dec 7, 2014
Wilfred added a commit to Wilfred/julia that referenced this issue Dec 8, 2014
Wilfred added a commit to Wilfred/julia that referenced this issue Dec 9, 2014
@Wilfred
Copy link
Contributor

Wilfred commented Dec 9, 2014

Aha, you're right. This was the test I did:

int foo() {
   x();
     indent_this_line();
}

Note that indent_this_line ends up with a three-space indent, so it's inspecting the line above. Nonetheless, it is indeed considering the full context, as you saw. Looking briefly at the code, it looks like Emacs has a something of a C parser (see c-indent-line and c-guess-basic-syntax).

I think considering the previous line is a reasonable approach, though I'm open to other suggestions. You can see the code on my branch -- I've also written a set of unit tests. Before sending a pull request, I also want to offer a Python/Haskell style indent toggle. This will give users flexibility and be considerably less annoying if the user hits a bug.

Wilfred added a commit to Wilfred/julia that referenced this issue Dec 10, 2014
Fixes JuliaLang#9254 -- performance is
just too bad on long files otherwise.
yuyichao pushed a commit to JuliaEditorSupport/julia-emacs that referenced this issue Mar 30, 2016
Fixes JuliaLang/julia#9254 -- performance is
just too bad on long files otherwise.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:regression Regression in behavior compared to a previous version performance Must go faster
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants