Introduction
I started ynote as a project to learn the .NET Framework. The first ynote version consisted of nothing, just a TextBox
control and some basic commands - Cut, Copy, etc. Then I saw the FastColoredTextBox
control. The FastColoredTextBox
control was first included in v2.0, supporting only 5 languages. Now, it has just everything a perfect code editor can have. Another reason was to know the capabilities of .NET because I didn't find any decent Text Editor written using the .NET Platform (not including C++) So I mae "Ynote Classic" - The Text Editor, coded with .NET.
Features
Ynote has a huge list of features which make it user friendly and interactive:
- Syntax Highlighting, Code Folding and Auto Indentation for about 40 languages
- Multiple Carets and Selections
- Macro Recording and Playback to automate task
- Extensible with Color Schemes, Scripts, Commands, Plugins and Custom Shortcuts
- Split Screen, Full Screen and Distraction Free Editing
- Powerful Search and Replace using Regular Expressions
- Amazing Multi and Single Window Environment
- Code Snippets to improve productivity
- Document Map and Ruler
This is just a basic list of features, dig into it to learn more.
Using the Code
Syntax Highlighting
The heart of Ynote Classic is the FastColoredTextBox control which is used for Syntax Highlight, Auto Indentation and Code Folding. FastColoredTextBox uses Styles and adds them with the help of Regular Expressions to a TextBox range, which has a Start and End Place.
Ynote Highlight's code using its inbuilt highlighter can also be extended using ynotesyntax files.
Color Schemes
Ynote has support for various color schemes.
A color scheme is an XML document with the extension .ynotetheme which is used to style the syntax highlighting and the control.
A ynote has 2 main tags. The "Key
" tag and the "Style
" tag. Style
tag is used to style the Syntax Highlighter and the Key
tag is used to style the textArea
.
The various styles are:
Comment
String
Keyword
Variable
Storage
Constant
TagName
TagBracket
AttributeName
AttributeValue
DoctypeDeclaration
CSSProperty
CSSPropertyValue
CSSSelector
Preprocessor
Punctuation
LibraryFunction
LibraryClass
The keys:
Background
Foreground
Caret
LineNumber
LineNumberPadding
CurrentLine
Selection
ServicesLine
Bookmark
FoldingIndication
SameWords
BracketStyle
BracketStyle2
How Does It Work?
See YnoteThemeReader.cs.
When ynote loads a theme file, the key values are parsed and assigned to the FastColoredTextBox
.
See SyntaxHighlighter.cs. It has various public styles (from FastColoredTextBoxNS.Style
) to which the values are assigned and the Syntax Highlighter uses that Style only. Like:
public void HighlightSyntax(Range r)
{
r.tb.CommentPrefix = "#";
r.ClearStyle(Comment, String);
r.SetStyle(Comment, @"#.*$", RegexOptions.Multiline)
r.SetStyle(String, @"""""|@""""|''|@"".*?""|(?<!@)(?<range>"".*?[^\\]"")|'.*?[^\\]'")
}
Docking
Ynote Classic uses the DockPanelSuite
for Docking with the VS2012 light theme.
Snippets
Ynote Classic has support for snippets which are loaded from a .ynotesnippet file. Each snippet has the following properties:
TabTrigger
: Snippet will be called when the user presses tab after {TabTrigger}
Content
: The content of the Snippet Scope
: The Scope of the Snippet (HTML, CSS, CSharp etc.)
Creating Snippets
Anyone can create a snippet for easy workflow. The syntax of a YnoteSnippet Content is:
^
: The Position of the Caret after inserting the Snippet $selection
: The Selected Text when the snippet was triggered $current_line
: The Text on current line when the snippet was triggered $file_name
: The name of the file being edited $file_name_extension
: The name of the file being edited with extension $clipboard
: The text on the Clipboard $eol
: Line Ending literal to get the current line ending $choose_file
: Loads an OpenFileDialog
and replaces with the chosen file
Editing
Ynote can make editing a great experience for you. Some features include:
Multiple Carets/Selections
Use Ctrl+Click to add another caret or selection and start editing. Ynote does not support multiple carets on the same line for now.
Vertical/Column Selection
Use Alt+Drag or Alt+Shift+Arrow Keys to select an area and start editing text.
Split Editing
Split Editing is the best way to make use of your wide-screen monitor. Ynote supports Split Editing with Dockable Windows. You can split-edit a file by -
- View -> Split -> Split Below - Splits the document below the active document
- View -> Split -> Split Beside - Splits the document beside the active document
- View -> Split -> Split Synchronized Scroll - Splits the document synchronizing the scrolling
Split Editing in Ynote
Search/Replace
Ynote has powerful search and replace capabilities. It supports "Find Next", "Find Previous", "Find In Folder", "Find in Project", and "Incremental Search" with regular expressions.
It can also find a character using Alt+F+{char}.
Ynote Incremental Search ( Regex )
Macros
Ynote uses FastColoredTextBox
's technique for recording and executing macros by storing the Key's Pressed.
A Ynote Macro is stored with .ynotemacro extension anywhere in the $ynotedata\ directory.
Recording a Macro
A Macro can be recorded by pressing Ctrl+M and performing some actions.
NOTE: Mouse Actions are not recorded in macros
Use Ctrl+M to Stop Recording Macro
Executing a Macro
Use can playback a macro using Ctrl+E.
You can also save the macro for execution later. It should be saved in the $ynotedata\
directory with the extension .ynotemacro.
Macro Shortcuts
So you want a shortcut to execute a macro? Ynote can do that. Create a file named User.ynotekeys in $ynotedata
directory.
You can type shortcuts in the form of YnoteCommands
Line-By-Line. Example (my User.ynotekeys
):
Ctrl+Shift+Q=Macro:AddLineBefore
Ctrl+Shfit+M=Script:ColorPicker
You need to enter the command as it appears in the Commander. It can contain any Command. The Shortcuts should be separated by a newline(\r\n
).
Scripting
Why I like ynote a lot is due to Scripting. Scripting has been possible using the CSScript library.
Scripts are stored in Ynote as .ys files. In ynote, Scripting has been used in:
- Ynote Commands (Commander) - in $ynotedata\Commands Directory
- Ynote Scripts - in $ynotedata\Scripts Directory
- RunScripts Tasks - in $ynotedata\RunScripts\Tasks
- Context Menu - in $ynotedata\ContextMenu.ys
Scripts are compiled to a .ysc file for faster execution.
The Commander
Ynote Commander is a tool which keeps all the useful commands at your finger tips. Just use Ctrl+Shift+P
and Commander will popup. Begin typing anything you want.
Using the Commander
Custom Commands
Ynote Supports adding custom commands from $ynotedata\Commands Directory.
A Ynote Command is a C# Script with the .ynotecommand extension. It contains a method GetCommand
with a parameter IYnote
. When called, it should return an instance of the ICommand
interface.
namespace SS.Ynote.Classic
{
public interface ICommand
{
string Key { get; }
string[] Commands { get; }
void ProcessCommand(string val, IYnote ynote);
}
}
Key
- The Key is the Class of the Command e.g., - In the Command SetSyntax:CSharp
, SetSyntax
is the Key and CSharp is the value. Commands
- List of Possible Commands (Used for Autocompletion) ProcessCommand(string,IYnote)
- Processes the Command with the Value val
.
Build System (RunScripts)
Ynote uses RunScripts which are in JSON format as Build Systems. Each RunScript
can invoke one or more Tasks
. Example RunScript:
{
"RunScripts\\Tasks\\Cmd": [
"python",
"$source"
]
}
Run Using Commander->Run:{runscript name}
This RunScript Invokes the Task Cmd.runtask
stored in $ynotedata\RunScripts\Tasks\ directory.
You can add unlimited tasks one after the another and they will invoke one by one.
Variables
$source
- The Active File being edited $source_dir
- The Directory of the Active File being edited $source_name
- The Name of the Active File being edited $source_extension
- The Extension of Active File being edited $project_dir
- The Directory of the currently Open Project $project_name
- The Name of the currently Open Project
Custom Tasks
A Ynote Task is nothing other than just a piece of C# code.
It should contain the RunTask
method with a string
array as arguments. Example:
using System.IO;
public void RunTask(string[] arguments)
{
if(arguments.Length == 0)
return;
string dir = arguments[0];
if(!Directory.Exists(dir))
Directory.CreateDirectory(dir);
}
RunTasks are stored in the $ynotedata\RunScripts\Tasks directory with the .runtask extension. You can store it in any directory but in $ynotedata.
Symbol List
This was a challenge for me. I thought it would make my program huge. But then, I thought about the idea to use Regular Expressions
. It made my task easier. This is what ynote does. It matches text with regexes to get list of functions/classes, etc.
The Regexes are fully customizable. Located in $ynotedata
\Symbols.json.
Symbols.json (preview)
{
"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": {
Key Bindings
Ynote uses .ynotekeys files for storing KeyBindings
. Its format is:
{Key}:{Command}
* They are separated by a newline character.
Editor.ynotekeys
The Editor keybindings are the keybindings of the FastColoredTextBox
control. It can be edited using the HotKeys Editor or opening Editor.ynotekeys
from $ynotedata\Editor.ynotekeys directory.
User.ynotekeys
The User.ynotekeys file does not exist by default. It can be created using the Tools->User Keys menu. It executes YnoteCommands
found in the Commander. e.g.:
Ctrl+Shift+K=Script:ColorPicker
When you press Ctrl+Shift+K, it executes ColorPicker.ys, which shows a color picker and inserts the color selected.
Packages
A Ynote Package is an archive with an index file. It contains resource files for extending ynote like:
- Plugin
- Color Scheme
- YnoteScript
- Snippet
- RunScript
- RunScript Task
- YnoteCommand
- Syntax File
- Macros
- ContextMenu and much more..
How does a package work?
A ynote package file is a zip file and has all the required files in the root directory with an index file. The index file contains information that where a file will go once it is installed. When installing a package, the first file which is extracted is the index file. Ynote uses ZipStorer
to manage zip files.The following code generates a dictionary where a file will go.
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;
}
It uses YnoteCommand
class to parse the string
because it is also of the format {key}
:{value}
Installing a Package
Ynote has built in support for installing packages by using the Package Manager
.
Tools->Package Manager will give you a list of available packages. It's a one-click download and install.
You can also install packages from file. Use Install From File to Install a Package from File
Creating a package
You can create a package using the Package Manager
.
GoTo Tools->Package Manager Select the Installed Packages Tab and Click Create Package.
Select an output file and add the files you want to and its output destination:
$ynotedata
- %appdata%\Ynote Classic or {install dir}\Packages in Portable Version $ynotedir
- {install dir}\ (same in portable and installable versions, used for copying required assemblies. If you use this, you should install the package as administrator because the user may have installed ynote in the Program Files Directory)
Submitting a Package
You can submit your package by creating a pull request at the ynotepackages repository. See the README.md in the repo for information.
TODO
Ynote has to improve day by day, version by version. Some things I will likely add in the next version (2.9) are listed below:
- Improve Snippets - Like Textmate's
- Better Performance and Startup time
- Switch to IronPython for scripting (Perhaps) and improve API
- Improved Multiple Caret and Selections support
- Themable DockPanel
- Better Syntax Highlighting Interface
- Improved Project TreeView GUI
- Improved Settings Framework
- Improved Commander
External Resources
History
- Initial release
- Updated Article ( 2.8.5 Beta )