public static void InvokeSelectedCode() { string code; bool toCleanCmdLine = false; WindowKind wt = Far.Api.Window.Kind; if (wt == WindowKind.Editor) { var editor = Far.Api.Editor; code = editor.GetSelectedText(); if (string.IsNullOrEmpty(code)) { code = editor[editor.Caret.Y].Text; } } else if (wt == WindowKind.Dialog) { IDialog dialog = Far.Api.Dialog; IEdit edit = dialog.Focused as IEdit; if (edit == null) { Far.Api.Message("The current control must be an edit box.", Res.Me); return; } code = edit.Line.SelectedText; if (string.IsNullOrEmpty(code)) { code = edit.Text; } } else { ILine cl = Far.Api.CommandLine; code = cl.SelectedText; if (string.IsNullOrEmpty(code)) { code = cl.Text; toCleanCmdLine = true; } string prefix; Entry.SplitCommandWithPrefix(ref code, out prefix); } if (code.Length == 0) { return; } // go bool ok = A.Psf.Act(code, null, wt != WindowKind.Editor); // clean the command line if ok if (ok && toCleanCmdLine && wt != WindowKind.Editor) { Far.Api.CommandLine.Text = string.Empty; } }
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; Interactive console; InteractiveArea 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 Interactive) != null && (area = console.CommandArea()) != 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) { } }
internal static void ShowHelpForContext(string defaultTopic = null) { ILine line = Far.Api.Line; if (line == null) { ShowAreaHelp(); return; } // line text, replace prefixes with spaces to avoid parsing problems string text = line.Text; string prefix = string.Empty; if (line.WindowKind == WindowKind.Panels) { Entry.SplitCommandWithPrefix(ref text, out prefix); } // trim end and process the empty case text = text.TrimEnd(); if (text.Length == 0) { if (defaultTopic == null) { ShowAreaHelp(); } else { Far.Api.ShowHelpTopic(defaultTopic); } return; } int pos = line.Caret - prefix.Length; string script = null; string command = null; object[] args = null; Collection <PSToken> tokens = PSParser.Tokenize(text, out _); foreach (PSToken token in tokens) { if (token.Type == PSTokenType.Command) { command = token.Content; } if (pos >= (token.StartColumn - 1) && pos <= token.EndColumn) { if (token.Type == PSTokenType.Command) { //! Call the Help function, just in case it is redefined. //! It used to call now retired Get-FarHelp. script = "Help $args[1] -Full > $args[0]"; args = new object[] { null, command }; } else if (token.Type == PSTokenType.CommandParameter) { string parameter = token.Content.TrimStart('-').ToUpperInvariant(); if (parameter == "VERBOSE" || parameter == "DEBUG" || parameter == "ERRORACTION" || parameter == "ERRORVARIABLE" || parameter == "WARNINGACTION" || parameter == "WARNINGVARIABLE" || parameter == "OUTVARIABLE" || parameter == "OUTBUFFER" || parameter == "WHATIF" || parameter == "CONFIRM") { script = "Get-Help about_CommonParameters > $args[0]"; args = new object[] { null }; } else { script = "Get-Help $args[1] -Parameter $args[2] > $args[0]"; args = new object[] { null, command, parameter }; } } else if (token.Type == PSTokenType.Keyword) { script = string.Format(null, "Get-Help about_{0} > $args[0]", token.Content); args = new object[] { null }; } else if (token.Type == PSTokenType.Operator) { script = "Get-Help about_operators > $args[0]"; args = new object[] { null }; } break; } } if (script == null) { Far.Api.Message("No help targets found at the editor caret position.", Res.Me); return; } bool ok = false; string file = Path.GetTempFileName(); try { args[0] = file; A.InvokeCode(script, args); ok = true; } catch (RuntimeException) { } finally { if (!ok && File.Exists(file)) { File.Delete(file); } } if (ok) { IViewer viewer = Far.Api.CreateViewer(); viewer.FileName = file; viewer.DeleteSource = DeleteSource.File; viewer.DisableHistory = true; viewer.Title = "Help"; viewer.Open(); } }