Пример #1
0
        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;
            }
        }
Пример #2
0
        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) { }
        }
Пример #3
0
        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();
            }
        }