├── .gitattributes ├── .gitignore ├── LICENSE.txt ├── PowerShellConsole.png ├── PowerShellConsole.sln ├── PowerShellConsole ├── App.xaml ├── App.xaml.cs ├── ApplicationExtensionPoints.cs ├── Commands │ ├── ControlSpacebarCommand.cs │ └── F5Command.cs ├── CompletionData.cs ├── FoldingStrategies │ └── BraceFoldingStrategy.cs ├── ITextMarker.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── PSConsolePowerShell.cs ├── PowerShell.xshd ├── PowerShellConsole.csproj ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Scripts │ ├── InvokeCompletedInput.ps1 │ ├── InvokeCurrentScriptClearScreen.ps1 │ ├── InvokeCurrentScriptTest.ps1 │ └── InvokeInitializeConsole.ps1 ├── TextFile.ps1 ├── TextMarkerService.cs ├── Utilities │ └── TextEditorUtilities.cs └── libs │ └── ICSharpCode.AvalonEdit.dll ├── README.md └── TestFile.ps1 /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | 66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 67 | #packages/ 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper* 82 | 83 | # Installshield output folder 84 | [Ee]xpress 85 | 86 | # DocProject is a documentation generator add-in 87 | DocProject/buildhelp/ 88 | DocProject/Help/*.HxT 89 | DocProject/Help/*.HxC 90 | DocProject/Help/*.hhc 91 | DocProject/Help/*.hhk 92 | DocProject/Help/*.hhp 93 | DocProject/Help/Html2 94 | DocProject/Help/html 95 | 96 | # Click-Once directory 97 | publish 98 | 99 | # Others 100 | [Bb]in 101 | [Oo]bj 102 | sql 103 | TestResults 104 | *.Cache 105 | ClientBin 106 | stylecop.* 107 | ~$* 108 | *.dbmdl 109 | Generated_Code #added for RIA/Silverlight projects 110 | 111 | # Backup & report files from converting an old project file to a newer 112 | # Visual Studio version. Backup files are not needed, because we have git ;-) 113 | _UpgradeReport_Files/ 114 | Backup*/ 115 | UpgradeLog*.XML 116 | 117 | 118 | 119 | ############ 120 | ## Windows 121 | ############ 122 | 123 | # Windows image file caches 124 | Thumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | 130 | ############# 131 | ## Python 132 | ############# 133 | 134 | *.py[co] 135 | 136 | # Packages 137 | *.egg 138 | *.egg-info 139 | dist 140 | build 141 | eggs 142 | parts 143 | bin 144 | var 145 | sdist 146 | develop-eggs 147 | .installed.cfg 148 | 149 | # Installer logs 150 | pip-log.txt 151 | 152 | # Unit test / coverage reports 153 | .coverage 154 | .tox 155 | 156 | #Translations 157 | *.mo 158 | 159 | #Mr Developer 160 | .mr.developer.cfg 161 | 162 | # Mac crap 163 | .DS_Store 164 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS -------------------------------------------------------------------------------- /PowerShellConsole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/PowerShellConsole/908638ca250cc474f2389fd4ae32ce43c82932d1/PowerShellConsole.png -------------------------------------------------------------------------------- /PowerShellConsole.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerShellConsole", "PowerShellConsole\PowerShellConsole.csproj", "{B3CF68CC-416E-4038-A203-F9E52FDA53CB}" 5 | EndProject 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{50CA12A2-E421-4074-9576-6455BE31D2EE}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x86 = Debug|x86 11 | Release|x86 = Release|x86 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B3CF68CC-416E-4038-A203-F9E52FDA53CB}.Debug|x86.ActiveCfg = Debug|x86 15 | {B3CF68CC-416E-4038-A203-F9E52FDA53CB}.Debug|x86.Build.0 = Debug|x86 16 | {B3CF68CC-416E-4038-A203-F9E52FDA53CB}.Release|x86.ActiveCfg = Release|x86 17 | {B3CF68CC-416E-4038-A203-F9E52FDA53CB}.Release|x86.Build.0 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /PowerShellConsole/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /PowerShellConsole/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Windows; 7 | 8 | namespace PowerShellConsole 9 | { 10 | /// 11 | /// Interaction logic for App.xaml 12 | /// 13 | public partial class App : Application 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /PowerShellConsole/ApplicationExtensionPoints.cs: -------------------------------------------------------------------------------- 1 | namespace PowerShellConsole 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | public class ApplicationExtensionPoints 9 | { 10 | public string InvokeCurrentScript = "InvokeCurrentScript"; 11 | public string InvokeInitializeConsole = "InvokeInitializeConsole"; 12 | 13 | private static ApplicationExtensionPoints applicationExtensionPointsInstance; 14 | public static ApplicationExtensionPoints ApplicationExtensionPointsInstance 15 | { 16 | get 17 | { 18 | if (applicationExtensionPointsInstance == null) 19 | { 20 | applicationExtensionPointsInstance = new ApplicationExtensionPoints(); 21 | } 22 | 23 | return applicationExtensionPointsInstance; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /PowerShellConsole/Commands/ControlSpacebarCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Management.Automation; 3 | using System.Windows.Input; 4 | using ICSharpCode.AvalonEdit; 5 | using PowerShellConsole.Utilities; 6 | 7 | namespace PowerShellConsole.Commands 8 | { 9 | public class ControlSpacebarCommand : ICommand 10 | { 11 | public event EventHandler CanExecuteChanged; 12 | 13 | private TextEditor textEditor; 14 | 15 | public ControlSpacebarCommand(TextEditor textEditor) 16 | { 17 | if (textEditor == null) 18 | { 19 | throw new ArgumentNullException("textEditor in ControlSpaceBarCommand ctor"); 20 | } 21 | 22 | this.textEditor = textEditor; 23 | } 24 | 25 | public bool CanExecute(object parameter) 26 | { 27 | return true; 28 | } 29 | 30 | public void Execute(object parameter) 31 | { 32 | TextEditorUtilities.InvokeCompletionWindow(textEditor); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /PowerShellConsole/Commands/F5Command.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Windows.Input; 4 | using ICSharpCode.AvalonEdit; 5 | 6 | namespace PowerShellConsole.Commands 7 | { 8 | public class F5Command : ICommand 9 | { 10 | public event EventHandler CanExecuteChanged; 11 | 12 | private TextEditor textEditor; 13 | 14 | public F5Command(TextEditor textEditor) 15 | { 16 | if (textEditor == null) 17 | { 18 | throw new ArgumentNullException("textEditor in F5Command ctor"); 19 | } 20 | 21 | this.textEditor = textEditor; 22 | } 23 | 24 | public bool CanExecute(object parameter) 25 | { 26 | return true; 27 | } 28 | 29 | public void Execute(object parameter) 30 | { 31 | ApplicationExtensionPoints 32 | .ApplicationExtensionPointsInstance 33 | .InvokeCurrentScript 34 | .ExecuteScriptEntryPoint(); 35 | 36 | foreach (var item in textEditor.Text.ExecutePS()) 37 | { 38 | Debug.WriteLine(item); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /PowerShellConsole/CompletionData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Management.Automation; 3 | using System.Windows.Media; 4 | using ICSharpCode.AvalonEdit.CodeCompletion; 5 | using ICSharpCode.AvalonEdit.Document; 6 | using ICSharpCode.AvalonEdit.Editing; 7 | 8 | namespace PowerShellConsole 9 | { 10 | public class CompletionData : ICompletionData 11 | { 12 | public string ToolTip { get; set; } 13 | public string CompletionText { get; set; } 14 | public CompletionResultType Resultype { get; set; } 15 | public int ReplacementLength { get; set; } 16 | 17 | public ImageSource Image 18 | { 19 | get 20 | { 21 | switch (Resultype) 22 | { 23 | case CompletionResultType.Command: 24 | break; 25 | case CompletionResultType.History: 26 | break; 27 | case CompletionResultType.Method: 28 | break; 29 | case CompletionResultType.Namespace: 30 | break; 31 | case CompletionResultType.ParameterName: 32 | break; 33 | case CompletionResultType.ParameterValue: 34 | break; 35 | case CompletionResultType.Property: 36 | break; 37 | case CompletionResultType.ProviderContainer: 38 | break; 39 | case CompletionResultType.ProviderItem: 40 | break; 41 | case CompletionResultType.Text: 42 | break; 43 | case CompletionResultType.Type: 44 | break; 45 | case CompletionResultType.Variable: 46 | break; 47 | default: 48 | break; 49 | } 50 | 51 | return null; 52 | } 53 | } 54 | 55 | public string Text 56 | { 57 | get 58 | { 59 | return CompletionText; 60 | } 61 | } 62 | 63 | // Use this property if you want to show a fancy UIElement in the drop down list. 64 | public object Content 65 | { 66 | get { return this.Text; } 67 | } 68 | 69 | public object Description 70 | { 71 | get { return this.ToolTip; } 72 | } 73 | 74 | public double Priority { get { return 0; } } 75 | 76 | public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs) 77 | { 78 | var length = textArea.Caret.Offset; 79 | var offset = completionSegment.Offset - ReplacementLength; 80 | 81 | length = offset == 0 ? 82 | length : 83 | length - completionSegment.Offset + ReplacementLength; 84 | 85 | textArea.Document.Replace(offset, length, this.Text); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /PowerShellConsole/FoldingStrategies/BraceFoldingStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using ICSharpCode.AvalonEdit.Folding; 6 | using ICSharpCode.AvalonEdit.Document; 7 | 8 | namespace PowerShellConsole.FoldingStrategies 9 | { 10 | public class BraceFoldingStrategy : AbstractFoldingStrategy 11 | { 12 | /// 13 | /// Gets/Sets the opening brace. The default value is '{'. 14 | /// 15 | public char OpeningBrace { get; set; } 16 | 17 | /// 18 | /// Gets/Sets the closing brace. The default value is '}'. 19 | /// 20 | public char ClosingBrace { get; set; } 21 | 22 | /// 23 | /// Creates a new BraceFoldingStrategy. 24 | /// 25 | public BraceFoldingStrategy() 26 | { 27 | this.OpeningBrace = '{'; 28 | this.ClosingBrace = '}'; 29 | } 30 | 31 | /// 32 | /// Create s for the specified document. 33 | /// 34 | public override IEnumerable CreateNewFoldings(TextDocument document, out int firstErrorOffset) 35 | { 36 | firstErrorOffset = -1; 37 | return CreateNewFoldings(document); 38 | } 39 | 40 | /// 41 | /// Create s for the specified document. 42 | /// 43 | public IEnumerable CreateNewFoldings(ITextSource document) 44 | { 45 | List newFoldings = new List(); 46 | 47 | Stack startOffsets = new Stack(); 48 | int lastNewLineOffset = 0; 49 | char openingBrace = this.OpeningBrace; 50 | char closingBrace = this.ClosingBrace; 51 | for (int i = 0; i < document.TextLength; i++) 52 | { 53 | char c = document.GetCharAt(i); 54 | if (c == openingBrace) 55 | { 56 | startOffsets.Push(i); 57 | } 58 | else if (c == closingBrace && startOffsets.Count > 0) 59 | { 60 | int startOffset = startOffsets.Pop(); 61 | // don't fold if opening and closing brace are on the same line 62 | if (startOffset < lastNewLineOffset) 63 | { 64 | newFoldings.Add(new NewFolding(startOffset, i + 1)); 65 | } 66 | } 67 | else if (c == '\n' || c == '\r') 68 | { 69 | lastNewLineOffset = i + 1; 70 | } 71 | } 72 | newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset)); 73 | return newFoldings; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /PowerShellConsole/ITextMarker.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) 2 | // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Windows.Media; 7 | 8 | namespace ICSharpCode.SharpDevelop.Editor 9 | { 10 | /// 11 | /// Represents a text marker. 12 | /// 13 | public interface ITextMarker 14 | { 15 | /// 16 | /// Gets the start offset of the marked text region. 17 | /// 18 | int StartOffset { get; } 19 | 20 | /// 21 | /// Gets the end offset of the marked text region. 22 | /// 23 | int EndOffset { get; } 24 | 25 | /// 26 | /// Gets the length of the marked region. 27 | /// 28 | int Length { get; } 29 | 30 | /// 31 | /// Deletes the text marker. 32 | /// 33 | void Delete(); 34 | 35 | /// 36 | /// Gets whether the text marker was deleted. 37 | /// 38 | bool IsDeleted { get; } 39 | 40 | /// 41 | /// Event that occurs when the text marker is deleted. 42 | /// 43 | event EventHandler Deleted; 44 | 45 | /// 46 | /// Gets/Sets the background color. 47 | /// 48 | Color? BackgroundColor { get; set; } 49 | 50 | /// 51 | /// Gets/Sets the foreground color. 52 | /// 53 | Color? ForegroundColor { get; set; } 54 | 55 | /// 56 | /// Gets/Sets the type of the marker. Use TextMarkerType.None for normal markers. 57 | /// 58 | TextMarkerType MarkerType { get; set; } 59 | 60 | /// 61 | /// Gets/Sets the color of the marker. 62 | /// 63 | Color MarkerColor { get; set; } 64 | 65 | /// 66 | /// Gets/Sets an object with additional data for this text marker. 67 | /// 68 | object Tag { get; set; } 69 | 70 | /// 71 | /// Gets/Sets an object that will be displayed as tooltip in the text editor. 72 | /// 73 | object ToolTip { get; set; } 74 | } 75 | 76 | public enum TextMarkerType 77 | { 78 | /// 79 | /// Use no marker 80 | /// 81 | None, 82 | /// 83 | /// Use squiggly underline marker 84 | /// 85 | SquigglyUnderline 86 | } 87 | 88 | public interface ITextMarkerService 89 | { 90 | /// 91 | /// Creates a new text marker. The text marker will be invisible at first, 92 | /// you need to set one of the Color properties to make it visible. 93 | /// 94 | ITextMarker Create(int startOffset, int length); 95 | 96 | /// 97 | /// Gets the list of text markers. 98 | /// 99 | IEnumerable TextMarkers { get; } 100 | 101 | /// 102 | /// Removes the specified text marker. 103 | /// 104 | void Remove(ITextMarker marker); 105 | 106 | /// 107 | /// Removes all text markers that match the condition. 108 | /// 109 | void RemoveAll(Predicate predicate); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /PowerShellConsole/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  7 | 8 | 13 | 14 | -------------------------------------------------------------------------------- /PowerShellConsole/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | // http://www.opensourcejavaphp.net/csharp/sharpdevelop/CodeEditor.cs.html 2 | 3 | using System; 4 | using System.Diagnostics; 5 | using System.Management.Automation.Language; 6 | using System.Reflection; 7 | using System.Windows; 8 | using System.Windows.Controls; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Threading; 12 | using System.Xml; 13 | using ICSharpCode.AvalonEdit.AddIn; 14 | using ICSharpCode.AvalonEdit.Folding; 15 | using ICSharpCode.AvalonEdit.Highlighting; 16 | using ICSharpCode.AvalonEdit.Highlighting.Xshd; 17 | using ICSharpCode.SharpDevelop.Editor; 18 | using PowerShellConsole.Commands; 19 | using PowerShellConsole.FoldingStrategies; 20 | using PowerShellConsole.Utilities; 21 | 22 | namespace PowerShellConsole 23 | { 24 | /// 25 | /// Interaction logic for MainWindow.xaml 26 | /// 27 | public partial class MainWindow : Window 28 | { 29 | AbstractFoldingStrategy foldingStrategy; 30 | FoldingManager foldingManager; 31 | TextMarkerService textMarkerService; 32 | ToolTip toolTip; 33 | 34 | public MainWindow() 35 | { 36 | InitializeComponent(); 37 | 38 | textEditor.Focus(); 39 | 40 | textEditor.TextArea.PreviewKeyUp += new KeyEventHandler(TextArea_PreviewKeyUp); 41 | textEditor.TextArea.TextEntered += new TextCompositionEventHandler(TextArea_TextEntered); 42 | 43 | textEditor.MouseHover += new MouseEventHandler(textEditor_MouseHover); 44 | textEditor.MouseHoverStopped += new MouseEventHandler(textEditor_MouseHoverStopped); 45 | 46 | textEditor.ShowLineNumbers = true; 47 | 48 | //textEditor.TextArea.TextView.LineTransformers.Add(new TransfromFunctionKeyword()); 49 | 50 | textEditor.Load("TextFile.ps1"); 51 | 52 | InstallFoldingStrategy(); 53 | AddSyntaxHighlighting(); 54 | SetupInputHandlers(); 55 | SetupMarkerService(); 56 | TestForSyntaxErrors(); 57 | 58 | PSConsolePowerShell.SetVariable("tse", this); 59 | PSConsolePowerShell.SetVariable("textEditor", this.textEditor); 60 | 61 | //ApplicationExtensionPoints 62 | // .ApplicationExtensionPointsInstance 63 | // .InvokeInitializeConsole 64 | // .ExecuteScriptEntryPoint(); 65 | 66 | "InvokeInitializeConsole".ExecuteScriptEntryPoint(this); 67 | } 68 | 69 | private void SetupMarkerService() 70 | { 71 | textMarkerService = new TextMarkerService(this.textEditor.Document); 72 | textEditor.TextArea.TextView.BackgroundRenderers.Add(textMarkerService); 73 | 74 | var textView = textEditor.TextArea.TextView; 75 | textView.LineTransformers.Add(textMarkerService); 76 | textView.Services.AddService(typeof(ITextMarkerService), textMarkerService); 77 | } 78 | 79 | private void SetupInputHandlers() 80 | { 81 | AddF5(); 82 | AddCtrlSpacebar(); 83 | } 84 | 85 | private void AddCtrlSpacebar() 86 | { 87 | var handleCtrlSpacebar = new KeyBinding(new ControlSpacebarCommand(textEditor), Key.Space, ModifierKeys.Control); 88 | AddKeyBinding(handleCtrlSpacebar); 89 | } 90 | 91 | private void AddF5() 92 | { 93 | KeyBinding handleF5 = new KeyBinding(new F5Command(textEditor), new KeyGesture(Key.F5)); 94 | AddKeyBinding(handleF5); 95 | } 96 | 97 | private void AddKeyBinding(KeyBinding targetBinding) 98 | { 99 | textEditor.TextArea.DefaultInputHandler.Editing.InputBindings.Add(targetBinding); 100 | } 101 | 102 | private void InstallFoldingStrategy() 103 | { 104 | foldingManager = FoldingManager.Install(textEditor.TextArea); 105 | foldingStrategy = new BraceFoldingStrategy(); 106 | foldingStrategy.UpdateFoldings(foldingManager, textEditor.Document); 107 | 108 | AddFoldingStrategyTimer(); 109 | } 110 | 111 | private void AddSyntaxHighlighting() 112 | { 113 | using (var s = Assembly.GetExecutingAssembly().GetManifestResourceStream("PowerShellConsole.PowerShell.xshd")) 114 | { 115 | if (s != null) 116 | { 117 | using (var reader = new XmlTextReader(s)) 118 | { 119 | textEditor.SyntaxHighlighting = HighlightingLoader.Load(reader, HighlightingManager.Instance); 120 | } 121 | } 122 | } 123 | } 124 | 125 | private void AddFoldingStrategyTimer() 126 | { 127 | var foldingUpdateTimer = new DispatcherTimer(); 128 | 129 | foldingUpdateTimer.Interval = TimeSpan.FromSeconds(2); 130 | foldingUpdateTimer.Tick += new EventHandler(foldingUpdateTimer_Tick); 131 | foldingUpdateTimer.Start(); 132 | } 133 | 134 | void foldingUpdateTimer_Tick(object sender, EventArgs e) 135 | { 136 | foldingStrategy.UpdateFoldings(foldingManager, textEditor.Document); 137 | } 138 | 139 | void TextArea_TextEntered(object sender, TextCompositionEventArgs e) 140 | { 141 | if (e.Text.IndexOfAny(@"$-.:\".ToCharArray()) != -1) 142 | { 143 | TextEditorUtilities.InvokeCompletionWindow(textEditor); 144 | } 145 | } 146 | 147 | void TextArea_PreviewKeyUp(object sender, KeyEventArgs e) 148 | { 149 | if ( 150 | e.KeyboardDevice.Modifiers == ModifierKeys.Control || 151 | e.KeyboardDevice.Modifiers == ModifierKeys.None || 152 | e.KeyboardDevice.Modifiers == ModifierKeys.Shift 153 | ) 154 | { 155 | if (e.Key == Key.Down || 156 | e.Key == Key.Up || 157 | e.Key == Key.PageDown || 158 | e.Key == Key.PageUp || 159 | e.Key == Key.Home || 160 | e.Key == Key.End || 161 | e.Key == Key.Left || 162 | e.Key == Key.Right || 163 | e.Key == Key.RightCtrl || 164 | e.Key == Key.LeftCtrl 165 | ) return; 166 | } 167 | 168 | // don't check for syntax errors 169 | // if any of those keys were pressed 170 | var msg = string.Format("PreviewKeyUp: {0} {1}", e.KeyboardDevice.Modifiers, e.Key); 171 | Debug.WriteLine(msg); 172 | 173 | TestForSyntaxErrors(); 174 | } 175 | 176 | private void TestForSyntaxErrors() 177 | { 178 | textMarkerService.RemoveAll(); 179 | var script = textEditor.TextArea.TextView.Document.Text; 180 | 181 | Token[] token; 182 | ParseError[] errors; 183 | var ast = Parser.ParseInput(script, out token, out errors); 184 | 185 | foreach (var item in errors) 186 | { 187 | var startOffset = item.Extent.StartOffset; 188 | var endOffset = item.Extent.EndOffset; 189 | var toolTip = item.Message; 190 | var length = endOffset - startOffset; 191 | var m = textMarkerService.Create(startOffset, length); 192 | 193 | m.MarkerType = TextMarkerType.SquigglyUnderline; 194 | m.MarkerColor = Colors.Red; 195 | m.ToolTip = toolTip; 196 | } 197 | } 198 | 199 | void textEditor_MouseHover(object sender, MouseEventArgs e) 200 | { 201 | var textView = textEditor.TextArea.TextView; 202 | var textMarkerService = textView.Services.GetService(typeof(ITextMarkerService)) as ITextMarkerService; 203 | if (textMarkerService != null) 204 | { 205 | foreach (var textMarker in textMarkerService.TextMarkers) 206 | { 207 | if (toolTip == null) 208 | { 209 | toolTip = new ToolTip(); 210 | } 211 | 212 | toolTip.Content = textMarker.ToolTip; 213 | toolTip.IsOpen = true; 214 | e.Handled = true; 215 | } 216 | } 217 | } 218 | 219 | void textEditor_MouseHoverStopped(object sender, MouseEventArgs e) 220 | { 221 | if (toolTip != null) 222 | { 223 | toolTip.IsOpen = false; 224 | } 225 | } 226 | 227 | } 228 | 229 | //public class TransfromFunctionKeyword : DocumentColorizingTransformer 230 | //{ 231 | // protected override void ColorizeLine(DocumentLine line) 232 | // { 233 | // int lineStartOffset = line.Offset; 234 | // string text = CurrentContext.Document.GetText(line); 235 | // int start = 0; 236 | // int index; 237 | // while ((index = text.IndexOf("function", start)) >= 0) 238 | // { 239 | // base.ChangeLinePart( 240 | // lineStartOffset + index, // startOffset 241 | // lineStartOffset + index + 10, // endOffset 242 | // (VisualLineElement element) => 243 | // { 244 | // // This lambda gets called once for every VisualLineElement 245 | // // between the specified offsets. 246 | // Typeface tf = element.TextRunProperties.Typeface; 247 | // // Replace the typeface with a modified version of 248 | // // the same typeface 249 | // element.TextRunProperties.SetTypeface(new Typeface( 250 | // tf.FontFamily, 251 | // FontStyles.Italic, 252 | // FontWeights.Bold, 253 | // tf.Stretch 254 | // )); 255 | // }); 256 | // start = index + 1; // search for next occurrence 257 | // } 258 | // } 259 | //} 260 | } 261 | -------------------------------------------------------------------------------- /PowerShellConsole/PSConsolePowerShell.cs: -------------------------------------------------------------------------------- 1 | namespace PowerShellConsole 2 | { 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | using System.Diagnostics; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Management.Automation; 9 | using System.Management.Automation.Runspaces; 10 | using System.Reflection; 11 | using System; 12 | 13 | public static class PSConsolePowerShell 14 | { 15 | static PowerShell powerShell; 16 | static Runspace rs; 17 | 18 | public static PowerShell PowerShellInstance 19 | { 20 | get 21 | { 22 | if (powerShell == null) 23 | { 24 | PSConsoleRunspace.SessionStateProxy.SetVariable("sep", ApplicationExtensionPoints.ApplicationExtensionPointsInstance); 25 | 26 | powerShell = PowerShell.Create(); 27 | powerShell.Runspace = PSConsoleRunspace; 28 | } 29 | 30 | return powerShell; 31 | } 32 | } 33 | 34 | internal static Runspace PSConsoleRunspace 35 | { 36 | get 37 | { 38 | if (rs == null) 39 | { 40 | rs = RunspaceFactory.CreateRunspace(); 41 | rs.ThreadOptions = PSThreadOptions.UseCurrentThread; 42 | rs.Open(); 43 | } 44 | 45 | return rs; 46 | } 47 | } 48 | 49 | public static Collection ExecutePS(this string script) 50 | { 51 | return PowerShellInstance 52 | .AddScript(script) 53 | .AddCommand("Out-String") 54 | .Invoke(); 55 | } 56 | 57 | public static void ExecuteScriptEntryPoint(this string scriptEntryPoint, object argument = null) 58 | { 59 | foreach (var file in GetScriptsToRun(scriptEntryPoint)) 60 | { 61 | var results = PowerShellInstance 62 | .AddCommand(file) 63 | .AddParameter("stuff", argument) 64 | .AddCommand("Out-String") 65 | .Invoke(); 66 | 67 | foreach (var item in results) 68 | { 69 | Debug.WriteLine(item); 70 | } 71 | } 72 | } 73 | 74 | private static IEnumerable GetScriptsToRun(string scriptEntryPoint) 75 | { 76 | var scriptDirectory = GetScriptsDirectory(); 77 | 78 | if (Directory.Exists(scriptDirectory)) 79 | { 80 | return Directory.GetFiles(scriptDirectory, scriptEntryPoint + "*.ps1").ToList(); 81 | } 82 | 83 | var message = string.Format("{0} does not exist, no scripts to run.", scriptDirectory); 84 | Debug.WriteLine(message); 85 | return new List(); 86 | } 87 | 88 | private static string GetScriptsDirectory() 89 | { 90 | var location = Assembly.GetExecutingAssembly().Location; 91 | var path = Path.GetDirectoryName(location); 92 | 93 | return Path.Combine(path, "scripts"); 94 | } 95 | 96 | public static void SetVariable(string name, object value) 97 | { 98 | PSConsoleRunspace.SessionStateProxy.SetVariable(name, value); 99 | } 100 | } 101 | } -------------------------------------------------------------------------------- /PowerShellConsole/PowerShell.xshd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | \# 19 | 20 | 21 | 22 | <\# 23 | \#> 24 | 25 | 26 | 27 | " 28 | " 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | ' 37 | ' 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | @" 46 | "@ 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | while 55 | param 56 | end 57 | define 58 | else 59 | from 60 | foreach 61 | var 62 | dynamicparam 63 | filter 64 | dp 65 | until 66 | for 67 | exit 68 | switch 69 | process 70 | begin 71 | elseif 72 | if 73 | in 74 | data 75 | class 76 | using 77 | function 78 | 79 | 80 | 81 | catch 82 | finally 83 | throw 84 | trap 85 | try 86 | 87 | 88 | 89 | break 90 | continue 91 | return 92 | 93 | 94 | 95 | class 96 | 97 | 98 | 99 | -not 100 | -band 101 | -bor 102 | -replace 103 | -ireplace 104 | -creplace 105 | -and 106 | -or 107 | -is 108 | -isnot 109 | -as 110 | -lt 111 | -le 112 | -gt 113 | -ge 114 | -eq 115 | -ne 116 | -contains 117 | -notcontains 118 | -like 119 | -notlike 120 | -match 121 | -notmatch 122 | 123 | 124 | 125 | \$[\d\w_]+ 126 | 127 | 128 | 129 | [\w]+-[\w]+ 130 | 131 | 132 | 133 | 134 | \b0[xX][0-9a-fA-F]+ # hex number 135 | | 136 | ( \b\d+(\.[0-9]+)? #number with optional floating point 137 | | \.[0-9]+ #or just starting with floating point 138 | ) 139 | ([eE][+-]?[0-9]+)? # optional exponent 140 | 141 | 142 | 143 | [?,.;()\[\]{}+\-/%*<>^+~!|&]+ 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /PowerShellConsole/PowerShellConsole.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {B3CF68CC-416E-4038-A203-F9E52FDA53CB} 9 | WinExe 10 | Properties 11 | PowerShellConsole 12 | PowerShellConsole 13 | v4.0 14 | Client 15 | 512 16 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 17 | 4 18 | 19 | 20 | x86 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | x86 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | 38 | 39 | 40 | False 41 | libs\ICSharpCode.AvalonEdit.dll 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 4.0 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | MSBuild:Compile 61 | Designer 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | MSBuild:Compile 73 | Designer 74 | 75 | 76 | App.xaml 77 | Code 78 | 79 | 80 | MainWindow.xaml 81 | Code 82 | 83 | 84 | 85 | 86 | 87 | Code 88 | 89 | 90 | True 91 | True 92 | Resources.resx 93 | 94 | 95 | True 96 | Settings.settings 97 | True 98 | 99 | 100 | ResXFileCodeGenerator 101 | Resources.Designer.cs 102 | 103 | 104 | Designer 105 | 106 | 107 | SettingsSingleFileGenerator 108 | Settings.Designer.cs 109 | 110 | 111 | 112 | Always 113 | 114 | 115 | Always 116 | 117 | 118 | Always 119 | 120 | 121 | Always 122 | 123 | 124 | Always 125 | 126 | 127 | 128 | 129 | 136 | -------------------------------------------------------------------------------- /PowerShellConsole/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("PowerShellConsole")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("Doug Finke")] 14 | [assembly: AssemblyProduct("PowerShellConsole")] 15 | [assembly: AssemblyCopyright("Copyright © Doug Finke 2012")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | // You can specify all the values or you can default the Build and Revision Numbers 52 | // by using the '*' as shown below: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("1.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.0.0.0")] 56 | -------------------------------------------------------------------------------- /PowerShellConsole/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.269 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace PowerShellConsole.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PowerShellConsole.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /PowerShellConsole/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /PowerShellConsole/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.269 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace PowerShellConsole.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /PowerShellConsole/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /PowerShellConsole/Scripts/InvokeCompletedInput.ps1: -------------------------------------------------------------------------------- 1 | param($stuff) 2 | 3 | $stuff | gm -------------------------------------------------------------------------------- /PowerShellConsole/Scripts/InvokeCurrentScriptClearScreen.ps1: -------------------------------------------------------------------------------- 1 | param($stuff) 2 | 3 | $tse.Title = "Hello from Script Entry Point: $(Get-Date)" -------------------------------------------------------------------------------- /PowerShellConsole/Scripts/InvokeCurrentScriptTest.ps1: -------------------------------------------------------------------------------- 1 | param($stuff) 2 | 3 | 1..5 -------------------------------------------------------------------------------- /PowerShellConsole/Scripts/InvokeInitializeConsole.ps1: -------------------------------------------------------------------------------- 1 | param($stuff) 2 | 3 | $stuff 4 | #$tse.Title = $stuff.ToString() 5 | #$tse.Title = "[Ready] $(Get-Date)" 6 | #$tse.TextEditor -------------------------------------------------------------------------------- /PowerShellConsole/TextFile.ps1: -------------------------------------------------------------------------------- 1 | (get-date).Ticks -------------------------------------------------------------------------------- /PowerShellConsole/TextMarkerService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) 2 | // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Diagnostics; 7 | using System.Linq; 8 | using System.Windows; 9 | using System.Windows.Media; 10 | using System.Windows.Threading; 11 | 12 | using ICSharpCode.AvalonEdit.Document; 13 | using ICSharpCode.AvalonEdit.Rendering; 14 | using ICSharpCode.SharpDevelop; 15 | using ICSharpCode.SharpDevelop.Editor; 16 | 17 | namespace ICSharpCode.AvalonEdit.AddIn 18 | { 19 | /// 20 | /// Handles the text markers for a code editor. 21 | /// 22 | public sealed class TextMarkerService : DocumentColorizingTransformer, IBackgroundRenderer, ITextMarkerService, ITextViewConnect 23 | { 24 | TextSegmentCollection markers; 25 | TextDocument document; 26 | 27 | public TextMarkerService(TextDocument document) 28 | { 29 | if (document == null) 30 | throw new ArgumentNullException("document"); 31 | this.document = document; 32 | this.markers = new TextSegmentCollection(document); 33 | } 34 | 35 | #region ITextMarkerService 36 | public ITextMarker Create(int startOffset, int length) 37 | { 38 | if (markers == null) 39 | throw new InvalidOperationException("Cannot create a marker when not attached to a document"); 40 | 41 | int textLength = document.TextLength; 42 | if (startOffset < 0 || startOffset > textLength) 43 | throw new ArgumentOutOfRangeException("startOffset", startOffset, "Value must be between 0 and " + textLength); 44 | if (length < 0 || startOffset + length > textLength) 45 | throw new ArgumentOutOfRangeException("length", length, "length must not be negative and startOffset+length must not be after the end of the document"); 46 | 47 | TextMarker m = new TextMarker(this, startOffset, length); 48 | markers.Add(m); 49 | // no need to mark segment for redraw: the text marker is invisible until a property is set 50 | return m; 51 | } 52 | 53 | public IEnumerable GetMarkersAtOffset(int offset) 54 | { 55 | if (markers == null) 56 | return Enumerable.Empty(); 57 | else 58 | return markers.FindSegmentsContaining(offset); 59 | } 60 | 61 | public IEnumerable TextMarkers 62 | { 63 | get { return markers ?? Enumerable.Empty(); } 64 | } 65 | 66 | public void RemoveAll() 67 | { 68 | if (markers != null) 69 | { 70 | foreach (TextMarker m in markers.ToArray()) 71 | { 72 | Remove(m); 73 | } 74 | } 75 | } 76 | 77 | public void RemoveAll(Predicate predicate) 78 | { 79 | if (predicate == null) 80 | throw new ArgumentNullException("predicate"); 81 | if (markers != null) 82 | { 83 | foreach (TextMarker m in markers.ToArray()) 84 | { 85 | if (predicate(m)) 86 | Remove(m); 87 | } 88 | } 89 | } 90 | 91 | public void Remove(ITextMarker marker) 92 | { 93 | if (marker == null) 94 | throw new ArgumentNullException("marker"); 95 | TextMarker m = marker as TextMarker; 96 | if (markers != null && markers.Remove(m)) 97 | { 98 | Redraw(m); 99 | m.OnDeleted(); 100 | } 101 | } 102 | 103 | /// 104 | /// Redraws the specified text segment. 105 | /// 106 | internal void Redraw(ISegment segment) 107 | { 108 | foreach (var view in textViews) 109 | { 110 | view.Redraw(segment, DispatcherPriority.Normal); 111 | } 112 | } 113 | #endregion 114 | 115 | #region DocumentColorizingTransformer 116 | protected override void ColorizeLine(DocumentLine line) 117 | { 118 | if (markers == null) 119 | return; 120 | int lineStart = line.Offset; 121 | int lineEnd = lineStart + line.Length; 122 | foreach (TextMarker marker in markers.FindOverlappingSegments(lineStart, line.Length)) 123 | { 124 | Brush foregroundBrush = null; 125 | if (marker.ForegroundColor != null) 126 | { 127 | foregroundBrush = new SolidColorBrush(marker.ForegroundColor.Value); 128 | foregroundBrush.Freeze(); 129 | } 130 | ChangeLinePart( 131 | Math.Max(marker.StartOffset, lineStart), 132 | Math.Min(marker.EndOffset, lineEnd), 133 | element => 134 | { 135 | if (foregroundBrush != null) 136 | { 137 | element.TextRunProperties.SetForegroundBrush(foregroundBrush); 138 | } 139 | } 140 | ); 141 | } 142 | } 143 | #endregion 144 | 145 | #region IBackgroundRenderer 146 | public KnownLayer Layer 147 | { 148 | get 149 | { 150 | // draw behind selection 151 | return KnownLayer.Selection; 152 | } 153 | } 154 | 155 | public void Draw(TextView textView, DrawingContext drawingContext) 156 | { 157 | if (textView == null) 158 | throw new ArgumentNullException("textView"); 159 | if (drawingContext == null) 160 | throw new ArgumentNullException("drawingContext"); 161 | if (markers == null || !textView.VisualLinesValid) 162 | return; 163 | var visualLines = textView.VisualLines; 164 | if (visualLines.Count == 0) 165 | return; 166 | int viewStart = visualLines.First().FirstDocumentLine.Offset; 167 | int viewEnd = visualLines.Last().LastDocumentLine.EndOffset; 168 | foreach (TextMarker marker in markers.FindOverlappingSegments(viewStart, viewEnd - viewStart)) 169 | { 170 | if (marker.BackgroundColor != null) 171 | { 172 | BackgroundGeometryBuilder geoBuilder = new BackgroundGeometryBuilder(); 173 | geoBuilder.AlignToWholePixels = true; 174 | geoBuilder.CornerRadius = 3; 175 | geoBuilder.AddSegment(textView, marker); 176 | Geometry geometry = geoBuilder.CreateGeometry(); 177 | if (geometry != null) 178 | { 179 | Color color = marker.BackgroundColor.Value; 180 | SolidColorBrush brush = new SolidColorBrush(color); 181 | brush.Freeze(); 182 | drawingContext.DrawGeometry(brush, null, geometry); 183 | } 184 | } 185 | if (marker.MarkerType != TextMarkerType.None) 186 | { 187 | foreach (Rect r in BackgroundGeometryBuilder.GetRectsForSegment(textView, marker)) 188 | { 189 | Point startPoint = r.BottomLeft; 190 | Point endPoint = r.BottomRight; 191 | 192 | Pen usedPen = new Pen(new SolidColorBrush(marker.MarkerColor), 1); 193 | usedPen.Freeze(); 194 | switch (marker.MarkerType) 195 | { 196 | case TextMarkerType.SquigglyUnderline: 197 | double offset = 2.5; 198 | 199 | int count = Math.Max((int)((endPoint.X - startPoint.X) / offset) + 1, 4); 200 | 201 | StreamGeometry geometry = new StreamGeometry(); 202 | 203 | using (StreamGeometryContext ctx = geometry.Open()) 204 | { 205 | ctx.BeginFigure(startPoint, false, false); 206 | ctx.PolyLineTo(CreatePoints(startPoint, endPoint, offset, count).ToArray(), true, false); 207 | } 208 | 209 | geometry.Freeze(); 210 | 211 | drawingContext.DrawGeometry(Brushes.Transparent, usedPen, geometry); 212 | break; 213 | } 214 | } 215 | } 216 | } 217 | } 218 | 219 | IEnumerable CreatePoints(Point start, Point end, double offset, int count) 220 | { 221 | for (int i = 0; i < count; i++) 222 | yield return new Point(start.X + i * offset, start.Y - ((i + 1) % 2 == 0 ? offset : 0)); 223 | } 224 | #endregion 225 | 226 | #region ITextViewConnect 227 | readonly List textViews = new List(); 228 | 229 | void ITextViewConnect.AddToTextView(TextView textView) 230 | { 231 | if (textView != null && !textViews.Contains(textView)) 232 | { 233 | Debug.Assert(textView.Document == document); 234 | textViews.Add(textView); 235 | } 236 | } 237 | 238 | void ITextViewConnect.RemoveFromTextView(TextView textView) 239 | { 240 | if (textView != null) 241 | { 242 | Debug.Assert(textView.Document == document); 243 | textViews.Remove(textView); 244 | } 245 | } 246 | #endregion 247 | } 248 | 249 | public sealed class TextMarker : TextSegment, ITextMarker 250 | { 251 | readonly TextMarkerService service; 252 | 253 | public TextMarker(TextMarkerService service, int startOffset, int length) 254 | { 255 | if (service == null) 256 | throw new ArgumentNullException("service"); 257 | this.service = service; 258 | this.StartOffset = startOffset; 259 | this.Length = length; 260 | this.markerType = TextMarkerType.None; 261 | } 262 | 263 | public event EventHandler Deleted; 264 | 265 | public bool IsDeleted 266 | { 267 | get { return !this.IsConnectedToCollection; } 268 | } 269 | 270 | public void Delete() 271 | { 272 | service.Remove(this); 273 | } 274 | 275 | internal void OnDeleted() 276 | { 277 | if (Deleted != null) 278 | Deleted(this, EventArgs.Empty); 279 | } 280 | 281 | void Redraw() 282 | { 283 | service.Redraw(this); 284 | } 285 | 286 | Color? backgroundColor; 287 | 288 | public Color? BackgroundColor 289 | { 290 | get { return backgroundColor; } 291 | set 292 | { 293 | if (backgroundColor != value) 294 | { 295 | backgroundColor = value; 296 | Redraw(); 297 | } 298 | } 299 | } 300 | 301 | Color? foregroundColor; 302 | 303 | public Color? ForegroundColor 304 | { 305 | get { return foregroundColor; } 306 | set 307 | { 308 | if (foregroundColor != value) 309 | { 310 | foregroundColor = value; 311 | Redraw(); 312 | } 313 | } 314 | } 315 | 316 | public object Tag { get; set; } 317 | 318 | TextMarkerType markerType; 319 | 320 | public TextMarkerType MarkerType 321 | { 322 | get { return markerType; } 323 | set 324 | { 325 | if (markerType != value) 326 | { 327 | markerType = value; 328 | Redraw(); 329 | } 330 | } 331 | } 332 | 333 | Color markerColor; 334 | 335 | public Color MarkerColor 336 | { 337 | get { return markerColor; } 338 | set 339 | { 340 | if (markerColor != value) 341 | { 342 | markerColor = value; 343 | Redraw(); 344 | } 345 | } 346 | } 347 | 348 | public object ToolTip { get; set; } 349 | } 350 | } 351 | -------------------------------------------------------------------------------- /PowerShellConsole/Utilities/TextEditorUtilities.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Management.Automation; 3 | using ICSharpCode.AvalonEdit; 4 | using ICSharpCode.AvalonEdit.CodeCompletion; 5 | 6 | namespace PowerShellConsole.Utilities 7 | { 8 | public class TextEditorUtilities 9 | { 10 | static CompletionWindow completionWindow; 11 | 12 | public static void InvokeCompletionWindow(TextEditor textEditor) 13 | { 14 | completionWindow = new CompletionWindow(textEditor.TextArea); 15 | 16 | completionWindow.Closed += delegate 17 | { 18 | completionWindow = null; 19 | }; 20 | 21 | var text = textEditor.Text; 22 | var offset = textEditor.TextArea.Caret.Offset; 23 | 24 | var completedInput = CommandCompletion.CompleteInput(text, offset, null, PSConsolePowerShell.PowerShellInstance); 25 | // var r = CommandCompletion.MapStringInputToParsedInput(text, offset); 26 | 27 | "InvokeCompletedInput".ExecuteScriptEntryPoint(completedInput.CompletionMatches); 28 | 29 | if (completedInput.CompletionMatches.Count > 0) 30 | { 31 | completedInput.CompletionMatches.ToList() 32 | .ForEach(record => 33 | { 34 | completionWindow.CompletionList.CompletionData.Add( 35 | new CompletionData 36 | { 37 | CompletionText = record.CompletionText, 38 | ToolTip = record.ToolTip, 39 | Resultype = record.ResultType, 40 | ReplacementLength = completedInput.ReplacementLength 41 | }); 42 | }); 43 | 44 | completionWindow.Show(); 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /PowerShellConsole/libs/ICSharpCode.AvalonEdit.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/PowerShellConsole/908638ca250cc474f2389fd4ae32ce43c82932d1/PowerShellConsole/libs/ICSharpCode.AvalonEdit.dll -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | This repository contains a C# solution for creating a PowerShell console with the AvalonEdit control http://www.icsharpcode.net/OpenSource/SD. 3 | This can then be embedded into another C# application and poof, you've added scripting capabilities to your app. 4 | 5 | ## Highlights 6 | * Does syntax verification including red squiggles and tooltips 7 | * Code folding 8 | * Syntax highlighting 9 | * Intellisense with *tooltips* 10 | * Even at the .NET level, try typing **System.** 11 | 12 | ![pic1] 13 | 14 | ## Code completion 15 | ### .NET types 16 | 17 | ![pic2] 18 | 19 | ### .NET types compiled on the fly 20 | 21 | ![pic3] 22 | 23 | [pic1]: http://dougfinke.com/powershellfordevelopers/powershellconsole.png 24 | [pic2]: http://dougfinke.com/powershellfordevelopers/PowerShellConsoleCodeCompletion.png 25 | [pic3]: http://dougfinke.com/powershellfordevelopers/PowerShellConsoleCodeCompletionOnTheFly.png 26 | -------------------------------------------------------------------------------- /TestFile.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/PowerShellConsole/908638ca250cc474f2389fd4ae32ce43c82932d1/TestFile.ps1 --------------------------------------------------------------------------------