Hi Doug, It came through all three times. Looks like a neat extension, and a good example for further experiments!
Todd -----Original Message----- >From: Doug Hale <[EMAIL PROTECTED]> >Sent: Oct 16, 2008 12:25 AM >To: advanced_delphi@yahoogroups.com >Subject: Re: [advanced_delphi] IDE extension - I found it. > >I sent this already but it never showed up - try again!!! > > > >Here it is, small and simple - thanks to Nafis Sadyko > >Just add to a package and install it. > >Doug > >---------------------------------------------------------------------------------------------------------------------------------------------------- > > >unit JBComment; > { > Keybinding for Delphi (versions 5, 6, 7) and > C++Builder (versions 5 and 6) editors. > Introduces 'Ctrl+/' shortcut for fast multi-line (JBuilder-style) >commenting. > How it works: select text block (with a mouse) and press 'Ctrl+/' > to comment/uncomment the lines contained. > Installation: just install as you'd install a new component > (by clicking "Component-> Install Component" IDE menu), then compile and > install the resulting package. > Note: for C++Builder - don't forget to add the path of your Builder's > Source\ToolsAPI folder to your package's library path in Project >Options. > >---------------------------------------------------------------------------- > > Copyright Nafis Sadykov - No restrictions on use. > e-mail: [EMAIL PROTECTED] > } >interface >uses >// SysUtils, {if using inttostr() or format() functions for debug >messages} > Classes, > Menus, > ToolsAPI, > Windows; >procedure Register; >implementation >const > VK_SLASH = 191; // not defined in 'windows.pas' >type > TJBCommentBinding = class(TNotifierObject, IOTAKeyboardBinding) > private > public > {required IOTAKeyboardBinding methods:} > function GetBindingType: TBindingType; > function GetDisplayName: string; > function GetName: string; > procedure BindKeyboard(const BindingServices: > IOTAKeyBindingServices); > {callback for the introduced shortcut - though not called automatically > for our specific "Ctrl+/" shortcut} > procedure JBComment(const Context: IOTAKeyContext; > KeyCode: TShortcut; > var BindingResult: TKeyBindingResult); > {callback for all the "unrecognized" shortcuts - this is where we >actually > catch 'Ctrl+/' shortcut using API call, and call the method above > ourselves} > procedure DefaultKeyProc(const Context: IOTAKeyContext; > KeyCode: TShortcut; > var BindingResult: TKeyBindingResult); > end; >procedure Register; > begin > (BorlandIDEServices as IOTAKeyboardServices). > AddKeyboardBinding(TJBCommentBinding.Create); > end; >function TJBCommentBinding.GetBindingType: TBindingType; > begin > {means we don't want to re-define the entire keyboard, but to introduce > just one or more shortcuts} > Result := btPartial; > end; >function TJBCommentBinding.GetDisplayName: string; > begin > {name to be displayed on the "Key Mappings" tab > when you click "Tools->Editor Options" menu in IDE} > Result := 'Multiline Commenting (JBuilder-style)'; > end; >function TJBCommentBinding.GetName: string; > begin > Result := 'ns.jbcomment'; // any unique string will do here > end; >procedure TJBCommentBinding.BindKeyboard( > const BindingServices: IOTAKeyBindingServices); > begin > {doesn't work for this specific shortcut, though works OK for "Ctrl+\" > for example.} > //BindingServices.AddKeyBinding([TextToShortCut('Ctrl+/')], JBComment, >nil); > {So, instead we define default callback for all unrecognized shortcuts} > BindingServices.SetDefaultKeyProc(DefaultKeyProc, nil, ''); > end; >procedure TJBCommentBinding.JBComment(const Context: IOTAKeyContext; > KeyCode: TShortcut; var BindingResult: TKeyBindingResult); > var > iEditPos: IOTAEditPosition; > iEditBlock: IOTAEditBlock; > startCol, endCol, > startRow, endRow: Integer; > topViewRow, topViewColumn: integer; > i: integer; > cursorAtStart: boolean;// is our cursor at the beginning of the >selection > procedure myCommentUncomment(Row: integer); > begin > iEditPos.Move(Row, 1); > if iEditPos.Read(2) = '//' then // if commented then uncomment the line > begin > {somehow, independent on the parameter, the .Delete() method only >deletes > a single character, so we need to call it twice here. (Another IOTA >bug ?)} > iEditPos.Delete(1); > iEditPos.Delete(1); > {now move the selection to the left} > if (Row = startRow) and (startCol <> 1) then > dec(startCol, 2); > if (Row = endRow) and (endCol <> 1) then > dec(endCol, 2); > end > else > begin // otherwise comment the line > iEditPos.InsertText('//'); > {now move the selection to the right} > if (Row = startRow) and (startCol <> 1) then > inc(startCol, 2); > if (Row = endRow) and (endCol <> 1) then > inc(endCol, 2); > end; > end; > begin > BindingResult := krHandled; > iEditBlock := Context.EditBuffer.EditBlock; > if not iEditBlock.IsValid then // do nothing if there is no selection > exit; > {store the EditBlock's parameters:} > startCol:= iEditBlock.StartingColumn; > endCol:= iEditBlock.EndingColumn; > startRow:= iEditBlock.StartingRow; > endRow:= iEditBlock.EndingRow; > iEditPos:= Context.EditBuffer.EditPosition; > {remember which side of the selection the cursor is at} > if (iEditPos.Row = startRow) and (iEditPos.Column = startCol) then > cursorAtStart:= true > else > cursorAtStart:= false; > {and remember the top line viewed in the editor} > topViewRow:= Context.EditBuffer.TopView.TopRow; > topViewColumn:= Context.EditBuffer.TopView.LeftColumn; > for i:= startRow to endRow -1 do > myCommentUncomment(i); > {process only if there is non-empty selection in the last row} > if (endRow <> startRow) and (endCol > 1) then > myCommentUncomment(endRow) > {process anyway if the selection doesn't span more than a single row} > else if (endRow = startRow) then > myCommentUncomment(endRow); > {now restore the selection and the cursor position} > if cursorAtStart then > begin > iEditPos.Move(endRow, endCol); > iEditBlock.EndBlock; > iEditPos.Move(startRow, startCol); > iEditBlock.BeginBlock; > end > else > begin > iEditPos.Move(startRow, startCol); > iEditBlock.BeginBlock; > iEditPos.Move(endRow, endCol); > iEditBlock.EndBlock; > end; > {restore the top row and left column - necessary for cases when you have > selections spanning more than a single page} > Context.EditBuffer.TopView.SetTopLeft(topViewRow, topViewColumn); > end; >var > ArrayKeysState: TKeyboardState; // type is defined in 'windows.pas' >function AreCorrectKeysPressed: boolean; > var > i: integer; > ctrlPressed, > slashPressed, > otherKeysPressed: boolean; > begin > result:= false; > ctrlPressed:= false; > slashPressed:= false; > otherKeysPressed:= false; > if GetKeyboardState(ArrayKeysState) then // make WinAPI call > begin > for i:= Low(ArrayKeysState) to High(ArrayKeysState) do > begin > {if the highest bit is set - see 'win32.hlp' for details on >GetKeyboardState()} > if (ArrayKeysState[i] and $80) > 0 then > begin > case i of > VK_CONTROL, VK_LCONTROL, VK_RCONTROL: > ctrlPressed:= true; > VK_SLASH: > slashPressed:= true; > else > begin > otherKeysPressed:= true; > break; > end; > end; //end case > end; > end; //end for > if (not otherKeysPressed)and ctrlPressed and slashPressed then > result:= true; > end; > end; >procedure TJBCommentBinding.DefaultKeyProc(const Context: IOTAKeyContext; > KeyCode: TShortcut; var BindingResult: TKeyBindingResult); > begin > { > Debugging message : if switched on, it'll show us that ALL the shortcuts > come with the same(!?) KeyCode parameter of $4040. > (You need the Messages window - same where you get the Compiler >messages - > visible to get this debug message.) > > Note: setting Breakpoints or trying to use Message Dialogs is of no use > when debugging Keybindings, so using >IOTAMessageServices).AddTitleMessage() > seems to be the only way to get the debugging info needed. > } >// (BorlandIDEServices as IOTAMessageServices).AddTitleMessage( >// format('DefaultKeyProc: ShortCut KeyCode= $%.4x',[KeyCode])); >if AreCorrectKeysPressed then > begin > self.JBComment(Context, KeyCode, BindingResult); > BindingResult:= krHandled; > end > else > BindingResult:= krUnhandled; > end; >end. >---------------------------------------------------------------------------------------------------------------------------------------------------- > > > > >Doug Hale wrote: >> My computer died so I have moved to a new one. I have a backupo ov >> everything but I can't find something. >> >> I had an IDE extension that would let me do a ctrl-allt-/ to >> comment/uncomment a block of code. >> Does anyone know what the name of this is and where I can find it? >> >> Thanks, >> Doug >> >> >> >> ------------------------------------ >> >> Yahoo! Groups Links >> >> >> >> >> >> >> > > > > >------------------------------------ > >Yahoo! Groups Links > > >