diff --git a/FarNet/FarNetMan/Far0.h b/FarNet/FarNetMan/Far0.h index d092dfa7..ebb7d117 100644 --- a/FarNet/FarNetMan/Far0.h +++ b/FarNet/FarNetMan/Far0.h @@ -35,8 +35,8 @@ ref class Far0 static void ShowDrawersMenu(); static void ShowMenu(ModuleToolOptions from); public: - static String^ FarNetRoot() { return Environment::GetEnvironmentVariable("FARHOME") + "\\FarNet"; } - static String^ HelpTopic() { return "<" + FarNetRoot() + "\\>"; } + static String^ FarNetManRoot() { return Environment::GetEnvironmentVariable("FARHOME") + "\\Plugins\\FarNet"; } + static String^ HelpTopic() { return "<" + FarNetManRoot() + "\\>"; } static void InvalidateProxyCommand(); static void UnregisterProxyTool(IModuleTool^ tool); private: diff --git a/FarNet/History.txt b/FarNet/History.txt index 968c4fbe..d674df55 100644 --- a/FarNet/History.txt +++ b/FarNet/History.txt @@ -1,6 +1,10 @@ https://www.nuget.org/packages/FarNet Far Manager 3.0.5505 += 5.4.18 = + +Fix internal help paths. + = 5.4.17 = Add IListMenu.TypeId assign the default. diff --git a/Get-Version.ps1 b/Get-Version.ps1 index 0cd032ac..432ee775 100644 --- a/Get-Version.ps1 +++ b/Get-Version.ps1 @@ -1,3 +1,3 @@ $FarVersion = "3.0.5505" -$FarNetVersion = "5.4.17" +$FarNetVersion = "5.4.18" $PowerShellFarVersion = "5.4.9" diff --git a/RightWords/.build.ps1 b/RightWords/.build.ps1 index 196ca952..24f39689 100644 --- a/RightWords/.build.ps1 +++ b/RightWords/.build.ps1 @@ -16,6 +16,16 @@ task build meta, { exec { dotnet msbuild RightWords.csproj /p:FarHome=$FarHome /p:Configuration=Release } } +task help @{ + Inputs = 'README.md' + Outputs = "$ModuleHome\RightWords.hlf" + Jobs = { + exec { pandoc.exe README.md --output=z.htm --from=gfm } + exec { HtmlToFarHelp from=z.htm to=$ModuleHome\RightWords.hlf } + remove z.htm + } +} + # https://github.com/nightroman/PowerShelf/blob/master/Invoke-Environment.ps1 task resgen @{ Inputs = 'RightWords.restext', 'RightWords.ru.restext' @@ -32,7 +42,7 @@ task resgen @{ } } -task publish resgen +task publish help, resgen task clean { remove z, bin, obj, README.htm, *.nupkg @@ -82,6 +92,7 @@ task package markdown, version, { "LICENSE.txt" "RightWords.macro.lua" "$ModuleHome\RightWords.dll" + "$ModuleHome\RightWords.hlf" "$ModuleHome\RightWords.resources" "$ModuleHome\RightWords.ru.resources" ) diff --git a/RightWords/Actor.cs b/RightWords/Actor.cs index 1cf8da30..58339cf4 100644 --- a/RightWords/Actor.cs +++ b/RightWords/Actor.cs @@ -17,9 +17,7 @@ static class Actor public static readonly HashSet IgnoreWords = new HashSet(); static readonly IModuleManager Manager = Far.Api.GetModuleManager(Settings.ModuleName); static readonly WeakReference CommonWords = new WeakReference(null); - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] - static readonly bool Initialized = Initialize(); - static bool Initialize() + static Actor() { // home directory, for libraries and dictionaries var home = Path.GetDirectoryName(typeof(Hunspell).Assembly.Location); @@ -44,8 +42,6 @@ static bool Initialize() } } } - - return true; } public static HashSet GetCommonWords() { @@ -80,8 +76,8 @@ public static Match MatchCaret(Regex regex, string input, int caret, bool next) } public static void CorrectWord() { - ILine line = null; - IEditor editor = null; + ILine line; + IEditor editor; var kind = Far.Api.Window.Kind; if (kind == WindowKind.Editor) @@ -164,6 +160,9 @@ public static void ShowThesaurus() var menu = Far.Api.CreateMenu(); menu.Title = word; + menu.HelpTopic = Far.Api.GetHelpTopic("thesaurus-menu"); + menu.AddKey(KeyCode.C, ControlKeyStates.LeftCtrlPressed); + menu.AddKey(KeyCode.Insert, ControlKeyStates.LeftCtrlPressed); Far.Api.UI.SetProgressState(TaskbarProgressBarState.Indeterminate); Far.Api.UI.WindowTitle = My.Searching; @@ -187,10 +186,20 @@ public static void ShowThesaurus() Far.Api.UI.SetProgressState(TaskbarProgressBarState.NoProgress); } - if (!menu.Show()) + if (!menu.Show() || menu.Selected < 0) return; - Far.Api.CopyToClipboard(menu.Items[menu.Selected].Text); + // copy + if (menu.Key.IsCtrl() && (menu.Key.VirtualKeyCode == KeyCode.C || menu.Key.VirtualKeyCode == KeyCode.Insert)) + { + // get text and remove "(...)" + var text = menu.Items[menu.Selected].Text; + var index = text.IndexOf('('); + if (index >= 0) + text = text.Substring(0, index).Trim(); + + Far.Api.CopyToClipboard(text); + } } public static bool HasMatch(MatchCollection matches, Match match) { @@ -203,7 +212,7 @@ public static bool HasMatch(MatchCollection matches, Match match) } public static MatchCollection GetMatches(Regex regex, string text) { - return regex == null ? null : regex.Matches(text); + return regex?.Matches(text); } public static Regex GetRegexSkip() { @@ -384,6 +393,7 @@ static string[] ShowMenuAddWord(string word) var menu = Far.Api.CreateMenu(); menu.Title = My.AddToDictionary; + menu.HelpTopic = My.AddToDictionaryHelp; menu.Add(word); menu.Add(word + ", " + word2); if (!menu.Show()) @@ -403,6 +413,7 @@ static void AddRightWord(HashSet words, string word) // dictionary menu var menu = Far.Api.CreateMenu(); menu.Title = My.AddToDictionary; + menu.HelpTopic = My.AddToDictionaryHelp; menu.AutoAssignHotkeys = true; menu.Add(My.Common); foreach (string name in languages) diff --git a/RightWords/Highlighter.cs b/RightWords/Highlighter.cs index c5c2c9e3..7899a4e9 100644 --- a/RightWords/Highlighter.cs +++ b/RightWords/Highlighter.cs @@ -8,9 +8,8 @@ namespace FarNet.RightWords { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable")] - [System.Runtime.InteropServices.Guid("bbed2ef1-97d1-4ba2-ac56-9de56bc8030c")] [ModuleDrawer(Name = "Spelling mistakes", Mask = "*.hlf;*.htm;*.html;*.lng;*.restext", Priority = 1)] + [System.Runtime.InteropServices.Guid("bbed2ef1-97d1-4ba2-ac56-9de56bc8030c")] public class Highlighter : ModuleDrawer { readonly MultiSpell Spell = MultiSpell.Get(); diff --git a/RightWords/History.txt b/RightWords/History.txt index b1af3ba2..d19fdb23 100644 --- a/RightWords/History.txt +++ b/RightWords/History.txt @@ -1,6 +1,14 @@ https://www.nuget.org/packages/FarNet.RightWords FarNet 5.4.13 += 2.3.3 = + +Add help and connect to user interface. + +Thesaurus menu: +- Esc, Enter - close, do nothing +- CtrlC, CtrlIns - copy to clipboard + = 2.3.2 = Update for FarNet 5.4.13 diff --git a/RightWords/My.cs b/RightWords/My.cs index f70cee8a..75b51cdb 100644 --- a/RightWords/My.cs +++ b/RightWords/My.cs @@ -2,30 +2,31 @@ // FarNet module RightWords // Copyright (c) Roman Kuzmin -using System; - namespace FarNet.RightWords { static class My { public const string GuidString = "ca7ecdc0-f446-4bff-a99d-06c90fe0a3a9"; - public readonly static Guid Guid = new Guid(GuidString); #region private static readonly IModuleManager Manager = Far.Api.GetModuleManager(Settings.ModuleName); - static string GetString(string name) { return Manager.GetString(name); } + static string GetString(string name) => Manager.GetString(name); + #endregion + #region help + public static string AddToDictionaryHelp => Far.Api.GetHelpTopic("add-to-dictionary"); #endregion - static public string AddToDictionary { get { return GetString("AddToDictionary"); } } - static public string DoIgnore { get { return GetString("DoIgnore"); } } - static public string DoIgnoreAll { get { return GetString("DoIgnoreAll"); } } - static public string DoAddToDictionary { get { return GetString("DoAddToDictionary"); } } - static public string Word { get { return GetString("Word"); } } - static public string Thesaurus { get { return GetString("Thesaurus"); } } - static public string DoCorrectWord { get { return GetString("DoCorrectWord"); } } - static public string DoCorrectText { get { return GetString("DoCorrectText"); } } - static public string DoThesaurus { get { return GetString("DoThesaurus"); } } - static public string Common { get { return GetString("Common"); } } - static public string Searching { get { return GetString("Searching"); } } - static public string NewWord { get { return GetString("NewWord"); } } - static public string ExampleStem { get { return GetString("ExampleStem"); } } + public static string AddToDictionary => GetString("AddToDictionary"); + public static string DoIgnore => GetString("DoIgnore"); + public static string DoIgnoreAll => GetString("DoIgnoreAll"); + public static string DoAddToDictionary => GetString("DoAddToDictionary"); + public static string Word => GetString("Word"); + public static string Thesaurus => GetString("Thesaurus"); + public static string DoCorrectWord => GetString("DoCorrectWord"); + public static string DoCorrectText => GetString("DoCorrectText"); + public static string DoThesaurus => GetString("DoThesaurus"); + public static string Common => GetString("Common"); + public static string Searching => GetString("Searching"); + public static string NewWord => GetString("NewWord"); + public static string ExampleStem => GetString("ExampleStem"); + public static string ExampleStem2 => GetString("ExampleStem"); } } diff --git a/RightWords/README.md b/RightWords/README.md index 1e1cebaa..f82d25e3 100644 --- a/RightWords/README.md +++ b/RightWords/README.md @@ -1,32 +1,35 @@ -# RightWords +[Contents]: #rightwords -FarNet module for Far Manager, spell-checker and thesaurus. +# RightWords + +RightWords is the FarNet module for Far Manager. It provides the spell-checker +and thesaurus based on NHunspell. The core Hunspell is used in OpenOffice and +it works with dictionaries published on OpenOffice.org. -* [Synopsis](#synopsis) * [Installation](#installation) -* [Description](#description) -* [Dictionaries](#dictionaries) * [Options](#options) * [Settings](#settings) -********************************************************************* -## Synopsis +Interface -RightWords is the FarNet module for Far Manager. It provides the spell-checker -and thesaurus based on NHunspell. The core Hunspell is used in OpenOffice and -it works with dictionaries published on OpenOffice.org. +* [Main menu](#main-menu) +* [Thesaurus menu](#thesaurus-menu) +* [Correction list](#correction-list) +* [Add to Dictionary](#add-to-dictionary) -**Project** +Project - * Source: - * Author: Roman Kuzmin +* Source: +* Author: Roman Kuzmin ********************************************************************* ## Installation +[Contents] + **FarNet and RightWords** -How to install and update FarNet and modules:\ +How to install and update FarNet and modules: **Dictionaries** @@ -51,6 +54,7 @@ The installed file structure (dictionaries may be different): LICENSE.txt - the license RightWords.dll - module assembly + RightWords.hlf - module help file RightWords.resources - English UI strings RightWords.ru.resources - Russian UI strings @@ -68,85 +72,38 @@ The installed file structure (dictionaries may be different): NOTES -- Do not rename or move the NHunspell directory. -- Collection of dictionaries is up to a user. +- Dictionaries are up to a user. - Thesaurus files are optional. - Dictionary directories may have any names. The names are used in the dictionary menu and in the user dictionary file names (e.g. English -> RightWords.English.dic). ********************************************************************* -## Description - -In order to turn "Spelling mistakes" highlighting on and off use the menu: -`[F11] \ FarNet \ Drawers \ Spelling mistakes` - -For other actions use the module menu `[F11] \ RightWords`: - -- Correct word (editor, dialog, command line) - - Checks spelling and shows the suggestion menu for the current word. Menu - actions are the same as for *Correct text*. - -- Correct text (editor) - - Checks spelling, shows suggestions, and corrects words in the selected text - or starting from the caret position. `[Enter]` in the suggestion menu - replaces the highlighted word with the selected suggestion. - -- Menu commands - - *Ignore* - ignores the word once - - *Ignore All* - ignores the word in the current session - - *Add to Dictionary* - adds the word to the user dictionary - - - -- Thesaurus - - Prompts to enter a word and shows the list of available meanings and - synonyms. `[Enter]` in the menu copies the current item text to the - clipboard. - -********************************************************************* -## Dictionaries - -*Add to Dictionary* command supports the common and language dictionaries. In -order to add a word into a language dictionary two stems should be provided: a -new word stem and its example stem. If the example stem is empty then the word -is added as it is, this case is not very different from the common dictionary. +## Options -Examples: +[Contents] -English stems: plugin + pin -These forms become correct: +`[F11] \ FarNet \ Drawers \ Spelling mistakes` - plugin plugins Plugin Plugins +Switches "Spelling mistakes" highlighting in the current editor. -Russian stems: плагин + камин -These forms become correct: - - плагин плагины Плагин Плагины - плагина плагинов Плагина Плагинов - плагину плагинам Плагину Плагинам - плагином плагинами Плагином Плагинами - плагине плагинах Плагине Плагинах +`[F9] \ Options \ Plugin configuration \ FarNet \ Drawers \ Spelling mistakes` -CAUTION: Mind word capitalization, e.g. add "plugin", not "Plugin". +The dialog with permanent options: -User dictionaries are UTF-8 text files in the module roaming directory: -*RightWords.dic* (common) and files like *RightWords.XYZ.dic* (languages). +- `Mask` -********************************************************************* -## Options + Specifies the files for "Spelling mistakes" highlighting turned on. -`[F9] \ Options \ Plugin configuration \ FarNet \ Drawers \ Spelling mistakes` +- `Priority` -* Mask - mask of files where the "Spelling mistakes" is turned on automatically. -* Priority - drawer color priority. + Specifies the color priority. ********************************************************************* ## Settings +[Contents] + Open the module settings panel: `[F11] \ FarNet \ Settings \ RightWords` Regular expression patterns are created with IgnorePatternWhitespace option, so @@ -198,3 +155,103 @@ The default is the module roaming directory. If it is set to a positive value then it tells to not check too long lines and highlight them all. Otherwise too long lines may cause lags on highlighting. + +********************************************************************* +## Main menu + +[Contents] + +This menu is called by `[F11] \ RightWords`. + +Commands: + +- *Correct word* (editor, dialog, command line) + + Checks spelling and shows suggestions for the current word. + See [Correction list](#correction-list). + +- *Correct text* (editor) + + Checks spelling and shows suggestions in the selected text or starting from the caret position. + See [Correction list](#correction-list). + +- *Thesaurus...* + + Prompts for a word and shows the list of its meanings and synonyms. + See [Thesaurus menu](#thesaurus-menu). + +See also [Options](#options). + +********************************************************************* +## Thesaurus menu + +[Contents] + +This menu shows words in groups of synonyms and related concepts. + +Keys and actions: + +- `[Esc]`, `[Enter]` + + Close the menu. + +- `[CtrlC]`, `[CtrlIns]` + + Copy the word to clipboard. + +********************************************************************* +## Correction list + +[Contents] + +This list shows suggestions for correcting a misspelled word and additional commands. + +Additional commands: + +- *Ignore* + + Ignores the word once. + +- *Ignore All* + + Ignores the word in the current session. + +- *Add to Dictionary* + + Adds the word to the user dictionary. + +********************************************************************* +## Add to Dictionary + +[Contents] + +*Add to Dictionary* supports the common and language dictionaries. + +On adding a word to the common dictionary, choose one of the suggested variants. + +On adding a word to a language dictionary, provide two stems: the new word stem +and its example stem. If the example stem is empty then the word is added as it +is (not very different from adding to the common dictionary). + +Examples: + +English stems: plugin + pin +These forms become correct: + + plugin plugins Plugin Plugins + +Russian stems: плагин + камин +These forms become correct: + + плагин плагины Плагин Плагины + плагина плагинов Плагина Плагинов + плагину плагинам Плагину Плагинам + плагином плагинами Плагином Плагинами + плагине плагинах Плагине Плагинах + +CAUTION: Mind word capitalization, e.g. add "plugin", not "Plugin". + +User dictionaries are UTF-8 text files in the module roaming directory: +*RightWords.dic* (common) and files like *RightWords.XYZ.dic* (languages). + +********************************************************************* diff --git a/RightWords/RightWords.macro.lua b/RightWords/RightWords.macro.lua index 80b9ecd2..de2cd226 100644 --- a/RightWords/RightWords.macro.lua +++ b/RightWords/RightWords.macro.lua @@ -1,36 +1,43 @@ +-- RightWords sample macros ---[[ - RightWords macros - - * CtrlShiftSpace - Correct the word (editor, dialog, command line). - * CtrlShiftF7 - Correct the selected text (editor). - * CtrlShiftH - Switch highlighting (editor). -]] - +-- Helpers local areaAnyEditor="Editor Dialog DialogAutoCompletion Shell ShellAutoCompletion Info QView Tree" local isEditor=function() return not (Area.Shell or Area.ShellAutoCompletion or Area.Info or Area.QView or Area.Tree) or not CmdLine.Empty end +-- Correct the word (editor, dialog, command line) Macro { -key="CtrlShiftSpace"; description="RightWords: Correct word"; area=areaAnyEditor; condition=isEditor; action=function() -if Area.DialogAutoCompletion or Area.ShellAutoCompletion then Keys("Esc") end -if Plugin.Menu("10435532-9BB3-487B-A045-B0E6ECAAB6BC", "CA7ECDC0-F446-4BFF-A99D-06C90FE0A3A9") then - Keys("1") -end -end; + key="CtrlShiftSpace"; description="RightWords: Correct word"; area=areaAnyEditor; condition=isEditor; + action=function() + if Area.DialogAutoCompletion or Area.ShellAutoCompletion then + Keys "Esc" + end + if Plugin.Menu("10435532-9BB3-487B-A045-B0E6ECAAB6BC", "CA7ECDC0-F446-4BFF-A99D-06C90FE0A3A9") then + Keys "1" + end + end; } +-- Correct the selected text (editor) Macro { -area="Editor"; key="CtrlShiftF7"; description="RightWords: Correct text"; action=function() -if Plugin.Menu("10435532-9BB3-487B-A045-B0E6ECAAB6BC", "CA7ECDC0-F446-4BFF-A99D-06C90FE0A3A9") then - Keys("2") -end -end; + key="CtrlShiftF7"; description="RightWords: Correct text"; area="Editor"; + action=function() + if Plugin.Menu("10435532-9BB3-487B-A045-B0E6ECAAB6BC", "CA7ECDC0-F446-4BFF-A99D-06C90FE0A3A9") then + Keys "2" + end + end; } +-- Switch highlighting (editor) Macro { -area="Editor"; key="CtrlShiftH"; description="RightWords: Highlighting"; action=function() -if not Plugin.Menu("10435532-9BB3-487B-A045-B0E6ECAAB6BC", "10435532-9BB3-487B-A045-B0E6ECAAB6BC") then return end -if 0 == Menu.Select("Drawers") then return end Keys("Enter") -if 0 == Menu.Select("Spelling mistakes") then return end Keys("Enter") -end; + key="CtrlShiftH"; description="RightWords: Highlighting"; area="Editor"; + action=function() + if Plugin.Menu("10435532-9BB3-487B-A045-B0E6ECAAB6BC", "10435532-9BB3-487B-A045-B0E6ECAAB6BC") then + if Menu.Select("Drawers") > 0 then + Keys "Enter" + if Menu.Select("Spelling mistakes") > 0 then + Keys "Enter" + end + end + end + end; } diff --git a/RightWords/Settings.cs b/RightWords/Settings.cs index 34cf9499..4bd748fa 100644 --- a/RightWords/Settings.cs +++ b/RightWords/Settings.cs @@ -62,7 +62,6 @@ public int MaximumLineLength get { return (int)this["MaximumLineLength"]; } set { this["MaximumLineLength"] = value; } } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults")] public override void Save() { if (!string.IsNullOrEmpty(SkipPattern)) diff --git a/RightWords/TheTool.cs b/RightWords/TheTool.cs index d6556548..43e32f62 100644 --- a/RightWords/TheTool.cs +++ b/RightWords/TheTool.cs @@ -14,6 +14,7 @@ public override void Invoke(object sender, ModuleToolEventArgs e) var menu = Far.Api.CreateMenu(); menu.Title = Settings.ModuleName; + menu.HelpTopic = Far.Api.GetHelpTopic("main-menu"); menu.Add(My.DoCorrectWord).Click = delegate { Actor.CorrectWord(); }; diff --git a/RightWords/UIWordDialog.cs b/RightWords/UIWordDialog.cs index bbb5c221..e3e351bc 100644 --- a/RightWords/UIWordDialog.cs +++ b/RightWords/UIWordDialog.cs @@ -17,6 +17,8 @@ public UIWordDialog(string stem1, string stem2) const int x = 20; _Dialog = Far.Api.CreateDialog(-1, -1, 77, h); + _Dialog.HelpTopic = My.AddToDictionaryHelp; + _Dialog.AddBox(3, 1, 0, 0, My.AddToDictionary); int y = 1; diff --git a/RightWords/UIWordMenu.cs b/RightWords/UIWordMenu.cs index c337b45f..24b5040a 100644 --- a/RightWords/UIWordMenu.cs +++ b/RightWords/UIWordMenu.cs @@ -20,6 +20,7 @@ public UIWordMenu(List words, string word, int column, int line) _menu.NoInfo = true; _menu.X = column; _menu.Y = line; + _menu.HelpTopic = Far.Api.GetHelpTopic("correction-list"); // menu keys _menu.AddKey(KeyCode.D1); diff --git a/RightWords/Works.cs b/RightWords/Works.cs index fcf480f6..738d997b 100644 --- a/RightWords/Works.cs +++ b/RightWords/Works.cs @@ -6,10 +6,10 @@ namespace FarNet.RightWords { class DictionaryInfo { - public string Language { get; set; } - public string HunspellAffFile { get; set; } - public string HunspellDictFile { get; set; } - public string MyThesDatFile { get; set; } - public int HitCount { get; set; } + public string Language; + public string HunspellAffFile; + public string HunspellDictFile; + public string MyThesDatFile; + public int HitCount; } }