1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/lunarsf-Lunar-Markdown-Editor

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Это зеркальный репозиторий, синхронизируется ежедневно с исходного репозитория.
Клонировать/Скачать
TextCommandManager.cs 24 КБ
Копировать Редактировать Исходные данные Просмотреть построчно История
LunarSF Отправлено 8 лет назад 9fcd9c8
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Input;
namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor
{
public class TextCommandManager : List<TextCommandItem>
{
private static TextCommandManager cmds;
/// <summary>
/// 整个程序应处理的文本命令都应在此类中注册。
/// </summary>
public static TextCommandManager TextCommands
{
get { return cmds; }
}
public static string inputedCommandText = "";
/// <summary>
/// 指用户连续输入的字符构成的命令。一条命令可能通过多次输入实现。
/// </summary>
public static string InputedCommandText
{
get { return inputedCommandText; }
set
{
inputedCommandText = value;
Globals.MainWindow.tbTextCommand.Text = value;
}
}
public static string TryToRun(string previewcmdText, string cmdText, out List<TextCommandItem> matchedTextCommandItems)
{
matchedTextCommandItems = new List<TextCommandItem>();
var items = GetMatchedTextCommands(previewcmdText + cmdText);
if (items.Count == 1)
{
matchedTextCommandItems.Add(items[0]);
var result = items[0].Run(items[0]);
if (result)
{
InputedCommandText = "";
return "完成";//这个不能修改
}
else
{
//inputedCommandText不变
return "未能执行命令。";
}
}
if (items.Count < 1)
{
return "无此命令。";
}
matchedTextCommandItems.AddRange(items);
InputedCommandText += cmdText;
return "等待继续输入..."; //有多个符合条件的命令。
}
public static List<TextCommandItem> GetMatchedTextCommands(string cmdText)
{
List<TextCommandItem> items = new List<TextCommandItem>();
foreach (var item in cmds)
{
switch (item.Type)
{
case TextCommandType.NormalText: //纯文本命令
{
if (item.CommandText.StartsWith(cmdText))
items.Add(item);
break;
}
case TextCommandType.RegexText: //使用正则表达式的命令
{
Regex regex = new Regex(item.CommandText);
var match = regex.Match(cmdText);
if (match.Success) items.Add(item);
break;
}
}
}
return items;
}
static TextCommandManager()
{
cmds = new TextCommandManager();
cmds.Add(new TextCommandItem("i", TextCommandType.NormalText, "在当前字符前面插入字符。") { Run = InsertBefore, });
cmds.Add(new TextCommandItem("a", TextCommandType.NormalText, "在当前字符后面插入字符。") { Run = InsertAfter, });
cmds.Add(new TextCommandItem("h", TextCommandType.NormalText, "向左移动光标。") { Run = MoveLeft, });
cmds.Add(new TextCommandItem("j", TextCommandType.NormalText, "向下移动光标。") { Run = MoveDown, });
cmds.Add(new TextCommandItem("k", TextCommandType.NormalText, "向上移动光标。") { Run = MoveUp, });
cmds.Add(new TextCommandItem("l", TextCommandType.NormalText, "向右移动光标。") { Run = MoveRight, });
//高频快捷键不能安排双字符或更多字符的按键。例如:不应安排la lb 这样的快捷键组合,因为会造成 l 键须等待进一步选择。
cmds.Add(new TextCommandItem("w", TextCommandType.NormalText, "移动光标到下一个词。") { Run = MoveNextWord, });
cmds.Add(new TextCommandItem("b", TextCommandType.NormalText, "移动光标到上一个词。") { Run = MovePreviewWord, });
cmds.Add(new TextCommandItem("d", TextCommandType.NormalText, "剪切。") { Run = Cut, });
cmds.Add(new TextCommandItem("y", TextCommandType.NormalText, "复制。") { Run = Copy, });
cmds.Add(new TextCommandItem("p", TextCommandType.NormalText, "粘贴。") { Run = Paste, });
cmds.Add(new TextCommandItem("pp", TextCommandType.NormalText, "粘贴。") { Run = Paste, });
//单独输入一个p要等等或按回车,若直接输入两个p应该是极好的。
cmds.Add(new TextCommandItem("u", TextCommandType.NormalText, "撤销。") { Run = Undo, });
cmds.Add(new TextCommandItem("x", TextCommandType.NormalText, "删除当前字符。") { Run = Delete, });
cmds.Add(new TextCommandItem("o", TextCommandType.NormalText, "新插入一行,并在新行头部进入编辑模式。") { Run = InsertNewLine, });
//注意:所有的大写母快捷键组合都必须在小写字母之下,因为涉及顺序。
cmds.Add(new TextCommandItem("A", TextCommandType.NormalText, "在行尾插入。") { Run =AppandAtLineEnd, });
cmds.Add(new TextCommandItem("I", TextCommandType.NormalText, "在行首插入。") { Run = AppandAtLineHeader, });
//合并行
cmds.Add(new TextCommandItem("J", TextCommandType.NormalText, "合并行。") { Run = JoinLines, });
cmds.Add(new TextCommandItem("O", TextCommandType.NormalText, "在当前行上侧新插入一行,并在新行头部进入编辑模式。") { Run = InsertNewLineAtTop, });
//注意:所有的双字母快捷键组合都必须在单字母之下,因为涉及顺序。
cmds.Add(new TextCommandItem("dd", TextCommandType.NormalText, "删除当前行。") { Run = DeleteLine, });
cmds.Add(new TextCommandItem("rh", TextCommandType.NormalText, "移动到当前行行首。") { Run = MoveToLineStart, });
cmds.Add(new TextCommandItem("re", TextCommandType.NormalText, "移动到当前行行尾。") { Run = MoveToLineEnd, });
cmds.Add(new TextCommandItem("pf", TextCommandType.NormalText, "向下翻页。") { Run = PageDown, });
cmds.Add(new TextCommandItem("pb", TextCommandType.NormalText, "向上翻页。") { Run = PageUp, });
cmds.Add(new TextCommandItem("pu", TextCommandType.NormalText, "向上翻半页。") { Run = PageUpHalf, });
cmds.Add(new TextCommandItem("pd", TextCommandType.NormalText, "向下翻半页。") { Run = PageDownHalf, });
//添加[Step]标签
cmds.Add(new TextCommandItem("ss", TextCommandType.NormalText, "在行首添加 [Step] 标记") { Run = AddStepMark, });
cmds.Add(new TextCommandItem("sb", TextCommandType.NormalText, "在行首添加 [Step Begin] 标记") { Run = AddStepStartMark, });
cmds.Add(new TextCommandItem("se", TextCommandType.NormalText, "在行首添加 [Step End] 标记") { Run = AddStepEndMark, });
}
/// <summary>
/// 在当前行首进入编辑模式。
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
static bool AppandAtLineHeader(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
ae.EditingMode = EditingMode.NormalMode;
ae.EditingMode = EditingMode.NormalMode;
var line = ae.EditorBase.Document.GetLineByOffset(ae.EditorBase.SelectionStart);
ae.EditorBase.Select(line.Offset, 0);
if (ae.PreviewInputMethodState.HasValue)
{
Globals.SwitchInputMethod(true);
InputMethod.Current.ImeState = ae.PreviewInputMethodState.Value;
}
return true;
}
/// <summary>
/// 在当前行尾进入编辑模式。
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
static bool AppandAtLineEnd(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
ae.EditingMode = EditingMode.NormalMode;
var line = ae.EditorBase.Document.GetLineByOffset(ae.EditorBase.SelectionStart+ae.EditorBase.SelectionLength);
ae.EditorBase.Select(line.EndOffset, 0);
if (ae.PreviewInputMethodState.HasValue)
{
Globals.SwitchInputMethod(true);
InputMethod.Current.ImeState = ae.PreviewInputMethodState.Value;
}
return true;
}
public static bool AddStepStartMark(TextCommandItem item)
{
return AddStepMark("[Step Begin] ");
}
public static bool AddStepEndMark(TextCommandItem item)
{
return AddStepMark("[Step End] ");
}
public static bool AddStepMark(TextCommandItem item)
{
return AddStepMark("[Step] ");
}
private static bool AddStepMark(string stepText)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
var fstLine = ae.EditorBase.Document.GetLineByOffset(ae.EditorBase.SelectionStart);
var lstLine = ae.EditorBase.Document.GetLineByOffset(ae.EditorBase.SelectionStart + ae.EditorBase.SelectionLength);
Regex regexStepLine = new Regex(@"^[  ]{0,3}\[[  ]{0,}[sSsS]([tTtT][eEeE][pPpP]){0,1}[  ]{0,}(([bBbB]([eEeE][gGgG][iIiI][nNnN]){0,1})|([eEeE]([nNnN][dDdD]){0,1})){0,1}\][  ]{0,}");
ae.EditorBase.BeginChange();
for (int i = fstLine.LineNumber; i <= lstLine.LineNumber; i++)
{
var line = ae.EditorBase.Document.GetLineByNumber(i);
if (line == null) continue;
var lineText = ae.EditorBase.Document.GetText(line.Offset, line.Length);
var match = regexStepLine.Match(lineText);
if (match.Success)
{
ae.EditorBase.Document.Replace(line.Offset, line.Length, stepText + lineText.Substring(match.Length));
}
else
{
ae.EditorBase.Document.Replace(line.Offset, line.Length, stepText + lineText);
}
}
ae.EditorBase.EndChange();
return true;
}
public static bool JoinLines(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
var e = ae.EditorBase;
var fstLine = e.Document.GetLineByOffset(e.SelectionStart);
var lstLine = e.Document.GetLineByOffset(e.SelectionStart + e.SelectionLength);
if (fstLine.LineNumber == lstLine.LineNumber)
{
e.Document.Remove(e.Document.GetLineByOffset(e.SelectionStart).EndOffset, 2);
return true;
}
else if (fstLine.LineNumber < lstLine.LineNumber)
{
e.BeginChange();
var selStartOffset = e.SelectionStart;
var selLength = e.SelectionLength;
var srcText = e.SelectedText;
srcText = srcText.Replace("\r", "").Replace("\n", "");
e.Document.Replace(selStartOffset, selLength, srcText);
e.EndChange();
return true;
}
return true;
}
public static bool Cut(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
ae.EditorBase.Cut();
return true;
}
public static bool Copy(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
ae.EditorBase.Copy();
return true;
}
public static bool Paste(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
ae.EditorBase.BeginChange();
ae.EditorBase.Document.Replace(ae.EditorBase.SelectionStart, ae.EditorBase.SelectionLength, Clipboard.GetText(TextDataFormat.UnicodeText));
ae.EditorBase.EndChange();
return true;
}
public static bool Delete(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
ae.EditorBase.Document.Remove(ae.EditorBase.SelectionStart, ae.EditorBase.SelectionLength);
return true;
}
public static bool DeleteLine(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
var fstLine = ae.EditorBase.Document.GetLineByOffset(ae.EditorBase.SelectionStart);
var endLine = ae.EditorBase.Document.GetLineByOffset(ae.EditorBase.SelectionStart + ae.EditorBase.SelectionLength);
ae.EditorBase.BeginChange();
for (int i = endLine.LineNumber; i >= fstLine.LineNumber; i--)
{
ae.EditorBase.Document.Remove(ae.EditorBase.Document.GetLineByNumber(i));
}
ae.EditorBase.EndChange();
return true;
}
public static bool Undo(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
if (ae.EditorBase.CanRedo) ae.EditorBase.Undo();
return true;
}
/// <summary>
/// 在当前行的上侧另起一个新行,并在新行头部进入编辑模式。
/// </summary>
/// <returns></returns>
public static bool InsertNewLineAtTop(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
var lineOffset = ae.EditorBase.Document.GetLineByOffset(ae.EditorBase.SelectionStart).Offset;
ae.EditorBase.BeginChange();
ae.EditorBase.Document.Insert(lineOffset, "\r\n");
ae.EditorBase.EndChange();
ae.EditorBase.Select(lineOffset, 0);
ae.EditingMode = EditingMode.NormalMode;
if (ae.PreviewInputMethodState.HasValue)
{
Globals.SwitchInputMethod(true);
InputMethod.Current.ImeState = ae.PreviewInputMethodState.Value;
}
return true;
}
/// <summary>
/// 在当前行下面另起一行,并在新行首进入编辑模式。
/// </summary>
/// <returns></returns>
public static bool InsertNewLine(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
var lineEndOffset = ae.EditorBase.Document.GetLineByOffset(ae.EditorBase.SelectionStart).EndOffset;
ae.EditorBase.BeginChange();
ae.EditorBase.Document.Insert(lineEndOffset, "\r\n");
ae.EditorBase.EndChange();
ae.EditorBase.Select(lineEndOffset + 2, 0);
ae.EditingMode = EditingMode.NormalMode;
if (ae.PreviewInputMethodState.HasValue)
{
Globals.SwitchInputMethod(true);
InputMethod.Current.ImeState = ae.PreviewInputMethodState.Value;
}
return true;
}
/// <summary>
/// 在当前字符后面进入编辑模式。
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
static bool InsertAfter(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
ae.EditorBase.Select(ae.EditorBase.SelectionStart + 1, 0);
ae.EditingMode = EditingMode.NormalMode;
if (ae.PreviewInputMethodState.HasValue)
{
Globals.SwitchInputMethod(true);
InputMethod.Current.ImeState = ae.PreviewInputMethodState.Value;
}
return true;
}
/// <summary>
/// 在当前字符前面进入编辑模式。
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
static bool InsertBefore(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
ae.EditingMode = EditingMode.NormalMode;
if (ae.PreviewInputMethodState.HasValue)
{
Globals.SwitchInputMethod(true);
InputMethod.Current.ImeState = ae.PreviewInputMethodState.Value;
}
return true;
}
/// <summary>
/// 向左移动光标。
/// </summary>
static bool MoveLeft(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
if (ae.EditorBase.SelectionLength > 0)
{
var selStartOffset = ae.EditorBase.SelectionStart;
ae.EditorBase.Select(selStartOffset, 0);
}
ae.EditorBase.MoveCaret(ICSharpCode.AvalonEdit.Editing.CaretMovementType.CharLeft);
return true;
}
/// <summary>
/// 向右移动光标。
/// </summary>
static bool MoveRight(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
var selStartOffset = ae.EditorBase.SelectionStart;
if (ae.EditorBase.SelectionLength > 0)
{
ae.EditorBase.Select(selStartOffset, 0);
}
//要注意不能选中最后一个位置
if (selStartOffset < ae.EditorBase.Document.TextLength - 1)
{
ae.EditorBase.MoveCaret(ICSharpCode.AvalonEdit.Editing.CaretMovementType.CharRight);
}
return true;
}
/// <summary>
/// 向上移动光标。
/// </summary>
static bool MoveUp(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
if (ae.EditorBase.SelectionLength > 0)
{
var selStartOffset = ae.EditorBase.SelectionStart;
ae.EditorBase.Select(selStartOffset, 0);
}
ae.EditorBase.MoveCaret(ICSharpCode.AvalonEdit.Editing.CaretMovementType.LineUp);
return true;
}
/// <summary>
/// 向下移动光标。
/// </summary>
static bool MoveDown(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
if (ae.EditorBase.SelectionLength > 0)
{
var selStartOffset = ae.EditorBase.SelectionStart;
ae.EditorBase.Select(selStartOffset, 0);
}
ae.EditorBase.MoveCaret(ICSharpCode.AvalonEdit.Editing.CaretMovementType.LineDown);
return true;
}
/// <summary>
/// 光标移动到行首。
/// </summary>
static bool MoveToLineStart(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
if (ae.EditorBase.SelectionLength > 0)
{
var selStartOffset = ae.EditorBase.SelectionStart;
ae.EditorBase.Select(selStartOffset, 0);
}
ae.EditorBase.MoveCaret(ICSharpCode.AvalonEdit.Editing.CaretMovementType.LineStart);
return true;
}
/// <summary>
/// 光标移动到行尾。
/// </summary>
static bool MoveToLineEnd(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
if (ae.EditorBase.SelectionLength > 0)
{
var selStartOffset = ae.EditorBase.SelectionStart;
ae.EditorBase.Select(selStartOffset, 0);
}
ae.EditorBase.MoveCaret(ICSharpCode.AvalonEdit.Editing.CaretMovementType.LineEnd);
return true;
}
/// <summary>
/// 光标移动到下一个词。
/// </summary>
static bool MoveNextWord(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
if (ae.EditorBase.SelectionLength > 0)
{
var selStartOffset = ae.EditorBase.SelectionStart;
ae.EditorBase.Select(selStartOffset, 0);
}
ae.EditorBase.MoveCaret(ICSharpCode.AvalonEdit.Editing.CaretMovementType.WordRight);
return true;
}
/// <summary>
/// 光标移动到上一个词。
/// </summary>
static bool MovePreviewWord(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
if (ae.EditorBase.SelectionLength > 0)
{
var selStartOffset = ae.EditorBase.SelectionStart;
ae.EditorBase.Select(selStartOffset, 0);
}
ae.EditorBase.MoveCaret(ICSharpCode.AvalonEdit.Editing.CaretMovementType.WordLeft);
return true;
}
/// <summary>
/// 向下翻页。
/// </summary>
static bool PageDown(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
if (ae.EditorBase.SelectionLength > 0)
{
var selStartOffset = ae.EditorBase.SelectionStart;
ae.EditorBase.Select(selStartOffset, 0);
}
ae.EditorBase.MoveCaret(ICSharpCode.AvalonEdit.Editing.CaretMovementType.PageDown);
return true;
}
/// <summary>
/// 向上翻页。
/// </summary>
static bool PageUp(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
if (ae.EditorBase.SelectionLength > 0)
{
var selStartOffset = ae.EditorBase.SelectionStart;
ae.EditorBase.Select(selStartOffset, 0);
}
ae.EditorBase.MoveCaret(ICSharpCode.AvalonEdit.Editing.CaretMovementType.PageUp);
return true;
}
/// <summary>
/// 向上翻半页。
/// </summary>
static bool PageUpHalf(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
if (ae.EditorBase.SelectionLength > 0)
{
var selStartOffset = ae.EditorBase.SelectionStart;
ae.EditorBase.Select(selStartOffset, 0);
}
ae.EditorBase.MoveCaret(ICSharpCode.AvalonEdit.Editing.CaretMovementType.PageUpHalf);
return true;
}
/// <summary>
/// 向下翻半页。
/// </summary>
static bool PageDownHalf(TextCommandItem item)
{
var ae = Globals.MainWindow.ActivedEditor;
if (ae == null) return false;
if (ae.EditorBase.SelectionLength > 0)
{
var selStartOffset = ae.EditorBase.SelectionStart;
ae.EditorBase.Select(selStartOffset, 0);
}
ae.EditorBase.MoveCaret(ICSharpCode.AvalonEdit.Editing.CaretMovementType.PageDownHalf);
return true;
}
}
}

Комментарий ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://gitlife.ru/oschina-mirror/lunarsf-Lunar-Markdown-Editor.git
git@gitlife.ru:oschina-mirror/lunarsf-Lunar-Markdown-Editor.git
oschina-mirror
lunarsf-Lunar-Markdown-Editor
lunarsf-Lunar-Markdown-Editor
v0.4-beta8