public void RemoveRangeCommand_RemoveLines()
        {
            RemoveRangeCommand command = new RemoveRangeCommand(3, 5);
            command.Execute(this.document);
            List<string> expected = new List<string>()
            { "helrld", "", "123" };
            string expectedString = string.Join("\n", expected);
            Assert.AreEqual(expectedString, this.document.Text);
            command.Undo();
            Assert.AreEqual(this.initialDocument.Text, this.document.Text);

            command = new RemoveRangeCommand(0, this.document.Text.Length);
            command.Execute(this.document);
            Assert.AreEqual("", this.document.Text);
            command.Undo();
            Assert.AreEqual(this.initialDocument.Text, this.document.Text);

            command = new RemoveRangeCommand(12, 4);
            command.Execute(this.document);
            expected = new List<string>()
            { "hello", "world", "" };
            expectedString = string.Join("\n", expected);
            Assert.AreEqual(expectedString, this.document.Text);
            command.Undo();
            Assert.AreEqual(this.initialDocument.Text, this.document.Text);

            command = new RemoveRangeCommand(11, 5);
            command.Execute(this.document);
            expected = new List<string>()
            { "hello", "world" };
            expectedString = string.Join("\n", expected);
            Assert.AreEqual(expectedString, this.document.Text);
            command.Undo();
            Assert.AreEqual(this.initialDocument.Text, this.document.Text);
        }
        public void RemoveRangeCommand_RemoveCharacter()
        {
            RemoveRangeCommand command = new RemoveRangeCommand(0, 1);
            command.Execute(this.document);
            Assert.AreEqual("ello", this.document.Lines[0]);
            command.Undo();
            Assert.AreEqual(this.initialDocument.Text, this.document.Text);

            command = new RemoveRangeCommand(4, 1);
            command.Execute(this.document);
            Assert.AreEqual("hell", this.document.Lines[0]);
            command.Undo();
            Assert.AreEqual(this.initialDocument.Text, this.document.Text);

            command = new RemoveRangeCommand(5, 1);
            command.Execute(this.document);
            Assert.AreEqual("helloworld", this.document.Lines[0]);
            command.Undo();
            Assert.AreEqual(this.initialDocument.Text, this.document.Text);

            command = new RemoveRangeCommand(11, 1);
            command.Execute(this.document);
            Assert.AreEqual(3, this.document.Lines.Count);
            Assert.AreEqual("hello\nworld\n123", this.document.Text);
            command.Undo();
            Assert.AreEqual(this.initialDocument.Text, this.document.Text);

            command = new RemoveRangeCommand(12, 1);
            command.Execute(this.document);
            Assert.AreEqual(3, this.document.Lines.Count);
            Assert.AreEqual("hello\nworld\n123", this.document.Text);
            command.Undo();
            Assert.AreEqual(this.initialDocument.Text, this.document.Text);

            command = new RemoveRangeCommand(this.document.Text.Length, 1);
            command.Execute(this.document);
            Assert.AreEqual(this.initialDocument.Text, this.document.Text);
            command.Undo();
            Assert.AreEqual(this.initialDocument.Text, this.document.Text);
        }
        /// <summary>
        /// Executes command.
        /// </summary>
        /// <param name="document">Document to run command.</param>
        public void Execute(ITextEditorDocument document)
        {
            if (document == null)
            {
                return;
            }

            this.line = document.LineNumberByIndex(this.caretIndex);
            this.position = document.CaretPositionInLineByIndex(this.caretIndex);

            string paragrapgh = document.AllLines[this.line];
            int paragraphIndex = this.position;
            int length = 0;
            while (paragraphIndex < paragrapgh.Length && paragrapgh[paragraphIndex] == this.snippet.Name[length])
            {
                paragraphIndex++;
                length++;
            }

            this.removeCommand = new RemoveRangeCommand(this.caretIndex, length);
            this.removeCommand.Execute(document);
            this.insertCommand = new InsertLinesCommand(this.snippet.Content, this.caretIndex);
            this.insertCommand.Execute(document);
        }
        /// <summary>
        /// Handles KeyDown.
        /// </summary>
        /// <param name="e">Key event arguments.</param>
        protected override void OnPreviewKeyDown(KeyEventArgs e)
        {
            if (e == null)
            {
                return;
            }
            else if (this.Document == null)
            {
                e.Handled = true;
                return;
            }

            char pressedChar = e.Key.GetChar();

            // CTRL + Z
            if (e.Key == Key.Z && Keyboard.Modifiers == ModifierKeys.Control)
            {
                this.lastCarretIndex = this.CaretIndex - this.document.CaretPositionInLineByIndex(this.CaretIndex);
                this.commandManager.Undo();
                this.UpdateUi();
                e.Handled = true;
            }

            // Backspace
            else if (e.Key == Key.Back)
            {
                RemoveRangeCommand removeCommand;
                if (this.SelectionLength > 0)
                {
                    this.lastCarretIndex = this.SelectionStart;
                    removeCommand = new RemoveRangeCommand(this.SelectionStart, this.SelectionLength);
                }
                else
                {
                    if (this.CaretIndex == 0)
                    {
                        return;
                    }

                    this.lastCarretIndex = this.CaretIndex - 1;
                    removeCommand = new RemoveRangeCommand(this.CaretIndex - 1, 1);
                }

                this.RunCommand(removeCommand);
                e.Handled = true;
            }

            // Tab
            else if (e.Key == Key.Tab)
            {
                this.lastCarretIndex = this.CaretIndex + 2;
                InsertStringCommand insertCommand = new InsertStringCommand("  ", this.CaretIndex);
                this.RunCommand(insertCommand);

                e.Handled = true;
            }

            // Enter
            else if (e.Key == Key.Return)
            {
                int line = this.document.LineNumberByIndex(this.CaretIndex);

                if (line == -1)
                {
                    line = 0;
                    this.document.AddLine(string.Empty);
                }

                string paragraph = this.document.AllLines[line];
                int spaceCount = 0;
                while (spaceCount < paragraph.Length && paragraph[spaceCount] == ' ')
                {
                    spaceCount++;
                }

                NewLineCommand newLineCommand = new NewLineCommand(spaceCount, this.CaretIndex);
                this.lastCarretIndex = this.CaretIndex + 1 + spaceCount;
                this.RunCommand(newLineCommand);
                e.Handled = true;
            }

            // Ctrl+V
            else if (e.Key == Key.V && Keyboard.Modifiers == ModifierKeys.Control)
            {
                string clipboardText = Clipboard.GetText();
                List<string> clipboardLines = clipboardText.Split('\n').Select(l => l.Replace("\r", string.Empty)).ToList();
                this.lastCarretIndex += clipboardText.Length;

                InsertLinesCommand command = new InsertLinesCommand(clipboardLines, this.CaretIndex);
                this.RunCommand(command);
            }

            // Some symbol
            else if ((!char.IsControl(pressedChar) && !pressedChar.Equals(' ')) || e.Key == Key.Space)
            {
                this.lastCarretIndex = this.CaretIndex + 1;
                InsertStringCommand insertCommand = new InsertStringCommand(e.Key.GetChar().ToString(), this.CaretIndex);
                this.RunCommand(insertCommand);

                // Autocompletion analyzing
                string currentWord = this.document.GetWordByCaretIndex(this.CaretIndex);

                List<string> snippetsNames = SnippetLibrary.Names.Where(s => s.StartsWith(currentWord)).ToList();
                if (snippetsNames.Count > 0)
                {
                    this.OnLibraryWordEntered(
                        new LibraryWordEnteredEventArgs(snippetsNames, this.GetRectFromCharacterIndex(this.CaretIndex)));
                }

                e.Handled = true;
            }

            base.OnPreviewKeyDown(e);
        }
 public void RemoveRangeCommand_RemoveCharacter_InvalidCaretIndex()
 {
     RemoveRangeCommand command = new RemoveRangeCommand(this.document.Text.Length + 1, 1);
     command.Execute(this.document);
 }