Changeset 11741


Ignore:
Timestamp:
01/09/15 07:24:57 (7 years ago)
Author:
jkarder
Message:

#2077: added <Alt> + <Up> and <Alt> + <Down> keystrokes to move lines

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/CodeEditor/HeuristicLab.CodeEditor/3.4/CodeEditor.cs

    r11700 r11741  
    2424using System.Collections.Generic;
    2525using System.ComponentModel;
     26using System.Linq;
    2627using System.Reflection;
    2728using System.Threading.Tasks;
     
    3233using ICSharpCode.AvalonEdit.CodeCompletion;
    3334using ICSharpCode.AvalonEdit.Document;
     35using ICSharpCode.AvalonEdit.Editing;
    3436using ICSharpCode.AvalonEdit.Highlighting;
    3537using ICSharpCode.AvalonEdit.Search;
     
    212214      #endregion
    213215
     216      #region MoveLinesUpCommand
     217      var moveLinesUpCommand = new Input.RoutedCommand();
     218      moveLinesUpCommand.InputGestures.Add(new Input.KeyGesture(Input.Key.Up, Input.ModifierKeys.Alt));
     219      var moveLinesUpCommandBinding = new Input.CommandBinding(moveLinesUpCommand, (sender, args) => MoveLines(MovementDirection.Up));
     220      TextEditor.CommandBindings.Add(moveLinesUpCommandBinding);
     221      #endregion
     222
     223      #region MoveLinesDownCommand
     224      var moveLinesDownCommand = new Input.RoutedCommand();
     225      moveLinesDownCommand.InputGestures.Add(new Input.KeyGesture(Input.Key.Down, Input.ModifierKeys.Alt));
     226      var moveLinesDownCommandBinding = new Input.CommandBinding(moveLinesDownCommand, (sender, args) => MoveLines(MovementDirection.Down));
     227      TextEditor.CommandBindings.Add(moveLinesDownCommandBinding);
     228      #endregion
     229
    214230      TextEditorSyntaxHighlighting = DefaultTextEditorSyntaxHighlighting;
    215231      TextEditorShowLineNumbers = DefaultTextEditorShowLineNumbers;
     
    261277    }
    262278
     279    private enum MovementDirection { Up, Down }
     280    private void MoveLines(MovementDirection movementDirection) {
     281      var textArea = TextEditor.TextArea;
     282      var selection = textArea.Selection;
     283
     284      int selectionStart, selectionEnd;
     285      if (!(selection is RectangleSelection) && selection.IsEmpty) {
     286        selectionStart = selectionEnd = TextEditor.SelectionStart;
     287      } else {
     288        selectionStart = Doc.GetOffset(selection.StartPosition.Location);
     289        selectionEnd = Doc.GetOffset(selection.EndPosition.Location);
     290        if (selectionStart > selectionEnd) {
     291          int temp = selectionStart;
     292          selectionStart = selectionEnd;
     293          selectionEnd = temp;
     294        }
     295      }
     296
     297      int selectionLength = selection.Length;
     298      var selectionSegments = selection.Segments;
     299      int caretOffset = TextEditor.CaretOffset;
     300
     301      var startLine = Doc.GetLineByOffset(selectionStart);
     302      var endLine = Doc.GetLineByOffset(selectionEnd);
     303
     304      if (movementDirection == MovementDirection.Up && startLine.LineNumber == 1) return;
     305      if (movementDirection == MovementDirection.Down && endLine.LineNumber == Doc.LineCount) return;
     306
     307      int startOffset = startLine.Offset;
     308      string primaryText = Doc.GetText(startOffset, endLine.EndOffset - startOffset);
     309      string primaryDelimiter = Doc.GetText(endLine.EndOffset, endLine.DelimiterLength);
     310
     311      var secondaryLine = movementDirection == MovementDirection.Up ? startLine.PreviousLine : endLine.NextLine;
     312      string secondaryText = Doc.GetText(secondaryLine.Offset, secondaryLine.Length);
     313      string secondaryDelimiter = Doc.GetText(secondaryLine.EndOffset, secondaryLine.DelimiterLength);
     314
     315      if (movementDirection == MovementDirection.Up) {
     316        string replacementText = primaryText + secondaryDelimiter + secondaryText + primaryDelimiter;
     317        Doc.Replace(secondaryLine.Offset, replacementText.Length, replacementText);
     318        int correctionLength = secondaryText.Length + secondaryDelimiter.Length;
     319        selectionStart -= correctionLength;
     320        caretOffset -= correctionLength;
     321      } else {
     322        string replacementText = secondaryText + primaryDelimiter + primaryText + secondaryDelimiter;
     323        Doc.Replace(startLine.Offset, replacementText.Length, replacementText);
     324        int correctionLength = secondaryText.Length + primaryDelimiter.Length;
     325        selectionStart += correctionLength;
     326        caretOffset += correctionLength;
     327      }
     328
     329      if (textArea.Selection is RectangleSelection) {
     330        textArea.ClearSelection();
     331        int lowestOffset = selectionSegments.Min(x => x.StartOffset);
     332        int highestOffset = selectionSegments.Max(x => x.EndOffset);
     333        selectionLength = highestOffset - lowestOffset;
     334        var startPosition = new TextViewPosition(Doc.GetLocation(selectionStart));
     335        var endPosition = new TextViewPosition(Doc.GetLocation(selectionStart + selectionLength));
     336        textArea.Selection = new RectangleSelection(textArea, startPosition, endPosition);
     337      } else {
     338        TextEditor.SelectionStart = selectionStart;
     339        TextEditor.SelectionLength = selectionLength;
     340      }
     341
     342      TextEditor.CaretOffset = caretOffset;
     343    }
     344
    263345    #region Compiler Errors
    264346    public void ShowCompileErrors(CompilerErrorCollection compilerErrors) {
Note: See TracChangeset for help on using the changeset viewer.