public static void ExpandText(ILine editLine, int replacementIndex, int replacementLength, IList words) { bool isEmpty = words.Count == 0; var text = editLine.Text; var last = replacementIndex + replacementLength - 1; bool custom = last > 0 && last < text.Length && text[last] == '='; //_140112_150217 last can be out of range // select a word string word; if (words.Count == 1) { // 1 word if (words[0] == null) return; word = TECompletionText(words[0]); } else { // make menu IListMenu menu = Far.Api.CreateListMenu(); var cursor = Far.Api.UI.WindowCursor; menu.X = cursor.X; menu.Y = cursor.Y; Settings.Default.PopupMenu(menu); if (isEmpty) { menu.Add(Res.Empty).Disabled = true; menu.NoInfo = true; menu.Show(); return; } menu.Incremental = "*"; menu.IncrementalOptions = PatternOptions.Substring; foreach (var it in words) { if (it == null) continue; var item = new SetItem(); item.Text = TEListItemText(it); item.Data = it; menu.Items.Add(item); } if (menu.Items.Count == 0) return; if (menu.Items.Count == 1) { word = TECompletionText(menu.Items[0].Data); } else { // show menu if (!menu.Show()) return; word = TECompletionText(menu.Items[menu.Selected].Data); } } // replace // head before replaced part string head = text.Substring(0, replacementIndex); // custom pattern int index, caret; if (custom && (index = word.IndexOf('#')) >= 0) { word = word.Substring(0, index) + word.Substring(index + 1); caret = head.Length + index; } // standard else { caret = head.Length + word.Length; } // set new text = old head + expanded + old tail editLine.Text = head + word + text.Substring(replacementIndex + replacementLength); // set caret editLine.Caret = caret; }
public static void ExpandCode(ILine editLine, Runspace runspace) { InitTabExpansion(); // hot line if (editLine == null) { editLine = Far.Api.Line; if (editLine == null) { A.Message("There is no current editor line."); return; } } int lineOffset = 0; string inputScript; int cursorColumn; var prefix = string.Empty; IEditor editor = null; EditorConsole console; EditorConsole.Area area; // script? if (A.Psf.PSVersion.Major > 2 && editLine.WindowKind == WindowKind.Editor && My.PathEx.IsPSFile((editor = Far.Api.Editor).FileName)) { int lineIndex = editor.Caret.Y; int lastIndex = editor.Count - 1; // previous text var sb = new StringBuilder(); for (int i = 0; i < lineIndex; ++i) sb.AppendLine(editor[i].Text); // current line lineOffset = sb.Length; cursorColumn = lineOffset + editLine.Caret; // remaining text for (int i = lineIndex; i < lastIndex; ++i) sb.AppendLine(editor[i].Text); sb.Append(editor[lastIndex]); // whole text inputScript = sb.ToString(); } // area? else if (editor != null && (console = editor.Host as EditorConsole) != null && (area = console.GetCommandArea()) != null) { int lineIndex = area.Caret.Y; int lastIndex = area.LastLineIndex; // previous text var sb = new StringBuilder(); for (int i = area.FirstLineIndex; i < lineIndex; ++i) sb.AppendLine(editor[i].Text); // current line lineOffset = sb.Length; cursorColumn = lineOffset + area.Caret.X; // remaining text for (int i = lineIndex; i < lastIndex; ++i) sb.AppendLine(editor[i].Text); sb.Append(editor[lastIndex]); // whole text inputScript = sb.ToString(); } // line else { // original line inputScript = editLine.Text; cursorColumn = editLine.Caret; // process prefix, used to be just for panels but it is needed in dialogs, too Entry.SplitCommandWithPrefix(ref inputScript, out prefix); // correct caret cursorColumn -= prefix.Length; if (cursorColumn < 0) return; } // skip empty (also avoid errors) if (inputScript.Length == 0) return; // invoke try { // call TabExpansion Hashtable result; using (var ps = runspace == null ? A.Psf.NewPowerShell() : PowerShell.Create()) { if (runspace != null) ps.Runspace = runspace; result = (Hashtable)ps.AddScript(_callTabExpansion, true).AddArgument(inputScript).AddArgument(cursorColumn).Invoke()[0].BaseObject; } // results var words = Cast<IList>.From(result["CompletionMatches"]); //! remote gets PSObject int replacementIndex = (int)result["ReplacementIndex"]; int replacementLength = (int)result["ReplacementLength"]; replacementIndex -= lineOffset; if (replacementIndex < 0 || replacementLength < 0) return; // variables from the current editor if (editLine.WindowKind == WindowKind.Editor) { // replaced text var lastWord = inputScript.Substring(lineOffset + replacementIndex, replacementLength); //! as TabExpansion.ps1 but ends with \$(\w*)$ var matchVar = Regex.Match(lastWord, @"^(.*[!;\(\{\|""'']*)\$(global:|script:|private:)?(\w*)$", RegexOptions.IgnoreCase); if (matchVar.Success) { var start = matchVar.Groups[1].Value; var scope = matchVar.Groups[2].Value; var re = new Regex(@"\$(global:|script:|private:)?(" + scope + matchVar.Groups[3].Value + @"\w+:?)", RegexOptions.IgnoreCase); var variables = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (var line1 in Far.Api.Editor.Lines) { foreach (Match m in re.Matches(line1.Text)) { var all = m.Value; if (all[all.Length - 1] != ':') { variables.Add(start + all); if (scope.Length == 0 && m.Groups[1].Value.Length > 0) variables.Add(start + "$" + m.Groups[2].Value); } } } // union lists foreach (var x in words) if (x != null) variables.Add(TECompletionText(x)); // final sorted list words = variables.OrderBy(x => x, StringComparer.OrdinalIgnoreCase).ToList(); } } // expand ExpandText(editLine, replacementIndex + prefix.Length, replacementLength, words); } catch (RuntimeException) { } }
public static void CompleteText(ILine editLine, string tail, string line, string lastWord, IEnumerable words) { // menu IListMenu menu = Far.Api.CreateListMenu(); var cursor = Far.Api.UI.WindowCursor; menu.X = cursor.X; menu.Y = cursor.Y; Settings.Default.PopupMenu(menu); menu.Incremental = lastWord + "*"; menu.IncrementalOptions = PatternOptions.Prefix; foreach (var it in words) { if (it == null) continue; var candidate = it.ToString(); if (candidate.Length == 0) { menu.Add(string.Empty).IsSeparator = true; continue; } if (lastWord.Length == 0 || candidate.StartsWith(lastWord, StringComparison.OrdinalIgnoreCase)) menu.Add(candidate); } if (menu.Items.Count == 0) { menu.Add(Res.Empty).Disabled = true; menu.NoInfo = true; menu.Show(); return; } string word; if (menu.Items.Count == 1) { word = menu.Items[0].Text; } else { // show menu if (!menu.Show()) return; word = menu.Items[menu.Selected].Text; } // expand last word // head before the last word line = line.Substring(0, line.Length - lastWord.Length); // new caret int caret = line.Length + word.Length; // set new text = old head + expanded + old tail editLine.Text = line + word + tail; // set caret editLine.Caret = caret; }
public void ExpandCode(ILine editLine) { EditorKit.ExpandCode(editLine, null); }
public static void CompleteWord(ILine editLine, IEnumerable words) { // hot line if (editLine == null) { editLine = Far.Api.Line; if (editLine == null) { A.Message("There is no current editor line."); return; } } // line and last word string text = editLine.Text; string head = text.Substring(0, editLine.Caret); string tail = text.Substring(head.Length); Match match = Regex.Match(head, @"(?:^|\s)(\S+)$"); string lastWord = match.Success ? match.Groups[1].Value : string.Empty; // complete CompleteText(editLine, tail, head, lastWord, words); }