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

Support arrow functions #3

Open
cpixl opened this issue May 2, 2015 · 19 comments
Open

Support arrow functions #3

cpixl opened this issue May 2, 2015 · 19 comments

Comments

@cpixl
Copy link

cpixl commented May 2, 2015

var foo = [1, 2, 3];
var bar = foo.map(x => x * x);

It would be nice if ES6 arrow functions (like the one above) were supported.

@simonsmith
Copy link

Object literal methods would be lovely too:

{
  test() {

  }
}

@yasen-atanasov
Copy link
Contributor

Added pull request for fat arrow functions - #4

@bag-man
Copy link

bag-man commented Apr 6, 2017

Just tested, it looks like arrorw functions are working, but not object literal methods. Would be amazing if someone could add that!

@alex-shamshurin
Copy link

I there any update? Can anybody fix it?

@alex-shamshurin
Copy link

It can select es5 functions which starting from function.

@kubek2k
Copy link

kubek2k commented Mar 5, 2018

the fat arrow functions work as a charm - I think the issue might be with functions using new destructuring operators, or ...

@alex-shamshurin
Copy link

and generator functions, async functions and so on. Practically this extension does not help at all, 80% of modern javascript is not supported.

@kubek2k
Copy link

kubek2k commented Mar 6, 2018

@alex-shamshurin instead of complaining we should fix it :)

@alex-shamshurin
Copy link

unfortunately I'm not good at vimscript

@kubek2k
Copy link

kubek2k commented Mar 6, 2018

@alex-shamshurin I think its enough to understand a bit of regex to fix it - lets make a deal - I will try to provide a fix for it and you will tell me what is missing/not working. Good idea?

@mattn
Copy link

mattn commented Mar 8, 2018

Anyone, could you please try this?

diff --git a/autoload/textobj/function/javascript.vim b/autoload/textobj/function/javascript.vim
index d60b209..c2ab901 100644
--- a/autoload/textobj/function/javascript.vim
+++ b/autoload/textobj/function/javascript.vim
@@ -88,7 +88,7 @@ endfunction
 function! s:function_range()
   let start = getpos('.')
   " look backward for function definition or fat arrow
-  while search('\v<function>|(\(%(\k|,|\s)*\)|\k+)\s*\=\>\s*', 'bcW') != 0
+  while search('\v<function>|(\(%(\k|\.\.\.|,|\s)*\)|\k+)\s*\=\>\s*', 'bcW') != 0
     let b = getpos('.')
 
     " go to either the start of the function argument list or right after the fat arrow

@mattn
Copy link

mattn commented Mar 8, 2018

And I noticed that goes endless loop in sometimes.

diff --git a/autoload/textobj/function/javascript.vim b/autoload/textobj/function/javascript.vim
index d60b209..48101c9 100644
--- a/autoload/textobj/function/javascript.vim
+++ b/autoload/textobj/function/javascript.vim
@@ -88,8 +88,13 @@ endfunction
 function! s:function_range()
   let start = getpos('.')
   " look backward for function definition or fat arrow
-  while search('\v<function>|(\(%(\k|,|\s)*\)|\k+)\s*\=\>\s*', 'bcW') != 0
+  let prev = start
+  while search('\v<function>|(\(%(\k|\.\.\.|,|\s)*\)|\k+)\s*\=\>\s*', 'bcW') != 0
     let b = getpos('.')
+    if b ==# prev
+      break
+    endif
+    let prev = b
 
     " go to either the start of the function argument list or right after the fat arrow
     if (search('\v<function>\s*\k*\s*\(|\=\>\s*', 'ceW'))

@simonsmith
Copy link

@mattn What should I be testing?

@mattn
Copy link

mattn commented Mar 8, 2018

As far as I can see, my patch fixes problems you mentioned.

tests

But, there may still be unknown cases.

@kubek2k
Copy link

kubek2k commented Mar 8, 2018

@mattn I think its better to provide a PR in your own fork.

As a sidenote - I looked at the code and as @alex-shamshurin pointed out about himself I always have a hard time reading vimml :). But my first takeaway about this, is that I would branch out on function or => (nearer wins) and then delegate to specific functions - that would make code and regexes clearer.

@mattn
Copy link

mattn commented Mar 8, 2018

I may not fully understand what the case you want. Could you please show me the code? (to reproduce)

@simonsmith
Copy link

@mattn Excellent work! I think the only one I can see missing there are class methods/object methods:

class {
  someMethod() {

  }
}
{
  test() {

  }
}

Is that tricky to add?

@mattn
Copy link

mattn commented Mar 8, 2018

Ah, I understand the case. Hmm, it's hard to implement without syntax-contained feature of vim.

@mattn
Copy link

mattn commented Mar 8, 2018

diff --git a/autoload/textobj/function/javascript.vim b/autoload/textobj/function/javascript.vim
index d60b209..d31f11c 100644
--- a/autoload/textobj/function/javascript.vim
+++ b/autoload/textobj/function/javascript.vim
@@ -88,11 +88,16 @@ endfunction
 function! s:function_range()
   let start = getpos('.')
   " look backward for function definition or fat arrow
-  while search('\v<function>|(\(%(\k|,|\s)*\)|\k+)\s*\=\>\s*', 'bcW') != 0
+  let prev = start
+  while search('\v<function>|(\(%(\k|\.\.\.|,|\s)*\)|\k+)\s*\=\>\s*', 'bcW') != 0
     let b = getpos('.')
+    if b ==# prev
+      break
+    endif
+    let prev = b
 
     " go to either the start of the function argument list or right after the fat arrow
-    if (search('\v<function>\s*\k*\s*\(|\=\>\s*', 'ceW'))
+    if (search('\v<function>\s*\k*\s*\(|\k\+|\=\>\s*', 'ceW'))
       " if we're on the start of a normal function argument list - skip it
       if s:cursor_char() == '('
         call s:jump_to_pair()
@@ -130,7 +135,34 @@ function! s:function_range()
     endif
     return [b, e]
   endwhile
-  return 0
+
+  call setpos('.', start)
+
+  " handle ES6 class method. back to something like "foo("
+  if !search('\v\k+\s*\(', 'bcW')
+    return 0
+  endif
+  let b = getpos('.')
+  call s:left()
+  " in left side back, syntax have Class identifier
+  if s:cursor_syn() !~ 'Class'
+    return 0
+  endif
+  " move forward to the end of block
+  if !search('(', 'ceW')
+    return 0
+  endif
+  call s:jump_to_pair()
+
+  while search('\S', 'W') != 0 && s:cursor_syn() ==# 'Comment'
+  endwhile
+  if s:cursor_char() != '{'
+    return 0
+  endif
+  call s:jump_to_pair()
+
+  let e = getpos('.')
+  return [b, e]
 endfunction
 
 function! s:jump_to_pair()

If you install syntax plugin that support ES6, and it have syntax identifier contains Class, this may work well. But this have some ugly workaround.

thenoseman added a commit to thenoseman/vim-textobj-function-javascript that referenced this issue Oct 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants