65.9K
CodeProject 正在变化。 阅读更多。
Home

Ynote Classic - 文本和源代码编辑器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (8投票s)

2014 年 7 月 29 日

GPL3

9分钟阅读

viewsIcon

41207

一款多功能开源文本编辑器和源代码编辑器,支持语法高亮、代码折叠、自动缩进等功能

引言

我开始 ynote 是为了学习 .NET Framework 的一个项目。第一个 ynote 版本什么都没有,只是一个 TextBox 控件和一些基本命令——剪切、复制等。然后我看到了 FastColoredTextBox 控件。FastColoredTextBox 控件最初包含在 v2.0 中,只支持 5 种语言。现在,它拥有一个完美的代码编辑器所能拥有的一切。另一个原因是想了解 .NET 的能力,因为我没有找到任何使用 .NET 平台编写的体面的文本编辑器(不包括 C++),所以我制作了 “Ynote Classic” —— 用 .NET 编写的文本编辑器。

特点

Ynote 拥有大量功能,使其用户友好且交互性强

  • 约 40 种语言的语法高亮、代码折叠和自动缩进
  • 多光标和多选
  • 宏录制和回放以自动化任务
  • 可通过配色方案、脚本、命令、插件和自定义快捷方式进行扩展
  • 分屏、全屏和无干扰编辑
  • 使用正则表达式进行强大的搜索和替换
  • 惊人的多窗口和单窗口环境
  • 代码片段以提高生产力
  • 文档地图和标尺

这只是一个基本功能列表,深入了解更多。

Using the Code

语法高亮

Ynote Classic 的核心是 FastColoredTextBox 控件,它用于语法高亮、自动缩进和代码折叠。FastColoredTextBox 使用样式,并借助正则表达式将它们添加到具有开始和结束位置的 TextBox 范围。

Ynote 使用其内置高亮器高亮代码,也可以使用 ynotesyntax 文件进行扩展。

颜色方案

Ynote 支持各种配色方案。

配色方案是一个扩展名为 .ynotetheme 的 XML 文档,用于设置语法高亮和控件的样式。

ynote 有两个主要标签。“Key”标签和“Style”标签。Style 标签用于设置语法高亮器的样式,Key 标签用于设置 textArea 的样式。

各种样式包括

  • 注释
  • 字符串
  • 关键字
  • 变量
  • 存储
  • 恒定
  • TagName
  • TagBracket
  • AttributeName
  • AttributeValue
  • DoctypeDeclaration
  • CSSProperty
  • CSSPropertyValue
  • CSSSelector
  • 预处理器
  • Punctuation
  • LibraryFunction
  • LibraryClass

  • 背景
  • Foreground
  • Caret
  • LineNumber
  • LineNumberPadding
  • CurrentLine
  • 选择
  • ServicesLine
  • 书签
  • FoldingIndication
  • SameWords
  • BracketStyle
  • BracketStyle2

它是如何工作的?

请参阅 YnoteThemeReader.cs

当 ynote 加载主题文件时,键值会被解析并分配给 FastColoredTextBox

请参阅 SyntaxHighlighter.cs。它有各种公共样式(来自 FastColoredTextBoxNS.Style),值被分配给这些样式,并且语法高亮器只使用该样式。例如

public void HighlightSyntax(Range r)
{
    r.tb.CommentPrefix = "#";
    r.ClearStyle(Comment, String);
    r.SetStyle(Comment, @"#.*$", RegexOptions.Multiline)
    r.SetStyle(String, @"""""|@""""|''|@"".*?""|(?<!@)(?<range>"".*?[^\\]"")|'.*?[^\\]'")
}

停靠

Ynote Classic 使用 DockPanelSuite 进行停靠,并采用 VS2012 浅色主题。

代码片段

Ynote Classic 支持从 .ynotesnippet 文件加载的代码片段。每个代码片段具有以下属性

  • TabTrigger:当用户在 {TabTrigger} 后按下 Tab 键时,将调用代码片段
  • Content:代码片段的内容
  • Scope:代码片段的范围(HTML、CSS、CSharp 等)

创建代码片段

任何人都可以创建代码片段以简化工作流程。YnoteSnippet 内容的语法是

  • ^:插入代码片段后光标的位置
  • $selection:触发代码片段时选定的文本
  • $current_line:触发代码片段时当前行的文本
  • $file_name:正在编辑的文件名
  • $file_name_extension:正在编辑的文件的名称和扩展名
  • $clipboard:剪贴板上的文本
  • $eol:行尾文字以获取当前行尾
  • $choose_file:加载 OpenFileDialog 并替换为选定的文件

编辑

Ynote 可以让您的编辑体验非常棒。一些功能包括

多光标/多选

使用 Ctrl+单击 添加另一个光标或选择并开始编辑。Ynote 目前不支持同一行上的多个光标。

垂直/列选择

使用 Alt+拖动 或 Alt+Shift+箭头键选择一个区域并开始编辑文本。

分屏编辑

分屏编辑是充分利用宽屏显示器的最佳方式。Ynote 支持带可停靠窗口的分屏编辑。您可以通过以下方式分屏编辑文件:

  • 视图 -> 分割 -> 在下方分割 - 在活动文档下方分割文档
  • 视图 -> 分割 -> 在旁边分割 - 在活动文档旁边分割文档
  • 视图 -> 分割 -> 同步滚动分割 - 同步滚动分割文档

Ynote Split Edit

Ynote 中的分屏编辑

搜索/替换

Ynote 具有强大的搜索和替换功能。它支持“查找下一个”、“查找上一个”、“在文件夹中查找”、“在项目中查找”以及带正则表达式的“增量搜索”。

它还可以使用 Alt+F+{char} 查找字符。

Ynote 增量搜索 (正则表达式)

Ynote 使用 FastColoredTextBox 的技术通过存储按下的键来录制和执行宏。

Ynote 宏以 .ynotemacro 扩展名存储在 $ynotedata\ 目录中的任何位置。

录制宏

可以通过按 Ctrl+M 并执行一些操作来录制宏。

注意:鼠标操作不被记录在宏中

使用 Ctrl+M 停止录制宏

执行宏

可以使用 Ctrl+E 播放宏。

您也可以保存宏以供以后执行。它应该保存在 $ynotedata\ 目录中,扩展名为 .ynotemacro

宏快捷方式

所以你想用快捷方式执行宏?Ynote 可以做到。在 $ynotedata 目录下创建一个名为 User.ynotekeys 的文件。

您可以逐行输入 YnoteCommands 形式的快捷方式。例如(我的 User.ynotekeys

    Ctrl+Shift+Q=Macro:AddLineBefore
    Ctrl+Shfit+M=Script:ColorPicker

您需要按照它在 Commander 中显示的方式输入命令。它可以包含任何命令。快捷方式应由换行符(\r\n)分隔。

脚本

我非常喜欢 ynote 的原因之一是脚本功能。脚本功能是通过 CSScript 库实现的。

脚本在 Ynote 中以 .ys 文件存储。在 ynote 中,脚本已被用于

  • Ynote 命令(Commander)——位于 $ynotedata\Commands 目录
  • Ynote 脚本——位于 $ynotedata\Scripts 目录
  • 运行脚本任务——位于 $ynotedata\RunScripts\Tasks
  • 上下文菜单——位于 $ynotedata\ContextMenu.ys

脚本被编译成 .ysc 文件以加快执行速度。

命令器

Ynote Commander 是一款将所有有用命令置于您指尖的工具。只需使用 Ctrl+Shift+P,Commander 就会弹出。开始输入您想要的任何内容。

使用命令器

自定义命令

Ynote 支持从 $ynotedata\Commands 目录添加自定义命令。

Ynote 命令是一个 C# 脚本,扩展名为 .ynotecommand。它包含一个带参数 IYnote 的方法 GetCommand。当被调用时,它应该返回 ICommand 接口的一个实例。

namespace SS.Ynote.Classic
{
    /// <summary>
    ///     A Ynote Command which when executed
    ///     is stored in a YnoteCommand
    /// </summary>
    public interface ICommand
    {
        /// <summary>
        ///     Command Key
        /// </summary>
        string Key { get; }

        /// <summary>
        ///     Possible Commands
        /// </summary>
        string[] Commands { get; }

        /// <summary>
        ///     Processes Command
        /// </summary>
        /// <param name="val"></param>
        /// <param name="ynote"></param>
        void ProcessCommand(string val, IYnote ynote);
    }
}
  • Key - Key 是命令的类,例如 - 在命令 SetSyntax:CSharp 中,SetSyntax 是 Key,CSharp 是值。
  • Commands - 可能的命令列表(用于自动补全)
  • ProcessCommand(string,IYnote) - 处理值为 val 的命令。

构建系统 (RunScripts)

Ynote 使用 JSON 格式的 RunScripts 作为构建系统。每个 RunScript 可以调用一个或多个 Tasks。示例 RunScript

// Run Script to Run a python file
{
  // Path of the task and arguments (task specific) from $ynotedata directory
  "RunScripts\\Tasks\\Cmd": [
    "python",
    "$source"
  ]
}

通过 Commander->Run:{runscript 名称} 运行

此 RunScript 调用存储在 $ynotedata\RunScripts\Tasks\ 目录中的任务 Cmd.runtask

您可以添加无限个任务,它们将一个接一个地被调用。

变量
  • $source - 正在编辑的活动文件
  • $source_dir - 正在编辑的活动文件的目录
  • $source_name - 正在编辑的活动文件的名称
  • $source_extension - 正在编辑的活动文件的扩展名
  • $project_dir - 当前打开项目的目录
  • $project_name - 当前打开项目的名称

自定义任务

Ynote 任务不过是一段 C# 代码。

它应该包含一个带有 string 数组作为参数的 RunTask 方法。例如

// RunScript Task to Create A Directory
using System.IO;

// Cmd Run Script Task
public void RunTask(string[] arguments)
{
    if(arguments.Length == 0)
        return;
    string dir = arguments[0];
    if(!Directory.Exists(dir))
        Directory.CreateDirectory(dir);
}

RunTasks 存储在 $ynotedata\RunScripts\Tasks 目录中,扩展名为 .runtask。您可以将其存储在任何目录中,但必须在 $ynotedata 中。

符号列表

这对我来说是一个挑战。我以为这会让我的程序变得庞大。但是,我后来想到了使用 Regular Expressions 的想法。它让我的任务变得更轻松。这就是 ynote 的工作方式。它将文本与正则表达式匹配以获取函数/类等的列表。

正则表达式是完全可定制的。位于 $ynotedata\Symbols.json

Symbols.json(预览)

{
  "CSharp": {
    "Pattern": "\\b(class|struct|enum|interface|void)\\s+(?<range>\\w+?)\\b",
    "Options": 0
  },
  "C": {
    "Pattern": "\\b(class|struct|enum|interface|void|int|bool)\\s+(?<range>\\w+?)\\b",
    "Options": 0
  },
  "CPP": {
    "Pattern": "\\b(class|struct|enum|interface|void|int|bool)\\s+(?<range>\\w+?)\\b",
    "Options": 0
  },
  "VB": {
    "Pattern": "\\b(Class|Sub|Interface)\\s+(?<range>\\w+?)\\b",
    "Options": 0nn
  },
  "D": {

按键绑定

Ynote 使用 .ynotekeys 文件存储 KeyBindings。其格式为

{Key}:{Command}

* 它们由换行符分隔。

Editor.ynotekeys

编辑器按键绑定是 FastColoredTextBox 控件的按键绑定。可以通过热键编辑器或从 $ynotedata\Editor.ynotekeys 目录打开 Editor.ynotekeys 进行编辑。

User.ynotekeys

User.ynotekeys 文件默认不存在。可以通过“工具”->“用户按键”菜单创建。它执行在 Commander 中找到的 YnoteCommands。例如:

Ctrl+Shift+K=Script:ColorPicker

当您按下 Ctrl+Shift+K 时,它会执行 ColorPicker.ys,该脚本会显示一个颜色选择器并插入所选颜色。

软件包

Ynote 包是一个包含索引文件的归档文件。它包含用于扩展 ynote 的资源文件,例如

  • 插件
  • 配色方案
  • Ynote脚本
  • 片段
  • 运行脚本
  • 运行脚本任务
  • Ynote命令
  • 语法文件
  • 上下文菜单等等。

包如何工作?

ynote 包文件是一个 zip 文件,在根目录中包含所有必需文件和一个索引文件。索引文件包含文件安装后应放置位置的信息。安装包时,第一个提取的文件是索引文件。Ynote 使用 ZipStorer 管理 zip 文件。以下代码生成一个字典,指示文件应放置的位置。

internal static IDictionary<string, string> GenerateDictionary(string manifest)
{
    IDictionary<string,string> dic = new Dictionary<string,string>();
    string[] lines = File.ReadAllLines(manifest);
    foreach (var line in lines)
    {
        var command = YnoteCommand.FromString(line);
        command.Value = command.Value.Replace("$ynotedata", GlobalSettings.SettingsDir);
        if (command.Value.IndexOf("$ynotedir") != -1)
            command.Value = command.Value.Replace("$ynotedir", Application.StartupPath);
        dic.Add(command.Key, command.Value);
    }
    return dic;
}

它使用 YnoteCommand 类来解析 string ,因为它也是 {key}:{value} 格式。

安装软件包

Ynote 内置支持通过使用 Package Manager 安装软件包。

工具->包管理器 将为您提供可用包列表。它是一键下载和安装。

您也可以从文件安装软件包。使用“从文件安装”来从文件安装软件包。

创建包

您可以使用 Package Manager 创建包。

转到“工具”->“包管理器”,选择“已安装包”选项卡,然后单击“创建包”。

选择一个输出文件并添加您想要的文件及其输出目的地

  • $ynotedata - %appdata%\Ynote Classic 或便携版中的 {install dir}\Packages
  • $ynotedir - {安装目录}\(便携版和安装版相同,用于复制所需的程序集。如果使用此选项,您应该以管理员身份安装包,因为用户可能已将 ynote 安装在 Program Files 目录中)

提交包

您可以通过在 ynotepackages 仓库中创建拉取请求来提交您的包。请参阅仓库中的 README.md 文件以获取信息。

待办事项

Ynote 必须日复一日,版本接版本地改进。我可能在下一个版本 (2.9) 中添加的一些内容如下所示

  • 改进代码片段 - 像 Textmate 的那样
  • 更好的性能和启动时间
  • 切换到 IronPython 进行脚本编写(也许)并改进 API
  • 改进多光标和多选支持
  • 可主题化的停靠面板
  • 更好的语法高亮界面
  • 改进的项目 TreeView GUI
  • 改进的设置框架
  • 改进的 Commander

外部资源

历史

  • 首次发布
  • 更新的文章 ( 2.8.5 Beta )
© . All rights reserved.