Skip to content

indent after one-line if statement without semicolon #291

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

Closed
camsteffen opened this issue Aug 28, 2015 · 10 comments
Closed

indent after one-line if statement without semicolon #291

camsteffen opened this issue Aug 28, 2015 · 10 comments

Comments

@camsteffen
Copy link
Contributor

This is incorrectly indented

if(1) return
    console.log('foo')
@qstrahl
Copy link
Collaborator

qstrahl commented Aug 28, 2015

Oh man, I have a feeling this one is going to be absurdly difficult to solve. Thanks for the report.

@camsteffen
Copy link
Contributor Author

Admittedly I am not familiar with the code, but shouldn't this be pretty simple? If there is anything after the parenthesis, then that is the if block and the next line is not.

@camsteffen
Copy link
Contributor Author

I decided to get my hands dirty.

Looking at indent/javascript.vim...

The problem is that s:InOneLineScope(lnum) evaluates true (non-zero) with the line if(1) return. I believe the function would be better named BeginsOneLineScope. Fixing it will require changing s:one_line_scope_regex so that it does not match when there is a statement following the if/for/while/.... I'm not very good at Vim regular expressions but I will keep at it unless someone wants to step in.

@camsteffen
Copy link
Contributor Author

Related to #192 and #253

@qstrahl
Copy link
Collaborator

qstrahl commented Sep 1, 2015

Thanks for the detective work, @cambunctious!

Using regexes for this stuff makes me throw up in my mouth a bit, but unless/until we can make use of the underlying syntax groups to do this stuff, it's pretty unavoidable... I have a knack for vim regex so I'll take a crack at getting something in place that won't break under the smallest amount of pressure, and hopefully we'll be able to put this to bed for now.

@qstrahl
Copy link
Collaborator

qstrahl commented Sep 1, 2015

Also, with regard to:

Admittedly I am not familiar with the code, but shouldn't this be pretty simple? If there is anything after the parenthesis, then that is the if block and the next line is not.

Corner cases. Consider the following:

if (something) { doLittle(); } else
    bigNamedVariable.doTonsOfStuffHolyCrapThisMethodNameIsSoConvenientlyDescriptive();

I don't have a very good idea of how all those indent-related functions operate, but I assume that cases like the above could throw it for a loop. We can ignore those cases, but only until somebody posts an issue here complaining that it doesn't work. =P

@camsteffen
Copy link
Contributor Author

Corner cases.

Blast!

Maybe s:InOneLineScope(lnum) could work something like this:

  1. if the line ends with else, return true
  2. If the line ends with if|while|for followed by a parenthetical, return true
  3. return false

I see the tricky part is the parenthetical with regex. Is it possible to use the % command to find matching parenthesis? If so, begin step 2 by detecting a ) at the end of the line and work backwards.

@qstrahl
Copy link
Collaborator

qstrahl commented Sep 1, 2015

I will have to take a look at it, but using normal commands/moving the
cursor around sounds like it could break stuff, if it's even possible.
Don't worry, I'll figure something out. Just gotta dive into the code. =)

On Tue, 1 Sep 2015 17:11 Cameron Steffen [email protected] wrote:

Maybe s:InOneLineScope(lnum) could work something like this:

  1. if the line ends with else, return true
  2. If the line ends with if|while|for followed by a parenthetical,
    return true
  3. return false

I see the tricky part is the parenthetical with regex. Is it possible to
use the % command to find matching parenthesis? If so, start step 2 by
detecting a ) at the end of the line.


Reply to this email directly or view it on GitHub
#291 (comment)
.

@evgenyzinoviev
Copy link

Just faced this problem. I've never used regular expressions in vimscript before, so I'm almost sure that my solution is completely wrong and dirty, but it seems to work for me for now (tested for a few seconds lol)

let s:one_line_scope_regex = '\<\%(if\|for\|while\)\>\s*([^)]*)\s*' . s:line_term
let s:one_line_scope_regex_else = 'else\s*' . s:line_term

...

function s:InOneLineScope(lnum)
  let msl = s:GetMSL(a:lnum, 1)
  if msl > 0 && (s:Match(msl, s:one_line_scope_regex) || s:Match(msl, s:one_line_scope_regex_else))
    return msl
  endif
  return 0
endfunction

@camsteffen
Copy link
Contributor Author

I already have a pull request submitted for this.

qstrahl added a commit that referenced this issue Feb 22, 2016
Issue #291 better one line scope indentation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants