Author Topic: toggle_comment command  (Read 16283 times)

hs2

  • Senior Community Member
  • Posts: 2737
  • Hero Points: 288
toggle_comment command
« on: July 06, 2007, 12:25:12 pm »
Hi,

as an addition to the greatly improved 'comment'/'comment-erase' commands in v12.02 I've implemented a 'toggle-comment'.
I'm using it most of the time, but the explicit commands are also useful sometimes.
The command makes use of the following heuristics:
If at least 1 uncommented line is contained in the selection it's commented and uncommented otherwise.
(Also the current cursor position restored and the selection is cleared (@param deselect), but this can be easily adopted.)

Code: [Select]
// toggle line comments of current selection / current line
// if at least 1 uncommented line is contained in the selection it's commented
_command void toggle_comment( boolean deselect = true ) name_info (','VSARG2_REQUIRES_EDITORCTL|VSARG2_MARK)
{
   typeless orig_pos;
   _save_pos2 (orig_pos);

   bottomline := p_line;
   if ( select_active () )
   {
      end_select ();
      bottomline = p_line;
      begin_select ();
   }

   loop
   {
      first_non_blank ();
      commenting = ( _clex_find ( 0, 'G' ) != CFG_COMMENT );
      if ( commenting || (++p_line > bottomline) ) break;
   }
   _restore_pos2 (orig_pos);

   _save_pos2 (orig_pos);
   if ( commenting ) comment ();
   else              comment_erase ();
   _restore_pos2 (orig_pos);

   if ( select_active () && deselect ) _deselect ();
}

And last but not least it saves me 1 keybinding ;)

Have fun,
HS2
« Last Edit: July 06, 2007, 12:29:55 pm by hs2 »

jbhurst

  • Senior Community Member
  • Posts: 405
  • Hero Points: 33
Re: toggle_comment command
« Reply #1 on: July 18, 2007, 02:54:06 am »
Hi hs2,

I did something similar to your toggle-comment. I also do one other thing, which I stole from IntelliJ IDEA: If there is no selection, toggle the comment for the current line, and then move the cursor down to the next line. This makes it quick to toggle comments on a small set of lines without having to select them first. Generally one is toggling comments on a few lines at a time.

Regards

John Hurst
Wellington, New Zealand

hs2

  • Senior Community Member
  • Posts: 2737
  • Hero Points: 288
Re: toggle_comment command
« Reply #2 on: July 18, 2007, 08:50:37 am »
Hi John,

yes, I know your tweak when discussing the 'old' toggle_comment macro. I though about it again when doing the new one, but I still coudn't convince me to use it... But I'll give it a try b/c that's the best way to find out if it's ok for me too.

Thanks for reminding me,
HS2

Change to prev. posted toggle_comment macro:
Edit:
Code: [Select]
_command void toggle_comment( boolean godown = true, boolean deselect = true ) name_info (','VSARG2_REQUIRES_EDITORCTL|VSARG2_MARK)
{
   typeless orig_pos;
   _save_pos2 (orig_pos);

   bottomline := p_line;
   if ( select_active () )
   {
      end_select ();
      bottomline = p_line;
      begin_select ();

      // move cursor down to next line for single line commenting only
      godown = false;
   }

   loop
   {
      first_non_blank ();
      commenting = ( _clex_find ( 0, 'G' ) != CFG_COMMENT );
      if ( commenting || (++p_line > bottomline) ) break;
   }
   _restore_pos2 (orig_pos);

   _save_pos2 (orig_pos);
   if ( commenting ) comment ();
   else              comment_erase ();
   _restore_pos2 (orig_pos);

   if ( select_active () && deselect ) _deselect ();
   if ( godown )                       down ();
}

« Last Edit: July 18, 2007, 09:39:45 am by hs2 »

cappy2112

  • Community Member
  • Posts: 91
  • Hero Points: 0
Re: toggle_comment command
« Reply #3 on: July 23, 2007, 06:49:12 pm »
Hi,

as an addition to the greatly improved 'comment'/'comment-erase' commands in v12.02 I've implemented a 'toggle-comment'.
I'm using it most of the time, but the explicit commands are also useful sometimes.
The command makes use of the following heuristics:
If at least 1 uncommented line is contained in the selection it's commented and uncommented otherwise.
(Also the current cursor position restored and the selection is cleared (@param deselect), but this can be easily adopted.)

Code: [Select]
// toggle line comments of current selection / current line
// if at least 1 uncommented line is contained in the selection it's commented
_command void toggle_comment( boolean deselect = true ) name_info (','VSARG2_REQUIRES_EDITORCTL|VSARG2_MARK)
{
   typeless orig_pos;
   _save_pos2 (orig_pos);

   bottomline := p_line;
   if ( select_active () )
   {
      end_select ();
      bottomline = p_line;
      begin_select ();
   }

   loop
   {
      first_non_blank ();
      commenting = ( _clex_find ( 0, 'G' ) != CFG_COMMENT );
      if ( commenting || (++p_line > bottomline) ) break;
   }
   _restore_pos2 (orig_pos);

   _save_pos2 (orig_pos);
   if ( commenting ) comment ();
   else              comment_erase ();
   _restore_pos2 (orig_pos);

   if ( select_active () && deselect ) _deselect ();
}

And last but not least it saves me 1 keybinding ;)

Have fun,
HS2

Nice feature!

Is there a way to apply this to the entire file, instead of just the current line?
Will it hide all comments in a file if the entire file is highlighted?
 Will this macro work in 12.01, or does it depend on new functionality in 12.02?


Thanks

hs2

  • Senior Community Member
  • Posts: 2737
  • Hero Points: 288
Re: toggle_comment command
« Reply #4 on: July 23, 2007, 07:58:32 pm »
As described in the comment it works with selections and just the current line if nothing is selected.
The latest version uses the new line commenting support and the loop statement of v12.02, but you could replace 'loop' and try it with v12.01.
But it's anyway better to upgrade :)

HS2

Sandra

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 754
  • Hero Points: 35
Re: toggle_comment command
« Reply #5 on: August 13, 2007, 06:38:22 pm »
I really like the toggle_comment command - I've used it a bunch while debugging the comment and comment-erase.

However, if you try to use it to uncomment something on the last line, you're going to have trouble.  The editor will hang in an infinite loop, because of this line:
Code: [Select]
if ( commenting || (++p_line > bottomline) ) break;
If you try to set p_line to something greater than the number of lines in the buffer, it will be set to the last line of the buffer.  I tried changing the above line to this

Code: [Select]
if ( commenting || (++p_line > bottomline) || p_line == p_Noflines ) break;
and that seemed to work.

hs2

  • Senior Community Member
  • Posts: 2737
  • Hero Points: 288
Re: toggle_comment command
« Reply #6 on: August 13, 2007, 07:04:51 pm »
Thanks a lot Sandra and get big HP !
I didn't get into this trouble yet, but your fix is highly appreciated.
Now as I' m seeing the fix it was a quite stupid mistake ;)
...
Fixed it !

HS2

BTW: This is the latest'n greatest version incl. some blank line handling for non-selection commenting and your fix of course:
Code: [Select]
// toggle line comments of current selection / current line
// HS2-NOT: if at least 1 uncommented line is contained in the selection it's commented
_command void hs2_toggle_comment( boolean godown = true, boolean deselect = true ) name_info (','VSARG2_REQUIRES_EDITORCTL|VSARG2_MARK)
{
   typeless orig_pos;
   _save_pos2 (orig_pos);

   bottomline := p_line;
   multi_line := select_active();
   if ( multi_line )
   {
      end_select ();
      bottomline = p_line;
      begin_select ();

      // move cursor down to next line for single line commenting only
      godown = false;
   }

   int commenting = -1;
   loop
   {
      // skip blank lines for commenting test
      first_non_blank ();
      if ( p_col >= _end_line_col() && !multi_line) break;  // bail out on blanklines in single line mode #1
      else commenting = ( _clex_find ( 0, 'G' ) != CFG_COMMENT ) ? 1 : 0;
      if ( commenting || (++p_line > bottomline) || (p_line == p_Noflines) ) break;
   }
   _restore_pos2 (orig_pos);

   // bail out on blanklines in single line mode #2
   if ( commenting < 0 )
   {
      // this is only reached for single lines hence we just down()
      down ();
      return;
   }

   _save_pos2 (orig_pos);

   if ( commenting ) comment ();
   else              comment_erase ();
   _restore_pos2 (orig_pos);

   if ( select_active () && deselect ) _deselect ();
   if ( godown )                       down ();
}

mikesart

  • Community Member
  • Posts: 56
  • Hero Points: 11
Re: toggle_comment command
« Reply #7 on: August 14, 2007, 09:55:04 pm »
Hi HS2.

I'm getting an error due to the "_end_line_col()" function not being defined with your latest. Is that one of yours or is there a hotfix I might be missing or something?

Thanks much.

hs2

  • Senior Community Member
  • Posts: 2737
  • Hero Points: 288
Re: toggle_comment command
« Reply #8 on: August 14, 2007, 10:36:54 pm »
Ups - sorry  :-[ It's an add. extension mainly for Brief mode...
Just add this 'near' the toggle_comment.
Code: [Select]
// HS2-ADD: stdcmds.e extensions for brief_home/end
_end_line_col(...)
{
   typeless p;
   save_pos(p);

   if (p_hex_mode==1)   _hex_end_line();
   else
   {
      // ripped from end_line_text_toggle
      // save the original column and jump to the end of the line
      orig_col := p_col;

      // find the last nonblank column
      _begin_line();
      search(':b$|$','@rh');
      nonblank_col := p_col;

      // find the actual end of the line
      _TruncEndLine();

      // check if we can use the last non-blank column
      if (nonblank_col > orig_col && nonblank_col < p_col) {
         p_col = nonblank_col;
      }
   }

   int col=p_col;
   restore_pos(p);
   // message ("_end_line_col=" col);
   return (col);
}

HS2

hs2

  • Senior Community Member
  • Posts: 2737
  • Hero Points: 288
Re: toggle_comment command
« Reply #9 on: August 30, 2007, 09:50:27 pm »
@Sandra:
What do you think about supporting un-commenting selected lines as follows:
Code: [Select]
// comment line 1

// comment line 3
Note the blank line 2.

Seems that this change does the trick:
box.e - comment_erase() [line 1484]: v12.03
Code: [Select]
            if (!strieq(cmtLeft, expand_tabs(line, lcPos, size_left_comment, 'S'))) {
               status = 1;
               break;
            }
now:
Code: [Select]
            if (!strieq(cmtLeft, expand_tabs(line, lcPos, size_left_comment, 'S'))) {
               // HS2-CHG: added blank line check
               nonblank_col = pos('[~ \t]', expand_tabs(line), 1, p_rawpos'er');
               if (nonblank_col) {
                  status = 1;
                  break;
               }
            }

This was quite easy to find for line comments but the same 'problem' applies to box comments too.

It's possible to box this text:
Code: [Select]
   text line 1

   text line 2
which e.g. gives:
Code: [Select]
   /*
    * text line 1
    *
    * text line 2
    */

But box-erase fails on it's own created comment block with 'Bad comment'.
(I quickly recognized that this would take longer than 3 minutes to find/fix for me so I stopped diggin into it ;))
However, I think this should be fixed.

In my latest 'toggle_comment' version blanklines are always omitted when doing the 'commenting' check even for seleced lines.
This revealed the issue with uncommenting non-contiguous (commented) lines as described above.

HS2

Sandra

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 754
  • Hero Points: 35
Re: toggle_comment command
« Reply #10 on: August 31, 2007, 01:19:01 pm »
I like this change.  I know I've tried to uncomment a big bunch of comments and then been unable to figure out why it failed - there was a blank line somewhere in the middle.  I'll check around and see if there are any good reasons we shouldn't add this.

As far as the box problem, I recently made some general fixes to box-erase, because it was failing on its own boxes.  I'll see if your issue got fixed, and if not, fix that one, too.

Thanks!

hs2

  • Senior Community Member
  • Posts: 2737
  • Hero Points: 288
Re: toggle_comment command
« Reply #11 on: August 31, 2007, 01:29:26 pm »
Cool - thank you !
I really hope that you find the issue in box(_erase)() yourself b/c it's quite complicated and lacks ... comments ;)
HS2

Sandra

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 754
  • Hero Points: 35
Re: toggle_comment command
« Reply #12 on: September 04, 2007, 02:38:53 pm »
The issue with box that you mentioned did already get fixed for v13.  I'm also adding the allowance for blank lines that you mentioned.  Thanks again!

hs2

  • Senior Community Member
  • Posts: 2737
  • Hero Points: 288
Re: toggle_comment command
« Reply #13 on: September 04, 2007, 02:44:59 pm »
I really thought that v12.03 is the best release ever - but it seems this will apply to v13 ;)
Thanks Sandra,
HS2

witness9

  • Community Member
  • Posts: 54
  • Hero Points: 2
Re: toggle_comment command
« Reply #14 on: October 10, 2007, 09:03:38 pm »
HS2 - i get 'Expecting statement' (at the 'loop' statement) when i try to load your macro. Slick-C is a second language for me at best.  Loop is a legitimate statement in Ada, but i'm not finding it in the help.   ???