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) { } }
/// <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; } }
static string TypeName(object value) { var it = Cast <object> .From(value); return(it == null ? "null" : it.GetType().FullName); }
/// <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)); }