typescript.el icon indicating copy to clipboard operation
typescript.el copied to clipboard

function return type breaks `beginning-of-defun` and `end-of-defun`

Open oneeman opened this issue 8 years ago • 9 comments

Hi.

I've noticed problems using functionality that depends on beginning-of-defun. So I had a closer look and it looks like function return types are throwing it off.

With this code:

const x = 10;

function foo() {
  return "nothing";
}

doing beginning-of-defun from inside the function takes me to the function declaration.

On the other hand, with this code:

const x = 10;

function foo(): string {
  return "nothing";
}

it takes me to the top of the file (the const declaration).

The same problem happens with end-of-defun (if the function has a return type, it takes me to the end of the file). I wouldn't be surprised if the same problem underlies both of them failing.

Thanks, and my apologies if I've misunderstood the expected behavior or if this is a problem in another package (not too familiar with which functions belong where).

oneeman avatar Nov 09 '17 15:11 oneeman

Yeah, I noticed that they are broken a while back. I thought I might need to fix them in order to fix an indentation issue but it turned out that I did not need them. I've not spent time fixing them because their brokenness does not have an actual impact on my work.

Using git blame it looks like nobody spent any time on them. They are probably exactly like their counterpart in js-mode and so have no TypeScript-specific knowledge.

I suspect they are going to get fixed when they become a real obstacle to someone's work. When that happens, whoever fixes them may want to think about biting the bullet to get the mode to use an AST. The fact of the matter is that TS allows for really complex code structures that would probably throw off the kind of logic that just looks around (point) to figure what is going on. I mean, stuff like this is legit, except for the return undefined (I did not feel like writing a proper return value):

class Q<X> {
}

function glerb(a: any = new class extends Object {
    private x = 1;

    moo(): void {
    }
}): Q<{
    a: 1,   
    b: () => void,  
}> {
    return undefined;
}

And I'm just scratching the surface of what TS allows.

lddubeau avatar Nov 09 '17 16:11 lddubeau

Makes sense. Thanks for the details.

oneeman avatar Nov 09 '17 16:11 oneeman

I encountered same issue. Is there anybody who is working on fixing this issue?

kishiguro avatar Jun 15 '20 04:06 kishiguro

I have similar problems, using the beginning-of-defun and end-of-defun implicitly with narrow-to-defun. Another place where beginning/end of defun completely fails is lambda functions () => "I'm a a result" or named lambda functions const getTheAnswer = () => 42. I don't know enough emacs lisp to be of any help, though...

hermann-p avatar Mar 12 '21 14:03 hermann-p

In csharp-mode we are experimenting on a complete rewrite based on tree-sitter-mode, which gives us a real AST to work with.

The results there have been very promising.

If we were to fix all those small issues we have here, without creating some insane complexity in the lisp-code, I believe we may have to consider doing the same.

josteink avatar Mar 16 '21 08:03 josteink

@josteink from what I understand tree-sitter only supports highlighting? does it support other functions like mark-sexp, end-of-defun etc? which is more related to movement. I actually want to use tree-sitter for movement functionality, but can't find any reference or how to use it.

ananthakumaran avatar Mar 16 '21 12:03 ananthakumaran

@josteink from what I understand tree-sitter only supports highlighting? does it support other functions like mark-sexp, end-of-defun etc? which is more related to movement. I actually want to use tree-sitter for movement functionality, but can't find any reference or how to use it.

Tree-sitter supports navigation based on AST knowledge.

Based on this it is fairly trivial to create move-to-beginning-of-defun functions.

See this issue in csharp-mode for an example: https://github.com/emacs-csharp/csharp-mode/issues/219

The discovery there though was that pretty much all of those functions can be generalised for all tree-sitter based major-modes so we decided we should try to get such functions upstreamed rather than implement it in a major-mode specific way.

josteink avatar Mar 16 '21 12:03 josteink

sweet, tree-sitter-node-at-point this is what I am looking for.

ananthakumaran avatar Mar 16 '21 12:03 ananthakumaran

So... We're rewriting typescript-mode to be tree-sitter-mode based too now? :grin:

If so, I would suggest taking a look at csharp-tree-sitter-mode as a whole, and start from scratch based on something like that (sans grammar-portion), instead of incrementally trying to rewrite what we have.

Edit: it seems like tree-sitter-langs-package already contains typescript-grammar.

So ... What's left for us to do then? :smile:

josteink avatar Mar 23 '21 09:03 josteink

This issue is old and has seen no activity in a year+.

Closing this issue. Typescript support is now included in Emacs core, so if you still have problems, open a new issue on the GNU Emacs bug-tracker 😄

josteink avatar Oct 12 '23 07:10 josteink