コード例 #1
0
        /// <summary>
        /// Opens a file.
        /// </summary>
        /// <param name="file">The file to open.</param>
        /// <remarks>
        /// The base method calls Invoke-Item for <see cref="FileSystemInfo"/> files.
        /// </remarks>
        public virtual void OpenFile(FarFile file)
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }

            if (file.Data == null)
            {
                return;
            }

            //! use try, e.g. Invoke-Item throws exception with any error action (PS bug?)
            try
            {
                // case: file system
                FileSystemInfo fi = Cast <FileSystemInfo> .From(file.Data);

                if (fi != null)
                {
                    A.InvokeCode("Invoke-Item -LiteralPath $args[0] -ErrorAction Stop", fi.FullName);
                    return;
                }
            }
            catch (RuntimeException ex)
            {
                A.Msg(ex);
            }
        }
コード例 #2
0
        /// <inheritdoc/>
        public override void GetContent(GetContentEventArgs args)
        {
            if (args == null)
            {
                return;
            }

            // info
            PSPropertyInfo pi = Cast <PSPropertyInfo> .From(args.File.Data);

            if (pi == null)
            {
                args.Result = JobResult.Ignore;
                return;
            }

            // text
            args.UseText = Converter.InfoToText(pi);
            if (args.UseText == null)
            {
                args.Result = JobResult.Ignore;
                return;
            }

            args.CanSet = pi.IsSettable;
        }
コード例 #3
0
ファイル: Stepper.cs プロジェクト: shupoval/FarNet
        // Inserts steps at
        void InsertRange(int index, IEnumerable steps)
        {
            // state
            State = StepperState.Parsing;

            // steps
            foreach (object step in steps)
            {
                object      insert = null;
                ScriptBlock block  = Cast <ScriptBlock> .From(step);

                if (block != null)
                {
                    insert = block;
                }
                else
                {
                    string macro = Cast <string> .From(step);

                    if (macro != null)
                    {
                        insert = macro;
                    }
                    else
                    {
                        Throw("Invalid step: " + TypeName(step));
                    }
                }
                _steps.Insert(index, insert);
                ++index;
            }
        }
コード例 #4
0
ファイル: ObjectExplorer.cs プロジェクト: shupoval/FarNet
        internal void AddObjects(object values)
        {
            if (values == null)
            {
                return;
            }

            var added = AddedValues;

            IEnumerable enumerable = Cast <IEnumerable> .From(values);

            if (enumerable == null || enumerable is string)
            {
                added.Add(PSObject.AsPSObject(values));
            }
            else
            {
                int maximumFileCount = Settings.Default.MaximumPanelFileCount;
                int fileCount        = 0;
                foreach (object value in enumerable)
                {
                    if (value == null)
                    {
                        continue;
                    }

                    // ask to cancel
                    if (fileCount >= maximumFileCount && maximumFileCount > 0)
                    {
                        int res = ShowTooManyFiles(maximumFileCount, enumerable);

                        // abort, show what we have got
                        if (res == 0)
                        {
                            break;
                        }

                        if (res == 1)
                        {
                            // retry with a larger number
                            maximumFileCount *= 2;
                        }
                        else
                        {
                            // ignore the limit
                            maximumFileCount = 0;
                        }
                    }

                    // add
                    added.Add(PSObject.AsPSObject(value));
                    ++fileCount;
                }
            }
        }
コード例 #5
0
ファイル: EditorKit.cs プロジェクト: fcenobi/FarNet
        static string TECompletionText(object value)
        {
            var t = Cast <Hashtable> .From(value);           //! remote gets PSObject

            if (t == null)
            {
                return(value.ToString());
            }

            return(t[CompletionText].ToString());
        }
コード例 #6
0
        /// <summary>
        /// Puts a value into the command line or opens a lookup panel or member panel.
        /// </summary>
        /// <param name="file">The file to process.</param>
        public override void OpenFile(FarFile file)
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }

            PSPropertyInfo pi = file.Data as PSPropertyInfo;

            // e.g. visible mode: sender is MemberDefinition
            if (pi == null)
            {
                return;
            }

            // lookup opener?
            if (_LookupOpeners != null)
            {
                ScriptHandler <OpenFileEventArgs> handler;
                if (_LookupOpeners.TryGetValue(file.Name, out handler))
                {
                    handler.Invoke(this, new OpenFileEventArgs(file));
                    return;
                }
            }

            // case: can show value in the command line
            string s = Converter.InfoToLine(pi);

            if (s != null)
            {
                // set command line
                ILine cl = Far.Api.CommandLine;
                cl.Text = "=" + s;
                cl.SelectText(1, s.Length + 1);
                return;
            }

            // case: enumerable
            IEnumerable ie = Cast <IEnumerable> .From(pi.Value);

            if (ie != null)
            {
                ObjectPanel op = new ObjectPanel();
                op.AddObjects(ie);
                op.OpenChild(this);
                return;
            }

            // open members
            OpenFileMembers(file);
        }
コード例 #7
0
        /// <inheritdoc/>
        public override void SetText(SetTextEventArgs args)
        {
            if (args == null)
            {
                return;
            }

            PSPropertyInfo pi = Cast <PSPropertyInfo> .From(args.File.Data);

            if (pi == null)
            {
                args.Result = JobResult.Ignore;
            }
            else
            {
                A.SetPropertyFromTextUI(Value, pi, args.Text.TrimEnd());
            }
        }
コード例 #8
0
        /// <summary>
        /// Creates a lookup handler designed only for <see cref="DataRow"/>.
        /// </summary>
        /// <param name="namePairs">Destination and source field name pairs.</param>
        /// <returns>Lookup handler to assigned to <see cref="AnyPanel.Lookup"/>.</returns>
        /// <remarks>
        /// This panel <see cref="Value"/> and lookup panel items should be <see cref="DataRow"/> objects,
        /// e.g. this panel shows members of a row from parent <see cref="DataPanel"/>
        /// and a lookup panel is also <see cref="DataPanel"/>.
        /// <para>
        /// The returned handler copies data from the source (lookup) row to the destination row using
        /// destination and source field name pairs, e.g.: <c>dst1, src1 [, dst2, src2 [, ...]]</c>.
        /// Example script: <c>Test-Panel-DbNotes-.ps1</c>.
        /// </para>
        /// </remarks>
        public EventHandler <OpenFileEventArgs> CreateDataLookup(string[] namePairs)
        {
            if (Cast <DataRow> .From(Target) == null)
            {
                throw new InvalidOperationException("Data lookup is designed only for data row objects.");
            }

            if (namePairs == null || namePairs.Length == 0)
            {
                throw new ArgumentException("'namePairs' must not be null or empty.");
            }

            if (namePairs.Length % 2 != 0)
            {
                throw new ArgumentException("'namePairs' must contain even number of items.");
            }

            return((new DataLookup(namePairs)).Invoke);
        }
コード例 #9
0
ファイル: A.cs プロジェクト: fcenobi/FarNet
        /// <summary>
        /// Writes invocation errors.
        /// </summary>
        public static void WriteErrors(TextWriter writer, IEnumerable errors)
        {
            if (errors == null)
            {
                return;
            }

            foreach (object error in errors)
            {
                writer.WriteLine("ERROR:");
                writer.WriteLine(error.ToString());

                ErrorRecord asErrorRecord = Cast <ErrorRecord> .From(error);

                if (asErrorRecord != null && asErrorRecord.InvocationInfo != null)
                {
                    writer.WriteLine(Kit.PositionMessage(asErrorRecord.InvocationInfo.PositionMessage));
                }
            }
        }
コード例 #10
0
ファイル: ObjectExplorer.cs プロジェクト: shupoval/FarNet
        /// <inheritdoc/>
        public override Explorer DoOpenFile(OpenFileEventArgs args)
        {
            if (args == null)
            {
                return(null);
            }

            object   data   = args.File.Data;
            PSObject psData = PSObject.AsPSObject(data);
            var      type   = psData.BaseObject.GetType();

            // replace dictionary entry with its value if it is complex
            if (type == typeof(DictionaryEntry))
            {
                var value = ((DictionaryEntry)psData.BaseObject).Value;
                if (value != null && !Converter.IsLinearType(value.GetType()))
                {
                    data   = value;
                    psData = PSObject.AsPSObject(value);
                }
            }

            // replace key/value pair with its value if it is complex
            var typeName = type.FullName;

            if (typeName.StartsWith("System.Collections.Generic.KeyValuePair`", StringComparison.OrdinalIgnoreCase))
            {
                var value = psData.Properties["Value"].Value;
                if (value != null && !Converter.IsLinearType(value.GetType()))
                {
                    data   = value;
                    psData = PSObject.AsPSObject(value);
                }
            }

            // case: linear type: ignore, it is useless to open
            if (Converter.IsLinearType(type))
            {
                args.Result = JobResult.Ignore;
                return(null);
            }

            // case: enumerable (string is excluded by linear type case)
            IEnumerable asIEnumerable = Cast <IEnumerable> .From(data);

            if (asIEnumerable != null)
            {
                var explorer = new ObjectExplorer();
                explorer.AddObjects(asIEnumerable);
                return(explorer);
            }

            // case: group
            PSPropertyInfo pi = psData.Properties["Group"];

            if (pi != null && pi.Value is IEnumerable && !(pi.Value is string))
            {
                var explorer = new ObjectExplorer();
                explorer.AddObjects(pi.Value);
                return(explorer);
            }

            // case: WMI
            if (typeName == "System.Management.ManagementClass")
            {
                pi = psData.Properties[Word.Name];
                if (pi != null && pi.Value != null)
                {
                    var values   = A.InvokeCode("Get-WmiObject -Class $args[0] -ErrorAction SilentlyContinue", pi.Value.ToString());
                    var explorer = new ObjectExplorer();
                    explorer.AddObjects(values);
                    return(explorer);
                }
            }

            // open members
            return(new MemberExplorer(data));
        }
コード例 #11
0
ファイル: EditorKit.cs プロジェクト: jesterret/FarNet
        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) { }
        }
コード例 #12
0
ファイル: Stepper.cs プロジェクト: shupoval/FarNet
        static string TypeName(object value)
        {
            var it = Cast <object> .From(value);

            return(it == null ? "null" : it.GetType().FullName);
        }
コード例 #13
0
ファイル: Stepper.cs プロジェクト: shupoval/FarNet
        /// <summary>
        /// Invokes the next step in the step sequence.
        /// </summary>
        public bool MoveNext()
        {
            AssumeCanStep();
            _current = null;

            try
            {
                // this is running
                _RunningInstance = this;

                // done with steps?
                if (_StepIndex >= _steps.Count)
                {
                    // event
                    UnitCompleted?.Invoke(this, null);

                    // remove user data
                    if (_Data != null)
                    {
                        _Data.Clear();
                    }

                    // done with units?
                    if (++_UnitIndex >= _units.Count)
                    {
                        // state
                        State = StepperState.Completed;
                        _continuation?.Invoke(null);
                        return(false);
                    }

                    // state
                    State = StepperState.Loading;

                    // reset steps
                    _steps.Clear();
                    _StepIndex = 0;

                    // get steps from the unit
                    Collection <PSObject> steps;
                    var path = _units[_UnitIndex];
                    using (var ps = A.Psf.NewPowerShell())
                        steps = ps.AddCommand(path).Invoke();

                    // no steps? 'continue'
                    if (steps.Count == 0)
                    {
                        return(true);
                    }

                    // add steps and start
                    InsertRange(0, steps);
                }

                // state
                State = StepperState.Stepping;

                // counter
                ++_StepCount;

                // next step object
                object it = _steps[_StepIndex];
                if (it == null)
                {
                    Throw("Step is null.");
                }

                // show
                if (Ask)
                {
                    string text  = it.ToString();
                    string title = "Step " + (_StepIndex + 1) + "/" + _steps.Count;
                    if (_units.Count > 0)
                    {
                        if (_UnitIndex >= 0)
                        {
                            text = _units[_UnitIndex].ToString().Trim() + "\r" + text;
                        }
                        title += " Unit " + (_UnitIndex + 1) + "/" + _units.Count;
                    }

                    var args = new MessageArgs()
                    {
                        Text     = text,
                        Caption  = title,
                        Options  = MessageOptions.LeftAligned,
                        Buttons  = new string[] { "Step", "Continue", "Cancel" },
                        Position = new Point(int.MaxValue, 1)
                    };
                    switch (Far.Api.Message(args))
                    {
                    case 0:
                        break;

                    case 1:
                        Ask = false;
                        break;

                    default:
                        return(false);
                    }
                }

                // invoke the next step
                ScriptBlock block = Cast <ScriptBlock> .From(it);

                if (block != null)
                {
                    // invoke the step script
                    Collection <PSObject> result = null;
                    try
                    {
                        result = block.Invoke();
                    }
                    catch (RuntimeException ex)
                    {
                        Throw(block, "Step failed: " + ex.Message, ex);
                    }

                    // extra script, normally starts modal UI
                    ScriptBlock script;
                    if (result.Count == 1 && null != (script = result[0].BaseObject as ScriptBlock))
                    {
                        ++_StepIndex;
                        _current = new Action(delegate { script.Invoke(); });
                        return(true);
                    }

                    // unexpected output
                    if (result.Count != 0)
                    {
                        Throw(block, string.Format(null,
                                                   "Unexpected step output: {0} item(s): [{1}]...",
                                                   result.Count, TypeName(result[0])), null);
                    }
                }
                else
                {
                    // post macro
                    _current = it;
                }

                // post
                ++_StepIndex;
                return(true);
            }
            catch (Exception error)
            {
                _Error = error;
                State  = StepperState.Failed;
                if (_continuation == null)
                {
                    throw;
                }

                _continuation(error);
                return(false);
            }
            finally
            {
                // step is over
                _RunningInstance = null;
            }
        }