/* * Copyright (C) 2013 FooProject * * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ using System; using System.Text; using System.Text.RegularExpressions; using Slusser.Collections.Generic; namespace FooEditEngine { struct TextRange { public int start; public int length; public TextRange(int start, int length) { this.start = start; this.length = length; } } sealed class ReplaceCommand : ICommand { StringBuffer Buffer; TextRange ReplacementRange, ReplacedRange; GapBuffer replacement, replaced; //置き換え後の文字列、置き換え前の文字列 public ReplaceCommand(StringBuffer buf, int start, int length, string str) { this.Buffer = buf; this.ReplacementRange = new TextRange(start,str.Length); this.replacement = new GapBuffer(); this.replacement.AddRange(Util.GetEnumrator(str),str.Length); this.ReplacedRange = new TextRange(start,length); this.replaced = new GapBuffer(); this.replaced.AddRange(this.Buffer.GetEnumerator(start, length)); } #region ICommand メンバー public void undo() { this.Buffer.Replace(this.ReplacementRange.start, this.replacement.Count,this.replaced,this.replaced.Count); } public void redo() { this.Buffer.Replace(this.ReplacedRange.start, this.replaced.Count, this.replacement, this.replacement.Count); } public bool marge(ICommand a) { ReplaceCommand cmd = a as ReplaceCommand; if (cmd == null) return false; if (this.ReplacedRange.length == 0 && cmd.ReplacementRange.start >= this.ReplacementRange.start && cmd.ReplacementRange.start + cmd.ReplacementRange.length <= this.ReplacementRange.start + this.ReplacementRange.length) { int bufferIndex = cmd.ReplacedRange.start - this.ReplacementRange.start; this.replacement.RemoveRange(bufferIndex, cmd.ReplacedRange.length); this.replacement.InsertRange(bufferIndex, cmd.replacement, cmd.replacement.Count); return true; } if (this.ReplacedRange.start + this.ReplacementRange.length == cmd.ReplacedRange.start && this.ReplacedRange.start == this.ReplacementRange.start) { this.replaced.AddRange(cmd.replaced,cmd.replaced.Count); this.replacement.AddRange(cmd.replacement,cmd.replacement.Count); this.ReplacedRange.length += cmd.ReplacedRange.length; this.ReplacementRange.length += cmd.ReplacementRange.length; return true; } return false; } public bool isempty() { return this.replaced.Count == 0 && this.replacement.Count == 0; } #endregion } sealed class ReplaceAllCommand : ICommand { StringBuffer buffer; Regex regex; StringBuffer oldBuffer; string replacePattern; bool groupReplace; public ReplaceAllCommand(StringBuffer buffer, Regex regex, string replacePattern,bool groupReplace) { this.buffer = buffer; this.regex = regex; this.replacePattern = replacePattern; this.groupReplace = groupReplace; } public void undo() { this.buffer.Clear(); this.buffer.Replace(0, 0, this.oldBuffer,this.oldBuffer.Length); } public void redo() { this.oldBuffer = new StringBuffer(this.buffer); GapBuffer result = new GapBuffer(); foreach (string line in this.buffer.GetLines(0, this.buffer.Length - 1)) { string output = this.regex.Replace(line, (m) =>{ if (this.groupReplace) return m.Result(this.replacePattern); else return this.replacePattern; }); result.AddRange(Util.GetEnumrator(output),output.Length); } this.buffer.Clear(); this.buffer.Replace(0, 0, result,result.Count); } public bool marge(ICommand a) { return false; } public bool isempty() { return false; } } }