add comment text object #586

Closed
muellan opened this Issue Jan 27, 2015 · 11 comments

Projects

None yet

3 participants

@muellan
muellan commented Jan 27, 2015

There are a couple of Vim scripts out there that enable a c text object so you can do dic or yac.
I catch myself all the time trying to do this in Eclipse+Vrapper, too, because it seems so natural.

@albertdev
Contributor

It should be possible to implement this, but I'm not going to give a target date...

Marked as feature request for now.

@keforbes
Contributor
keforbes commented Feb 6, 2015

@muellan, you say there are a couple vim scripts which enable a c text object. Do you have a favorite which you think our implementation should be based on? I'm guessing they're all pretty much the same but there may be some quirk or nuance that you'd like to see in Vrapper.

@albertdev
Contributor

True, it would always help if we got something to work from. I was thinking about this the other day and it hit me that this can be very language-specific. For example, do you treat two lines starting with // as one or as two elements? How do we deal with '#' in non-C languages?

Links to existing scripts are hence preferred.

@muellan
muellan commented Feb 6, 2015

I use this one: http://www.vim.org/scripts/script.php?script_id=4570
The documentation says it is file type aware but I don't know any details about other languages than C++ or Python.
There are some things about the comment text objects in the scipt I don't like. Personally I would prefer something along these lines instead:

ic: If the line starts with a line comment token (//, #, --, ...depending on the language) selects the range starting from the first non-whitespace character after that token to the last non-whitespace character in that line.
If the line starts with a block comment token (/*, {-, ...) selects everything from the first non-whitespace character after that token to the last non-whitespace character before the closing token (*/, -}, ...).

ac: Line comments: selects an entire paragraph of commented lines including the comment token but excluding leading whitespace on the first line of the range and trailing whitespace on the last line. Block comments: selects the range beginning with the comment start token to the comment end token. Excludes whitespace before and after the comment.

iC: Like ic but includes leading and trailing whitespace chars

aC: Like ac but includes leading and trailing whitespace chars

@keforbes
Contributor

Hey @muellan, since I know you're still actively watching these issues... I was thinking about working on this comment text object after my subword plugin. I wanted to get your thoughts on something first though. Do you think this comment text object should be implemented in Vrapper core or released as a new optional plugin? Technically it's a Vimscript so a plugin would make sense, but it also doesn't conflict with any existing features in Vim so we could put it in Vrapper core without affecting users who are unaware of the feature. Plus, more users may use it if it doesn't require them to install anything extra. We've added features in Vrapper core that don't exist in Vim before so I could go either way with this.

@muellan
muellan commented Apr 17, 2016

Since it doesn't conflict with existing mappings and commenting is a pretty fundamental thing in an IDE I could imagine this being in core.

@keforbes
Contributor

@muellan, I'm reading over your original request a little closer and I want to see if I understand it correctly. You want ic to select one line for single-line comments but you want ac to select all contiguous lines of single-line comments?

If I'm understanding you correctly, given the following commented-out code:

//  if([s]omething) {
//      doSomething();
//  }

If the cursor is on the s in something, you want ic to select if(something) { but you want ac to select all three lines? Is that right? While I understand the desire to support multiple single-line comments, that behavior seems confusing to me.

Also, are you saying iC would remove leading and trailing whitespace around the comment text but leave the comment characters (//) behind? aC makes sense to me to remove all whitespace and every part of the comment, but iC doesn't seem too useful. The difference between ic and iC is the whitespace between // and the comment text?

How about this:

  • ic
    • single-line comment (//): select from first non-whitespace after comment character to last non-whitespace on the line.
    • multi-line comment (/*): select from first non-whitespace after open comment token to last non-whitespace before closing token (*/).
  • ac
    • single-line comment (//): select from beginning of comment character (//) to end of the line.
    • multi-line comment (/*): select from beginning of open comment token (/*) to end of closing comment token (*/).
  • iC
    • single-line comment (//): same as ic except if there are multiple contiguous single-line comments we select from first non-whitespace after first comment character to last non-whitespace of last commented line. This would allow you to delete entire blocks of single-line commented code like my example above.
    • multi-line comment (/*): I'm not sure if this would do anything different than normal ic for multi-line comments. Maybe just include all characters between open token (/*) and closing token (*/)? Basically, include any leading or trailing whitespace within those tokens? I'd be open to suggestions.
  • aC
    • single-line comment(//): Line-wise operation. Select entire line of single-line comment (column 0 to newline). Select entire lines of contiguous single-line comments.
    • multi-line comment (/*): Line-wise operation. Select all lines from opening /* to closing */, including the lines with those tokens.

As I think more about this feature, I believe I will only support lines which start with comment characters. I plan on just hardcoding //, #, --, etc. which would only work if the line started with those characters. This means I wouldn't support the following scenario:

int x = y;  //this does stuff

If the line contains a comment but doesn't start with a comment, I'd ignore it. This is because I don't plan on looking at the filetype and determining that language's comment syntax. I wouldn't want to chop apart your code just because you used a -- decrement in Java. Although, with that said, hopefully you wouldn't use the c text object unless there was a comment on that line. Maybe I could support comments in the middle of the line and leave it to the user to not shoot themselves in the foot.

@muellan
muellan commented Apr 20, 2016

You are absolutely right. Your mappings make a lot more sense. Can't wait to try it!

@keforbes keforbes added a commit that referenced this issue Apr 20, 2016
@keforbes keforbes Work on #586. Add support for a comment text object 'ic'/'ac'.
Initial attempt.  There are still some corner cases that need work but the base feature seems functional.
d9292cb
@keforbes
Contributor

I've updated the unstable update site with a new build (0.67.20160420) which includes my first attempt at this feature. I think it works pretty well in the standard scenarios but I'm not handling cases like accidentally running the command outside a comment or block comments with repeated characters like /********. Give it a try though and tell me what you think.

@keforbes keforbes added a commit that referenced this issue Apr 21, 2016
@keforbes keforbes More work on #586, comment text object 'c'.
I believe it is fully functional now.  It handles all the scenarios I've come up with at least.
ccf569b
@muellan
muellan commented Apr 21, 2016

Great work! This is even better than the VIM plugin I use.

@keforbes
Contributor

I've updated the unstable update site with more updates to this feature. Please try it again. It handles every case I threw at it but of course I'm sure there are some I missed.

Among other things, I now handle this case correctly:

/*********************
 * this is a comment
 *********************/
@keforbes keforbes closed this Apr 22, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment