Einzelnen Beitrag anzeigen

madtom

Registriert seit: 24. Feb 2005
Ort: Hamburg
115 Beiträge
 
Delphi XE7 Professional
 
#20

AW: Feature: Block oder Zeile duplizieren

  Alt 30. Jan 2012, 17:14
Hallo,

ein Stichwort wäre Key Binding über die ToolsAPI:
Delphi-Quellcode:
// Duplicate Line Key Binding
// Copyright (c) 2001-2010 Cary Jensen, Jensen Data Systems, Inc.


unit Dupline;

// Duplicate Line Key Binding
// Copyright (c) 2001-2010 Cary Jensen, Jensen Data Systems, Inc.
//
// You may freely distribute this unit, so long as this comment
// section is retained, and no fee is charged for it.
//
// This key binding is provided as a demonstration of key bindings.
//
// To use this key binding, install it into a design-time package.
//
// Once installed, this key binding adds a Ctrl-Shift-D (duplicate line) function to the code editor.
//
// No warranty is intended or implied concerning the
// appropriateness of this code example for any other use. If you use
// this examples, or any part of it, you assume all responsibility
// for ensuring that it works as intended.
//
// For information concerning Delphi training, visit www.jensendatasystems.com.

interface

uses
  SysUtils, Classes, Dialogs, Controls, Windows, Menus, ToolsAPI;

procedure register;

implementation

type
  TDupLineBinding = class(TNotifierObject, IOTAKeyboardBinding)
  private
  public
    procedure Dupline(const Context: IOTAKeyContext; KeyCode: TShortcut;
      var BindingResult: TKeyBindingResult);
    procedure AppendComment(const Context: IOTAKeyContext; KeyCode: TShortcut;
      var BindingResult: TKeyBindingResult);
    procedure CommentToggle(const Context: IOTAKeyContext; KeyCode: TShortcut;
      var BindingResult: TKeyBindingResult);
    procedure CommentToggle1(const Context: IOTAKeyContext; KeyCode: TShortcut;
      var BindingResult: TKeyBindingResult);

    { IOTAKeyboardBinding }
    function GetBindingType: TBindingType;
    function GetDisplayName: string;
    function GetName: string;
    procedure BindKeyboard(const BindingServices: IOTAKeyBindingServices);
  end;

procedure register;
begin
  (BorlandIDEServices as IOTAKeyboardServices).AddKeyboardBinding(TDupLineBinding.Create);
end;

{ TKeyBindingImpl }

function TDupLineBinding.GetBindingType: TBindingType;
begin
  Result := btPartial;
end;

function TDupLineBinding.GetDisplayName: string;
begin
  Result := 'Duplicate Line Binding';
end;

function TDupLineBinding.GetName: string;
begin
  Result := 'jdsi.dupline';
end;

procedure TDupLineBinding.BindKeyboard(const BindingServices: IOTAKeyBindingServices);
begin
  BindingServices.AddKeyBinding([Shortcut(Ord('D'), [ssShift, ssCtrl])], Dupline, nil);
  // BindingServices.AddKeyBinding([Shortcut(Ord('C'), [ssShift, ssCtrl])], AppendComment, nil);
  BindingServices.AddKeyBinding([Shortcut(VK_F1, [ssShift, ssCtrl])], CommentToggle, nil);
  // BindingServices.AddKeyBinding([Shortcut(VK_F1, [ssShift, ssCtrl])], CommentToggle1, nil);
  // Add additional key bindings here
end;

procedure TDupLineBinding.Dupline(const Context: IOTAKeyContext; KeyCode: TShortcut;
  var BindingResult: TKeyBindingResult);
var
  EditPosition: IOTAEditPosition;
  EditBlock: IOTAEditBlock;
  CurrentRow: Integer;
  CurrentRowEnd: Integer;
  BlockSize: Integer;
  IsAutoIndent: Boolean;
  CodeLine: string;
begin
  EditPosition := Context.EditBuffer.EditPosition;
  EditBlock := Context.EditBuffer.EditBlock;
  // Save the current edit block and edit position
  EditBlock.Save;
  EditPosition.Save;
  try
    // Store original cursor row
    CurrentRow := EditPosition.Row;
    // Length of the selected block (0 means no block)
    BlockSize := EditBlock.Size;
    // Store AutoIndent property
    IsAutoIndent := Context.EditBuffer.BufferOptions.AutoIndent;
    // Turn off AutoIndent, if necessary
    if IsAutoIndent then
      Context.EditBuffer.BufferOptions.AutoIndent := False;
    // If no block is selected, or the selected block is a single line,
    // then duplicate just the current line
    if (BlockSize = 0) or (EditBlock.StartingRow = EditPosition.Row) or
      ((BlockSize <> 0) and ((EditBlock.StartingRow + 1) = (EditPosition.Row)) and
        (EditBlock.EndingColumn = 1)) then
    begin
      // Only a single line to duplicate
      // Move to end of current line
      EditPosition.MoveEOL;
      // Get the column position
      CurrentRowEnd := EditPosition.Column;
      // Move to beginning of current line
      EditPosition.MoveBOL;
      // Get the text of the current line, less the EOL marker
      CodeLine := EditPosition.read(CurrentRowEnd - 1);
      // Add a line
      EditPosition.InsertText(#13);
      // Move to column 1
      EditPosition.Move(CurrentRow, 1);
      // Insert the copied line
      EditPosition.InsertText(CodeLine);
    end
    else
    begin
      // More than one line selected. Get block text
      CodeLine := EditBlock.Text;
      // Move to the end of the block
      EditPosition.Move(EditBlock.EndingRow, EditBlock.EndingColumn);
      // Add a line
      EditPosition.InsertText(#13);
      // Insert block text
      EditPosition.InsertText(CodeLine);
    end;
    // Restore AutoIndent, if necessary
    if IsAutoIndent then
      Context.EditBuffer.BufferOptions.AutoIndent := True;
    BindingResult := krHandled;
  finally
    // Move cursor to original position
    EditPosition.Restore;
    // Restore the original block (if one existed)
    EditBlock.Restore;
  end;
end;

procedure TDupLineBinding.AppendComment(const Context: IOTAKeyContext; KeyCode: TShortcut;
  var BindingResult: TKeyBindingResult);
var
  EditPosition: IOTAEditPosition;
  eColumn: Integer;
begin
  EditPosition := Context.EditBuffer.EditPosition;
  EditPosition.MoveEOL;
  eColumn := EditPosition.Column;
  EditPosition.InsertText(' // ' + DateTimeToStr(Now) + #13);
  EditPosition.Move(EditPosition.Row, eColumn);
  EditPosition.InsertText(' // Author: Cary Jensen');
  BindingResult := krHandled;
end;

procedure TDupLineBinding.CommentToggle(const Context: IOTAKeyContext; KeyCode: TShortcut;
  var BindingResult: TKeyBindingResult);
var
  EditPosition: IOTAEditPosition;
  EditBlock: IOTAEditBlock;
  StartRow: Integer;
  EndRow: Integer;
  Comment: Boolean;
begin
  // original edit position
  EditPosition := Context.EditBuffer.EditPosition;
  EditPosition.Save;
  // edit block
  EditBlock := Context.EditBuffer.EditBlock;
  // find the starting and ending rows to operate on
  if EditBlock.Size = 0 then
  begin
    StartRow := EditPosition.Row;
    EndRow := EditPosition.Row;
  end

  else if (EditBlock.EndingColumn = 1) then
  begin
    StartRow := EditBlock.StartingRow;
    EndRow := EditBlock.EndingRow - 1;
  end

  else
  begin
    StartRow := EditBlock.StartingRow;
    EndRow := EditBlock.EndingRow;
  end;

  // toggle comments
  repeat
  begin
    EditPosition.Move(StartRow, 1);
    while EditPosition.IsWhiteSpace do
      EditPosition.MoveRelative(0, 1);
    if EditPosition.Character = '/then
    begin
      EditPosition.MoveRelative(0, 1);
      if EditPosition.Character = '/then
        Comment := True
      else
        Comment := False
    end
    else
      Comment := False;

    if Comment then
    begin
      EditPosition.MoveRelative(0, -1);
      EditPosition.Delete(2);
    end
    else
    begin
      EditPosition.MoveBOL;
      EditPosition.InsertText('//');
    end;
    Inc(StartRow);
  end;
  until
    (StartRow > EndRow);
  // update caret position
  EditPosition.Restore;
  EditPosition.Move(StartRow, EditPosition.Column);
  // All done
  BindingResult := krHandled;
end;

procedure TDupLineBinding.CommentToggle1(const Context: IOTAKeyContext; KeyCode: TShortcut;
  var BindingResult: TKeyBindingResult);
begin
  //
end;

end.
Thomas
Delphi Programming
  Mit Zitat antworten Zitat