├── .chezmoi.yaml.tmpl
├── .chezmoiexternal.toml
├── .chezmoiignore
├── .gitignore
├── .vscode
├── launch.json
└── settings.json
├── AppData
├── Local
│ ├── Packages
│ │ ├── Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe
│ │ │ └── LocalState
│ │ │ │ └── settings.json
│ │ └── Microsoft.WindowsTerminal_8wekyb3d8bbwe
│ │ │ └── LocalState
│ │ │ └── settings.json.tmpl
│ └── nvim
│ │ ├── coc-settings.json
│ │ └── init.vim
└── Roaming
│ └── apex-config
│ ├── CopyConfigs.ps1
│ ├── apex-config.cfg
│ └── autoexec.cfg
├── Documents
├── PowerShell
│ ├── CompletionClasses.ps1
│ ├── CompletionExtensions.ps1
│ ├── EditorCommands.ps1
│ ├── EnvironmentVariables.ps1
│ ├── InstallPwshCommands.ps1
│ ├── LinqETS.ps1
│ ├── Microsoft.PowerShell_profile.ps1
│ ├── Microsoft.VSCode_profile.ps1
│ ├── Modules
│ │ └── PSWriteline
│ │ │ └── 0.1.0
│ │ │ ├── Classes
│ │ │ └── TextWalker.ps1
│ │ │ ├── KeyHandlers
│ │ │ ├── CommandPalette.ps1
│ │ │ ├── DeleteRealLine.ps1
│ │ │ ├── SmartBrace.ps1
│ │ │ ├── SmartCloseBrace.ps1
│ │ │ ├── SmartDelete.ps1
│ │ │ ├── SmartQuote.ps1
│ │ │ ├── SmartSelfInsert.ps1
│ │ │ ├── SmartTab.ps1
│ │ │ └── YouSurround.ps1
│ │ │ ├── PSWriteline.psd1
│ │ │ ├── PSWriteline.psm1
│ │ │ ├── PSWriteline.types.ps1xml
│ │ │ ├── Private
│ │ │ ├── GetBufferState.ps1
│ │ │ ├── GetFunctionMap.ps1
│ │ │ ├── GetHandlerAction.ps1
│ │ │ ├── GetHotstring.ps1
│ │ │ ├── GetMotion.ps1
│ │ │ ├── GetSingleton.ps1
│ │ │ ├── InvokeStatusPrompt.ps1
│ │ │ ├── NewHotstring.ps1
│ │ │ ├── NewUnboundHandler.ps1
│ │ │ └── SetInternalHandler.ps1
│ │ │ └── Public
│ │ │ ├── Get-PSWritelineKeyHandler.ps1
│ │ │ ├── Import-PSWriteline.ps1
│ │ │ └── Set-PSWritelineKeyHandler.ps1
│ ├── NamespaceAwareCompletion.ps1
│ ├── OpCodeDescriptions.ps1
│ ├── PSReadLine.ps1
│ ├── PreviewCommands.ps1
│ ├── Profile
│ │ └── src
│ │ │ └── Profile
│ │ │ ├── Any.cs
│ │ │ ├── Assert.cs
│ │ │ ├── BindTo.cs
│ │ │ ├── Commands
│ │ │ ├── InstallerCommandBase.cs
│ │ │ ├── InvokeWithPipeCommand.cs
│ │ │ ├── NewObjectPath.cs
│ │ │ └── UseConstrainedLanguageCommand.cs
│ │ │ ├── CompletionHelper.cs
│ │ │ ├── FlagsExpressionArgumentCompleter.cs
│ │ │ ├── Functional.cs
│ │ │ ├── GetWindowCommand.cs
│ │ │ ├── Infer.cs
│ │ │ ├── InferredValueVisitor.cs
│ │ │ ├── InterfaceOps.cs
│ │ │ ├── InvokeFormatBinder.cs
│ │ │ ├── Links
│ │ │ ├── DarwinLink.cs
│ │ │ ├── DataBlockHeader.cs
│ │ │ ├── GpfIdlFlags.cs
│ │ │ ├── HeapRef.cs
│ │ │ ├── LinkConsoleFeProps.cs
│ │ │ ├── LinkConsoleProps.cs
│ │ │ ├── LinkCoord.cs
│ │ │ ├── LinkDataBlockSignature.cs
│ │ │ ├── LinkIdList.cs
│ │ │ ├── LinkIdListDescriptionId.cs
│ │ │ ├── LinkSigDn.cs
│ │ │ ├── LinkSpecialFolder.cs
│ │ │ ├── LnkConsoleColorRef.cs
│ │ │ ├── LnkConsoleColorTable.cs
│ │ │ ├── LnkConsoleSettings.cs
│ │ │ ├── LnkFile.cs
│ │ │ ├── PathInlineArray.cs
│ │ │ ├── PinnedArrayMemoryManager.cs
│ │ │ ├── PitchAndFamily.cs
│ │ │ ├── ShortcutFlags.cs
│ │ │ └── ShowWindowCmd.cs
│ │ │ ├── LooseHandle.cs
│ │ │ ├── NativeMethods.json
│ │ │ ├── NativeMethods.txt
│ │ │ ├── PointerOps.cs
│ │ │ ├── PooledConverter.cs
│ │ │ ├── PooledRunspaces.cs
│ │ │ ├── Profile.csproj
│ │ │ ├── PropVariant.cs
│ │ │ ├── Rect.cs
│ │ │ ├── ReflectionCache.cs
│ │ │ ├── StaticInterfaceProxies.cs
│ │ │ ├── Throw.cs
│ │ │ ├── TypedVisitor.cs
│ │ │ ├── UnsafeExtensions.cs
│ │ │ ├── WinError.cs
│ │ │ ├── WindowInfo.cs
│ │ │ ├── pooled.cs
│ │ │ ├── ptr.NumberImpl.cs
│ │ │ └── ptr.cs
│ ├── Prompt.ps1
│ ├── ReplacePSScriptRoot.ps1
│ ├── SetConsoleFont.ps1
│ ├── SetTypeCache.ps1
│ ├── Utility.psm1
│ ├── VT.ps1
│ ├── WindowCommands.ps1
│ ├── consoleColors.reg
│ ├── gh.Completer.ps1
│ ├── intrinsics.ps1
│ ├── locationAliases.json
│ ├── profile.format.ps1xml
│ ├── profile.ps1
│ └── profile.types.ps1xml
└── symlink_WindowsPowerShell.tmpl
├── LICENSE
├── README.md
├── VSCode
├── keybindings.json
└── settings.json
├── admin_tasks.ps1
├── chezmoi.sln
├── dot_gitconfig.tmpl
├── dot_vimfiles
├── auto.vim
├── dot_vimrc
├── maps.vim
├── plugins.vim
├── settings.vim
└── theme.vim
├── dot_vsvimrc
├── install.ps1
├── run_once_before_main.ps1
├── scoop
└── persist
│ ├── flow-launcher
│ └── UserData
│ │ └── Settings
│ │ └── create_Settings.json.tmpl
│ └── gpg
│ └── home
│ ├── create_pubring.kbx.tmpl
│ ├── create_sshcontrol
│ ├── create_trustdb.gpg.tmpl
│ ├── gpg-agent.conf
│ ├── gpg.conf
│ └── private-keys-v1.d
│ ├── create_46DB57DD7EEAF5072638F87027305014F88D8672.key.tmpl
│ ├── create_4CAE9C47015539C8746E2D7DD996FA9EF07734E5.key.tmpl
│ └── create_B89472198FD14885C51A9166A82BD71BA5A7CA5D.key.tmpl
├── symlink_dot_vim.tmpl
└── symlink_dot_vimrc.tmpl
/.chezmoi.yaml.tmpl:
--------------------------------------------------------------------------------
1 | {{- $secrets := not (env "NO_SECRETS") -}}
2 | {{- $work := not (not (env "WORK")) -}}
3 |
4 | sourceDir: {{ .chezmoi.sourceDir }}
5 |
6 | merge:
7 | command: "code"
8 | args:
9 | - --wait
10 | - --merge
11 | - "{{ "{{ .Destination }}" }}"
12 | - "{{ "{{ .Source }}" }}"
13 | - "{{ "{{ .Target }}" }}"
14 | data:
15 | name: "Patrick Meinecke"
16 | email: "seeminglyscience@gmail.com"
17 | gpgkey: "1399631D3A499DBB"
18 | work: {{ $work }}
19 | secrets: {{ $secrets }}
20 | {{- if $secrets }}
21 | bitwarden:
22 | pgp_files: a2cc3139-a5c0-44bd-8549-ae6e00291c73
23 | {{- end }}
24 |
--------------------------------------------------------------------------------
/.chezmoiexternal.toml:
--------------------------------------------------------------------------------
1 | ["AppData/Local/nvim/autoload/plug.vim"]
2 | type = "file"
3 | url = "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim"
4 | refreshPeriod = "168h"
5 |
6 | ["scoop/persist/flow-launcher/UserData/Plugins/Window Walker-2.0.2"]
7 | type = "archive"
8 | url = "https://github.com/taooceros/Flow.Plugin.WindowWalker/releases/download/v2.0.2/WindowWalker-2.0.2.zip"
9 |
10 | ["scoop/persist/flow-launcher/UserData/Plugins/Everything-1.7.2"]
11 | type = "archive"
12 | url = "https://github.com/Flow-Launcher/Flow.Launcher.Plugin.Everything/releases/download/v1.7.2/Flow.Launcher.Plugin.Everything.zip"
13 |
--------------------------------------------------------------------------------
/.chezmoiignore:
--------------------------------------------------------------------------------
1 | README.md
2 | LICENSE
3 | admin_tasks.ps1
4 | install.ps1
5 | VSCode/
6 | .vscode/
7 | Documents/PowerShell/Profile/src/Profile/obj/
8 | Documents/PowerShell/Profile/src/Profile/bin/
9 |
10 | {{- if .work }}
11 | AppData/Roaming/apex-config/
12 | {{- end -}}
13 |
14 | {{- if not .secrets }}
15 | scoop/persist/gpg/home/
16 | {{- end }}
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 | obj/
3 | project.nuget.cache
4 | project.assets.json
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": ".NET Core Attach",
9 | "type": "coreclr",
10 | "request": "attach",
11 | "justMyCode": false,
12 | "sourceFileMap": {
13 | "C:\\Users\\pmeinecke\\Documents\\PowerShell\\Profile\\src\\Profile": "C:\\Users\\pmeinecke\\.local\\share\\chezmoi\\Documents\\PowerShell\\Profile\\src\\Profile"
14 | }
15 | }
16 | ]
17 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.insertFinalNewline": false
3 | }
4 |
--------------------------------------------------------------------------------
/AppData/Local/Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/LocalState/settings.json.tmpl:
--------------------------------------------------------------------------------
1 | {{ include "./AppData/Local/Packages/Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe/LocalState/settings.json" }}
2 |
--------------------------------------------------------------------------------
/AppData/Local/nvim/coc-settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "powershell.integratedConsole.showOnStartup": false,
3 | "powershell.powerShellExePath": "C:/Program Files/PowerShell/7-preview/pwsh.exe",
4 | "languageserver": {
5 | "efm": {
6 | "command": "efm-langserver",
7 | "args": [],
8 | "filetypes": ["vim", "markdown"],
9 | },
10 | },
11 | }
12 |
--------------------------------------------------------------------------------
/AppData/Local/nvim/init.vim:
--------------------------------------------------------------------------------
1 | source $HOME\.vimfiles\.vimrc
2 |
--------------------------------------------------------------------------------
/AppData/Roaming/apex-config/CopyConfigs.ps1:
--------------------------------------------------------------------------------
1 | # Originally this was going to make symlinks but that doesn't seem to work either :/
2 | [CmdletBinding()]
3 | param(
4 | [Parameter()]
5 | [ValidateNotNullOrEmpty()]
6 | [string] $ApexPath
7 | )
8 | end {
9 | if (-not $ApexPath) {
10 | $ApexPath = "${env:ProgramFiles(x86)}\Steam\steamapps\common\Apex Legends"
11 | }
12 |
13 | $configFolder = Join-Path $ApexPath cfg
14 | $autoExec = Join-Path $configFolder autoexec.cfg
15 | $apexConfig = Join-Path $configFolder apex-config.cfg
16 | $splat = @{ ErrorAction = 'Stop' }
17 | Copy-Item @splat -Path (Join-Path $PSScriptRoot autoexec.cfg) -Destination $autoExec
18 | Copy-Item @splat -Path (Join-Path $PSScriptRoot apex-config.cfg) -Destination $apexConfig
19 | }
20 |
--------------------------------------------------------------------------------
/AppData/Roaming/apex-config/autoexec.cfg:
--------------------------------------------------------------------------------
1 | exec apex-config.cfg
2 |
--------------------------------------------------------------------------------
/Documents/PowerShell/CompletionExtensions.ps1:
--------------------------------------------------------------------------------
1 | . $PSScriptRoot\ReplacePSScriptRoot.ps1
2 | $global:__registered_extensions = . "$PSScriptRoot/CompletionClasses.ps1"
3 | function global:NewProxyTabExpansion2 {
4 | [OutputType([System.Management.Automation.CommandCompletion])]
5 | [CmdletBinding(DefaultParameterSetName = 'ScriptInputSet')]
6 | param(
7 | [Parameter(ParameterSetName = 'ScriptInputSet', Mandatory, Position = 0)]
8 | [string] $inputScript,
9 |
10 | [Parameter(ParameterSetName = 'ScriptInputSet', Mandatory, Position = 1)]
11 | [int] $cursorColumn,
12 |
13 | [Parameter(ParameterSetName = 'AstInputSet', Mandatory, Position = 0)]
14 | [System.Management.Automation.Language.Ast] $ast,
15 |
16 | [Parameter(ParameterSetName = 'AstInputSet', Mandatory, Position = 1)]
17 | [System.Management.Automation.Language.Token[]] $tokens,
18 |
19 | [Parameter(ParameterSetName = 'AstInputSet', Mandatory, Position = 2)]
20 | [System.Management.Automation.Language.IScriptPosition] $positionOfCursor,
21 |
22 | [Parameter(ParameterSetName = 'AstInputSet', Position = 3)]
23 | [Parameter(ParameterSetName = 'ScriptInputSet', Position = 2)]
24 | [hashtable] $options
25 | )
26 | begin {
27 | $boundParams = $PSBoundParameters
28 | if ($PSCmdlet.ParameterSetName -eq 'ScriptInputSet') {
29 | $null = & {
30 | $completionInfo = [System.Management.Automation.CommandCompletion]::
31 | MapStringInputToParsedInput(
32 | $boundParams['inputScript'],
33 | $boundParams['cursorColumn'])
34 |
35 | $boundParams.Remove('inputScript')
36 | $boundParams.Remove('cursorColumn')
37 | $boundParams.Add('ast', $completionInfo.Item1)
38 | $boundParams.Add('tokens', $completionInfo.Item2)
39 | $boundParams.Add('positionOfCursor', $completionInfo.Item3)
40 | }
41 | }
42 |
43 | $namespaces = & {
44 | $flags = [System.Reflection.BindingFlags]'Instance, NonPublic'
45 | $internalSessionState = $ExecutionContext.SessionState.GetType().
46 | GetProperty('Internal', $flags).
47 | GetValue($ExecutionContext.SessionState)
48 |
49 | $globalScope = $internalSessionState.GetType().
50 | GetProperty('GlobalScope', $flags).
51 | GetValue($internalSessionState)
52 |
53 | $typeResolutionState = $globalScope.GetType().
54 | GetProperty('TypeResolutionState', $flags).
55 | GetValue($globalScope)
56 |
57 | $namespaces = $typeResolutionState.GetType().
58 | GetField('namespaces', $flags).
59 | GetValue($typeResolutionState)
60 | }
61 |
62 | ${//completion_extensions} = & {
63 | $scriptAst = $boundParams['ast']
64 |
65 | $allRelatedAsts = $scriptAst.FindAll(
66 | {
67 | param([System.Management.Automation.Language.Ast] $a)
68 | end {
69 | return $positionOfCursor.Offset -ge $a.Extent.StartOffset -and
70 | $positionOfCursor.Offset -le $a.Extent.EndOffset
71 | }
72 | },
73 | $true)
74 |
75 | $lastRelatedAst = $allRelatedAsts | Select-Object -Last 1
76 | foreach (${//completion_extension} in $global:__registered_extensions) {
77 | ${//completion_extension} = ${//completion_extension}::new()
78 | ${//completion_extension}.Cmdlet = $PSCmdlet
79 | ${//completion_extension}.BoundParameters = $boundParams
80 | ${//completion_extension}.DynamicUsings = $namespaces
81 | ${//completion_extension}.RelatedAst = $lastRelatedAst
82 | ${//completion_extension}.OriginalAst = $scriptAst
83 | ${//completion_extension}.PreProcess()
84 |
85 | # yield
86 | ${//completion_extension}
87 | }
88 | }
89 |
90 | Remove-Variable boundParams
91 | Remove-Variable namespaces
92 |
93 | try {
94 | if ($PSBoundParameters.ContainsKey('OutBuffer')) {
95 | $PSBoundParameters['OutBuffer'] = 1
96 | }
97 |
98 | $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand(
99 | 'TabExpansion2',
100 | [System.Management.Automation.CommandTypes]::Function)
101 | $scriptCmd = { & $wrappedCmd @PSBoundParameters }
102 | $steppablePipeline = $scriptCmd.GetSteppablePipeline()
103 | $steppablePipeline.Begin($MyInvocation.ExpectingInput)
104 | } catch {
105 | }
106 | }
107 | process {
108 | try {
109 | $steppablePipeline.Process($PSItem)
110 | } catch {
111 |
112 | }
113 | }
114 | end {
115 | try {
116 | ${++completion} = $steppablePipeline.End()[0]
117 | ${++ref} = [ref] ${++completion}
118 | $boundParams = $PSBoundParameters
119 | & {
120 | $positionOfCursor = $boundParams['positionOfCursor']
121 | $scriptText = ${//completion_extensions}[0].OriginalAst.Extent.StartScriptPosition.GetFullScript()
122 |
123 | $textToBeReplaced = $scriptText.Substring(
124 | ${++completion}.ReplacementIndex,
125 | ${++completion}.ReplacementLength)
126 |
127 | foreach (${++completion_extension} in ${//completion_extensions}) {
128 | ${++completion_extension}.TextToBeReplaced = $textToBeReplaced
129 | ${++completion_extension}._result = ${++ref}
130 | ${++completion_extension}.DoPostProcess()
131 | }
132 | }
133 |
134 | return ${++ref}.Value
135 | } catch {
136 | $PSCmdlet.WriteError($PSItem)
137 | }
138 | }
139 | <#
140 | .ForwardHelpTargetName TabExpansion2
141 | .ForwardHelpCategory Function
142 | #>
143 | }
144 |
145 | Microsoft.PowerShell.Utility\Set-Alias TabExpansion2 -Value NewProxyTabExpansion2 -Scope Global
146 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Microsoft.PowerShell_profile.ps1:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Microsoft.VSCode_profile.ps1:
--------------------------------------------------------------------------------
1 | if ((Get-ChildItem $psEditor.Workspace.Path).Name -notcontains 'build.psake.ps1') {
2 | Set-Alias task Invoke-Build
3 | }
4 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/Classes/TextWalker.ps1:
--------------------------------------------------------------------------------
1 | class TextWalker {
2 | [int] $Cursor;
3 | [string] $Text;
4 |
5 | hidden [char[]] $Chars;
6 |
7 | TextWalker([string] $text, [int] $cursor) {
8 | $this.Chars = $text.ToCharArray()
9 | $this.Text = $text
10 | $this.Cursor = $cursor
11 | }
12 |
13 | }
14 |
15 | class Extent {
16 | [Position] $Start;
17 | [Position] $End;
18 |
19 | Extent([Position] $start, [Position] $end) {
20 | $this.Start = $start
21 | $this.End = $end
22 | }
23 | }
24 |
25 | class Position {
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/KeyHandlers/CommandPalette.ps1:
--------------------------------------------------------------------------------
1 | function CommandPalette {
2 | param(
3 | [System.Nullable[System.ConsoleKeyInfo]] $key,
4 | [object] $arg
5 | )
6 | end {
7 | $handlers = Get-PSWritelineKeyHandler
8 | $resultGetter = {
9 | param([string] $Query)
10 | end {
11 | return $handlers.Where{ $PSItem.Name -like "*$Query*" }
12 | }
13 | }
14 | $resultFormatter = {
15 | param([psobject] $Handler)
16 | end {
17 | return '{0} - {1}' -f $Handler.Name, $Handler.Description
18 | }
19 | }
20 |
21 | $result = InvokeStatusPrompt `
22 | -Prompt 'Command Search' `
23 | -ResultGetterCallback $resultGetter `
24 | -ResultFormatterCallback $resultFormatter
25 |
26 | if (-not $result) { return }
27 |
28 | $action = GetHandlerAction -Handler $result
29 | $action.Invoke()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/KeyHandlers/DeleteRealLine.ps1:
--------------------------------------------------------------------------------
1 | function DeleteRealLine {
2 | [CmdletBinding()]
3 | param()
4 | end {
5 | $state = GetBufferState
6 |
7 | if ($state.Ast.Extent.EndLineNumber -eq 1) {
8 | [Microsoft.PowerShell.PSConsoleReadLine]::DeleteLine()
9 | return
10 | }
11 |
12 | [Microsoft.PowerShell.PSConsoleReadLine]::Delete(
13 | $state.Cursor.Offset - $state.Cursor.ColumnNumber,
14 | $state.Cursor.Line.Length)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/KeyHandlers/SmartBrace.ps1:
--------------------------------------------------------------------------------
1 | function SmartBrace {
2 | [CmdletBinding()]
3 | param($key, $arg)
4 | end {
5 |
6 | $closeChar = switch ($key.KeyChar) {
7 | '(' { [char]')'; break }
8 | '{' { [char]'}'; break }
9 | '[' { [char]']'; break }
10 | }
11 |
12 | # Added selection test - pmm
13 | $selectionStart = $selectionLength = $null
14 | [Microsoft.PowerShell.PSConsoleReadLine]::GetSelectionState([ref]$selectionStart, [ref]$selectionLength)
15 |
16 | $line = $cursor = $null
17 | [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
18 | if ($selectionStart -ne -1) {
19 | [Microsoft.PowerShell.PSConsoleReadLine]::Replace(
20 | $selectionStart,
21 | $selectionLength,
22 | $key.KeyChar + $line.SubString($selectionStart, $selectionLength) + $closeChar)
23 | [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($selectionStart + $selectionLength + 2)
24 | return
25 | }
26 |
27 | if ($line[$cursor] -match '\w') {
28 | [Microsoft.PowerShell.PSConsoleReadLine]::Insert($key.KeyChar)
29 | return
30 | }
31 |
32 | [Microsoft.PowerShell.PSConsoleReadLine]::Insert("$($key.KeyChar)$closeChar")
33 | $line = $null
34 | $cursor = $null
35 | [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
36 | [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor - 1)
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/KeyHandlers/SmartCloseBrace.ps1:
--------------------------------------------------------------------------------
1 | function SmartCloseBrace {
2 | [CmdletBinding()]
3 | param($key, $arg)
4 | end {
5 | $line = $null
6 | $cursor = $null
7 | [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
8 |
9 | if ($line[$cursor] -eq $key.KeyChar) {
10 | [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor + 1)
11 | } else {
12 | [Microsoft.PowerShell.PSConsoleReadLine]::Insert("$($key.KeyChar)")
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/KeyHandlers/SmartDelete.ps1:
--------------------------------------------------------------------------------
1 | function SmartDelete {
2 | [CmdletBinding()]
3 | param($key, $arg)
4 | end {
5 | $line = $null
6 | $cursor = $null
7 | [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
8 |
9 | if ($cursor -gt 0) {
10 | if ($line[$cursor - 1] -eq ' ') {
11 | $mappedInput = [System.Management.Automation.CommandCompletion]::
12 | MapStringInputToParsedInput(
13 | $line,
14 | $cursor)
15 | if ($mappedInput.Item3.ColumnNumber -ge 4) {
16 | $totalOffset = 1
17 | foreach($offset in 2..4) {
18 | if ($line[$cursor - $offset] -ne ' ') {
19 | break
20 | }
21 |
22 | $totalOffset++
23 | }
24 |
25 | [Microsoft.PowerShell.PSConsoleReadLine]::
26 | Delete(
27 | $cursor - $totalOffset,
28 | $totalOffset)
29 | return
30 | }
31 | }
32 |
33 | $toMatch = $null
34 | if ($cursor -lt $line.Length) {
35 | switch ($line[$cursor]) {
36 | '"' { $toMatch = '"' }
37 | "'" { $toMatch = "'" }
38 | ')' { $toMatch = '(' }
39 | ']' { $toMatch = '[' }
40 | '}' { $toMatch = '{' }
41 | }
42 | }
43 |
44 | if ($toMatch -ne $null -and $line[$cursor-1] -eq $toMatch) {
45 | [Microsoft.PowerShell.PSConsoleReadLine]::Delete($cursor - 1, 2)
46 | } else {
47 | [Microsoft.PowerShell.PSConsoleReadLine]::BackwardDeleteChar($key, $arg)
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/KeyHandlers/SmartQuote.ps1:
--------------------------------------------------------------------------------
1 | function SmartQuote {
2 | [CmdletBinding()]
3 | param($key, $arg)
4 | end {
5 | $selectionStart = $selectionLength = $null
6 | [Microsoft.PowerShell.PSConsoleReadLine]::GetSelectionState([ref]$selectionStart, [ref]$selectionLength)
7 |
8 | $line = $cursor = $null
9 | [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
10 |
11 | if ($selectionStart -ne -1) {
12 | [Microsoft.PowerShell.PSConsoleReadLine]::Replace(
13 | $selectionStart,
14 | $selectionLength,
15 | $key.KeyChar + $line.SubString($selectionStart, $selectionLength) + $key.KeyChar)
16 | [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($selectionStart + $selectionLength + 2)
17 | return
18 | }
19 |
20 | $quoteNumber = Select-String -InputObject $line -Pattern $key.KeyChar -AllMatches
21 | if ($quoteNumber.Matches.Count % 2 -eq 1) {
22 | # Oneven amount of quotes, put just one quote
23 | [Microsoft.PowerShell.PSConsoleReadline]::Insert($key.KeyChar)
24 | } elseif ($line[$cursor] -eq $key.KeyChar) {
25 | # Just move the cursor
26 | [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor + 1)
27 | # Clause added - pmm
28 | } elseif ($line[$cursor] -match '\w' -or $line[$cursor - 1] -match '\w') {
29 | [Microsoft.PowerShell.PSConsoleReadLine]::Insert($key.KeyChar)
30 | } else {
31 | # Insert matching quotes, move cursor to be in between the quotes
32 | [Microsoft.PowerShell.PSConsoleReadLine]::Insert("$($key.KeyChar)" * 2)
33 | [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
34 | [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor - 1)
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/KeyHandlers/SmartSelfInsert.ps1:
--------------------------------------------------------------------------------
1 | using namespace Microsoft.PowerShell
2 |
3 | function SmartSelfInsert {
4 | [CmdletBinding()]
5 | param(
6 | [Nullable[ConsoleKeyInfo]] $key,
7 | [object] $arg
8 | )
9 | end {
10 | $bindingFlags = [System.Reflection.BindingFlags]'Instance, NonPublic'
11 | $editQueue = [PSConsoleReadLine].
12 | GetField('_edits', $bindingFlags).
13 | GetValue((GetSingleton))
14 |
15 | if (0 -eq $editQueue.Count) {
16 | [PSConsoleReadLine]::SelfInsert($key, $arg)
17 | return
18 | }
19 |
20 | $char = $key.KeyChar
21 |
22 | $hotstrings = GetHotstring -Character $char
23 | if (-not $hotstrings) {
24 | [PSConsoleReadLine]::SelfInsert($keys, $arg)
25 | return
26 | }
27 |
28 | foreach ($hotstring in $hotstrings) {
29 | $triggers = $hotstring.Chars
30 | $edits = $editQueue.Where({ $true }, 'Last', $triggers.Count - 1)
31 | if (($triggers.Count - 1) -gt $editQueue.Count) {
32 | continue
33 | }
34 |
35 | $isMatch = $true
36 | for ($i = 0; $i -lt $triggers.Count - 1; $i++) {
37 | $targetEdit = $edits[$i]
38 | if ($targetEdit.GetType().Name -ne 'EditItemInsertChar' -or
39 | $targetEdit.GetType().
40 | GetField('_insertedCharacter', $bindingFlags).
41 | GetValue($targetEdit) -ne $triggers[$i])
42 | {
43 | $isMatch = $false
44 | break
45 | }
46 | }
47 |
48 | if (-not $isMatch) {
49 | continue
50 | }
51 |
52 | $cursor = $null
53 | [PSConsoleReadLine]::GetBufferState([ref]$null, [ref]$cursor)
54 | [PSConsoleReadLine]::Delete(
55 | $cursor - ($triggers.Count - 1),
56 | $triggers.Count - 1)
57 |
58 | & $hotstring.Action $key $arg
59 | return
60 | }
61 |
62 | [PSConsoleReadLine]::SelfInsert($key, $arg)
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/KeyHandlers/SmartTab.ps1:
--------------------------------------------------------------------------------
1 | function SmartTab {
2 | param([Nullable[ConsoleKeyInfo]]$key, [object]$arg)
3 | end {
4 | $defaultIndent = ' '
5 |
6 | $singleton = GetSingleton
7 | $tabCommandCount = $singleton.GetType().
8 | GetField('_tabCommandCount', 60).
9 | GetValue($singleton)
10 |
11 | if ($tabCommandCount) {
12 | [Microsoft.PowerShell.PSConsoleReadLine]::TabCompleteNext()
13 | return
14 | }
15 | $buffer = $cursorLocation = $null
16 | [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$buffer, [ref]$cursorLocation)
17 |
18 | # if ([string]::IsNullOrWhiteSpace($buffer)) {
19 | # [Microsoft.PowerShell.PSConsoleReadLine]::Insert($defaultIndent)
20 | # return
21 | # }
22 |
23 | $mappedInput = [System.Management.Automation.CommandCompletion]::MapStringInputToParsedInput(
24 | $buffer,
25 | $cursorLocation)
26 |
27 | # try {
28 | # $completions = [System.Management.Automation.CommandCompletion]::CompleteInput(
29 | # $mappedInput.Item1,
30 | # $mappedInput.Item2,
31 | # $mappedInput.Item3,
32 | # @{})
33 | # } catch {
34 | # [System.Management.Automation.Hidden()]
35 | # $global:__LAST_TAB_COMPLETE_ERROR = $PSItem
36 | # $completions = $null
37 | # }
38 |
39 | $position = $mappedInput.Item3
40 | if (-not [string]::IsNullOrWhiteSpace($position.Line.Substring(0, $position.ColumnNumber - 1))) {
41 | [Microsoft.PowerShell.PSConsoleReadLine]::TabCompleteNext()
42 | return
43 | }
44 |
45 | $offsetInRow = $position.ColumnNumber - 1
46 | $indentSize = $defaultIndent.Length
47 | $indent = ' ' * ((($offsetInRow % $indentSize) - $indentSize) * -1)
48 | if ($indent.Length -gt $defaultIndent.Length) {
49 | $indent = $defaultIndent
50 | }
51 |
52 | [Microsoft.PowerShell.PSConsoleReadLine]::Insert($indent)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/KeyHandlers/YouSurround.ps1:
--------------------------------------------------------------------------------
1 | function YouSurround {
2 | [CmdletBinding()]
3 | param(
4 | [Nullable[ConsoleKeyInfo]] $Key,
5 |
6 | [object] $Arg
7 | )
8 | end {
9 |
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/PSWriteline.psd1:
--------------------------------------------------------------------------------
1 | #
2 | # Module manifest for module 'PSWriteline'
3 | #
4 | # Generated by: Patrick Meinecke
5 | #
6 | # Generated on: 9/14/2017
7 | #
8 |
9 | @{
10 |
11 | # Script module or binary module file associated with this manifest.
12 | RootModule = 'PSWriteline.psm1'
13 |
14 | # Version number of this module.
15 | ModuleVersion = '0.1.0'
16 |
17 | # ID used to uniquely identify this module
18 | GUID = '90b6b6fb-010f-4ebd-a590-ea31386ba293'
19 |
20 | # Author of this module
21 | Author = 'Patrick Meinecke'
22 |
23 | # Company or vendor of this module
24 | CompanyName = 'Community'
25 |
26 | # Copyright statement for this module
27 | Copyright = '(c) 2017 Patrick Meinecke. All rights reserved.'
28 |
29 | # Description of the functionality provided by this module
30 | # Description = ''
31 |
32 | # Minimum version of the Windows PowerShell engine required by this module
33 | PowerShellVersion = '3.0'
34 |
35 | # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
36 | DotNetFrameworkVersion = '4.0'
37 |
38 | # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
39 | CLRVersion = '4.0'
40 |
41 | # Processor architecture (None, X86, Amd64) required by this module
42 | ProcessorArchitecture = 'None'
43 |
44 | # Type files (.ps1xml) to be loaded when importing this module
45 | TypesToProcess = 'PSWriteline.types.ps1xml'
46 |
47 | # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
48 | FunctionsToExport = 'Get-PSWritelineKeyHandler',
49 | 'Import-PSWriteline',
50 | 'Set-PSWritelineKeyHandler'
51 |
52 | # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
53 | CmdletsToExport = @()
54 |
55 | # Variables to export from this module
56 | VariablesToExport = @()
57 |
58 | # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
59 | AliasesToExport = @()
60 |
61 | # List of all files packaged with this module
62 | FileList = 'PSWriteline.psd1',
63 | 'PSWriteline.psm1',
64 | 'Public\Get-PSWritelineKeyHandler.ps1',
65 | 'Public\Import-PSWriteline.ps1',
66 | 'Public\Set-PSWritelineKeyHandler.ps1'
67 |
68 | # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
69 | PrivateData = @{
70 |
71 | PSData = @{
72 |
73 | # Tags applied to this module. These help with module discovery in online galleries.
74 | Tags = @()
75 |
76 | # A URL to the license for this module.
77 | LicenseUri = 'https://github.com/SeeminglyScience/PSWriteline/blob/master/LICENSE'
78 |
79 | # A URL to the main website for this project.
80 | ProjectUri = 'https://github.com/SeeminglyScience/PSWriteline'
81 |
82 | # A URL to an icon representing this module.
83 | # IconUri = ''
84 |
85 | # ReleaseNotes of this module
86 | # ReleaseNotes = ''
87 |
88 | } # End of PSData hashtable
89 |
90 | } # End of PrivateData hashtable
91 |
92 | }
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/PSWriteline.psm1:
--------------------------------------------------------------------------------
1 | Import-LocalizedData -BindingVariable Strings -FileName Strings -ErrorAction Ignore
2 |
3 | $script:PSReadLineSingleton = `
4 | [Microsoft.PowerShell.PSConsoleReadLine].
5 | GetField('_singleton', 60).
6 | GetValue($null)
7 |
8 | # Include all function files.
9 | Get-ChildItem `
10 | $PSScriptRoot\Public\*.ps1,
11 | $PSScriptRoot\Private\*.ps1,
12 | $PSScriptRoot\KeyHandlers\*.ps1 |
13 | ForEach-Object { . $PSItem.FullName }
14 |
15 | # Export only the functions using PowerShell standard verb-noun naming.
16 | # Be sure to list each exported functions in the FunctionsToExport field of the module manifest file.
17 | # This improves performance of command discovery in PowerShell.
18 | Export-ModuleMember -Function *-*
19 |
20 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/PSWriteline.types.ps1xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PSWriteline.Handler
5 |
6 |
7 | PSStandardMembers
8 |
9 |
10 | DefaultDisplayPropertySet
11 |
12 | Key
13 | Name
14 | Description
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/Private/GetBufferState.ps1:
--------------------------------------------------------------------------------
1 | using namespace System.Management.Automation
2 | using namespace System.Management.Automation.Language
3 | using namespace Microsoft.PowerShell
4 | function GetBufferState {
5 | [CmdletBinding()]
6 | param()
7 | end {
8 | $buffer, $cursorLocation = $null
9 | [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState(
10 | [ref]$buffer,
11 | [ref]$cursorLocation)
12 |
13 | if ([string]::IsNullOrWhiteSpace($buffer)) {
14 | $tokens = $null
15 | $ast = [Parser]::ParseInput(
16 | '',
17 | [ref]$tokens,
18 | [ref]$null)
19 |
20 | return [PSCustomObject]@{
21 | Ast = $ast
22 | Tokens = $tokens
23 | Cursor = $ast.Extent.StartScriptPosition
24 | CommandCompletion = [CommandCompletion]::new(@(), 0, 0, 0)
25 | }
26 | }
27 |
28 | $mappedInput = [CommandCompletion]::
29 | MapStringInputToParsedInput(
30 | $buffer,
31 | $cursorLocation)
32 | try {
33 | $completions = [CommandCompletion]::
34 | CompleteInput(
35 | $mappedInput.Item1,
36 | $mappedInput.Item2,
37 | $mappedInput.Item3,
38 | @{})
39 | } catch {
40 | $completions = [CommandCompletion]::new(@(), 0, 0, 0)
41 | }
42 |
43 | return [PSCustomObject]@{
44 | Ast = $mappedInput.Item1
45 | Tokens = $mappedInput.Item2
46 | Cursor = $mappedInput.Item3
47 | CommandCompletion = $completions
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/Private/GetFunctionMap.ps1:
--------------------------------------------------------------------------------
1 | function GetFunctionMap {
2 | [OutputType([hashtable])]
3 | [CmdletBinding()]
4 | param()
5 | end {
6 | $functionMap = @{}
7 | $functionMap.CommandPalette = [PSCustomObject]@{
8 | BriefDescription = 'CommandPalette'
9 | Description = 'Search and invoke PSReadline key handlers by name.'
10 | ScriptBlock = ${function:CommandPalette}
11 | }
12 |
13 | $functionMap.SmartBrace = [PSCustomObject]@{
14 | BriefDescription = 'SmartBrace'
15 | Description = 'Insert matching braces'
16 | ScriptBlock = ${function:SmartBrace}
17 | }
18 |
19 | $functionMap.SmartCloseBrace = [PSCustomObject]@{
20 | BriefDescription = 'SmartCloseBrace'
21 | Description = 'Insert closing brace or skip'
22 | ScriptBlock = ${function:SmartCloseBrace}
23 | }
24 |
25 | $functionMap.SmartDelete = [PSCustomObject]@{
26 | BriefDescription = 'SmartDelete'
27 | Description = 'Delete previous character or matching quotes/parens/braces'
28 | ScriptBlock = ${function:SmartDelete}
29 | }
30 |
31 | $functionMap.SmartQuote = [PSCustomObject]@{
32 | BriefDescription = 'SmartQuote'
33 | Description = 'Insert paired quotes if not already on a quote'
34 | ScriptBlock = ${function:SmartQuote}
35 | }
36 |
37 | $functionMap.SmartSelfInsert = [PSCustomObject]@{
38 | BriefDescription = 'SmartSelfInsert'
39 | Description = 'Insert the character pressed or complete a hot string.'
40 | ScriptBlock = ${function:SmartSelfInsert}
41 | }
42 |
43 | $functionMap.SmartTab = [PSCustomObject]@{
44 | BriefDescription = 'SmartTab'
45 | Description = 'Complete the current expression or increase indent.'
46 | ScriptBlock = ${function:SmartTab}
47 | }
48 |
49 | $functionMap.DeleteRealLine = [PSCustomObject]@{
50 | BriefDescription = 'DeleteRealLine'
51 | Description = 'Delete the line that the cursor is on. This deletes the actual line instead of the entire buffer.'
52 | ScriptBlock = ${function:DeleteRealLine}
53 | }
54 |
55 | $functionMap.GotoStartOfBuffer = [PSCustomObject]@{
56 | BriefDescription = 'GotoStartOfBuffer'
57 | Description = 'Go to the start of the input buffer regardless of the current line.'
58 | ScriptBlock = {
59 | [Microsoft.PowerShell.PSConsoleReadLine]::BeginningOfLine()
60 | [Microsoft.PowerShell.PSConsoleReadLine]::BeginningOfLine()
61 | }
62 | }
63 |
64 | $functionMap.GotoEndOfBuffer = [PSCustomObject]@{
65 | BriefDescription = 'GotoEndOfBuffer'
66 | Description = 'Go to the start of the input buffer regardless of the current line.'
67 | ScriptBlock = {
68 | [Microsoft.PowerShell.PSConsoleReadLine]::EndOfLine()
69 | [Microsoft.PowerShell.PSConsoleReadLine]::EndOfLine()
70 | }
71 | }
72 |
73 | $PSCmdlet.WriteObject($functionMap, $false)
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/Private/GetHandlerAction.ps1:
--------------------------------------------------------------------------------
1 | function GetHandlerAction {
2 | [CmdletBinding()]
3 | param(
4 | [PSTypeName('PSWriteline.Handler')] $Handler
5 | )
6 | begin {
7 | $flags = [System.Reflection.BindingFlags]'Instance, NonPublic'
8 | $instance = GetSingleton
9 | $dispatchTable = $instance.GetType().GetField('_dispatchTable', $flags).GetValue($instance)
10 | $chordDispatchTable = $instance.GetType().GetField('_chordDispatchTable', $flags).GetValue($instance)
11 | }
12 | end {
13 | if ($Handler.Action) {
14 | return $Handler.Action
15 | }
16 |
17 | $realHandler = $dispatchTable.
18 | Values.
19 | Where({ $_.BriefDescription -eq $Handler.Name }, 'First')
20 |
21 | if (-not $realHandler) {
22 | $realHandler = $chordDispatchTable.
23 | Values.
24 | Values.
25 | Where({ $_.BriefDescription -eq $Handler.Name }, 'First')
26 | }
27 |
28 | if ($realHandler.ScriptBlock) {
29 | return $realHandler.ScriptBlock
30 | }
31 |
32 | return [Microsoft.PowerShell.PSConsoleReadLine]::($Handler.Name)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/Private/GetHotstring.ps1:
--------------------------------------------------------------------------------
1 | using namespace System.Collections.Generic
2 |
3 | function GetHotstring {
4 | [OutputType([System.Collections.Generic.List[psobject]], ParameterSetName='Character')]
5 | [OutputType([System.Collections.Generic.Dictionary[char, System.Collections.Generic.List[psobject]]])]
6 | [CmdletBinding(DefaultParameterSetName='__AllParameterSets')]
7 | param(
8 | [Parameter(Mandatory, ParameterSetName='Character')]
9 | [ValidateNotNullOrEmpty()]
10 | [char] $Character
11 | )
12 | end {
13 | if (-not $script:HOTSTRING_STORE) {
14 | $script:HOTSTRING_STORE = [Dictionary[char, List[psobject]]]::new()
15 | }
16 |
17 | $store = $script:HOTSTRING_STORE
18 | if ($null -eq $Character) {
19 | $PSCmdlet.WriteObject($store, $false)
20 | return
21 | }
22 |
23 | $bindingList = $null
24 | if ($store.TryGetValue($Character, [ref]$bindingList)) {
25 | $PSCmdlet.WriteObject($bindingList, $false)
26 | return
27 | }
28 |
29 | $bindingList = [List[psobject]]::new()
30 | $store.Add($Character, $bindingList)
31 |
32 | $PSCmdlet.WriteObject($bindingList, $false)
33 | return
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/Private/GetMotion.ps1:
--------------------------------------------------------------------------------
1 | function GetMotion {
2 | [CmdletBinding()]
3 | param(
4 | [string] $Prompt,
5 |
6 | [char[]] $AdditionalCharacters
7 | )
8 | end {
9 | if ($Prompt) {
10 | $splat = @{ Prompt = $Prompt }
11 | }
12 |
13 | $motionState = [PSCustomObject]@{
14 | ShouldExitAfterNext = $false
15 | }
16 |
17 | $motionText = InvokeStatusPrompt @splat -PromptKeyHandler {
18 | param([ConsoleKeyInfo] $PromptKey, [psobject] $State)
19 | end {
20 | if ($motionState.ShouldExitAfterNext) {
21 | $State.ShouldExit = $true
22 | return
23 | }
24 |
25 | switch -Regex ($PromptKey.KeyChar) {
26 | '\d' {
27 | if ($State.Prompt.Length -ne 1) {
28 | $null = $State.Prompt.Clear()
29 | $State.ShouldExit = $true
30 | }
31 | }
32 | '[weblh]' {
33 | $State.ShouldExit = $true
34 | }
35 | '[tf]' {
36 | $motionState.ShouldExitAfterNext = $true
37 | }
38 | default {
39 | if ($AdditionalCharacters -and $PromptKey.KeyChar -in $AdditionalCharacters) {
40 | return
41 | }
42 |
43 | $null = $State.Prompt.Clear()
44 | $State.ShouldExit = $true
45 | }
46 | }
47 | }
48 | }
49 |
50 | $pattern = [regex]::new(
51 | '
52 | (?\d)?
53 | (?[webhltf])
54 | (?.)?
55 | (?.+)?
56 | ',
57 | [System.Text.RegularExpressions.RegexOptions]'ExplicitCapture, IgnorePatternWhitespace')
58 |
59 | $motionMatches = $pattern.Match($motionText)
60 | $motionMatches.Groups
61 | $motionResult = [PSCustomObject]@{
62 | Digit = $motionMatches.Groups['Digit'].Value -as [int]
63 | Action = $motionMatches.Groups['Action'].Value -as [char]
64 | Arg = $motionMatches.Groups['Arg'].Value -as [char]
65 | Unknown = $motionMatches.Groups['Unknown'].Value -as [string]
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/Private/GetSingleton.ps1:
--------------------------------------------------------------------------------
1 | function GetSingleton {
2 | if ($script:PSReadLineSingleton) {
3 | return $script:PSReadLineSingleton
4 | }
5 |
6 | return $script:PSReadLineSingleton =
7 | [Microsoft.PowerShell.PSConsoleReadLine].
8 | GetField('_singleton', 60).
9 | GetValue($null)
10 | }
11 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/Private/NewHotstring.ps1:
--------------------------------------------------------------------------------
1 | using namespace System.Collections.Generic
2 | using namespace System.Management.Automation
3 |
4 | function NewHotstring {
5 | [CmdletBinding()]
6 | param(
7 | [Parameter(Mandatory)]
8 | [ValidateNotNullOrEmpty()]
9 | [string] $Trigger,
10 |
11 | [Parameter(Mandatory)]
12 | [ValidateNotNull()]
13 | [scriptblock] $Action,
14 |
15 | [ValidateNotNullOrEmpty()]
16 | [string] $Name,
17 |
18 | [ValidateNotNullOrEmpty()]
19 | [string] $Description,
20 |
21 | [switch] $ViOnly
22 | )
23 | end {
24 | $hotstring = [PSCustomObject]@{
25 | PSTypeName = 'PSWriteline.Handler'
26 | Key = '%', $Trigger, '%' -join ''
27 | Name = $Name
28 | Description = $Description
29 | Action = $Action
30 | Chars = $Trigger.ToCharArray()
31 | TriggerChar = $Trigger.ToCharArray()[-1]
32 | }
33 | $hotstring.PSTypeNames.Insert(0, 'PSWriteline.Hotstring')
34 |
35 | $bindingList = GetHotstring -Character $hotstring.TriggerChar
36 | $bindingList.Add($hotstring)
37 |
38 | SetInternalHandler SmartSelfInsert -InsertChord $hotstring.TriggerChar -ViOnly:$ViOnly.IsPresent
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/Private/NewUnboundHandler.ps1:
--------------------------------------------------------------------------------
1 | function NewUnboundHandler {
2 | [CmdletBinding()]
3 | param(
4 | [Parameter(Mandatory)]
5 | [ValidateNotNullOrEmpty()]
6 | [string] $Name,
7 |
8 | [ValidateNotNull()]
9 | [string] $Description,
10 |
11 | [ValidateNotNull()]
12 | [scriptblock] $Action
13 | )
14 | end {
15 | if ($null -eq $script:UNBOUND_STORE) {
16 | $script:UNBOUND_STORE = [System.Collections.Generic.Dictionary[string, psobject]]::new()
17 | }
18 |
19 | $handler = [PSCustomObject]@{
20 | PSTypeName = 'PSWriteLine.Handler'
21 | Key = 'Unbound'
22 | Name = $Name
23 | Description = $Description
24 | Action = $Action
25 | }
26 |
27 | $handler.PSTypeNames.Insert(0, 'PSWriteline.UnboundHandler')
28 | $store = $script:UNBOUND_STORE
29 | if ($store.ContainsKey($Name)) {
30 | $store[$Name] = $handler
31 | return
32 | }
33 |
34 | $store.Add($Name, $handler)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/Private/SetInternalHandler.ps1:
--------------------------------------------------------------------------------
1 | function SetInternalHandler {
2 | [CmdletBinding()]
3 | param(
4 | [string] $Name,
5 | [string[]] $CommandChord,
6 | [string[]] $InsertChord,
7 | [switch] $ViOnly,
8 | [switch] $Hotstring,
9 | [switch] $Unbound
10 | )
11 | end {
12 | $isVi = $script:IS_VI_MODE
13 | $functionMap = GetFunctionMap
14 | $mapping = $functionMap.$Name
15 | if (-not $mapping) { return }
16 |
17 | if ($Hotstring.IsPresent) {
18 | NewHotstring `
19 | -Trigger $InsertChord[0] `
20 | -Name $mapping.BriefDescription `
21 | -Description $mapping.Description `
22 | -Action $mapping.ScriptBlock
23 | return
24 | }
25 |
26 | if ($Unbound.IsPresent) {
27 | NewUnboundHandler `
28 | -Name $mapping.BriefDescription `
29 | -Description $mapping.Description `
30 | -Action $mapping.ScriptBlock
31 | return
32 | }
33 |
34 | $splat = @{
35 | ScriptBlock = $mapping.ScriptBlock
36 | BriefDescription = $mapping.BriefDescription
37 | Description = $mapping.Description
38 | }
39 |
40 | if (-not $isVi -and ($ViOnly.IsPresent -or -not $InsertChord)) {
41 | return
42 | }
43 |
44 | if ($isVi) {
45 | if ($CommandChord) {
46 | $splat.ViMode = 'Command'
47 | $splat.Chord = $CommandChord
48 | } else {
49 | $splat.ViMode = 'Insert'
50 | }
51 | }
52 |
53 | if (-not $splat.Chord) {
54 | $splat.Chord = $InsertChord
55 | }
56 |
57 | Set-PSReadlineKeyHandler @splat
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/Public/Get-PSWritelineKeyHandler.ps1:
--------------------------------------------------------------------------------
1 | function Get-PSWritelineKeyHandler {
2 | [OutputType([psobject])]
3 | [CmdletBinding()]
4 | param(
5 | [ValidateNotNullOrEmpty()]
6 | [SupportsWildcards()]
7 | [string] $Key,
8 |
9 | [Parameter(ValueFromPipeline)]
10 | [ValidateNotNullOrEmpty()]
11 | [SupportsWildcards()]
12 | [string] $Name
13 | )
14 | begin {
15 | $handlers = [System.Collections.Generic.List[psobject]]::new()
16 | Get-PSReadlineKeyHandler | Where-Object Function -ne 'SmartSelfInsert' | ForEach-Object {
17 | $proxyHandler = [PSCustomObject]@{
18 | PSTypeName = 'PSWriteline.Handler'
19 | Key = $PSItem.Key
20 | Name = $PSItem.Function
21 | Description = $PSItem.Description
22 | }
23 |
24 | $proxyHandler.PSTypeNames.Insert(0, 'PSWriteline.PSReadlineHandler')
25 | $handlers.Add($proxyHandler)
26 | }
27 |
28 | $hotstringStore = GetHotstring
29 | $hotstringStore.Values |
30 | ForEach-Object { $handlers.Add($PSItem) }
31 |
32 | if ($unbound = $script:UNBOUND_STORE) {
33 | $handlers.AddRange($unbound.Values)
34 | }
35 |
36 | $alreadyProcessed = [System.Collections.Generic.HashSet[psobject]]::new()
37 | }
38 | process {
39 | if (-not $Name -and -not $Key) {
40 | $PSCmdlet.WriteObject($handlers, $true)
41 | return
42 | }
43 |
44 | $handlers |
45 | Where-Object {
46 | (-not $Key -or $PSItem.Key -like $Key) -and
47 | (-not $Name -or $PSItem.Name -like $Name)
48 | } | ForEach-Object {
49 | if (-not $alreadyProcessed.Contains($PSItem)) {
50 | $null = $alreadyProcessed.Add($PSItem)
51 | $PSCmdlet.WriteObject($PSItem)
52 | }
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/Public/Import-PSWriteline.ps1:
--------------------------------------------------------------------------------
1 | function Import-PSWriteline {
2 | [CmdletBinding()]
3 | param(
4 | [switch]
5 | $ViMode
6 | )
7 | end {
8 | $script:IS_VI_MODE = $ViMode.IsPresent
9 |
10 | if ($ViMode.IsPresent) {
11 | Set-PSReadlineOption -EditMode Vi -ViModeIndicator Cursor -ShowToolTips
12 | Set-PSReadlineKeyHandler -Chord k -Function HistorySearchBackward -ViMode Command
13 | Set-PSReadlineKeyHandler -Chord j -Function HistorySearchForward -ViMode Command
14 | }
15 |
16 | SetInternalHandler CommandPalette -CommandChord ':'
17 | SetInternalHandler CommandPalette -InsertChord 'CTRL+SHIFT+P'
18 | SetInternalHandler SmartTab -InsertChord 'TAB'
19 | SetInternalHandler SmartQuote -InsertChord '"', "'"
20 | SetInternalHandler SmartBrace -InsertChord '(', '{', '['
21 | SetInternalHandler SmartCloseBrace -InsertChord ')', ']', '}'
22 | SetInternalHandler SmartDelete -InsertChord 'Backspace'
23 | SetInternalHandler DeleteRealLine -CommandChord 'd,d'
24 | SetInternalHandler GotoStartOfBuffer -CommandChord 'g,g'
25 | SetInternalHandler GotoEndOfBuffer -CommandChord SHIFT+g
26 |
27 | Set-PSWritelineKeyHandler -Chord 'jj' -Function ViCommandMode -ViMode Insert -ViOnly -Hotstring
28 | Set-PSWritelineKeyHandler -Chord 'g,d' -ViMode Command -Function DeleteLine
29 | Set-PSWritelineKeyHandler -Chord CTRL+a -Function SelectAll -ViMode Insert
30 | Set-PSWritelineKeyHandler -Chord CTRL+a -Function SelectAll -ViMode Command
31 | Set-PSWritelineKeyHandler -Chord SHIFT+LeftArrow -Function SelectBackwardChar -ViMode Insert
32 | Set-PSWritelineKeyHandler -Chord SHIFT+RightArrow -Function SelectForwardChar -ViMode Insert
33 | Set-PSWritelineKeyHandler -Chord CTRL+SHIFT+LeftArrow -Function SelectBackwardWord -ViMode Insert
34 | Set-PSWritelineKeyHandler -Chord CTRL+SHIFT+RightArrow -Function SelectNextWord -ViMode Insert
35 | Set-PSWritelineKeyHandler -Chord SHIFT+Home -Function SelectBackwardsLine -ViMode Insert
36 | Set-PSWritelineKeyHandler -Chord SHIFT+End -Function SelectLine -ViMode Insert
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Modules/PSWriteline/0.1.0/Public/Set-PSWritelineKeyHandler.ps1:
--------------------------------------------------------------------------------
1 | function Set-PSWritelineKeyHandler {
2 | [CmdletBinding(PositionalBinding=$false)]
3 | param(
4 | [Parameter(Mandatory)]
5 | [Alias('Key')]
6 | [ValidateNotNullOrEmpty()]
7 | [string[]] $Chord,
8 |
9 | [ValidateSet('Command', 'Insert')]
10 | [string] $ViMode = 'Insert',
11 |
12 | [Parameter(Mandatory, ParameterSetName='Function')]
13 | [ValidateNotNullOrEmpty()]
14 | [string] $Function,
15 |
16 | [Parameter(Mandatory, ParameterSetName='ScriptBlock')]
17 | [ValidateNotNull()]
18 | [scriptblock] $ScriptBlock,
19 |
20 | [Parameter(ParameterSetName='ScriptBlock')]
21 | [ValidateNotNullOrEmpty()]
22 | [Alias('Name')]
23 | [string] $BriefDescription,
24 |
25 | [Parameter(ParameterSetName='ScriptBlock')]
26 | [ValidateNotNullOrEmpty()]
27 | [string] $Description,
28 |
29 | [switch] $Hotstring,
30 |
31 | [switch] $ViOnly
32 | )
33 | end {
34 | if ($Hotstring.IsPresent) {
35 | $action = $ScriptBlock
36 | if ($PSCmdlet.ParameterSetName -eq 'Function') {
37 | $targetFunction = Get-PSReadlineKeyHandler | Where-Object Function -eq $Function
38 | if (-not $targetFunction) {
39 | $PSCmdlet.ThrowTerminatingError(
40 | [System.Management.Automation.ErrorRecord]::new(
41 | [ArgumentException]::new('Unable to find the PSReadline method "{0}".' -f $Function),
42 | 'MissingPSReadlineMethod',
43 | 'ObjectNotFound',
44 | $Function))
45 | }
46 |
47 | $action = [scriptblock]::Create(
48 | $PSCmdlet.InvokeCommand.ExpandString(
49 | '[Microsoft.PowerShell.PSConsoleReadLine]::$Function.Invoke(`$args)'))
50 | $BriefDescription = $Function
51 | $Description = $targetFunction.Description
52 | }
53 |
54 | NewHotstring `
55 | -Trigger $Chord[0] `
56 | -Action $action `
57 | -Name $BriefDescription `
58 | -Description $Description `
59 | -ViOnly:$ViOnly.IsPresent
60 | return
61 | }
62 |
63 | $splat = @{ Chord = $Chord }
64 |
65 | if ($script:IS_VI_MODE) {
66 | $splat.ViMode = $ViMode
67 | } elseif ($ViOnly.IsPresent) {
68 | return
69 | }
70 |
71 | if ($PSCmdlet.ParameterSetName -eq 'Function') {
72 | $splat.Function = $Function
73 | } else {
74 | $splat.ScriptBlock = $ScriptBlock
75 | $splat.BriefDescription = $BriefDescription
76 | $splat.Description = $Description
77 | }
78 |
79 | Set-PSReadlineKeyHandler @splat
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/Documents/PowerShell/NamespaceAwareCompletion.ps1:
--------------------------------------------------------------------------------
1 | # AV was giving a false positive for this file. No idea why, but was very annoying and I don't actually use this.
2 | # Look at git history if you want to see it.
3 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Assert.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using System.Runtime.CompilerServices;
3 |
4 | namespace Profile;
5 |
6 | internal static class Assert
7 | {
8 | public static void IndexInRange(bool value, [CallerArgumentExpression(nameof(value))] string expression = "")
9 | {
10 | if (!value)
11 | {
12 | return;
13 | }
14 |
15 | ThrowIndexOutOfRange($"Index does not match, must be '{expression}'.");
16 |
17 | [DoesNotReturn, MethodImpl(MethodImplOptions.NoInlining)]
18 | static void ThrowIndexOutOfRange(string message)
19 | {
20 | throw new IndexOutOfRangeException(message);
21 | }
22 | }
23 |
24 | public static void ArgumentInRange(bool value, [CallerArgumentExpression(nameof(value))] string expression = "")
25 | {
26 | if (!value)
27 | {
28 | return;
29 | }
30 |
31 | Throw($"Argument does not match, must be '{expression}'.");
32 |
33 | [DoesNotReturn, MethodImpl(MethodImplOptions.NoInlining)]
34 | static void Throw(string message)
35 | {
36 | throw new ArgumentOutOfRangeException(message);
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/BindTo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 |
3 | namespace Profile;
4 |
5 | internal static class BindTo
6 | {
7 | public static class Instance
8 | {
9 | public const BindingFlags Public = BindingFlags.Instance | BindingFlags.Public;
10 |
11 | public const BindingFlags NonPublic = BindingFlags.Instance | BindingFlags.NonPublic;
12 |
13 | public const BindingFlags Any = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
14 | }
15 |
16 | public static class Static
17 | {
18 | public const BindingFlags Public = BindingFlags.Static | BindingFlags.Public;
19 |
20 | public const BindingFlags NonPublic = BindingFlags.Static | BindingFlags.NonPublic;
21 |
22 | public const BindingFlags Any = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
23 | }
24 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Commands/InstallerCommandBase.cs:
--------------------------------------------------------------------------------
1 | // using System.Management.Automation;
2 |
3 | // namespace Profile.Commands;
4 |
5 | // public abstract class InstallerCommandBase : PSCmdlet
6 | // {
7 | // private const string PartialSetName = "Partial";
8 |
9 | // [Parameter(Position = 0, Mandatory = true, ParameterSetName = PartialSetName)]
10 | // public string? MajorAndMinor { get; set; }
11 |
12 | // public string? Preview
13 | // }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Commands/InvokeWithPipeCommand.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Diagnostics;
3 | using System.Management.Automation;
4 |
5 | namespace Profile.Commands;
6 |
7 | internal static class Sma
8 | {
9 | public static object GetOutputPipe(PSCmdlet source)
10 | {
11 | if (ReflectionCache.PSScriptCmdlet.Is(source))
12 | {
13 | return ReflectionCache.PSScriptCmdlet.GetOutputPipe(source);
14 | }
15 |
16 | return ReflectionCache.MshCommandRuntime.GetOutputPipe(source.CommandRuntime);
17 | }
18 | }
19 |
20 | [Cmdlet(VerbsLifecycle.Invoke, "WithPipe")]
21 | public sealed class InvokeWithPipeCommand : PSCmdlet
22 | {
23 |
24 | [Parameter(Position = 0, Mandatory = true)]
25 | [ValidateNotNull]
26 | public PSCmdlet? Context { get; set; }
27 |
28 | [Parameter(Position = 1, Mandatory = true)]
29 | [ValidateNotNull]
30 | public ScriptBlock? Body { get; set; }
31 |
32 | [Parameter]
33 | [ValidateSet("WriteToCurrentErrorPipe", "WriteToExternalErrorPipe", "SwallowErrors")]
34 | public string ErrorHandlingBehavior { get; set; } = "WriteToCurrentErrorPipe";
35 |
36 | [Parameter]
37 | public object? DollarUnder { get; set; }
38 |
39 | [Parameter]
40 | public object? Input { get; set; }
41 |
42 | [Parameter]
43 | public object? This { get; set; }
44 |
45 | [Parameter]
46 | public object? Pipe { get; set; }
47 |
48 | [Parameter]
49 | public SwitchParameter DoNotPropagateExceptionsToTop { get; set; }
50 |
51 | [Parameter]
52 | [ValidateNotNull]
53 | public Hashtable? Variables { get; set; }
54 |
55 | [Parameter]
56 | [ValidateNotNull]
57 | public Hashtable? Functions { get; set; }
58 |
59 | [Parameter]
60 | [AllowNull, AllowEmptyCollection]
61 | public object?[]? ArgumentList { get; set; }
62 |
63 | [Parameter]
64 | public SwitchParameter PassThru { get; set; }
65 |
66 | protected override void EndProcessing()
67 | {
68 | Debug.Assert(Context is not null);
69 | Debug.Assert(Body is not null);
70 | Pipe ??= Sma.GetOutputPipe(PassThru ? this : Context);
71 |
72 | ScriptInfo command = ReflectionCache.ScriptInfo.ctor(
73 | string.Empty,
74 | Body,
75 | ReflectionCache.LocalPipeline.GetExecutionContextFromTLS());
76 |
77 | InvocationInfo invocationInfo = InvocationInfo.Create(
78 | command,
79 | Context.MyInvocation.DisplayScriptPosition);
80 |
81 | Dictionary? functions = null;
82 | if (Functions is not null)
83 | {
84 | functions = new();
85 | foreach (DictionaryEntry kvp in Functions)
86 | {
87 | functions.Add(
88 | LanguagePrimitives.ConvertTo(kvp.Key),
89 | LanguagePrimitives.ConvertTo(kvp.Value));
90 | }
91 | }
92 |
93 | List? variables = null;
94 | if (Variables is not null)
95 | {
96 | variables = new();
97 | foreach (DictionaryEntry kvp in Variables)
98 | {
99 | variables.Add(
100 | new PSVariable(
101 | LanguagePrimitives.ConvertTo(kvp.Key),
102 | kvp.Value));
103 | }
104 | }
105 |
106 | ReflectionCache.ScriptBlock.InvokeWithPipe(
107 | Body,
108 | useLocalScope: true,
109 | ScriptBlockErrorHandlingBehavior.WriteToCurrentErrorPipe,
110 | DollarUnder,
111 | Input,
112 | This,
113 | Pipe,
114 | invocationInfo,
115 | !DoNotPropagateExceptionsToTop,
116 | variables,
117 | functions,
118 | ArgumentList);
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Commands/UseConstrainedLanguageCommand.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.Management.Automation;
3 |
4 | namespace Profile.Commands;
5 |
6 | [Cmdlet(VerbsOther.Use, "ConstrainedLanguage")]
7 | public sealed class UseConstrainedLanguageCommand : PSCmdlet
8 | {
9 | [Parameter(Mandatory = true, Position = 0)]
10 | [ValidateNotNull]
11 | public ScriptBlock? Body { get; set; }
12 |
13 | [Parameter]
14 | public SwitchParameter SetLockdown { get; set; }
15 |
16 | private const string PSLockdownPolicy = "__PSLockdownPolicy";
17 |
18 | protected override void EndProcessing()
19 | {
20 | Debug.Assert(Body is not null);
21 |
22 | PSLanguageMode? previousLangMode = ReflectionCache.ScriptBlock.LanguageMode.Get(Body);
23 | if (previousLangMode is not PSLanguageMode.FullLanguage)
24 | {
25 | ThrowTerminatingError(
26 | new ErrorRecord(
27 | new InvalidOperationException("Already in constrained language mode."),
28 | "CannotUseClmInClm",
29 | ErrorCategory.InvalidOperation,
30 | null));
31 |
32 | return;
33 | }
34 |
35 | if (SetLockdown)
36 | {
37 | Environment.SetEnvironmentVariable(
38 | PSLockdownPolicy,
39 | "0x80000007",
40 | EnvironmentVariableTarget.Machine);
41 | }
42 |
43 | try
44 | {
45 | ReflectionCache.ScriptBlock.LanguageMode.Set(Body, PSLanguageMode.ConstrainedLanguage);
46 | ReflectionCache.ScriptBlock.InvokeWithPipe(
47 | Body,
48 | useLocalScope: true,
49 | ScriptBlockErrorHandlingBehavior.WriteToCurrentErrorPipe,
50 | dollarUnder: null,
51 | input: null,
52 | scriptThis: null,
53 | ReflectionCache.MshCommandRuntime.GetOutputPipe(CommandRuntime),
54 | InvocationInfo.Create(
55 | ReflectionCache.ScriptInfo.ctor(
56 | "",
57 | Body,
58 | ReflectionCache.LocalPipeline.GetExecutionContextFromTLS()),
59 | MyInvocation.DisplayScriptPosition),
60 | propagateAllExceptionsToTop: true,
61 | variablesToDefine: null,
62 | functionsToDefine: null,
63 | args: null);
64 | }
65 | finally
66 | {
67 | ReflectionCache.ScriptBlock.LanguageMode.Set(Body, previousLangMode);
68 |
69 | if (SetLockdown)
70 | {
71 | Environment.SetEnvironmentVariable(
72 | PSLockdownPolicy,
73 | null,
74 | EnvironmentVariableTarget.Machine);
75 | }
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/CompletionHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Management.Automation;
3 | using System.Text;
4 | using Microsoft.PowerShell;
5 |
6 | namespace Profile
7 | {
8 | internal static class CompletionHelper
9 | {
10 | public static string FinishCompletionValue(string completionValue, (char prefix, char suffix) state)
11 | {
12 | int length = completionValue.Length;
13 | if (state.prefix is not '\0')
14 | {
15 | length++;
16 | }
17 |
18 | if (state.suffix is not '\0')
19 | {
20 | length++;
21 | }
22 |
23 | int replaceCount = 0;
24 | bool needsQuotes = false;
25 | foreach (char c in completionValue)
26 | {
27 | if (c is '\'' && state.prefix is not '"')
28 | {
29 | replaceCount++;
30 | needsQuotes = true;
31 | continue;
32 | }
33 |
34 | if (c is '"')
35 | {
36 | if (state.prefix is '"')
37 | {
38 | replaceCount++;
39 | continue;
40 | }
41 |
42 | needsQuotes = true;
43 | continue;
44 | }
45 |
46 | if (c is ' ')
47 | {
48 | needsQuotes = true;
49 | continue;
50 | }
51 |
52 | if (c is ',')
53 | {
54 | needsQuotes = true;
55 | }
56 | }
57 |
58 | if (needsQuotes && state.prefix is '\0')
59 | {
60 | length += 2;
61 | state.prefix = '\'';
62 | state.suffix = '\'';
63 | }
64 |
65 | length += replaceCount;
66 |
67 | return string.Create(
68 | length,
69 | (completionValue, state.prefix, state.suffix, replaceCount),
70 | static (buffer, state) =>
71 | {
72 | if (state.prefix is not '\0')
73 | {
74 | buffer[0] = state.prefix;
75 | buffer = buffer[1..];
76 | }
77 |
78 | if (state.replaceCount is 0)
79 | {
80 | state.completionValue.AsSpan().CopyTo(buffer);
81 | buffer = buffer[state.completionValue.Length..];
82 | }
83 | else
84 | {
85 | int j = 0;
86 | for (int i = 0; i < state.completionValue.Length; i++, j++)
87 | {
88 | char c = state.completionValue[i];
89 | if (c == state.prefix)
90 | {
91 | if (c is '\'')
92 | {
93 | buffer[j] = '\'';
94 | buffer[++j] = '\'';
95 | continue;
96 | }
97 |
98 | buffer[j] = '`';
99 | buffer[++j] = '"';
100 | continue;
101 | }
102 |
103 | buffer[j] = c;
104 | }
105 |
106 | buffer = buffer[j..];
107 | }
108 |
109 | if (state.suffix is not '\0')
110 | {
111 | buffer[0] = state.suffix;
112 | }
113 | });
114 | }
115 |
116 | public static string GetWordToComplete(string wordToComplete, out char prefix, out char suffix)
117 | {
118 | if (string.IsNullOrEmpty(wordToComplete))
119 | {
120 | prefix = default;
121 | suffix = default;
122 | return wordToComplete;
123 | }
124 |
125 | prefix = default;
126 | if (wordToComplete[0] is '\'' or '"')
127 | {
128 | prefix = wordToComplete[0];
129 | }
130 |
131 | suffix = default;
132 | if (prefix is not '\0' && wordToComplete is { Length: 1 })
133 | {
134 | return string.Empty;
135 | }
136 |
137 | char lastChar = wordToComplete[^1];
138 | if (lastChar is '\'' or '"')
139 | {
140 | suffix = lastChar;
141 | if (prefix != suffix)
142 | {
143 | suffix = default;
144 | }
145 | }
146 |
147 | if (suffix is not '\0' && prefix is not '\0')
148 | {
149 | return wordToComplete[1..^1];
150 | }
151 |
152 | if (prefix is not '\0')
153 | {
154 | return wordToComplete[1..];
155 | }
156 |
157 | if (suffix is not '\0')
158 | {
159 | return wordToComplete[..^1];
160 | }
161 |
162 | return wordToComplete;
163 | }
164 |
165 | public static CompletionResult GetCompletionResult(
166 | string completionText,
167 | string listItemText,
168 | string toolTip)
169 | {
170 | if (completionText.IndexOfAny(new[] { ',', ' ' }) is not -1)
171 | {
172 | if (completionText.IndexOf('\'') is not -1)
173 | {
174 | completionText = completionText.Replace("'", "''");
175 | }
176 |
177 | completionText = string.Create(
178 | completionText.Length + 2,
179 | completionText,
180 | (buffer, completionText) =>
181 | {
182 | buffer[0] = '\'';
183 | completionText.AsSpan().CopyTo(buffer[1..]);
184 | buffer[^1] = '\'';
185 | });
186 | }
187 |
188 | return new CompletionResult(
189 | completionText,
190 | listItemText,
191 | CompletionResultType.ParameterValue,
192 | toolTip);
193 | }
194 | }
195 | }
196 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/FlagsExpressionArgumentCompleter.cs:
--------------------------------------------------------------------------------
1 | using System.Buffers;
2 | using System.Collections;
3 | using System.Management.Automation;
4 | using System.Management.Automation.Language;
5 |
6 | namespace Profile;
7 |
8 | public sealed class FlagsExpressionArgumentCompleterAttribute : ArgumentCompleterFactoryAttribute, IArgumentCompleterFactory
9 | {
10 | public FlagsExpressionArgumentCompleterAttribute()
11 | {
12 | }
13 |
14 | public required Type EnumType { get; set; }
15 |
16 | public override IArgumentCompleter Create()
17 | {
18 | return new FlagsExpressionArgumentCompleter(EnumType);
19 | }
20 | }
21 |
22 | internal sealed class FlagsExpressionArgumentCompleter : IArgumentCompleter
23 | {
24 | public FlagsExpressionArgumentCompleter(Type type)
25 | {
26 | Type = type;
27 | }
28 |
29 | public Type Type { get; }
30 |
31 | public IEnumerable CompleteArgument(
32 | string commandName,
33 | string parameterName,
34 | string wordToComplete,
35 | CommandAst commandAst,
36 | IDictionary fakeBoundParameters)
37 | {
38 | HashSet names = new(Type.GetEnumNames());
39 | wordToComplete = CompletionHelper.GetWordToComplete(wordToComplete, out char prefix, out char suffix);
40 | ReadOnlySpan word = wordToComplete;
41 | int start = 0;
42 | for (int i = 0; i < word.Length; i++)
43 | {
44 | char c = word[i];
45 | if (c is '+' or ',' or ' ' or '!')
46 | {
47 | if (start == i)
48 | {
49 | start++;
50 | continue;
51 | }
52 |
53 | if (Enum.TryParse(Type, word[start..i], true, out object? result))
54 | {
55 | names.Remove(result.ToString()!);
56 | }
57 |
58 | start = i + 1;
59 | continue;
60 | }
61 | }
62 |
63 | ReadOnlySpan before = default;
64 | if (start != word.Length - 1)
65 | {
66 | before = word[..start];
67 | word = word[start..];
68 | }
69 |
70 | return GetCompletions(names, before.ToString(), word.ToString(), prefix, suffix, Type).ToArray();
71 |
72 | static IEnumerable GetCompletions(
73 | HashSet names,
74 | string beforeString,
75 | string word,
76 | char prefix,
77 | char suffix,
78 | Type type)
79 | {
80 | WildcardPattern pattern = WildcardPattern.Get(word + "*", WildcardOptions.IgnoreCase | WildcardOptions.CultureInvariant);
81 | foreach (string name in names)
82 | {
83 | if (pattern.IsMatch(name))
84 | {
85 | yield return new CompletionResult(
86 | CompletionHelper.FinishCompletionValue(
87 | $"{beforeString}{name}",
88 | (prefix, suffix)),
89 | name,
90 | CompletionResultType.ParameterValue,
91 | $"{type.Name}.{name}");
92 | }
93 | }
94 | }
95 | }
96 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Functional.cs:
--------------------------------------------------------------------------------
1 | global using static Profile.Functional;
2 |
3 | namespace Profile;
4 |
5 | internal static class Functional
6 | {
7 | public static TResult Out(TResult result, out TOut location)
8 | {
9 | location = default!;
10 | return result;
11 | }
12 |
13 | public static TResult Out(TResult result, TOut outValue, out TOut location)
14 | {
15 | location = outValue;
16 | return result;
17 | }
18 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/GetWindowCommand.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Diagnostics;
3 | using System.Management.Automation;
4 | using System.Runtime.CompilerServices;
5 | using System.Runtime.InteropServices;
6 | using Windows.Win32;
7 | using Windows.Win32.Foundation;
8 |
9 | namespace Profile;
10 |
11 | [Cmdlet(VerbsCommon.Get, "Window")]
12 | public sealed unsafe class GetWindowCommand : PSCmdlet
13 | {
14 | private const string PipedParent = "PipedParent";
15 |
16 | private const string Default = "Default";
17 |
18 | private WindowInfo[]? _allWindows;
19 |
20 | [Parameter(ValueFromPipeline = true)]
21 | public WindowInfo? Parent { get; set; }
22 |
23 | [Parameter(Position = 0)]
24 | [SupportsWildcards]
25 | [ValidateNotNullOrEmpty]
26 | public string? Text { get; set; }
27 |
28 | [Parameter(ValueFromPipelineByPropertyName = true)]
29 | [ValidateNotNullOrEmpty]
30 | public string? LiteralText { get; set; }
31 |
32 | [Parameter()]
33 | [SupportsWildcards]
34 | [ValidateNotNullOrEmpty]
35 | public string? ClassName { get; set; }
36 |
37 | [Parameter(ValueFromPipelineByPropertyName = true)]
38 | [ValidateNotNullOrEmpty]
39 | public string? LiteralClassName { get; set; }
40 |
41 | [Parameter(ValueFromPipeline = true)]
42 | public Any[]? Process { get; set; }
43 |
44 | [Parameter()]
45 | [FlagsExpressionArgumentCompleter(EnumType = typeof(WindowStyle))]
46 | public FlagsExpression? Style { get; set; }
47 |
48 | [Parameter()]
49 | [FlagsExpressionArgumentCompleter(EnumType = typeof(WindowExStyle))]
50 | public FlagsExpression? ExStyle { get; set; }
51 |
52 | internal static WindowInfo[] GetAllWindows(HWND parent = default)
53 | {
54 | List windows = [];
55 | GCHandle hWindows = GCHandle.Alloc(windows);
56 | try
57 | {
58 | // Docs say return value isn't used at all :shrug:
59 | Interop.EnumChildWindows(parent, &AddWindowToList, GCHandle.ToIntPtr(hWindows));
60 | }
61 | finally
62 | {
63 | hWindows.Free();
64 | }
65 |
66 | WindowInfo[] result = new WindowInfo[windows.Count];
67 | for (int i = 0; i < result.Length; i++)
68 | {
69 | result[i] = new WindowInfo(windows[i]);
70 | }
71 |
72 | return result;
73 | }
74 |
75 | [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])]
76 | private static BOOL AddWindowToList(HWND hWnd, LPARAM lParam)
77 | {
78 | if (GCHandle.FromIntPtr(lParam).Target is List list)
79 | {
80 | list.Add(hWnd);
81 | return true;
82 | }
83 |
84 | return false;
85 | }
86 |
87 | private HashSet? GetProcessIds()
88 | {
89 | if (Process is null)
90 | {
91 | return null;
92 | }
93 |
94 | Process[]? allProcesses = null;
95 | HashSet results = new();
96 | foreach (Any process in Process)
97 | {
98 | if (process.Some(out int id))
99 | {
100 | results.Add(unchecked((uint)id));
101 | continue;
102 | }
103 |
104 | if (process.Some(out string? name))
105 | {
106 | if (!WildcardPattern.ContainsWildcardCharacters(name))
107 | {
108 | foreach (Process procInstance in System.Diagnostics.Process.GetProcessesByName(name))
109 | {
110 | results.Add(unchecked((uint)procInstance.Id));
111 | }
112 |
113 | continue;
114 | }
115 |
116 | WildcardPattern pattern = WildcardPattern.Get(name, WildcardOptions.CultureInvariant | WildcardOptions.IgnoreCase);
117 | allProcesses ??= System.Diagnostics.Process.GetProcesses();
118 | foreach (Process procInstance in allProcesses)
119 | {
120 | if (pattern.IsMatch(procInstance.ProcessName))
121 | {
122 | results.Add(unchecked((uint)procInstance.Id));
123 | }
124 | }
125 |
126 | continue;
127 | }
128 |
129 | if (process.Some(out Process? proc))
130 | {
131 | results.Add(unchecked((uint)proc!.Id));
132 | }
133 | }
134 |
135 | return results;
136 | }
137 |
138 | protected override void ProcessRecord()
139 | {
140 | HashSet? processIds = GetProcessIds();
141 | Func? textMatcher = GetMatcher(Text, LiteralText, out bool isTextPattern);
142 | Func? classMatcher = GetMatcher(ClassName, LiteralClassName, out bool isClassPattern);
143 |
144 | bool shouldUseFindWindow = (textMatcher is not null || classMatcher is not null)
145 | && !isTextPattern
146 | && !isClassPattern
147 | && processIds is null
148 | && Style is null
149 | && ExStyle is null;
150 |
151 | if (shouldUseFindWindow)
152 | {
153 | UseFindWindow();
154 | return;
155 | }
156 |
157 | WindowInfo[] windows = _allWindows ?? GetAllWindows((HWND)(Parent?.Handle ?? 0));
158 | if (classMatcher is null && textMatcher is null && processIds is null && Style is null && ExStyle is null)
159 | {
160 | if (MyInvocation.ExpectingInput)
161 | {
162 | return;
163 | }
164 |
165 | WriteObject(windows, enumerateCollection: true);
166 | return;
167 | }
168 |
169 | foreach (WindowInfo window in windows)
170 | {
171 | if (processIds?.Contains(window.ProcessId) is false)
172 | {
173 | continue;
174 | }
175 |
176 | if (Style?.Evaluate(window.Style) is false)
177 | {
178 | continue;
179 | }
180 |
181 | if (ExStyle?.Evaluate(window.ExStyle) is false)
182 | {
183 | continue;
184 | }
185 |
186 | if (classMatcher?.Invoke(window.ClassName) is false)
187 | {
188 | continue;
189 | }
190 |
191 | if (textMatcher?.Invoke(window.Text) is false)
192 | {
193 | continue;
194 | }
195 |
196 | WriteObject(window);
197 | }
198 | }
199 |
200 | private Func? GetMatcher(string? pattern, string? literalValue, out bool isPattern)
201 | {
202 | if (literalValue is not null)
203 | {
204 | isPattern = false;
205 | return value => literalValue.Equals(value, StringComparison.OrdinalIgnoreCase);
206 | }
207 |
208 | if (pattern is null)
209 | {
210 | isPattern = false;
211 | return null;
212 | }
213 |
214 | if (WildcardPattern.ContainsWildcardCharacters(pattern))
215 | {
216 | isPattern = true;
217 | return WildcardPattern.Get(pattern, WildcardOptions.IgnoreCase | WildcardOptions.CultureInvariant).IsMatch;
218 | }
219 |
220 | isPattern = false;
221 | return value => pattern.Equals(value, StringComparison.OrdinalIgnoreCase);
222 | }
223 |
224 | private void UseFindWindow()
225 | {
226 | HWND after = HWND.Null;
227 | fixed (char* className = ClassName)
228 | fixed (char* text = Text)
229 | {
230 | while (true)
231 | {
232 | HWND result = Interop.FindWindowEx(
233 | (HWND)(Parent?.Handle ?? 0),
234 | after,
235 | className,
236 | text);
237 |
238 | if (result.IsNull)
239 | {
240 | throw new Win32Exception();
241 | }
242 |
243 | WriteObject(new WindowInfo(result));
244 | after = result;
245 | }
246 | }
247 | }
248 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/InterfaceOps.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 |
3 | namespace Profile;
4 |
5 | internal delegate TResult OutCall(T arg0, out TOut @out);
6 |
7 | internal static class InterfaceOps
8 | {
9 | public static OutCall CreateInterfaceImplInvocation(
10 | Type iType,
11 | Type implementingType,
12 | Type genericArg,
13 | string name)
14 | {
15 | MethodInfo? method = iType.GetMethod(
16 | name,
17 | BindingFlags.Static | BindingFlags.NonPublic,
18 | [typeof(T), typeof(TOut).MakeByRefType()]);
19 |
20 | if (method is null)
21 | {
22 | string parameterTypes = string.Join(
23 | ", ",
24 | typeof(T).FullName,
25 | typeof(TOut).MakeByRefType().FullName);
26 |
27 | throw new InvalidOperationException(
28 | $"Could not find method {iType}.{name}({parameterTypes}).");
29 | }
30 |
31 | InterfaceMapping mapping = implementingType.GetInterfaceMap(iType);
32 | MethodInfo? targetMethod = null;
33 | for (int i = 0; i < mapping.InterfaceMethods.Length; i++)
34 | {
35 | if (mapping.InterfaceMethods[i] == method)
36 | {
37 | targetMethod = mapping.TargetMethods[i];
38 | break;
39 | }
40 | }
41 |
42 | if (targetMethod is null)
43 | {
44 | string parameterTypes = string.Join(
45 | ", ",
46 | typeof(T).FullName,
47 | typeof(TOut).MakeByRefType().FullName);
48 |
49 | throw new InvalidOperationException(
50 | $"Could not find implementation of {iType.FullName}.{name}({parameterTypes}) in {implementingType.FullName}.");
51 | }
52 |
53 | return targetMethod.MakeGenericMethod(genericArg).CreateDelegate>();
54 | }
55 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/InvokeFormatBinder.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using System.Dynamic;
3 | using System.Linq.Expressions;
4 | using System.Management.Automation;
5 | using System.Reflection;
6 | using System.Runtime.CompilerServices;
7 |
8 | namespace Profile;
9 |
10 | internal static class Format
11 | {
12 | private static readonly CallSite> s_typeCallSite =
13 | CallSite>.Create(new InvokeFormatBinder("Type"));
14 |
15 | public static string Type(Type type, int maxLength = -1) => s_typeCallSite.Target(s_typeCallSite, null, type, maxLength);
16 |
17 | private static readonly CallSite> s_numberCallSite =
18 | CallSite>.Create(new InvokeFormatBinder("Number"));
19 | public static string Number(object? value, int maxLength = -1) => s_numberCallSite.Target(s_numberCallSite, null, value, maxLength);
20 |
21 | private static readonly CallSite> s_memberCallSite =
22 | CallSite>.Create(new InvokeFormatBinder("Member"));
23 | public static string Member(MemberInfo? value, int maxLength = -1, Type? targetType = null) => s_memberCallSite.Target(s_memberCallSite, null, value, maxLength, targetType);
24 | }
25 |
26 | internal class InvokeFormatBinder : DynamicMetaObjectBinder
27 | {
28 | private static readonly Lazy s_formatType = new(
29 | () =>
30 | {
31 | return AppDomain.CurrentDomain.GetAssemblies()
32 | .Where(a => a.GetName().Name == "ClassExplorer")
33 | .FirstOrDefault()
34 | ?.GetType("ClassExplorer.Internal._Format");
35 | });
36 |
37 | public InvokeFormatBinder(string name)
38 | {
39 | Name = name;
40 | }
41 |
42 | public string Name { get; }
43 |
44 | public override Type ReturnType => typeof(T);
45 |
46 | private static bool TryGetFormatType([NotNullWhen(true)] out Type? type)
47 | {
48 | try
49 | {
50 | if (s_formatType.Value is Type result)
51 | {
52 | type = result;
53 | return true;
54 | }
55 |
56 | type = null;
57 | return false;
58 | }
59 | catch
60 | {
61 | type = null;
62 | return false;
63 | }
64 | }
65 |
66 |
67 | public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args)
68 | {
69 | if (!TryGetFormatType(out Type? formatType))
70 | {
71 | return args[0];
72 | }
73 |
74 | MethodInfo? method = formatType.GetMethod(
75 | Name,
76 | BindingFlags.Public | BindingFlags.Static,
77 | args.Select(a => a.LimitType).ToArray());
78 |
79 | if (method is null)
80 | {
81 | return new DynamicMetaObject(
82 | Expression.Throw(
83 | Expression.New(
84 | typeof(MethodInvocationException).GetConstructor(
85 | [typeof(string)])!,
86 | Expression.Call(
87 | typeof(string).GetMethod(
88 | "Format",
89 | BindingFlags.Static | BindingFlags.Public,
90 | [typeof(string), typeof(object), typeof(object)])!,
91 | Expression.Constant("Could not find method ClassExplorer.Internal._Format.{0}({1})."),
92 | Expression.Constant(Name),
93 | Expression.Constant(
94 | string.Join(", ", args.Select(a => a.LimitType.ToString()).ToArray()))))),
95 | BindingRestrictions.Empty);
96 | }
97 |
98 | return new DynamicMetaObject(
99 | Expression.Call(
100 | method,
101 | args.Select(a => a.Expression)),
102 | BindingRestrictions.Empty);
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/DarwinLink.cs:
--------------------------------------------------------------------------------
1 | namespace Profile.Links;
2 |
3 | public unsafe struct DarwinLink
4 | {
5 | public DataBlockHeader dbh;
6 |
7 | internal PathInlineArray _szDarwinId;
8 |
9 | public byte[] szDarwinId =>_szDarwinId.Span.ToArray();
10 |
11 | internal PathInlineArray _szwDarwinId;
12 |
13 | public char[] szwDarwinId => _szwDarwinId.Span.ToArray();
14 | }
15 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/DataBlockHeader.cs:
--------------------------------------------------------------------------------
1 | namespace Profile.Links;
2 |
3 | public struct DataBlockHeader
4 | {
5 | public uint cbSize;
6 |
7 | public LinkDataBlockSignature dwSignature;
8 | }
9 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/GpfIdlFlags.cs:
--------------------------------------------------------------------------------
1 | namespace Profile.Links;
2 |
3 | [Flags]
4 | public enum GpfIdlFlags
5 | {
6 | ///
7 | /// Win32 file names, servers, and root drives are included.
8 | ///
9 | Default = 0x0000,
10 | ///
11 | /// Uses short file names.
12 | ///
13 | AltName = 0x0001,
14 | ///
15 | /// Include UNC printer names items.
16 | ///
17 | UncPrinter = 0x0002,
18 | }
19 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/HeapRef.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | namespace Profile;
4 |
5 | internal static unsafe class PinnedHeapRef
6 | {
7 | public static PinnedHeapRef Alloc()
8 | where T : unmanaged
9 | {
10 | T[] pinnedArray = GC.AllocateArray(1, pinned: true);
11 | return new PinnedHeapRef(
12 | pinnedArray,
13 | (T*)Unsafe.AsPointer(ref pinnedArray[0]));
14 | }
15 | }
16 |
17 | internal readonly unsafe struct PinnedHeapRef where T : unmanaged
18 | {
19 | private readonly object _keepAlive;
20 |
21 | private readonly T* _ptr;
22 |
23 | public PinnedHeapRef(object pinnedKeepAlive, T* ptr)
24 | {
25 | _keepAlive = pinnedKeepAlive;
26 | _ptr = ptr;
27 | }
28 |
29 | public ref T Value => ref *_ptr;
30 |
31 | public T* Ptr => _ptr;
32 |
33 | public PinnedHeapRef CreateDerivedRef(TResult* ptr)
34 | where TResult : unmanaged
35 | {
36 | return new PinnedHeapRef(_keepAlive, ptr);
37 | }
38 |
39 | public PinnedArrayMemoryManager CreateDerivedMemory(TResult* ptr, int length)
40 | where TResult : unmanaged
41 | {
42 | return new PinnedArrayMemoryManager(_keepAlive, ptr, length);
43 | }
44 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/LinkConsoleFeProps.cs:
--------------------------------------------------------------------------------
1 | namespace Profile.Links;
2 |
3 | public struct LinkConsoleFeProps
4 | {
5 | public DataBlockHeader dbh;
6 |
7 | public uint uCodePage;
8 | }
9 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/LinkConsoleProps.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace Profile.Links;
5 |
6 | internal unsafe struct LnkConsoleProps
7 | {
8 | public DataBlockHeader dbh;
9 | public ushort wFillAttribute;
10 | public ushort wPopupFillAttribute;
11 | public LnkCoord dwScreenBufferSize;
12 | public LnkCoord dwWindowSize;
13 | public LnkCoord dwWindowOrigin;
14 | public uint nFont;
15 | public uint nInputBufferSize;
16 | public LnkCoord dwFontSize;
17 | public uint uFontFamily;
18 | public uint uFontWeight;
19 | public FaceNameInlineArray FaceName;
20 | public uint uCursorSize;
21 | public int bFullScreen;
22 | public int bQuickEdit;
23 | public int bInsertMode;
24 | public int bAutoPosition;
25 | public uint uHistoryBufferSize;
26 | public uint uNumberOfHistoryBuffers;
27 | public int bHistoryNoDup;
28 | public ColorTableInlineArray ColorTable;
29 |
30 | [InlineArray(Length)]
31 | internal struct ColorTableInlineArray
32 | {
33 | public const int Length = 16;
34 |
35 | private uint _element0;
36 |
37 | public Span Span => MemoryMarshal.CreateSpan(ref _element0, Length);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/LinkCoord.cs:
--------------------------------------------------------------------------------
1 | namespace Profile.Links;
2 |
3 | internal struct LnkCoord
4 | {
5 | public short X;
6 |
7 | public short Y;
8 |
9 | public override string ToString() => $"{X}, {Y}";
10 | }
11 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/LinkDataBlockSignature.cs:
--------------------------------------------------------------------------------
1 | namespace Profile.Links;
2 |
3 | public enum LinkDataBlockSignature : uint
4 | {
5 | Link = 0xA0000001,
6 | Console = 0xA0000002,
7 | ConsoleFe = 0xA0000004,
8 | SpecialFolder = 0xA0000005,
9 | DarwinId = 0xA0000006,
10 | Icon = 0xA0000007,
11 | PropertyStorage = 0xA0000009,
12 | }
13 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/LinkIdList.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 | using System.Runtime.Versioning;
5 | using Windows.Win32;
6 | using Windows.Win32.Foundation;
7 | using Windows.Win32.UI.Shell;
8 | using Windows.Win32.UI.Shell.Common;
9 | using Windows.Win32.UI.Shell.PropertiesSystem;
10 |
11 | namespace Profile.Links;
12 |
13 | [SupportedOSPlatform("windows6.0.6000")]
14 | public unsafe sealed class LinkIdList : IDisposable
15 | {
16 | private const uint SHGDFIL_FINDDATA = 1;
17 |
18 | private const uint SHGDFIL_NETRESOURCE = 2;
19 |
20 | private const uint SHGDFIL_DESCRIPTIONID = 3;
21 |
22 | private readonly ITEMIDLIST* _list;
23 |
24 | private readonly bool _ownsList;
25 |
26 | private bool _isDisposed;
27 |
28 | internal LinkIdList(ITEMIDLIST* list, bool ownsList = false)
29 | {
30 | _list = list;
31 | _ownsList = ownsList;
32 | }
33 |
34 | public object DumpPropertyStore()
35 | {
36 | IPropertyStore* props = null;
37 | try
38 | {
39 | Interop.SHGetPropertyStoreFromIDList(
40 | _list,
41 | GETPROPERTYSTOREFLAGS.GPS_OPENSLOWITEM,
42 | To.Ref(in IPropertyStore.IID_Guid).ToPointer(),
43 | (void**)&props)
44 | .AssertSuccess();
45 |
46 | return props->DumpProperties();
47 | }
48 | finally
49 | {
50 | if (props is not null)
51 | {
52 | props->Release();
53 | }
54 | }
55 | }
56 |
57 | public List UnsafeGetItemIdListBytes()
58 | {
59 | List items = [];
60 | byte* p = (byte*)_list;
61 | while (true)
62 | {
63 | ushort cb = *(ushort*)p;
64 | p += sizeof(ushort);
65 | if (cb is 0)
66 | {
67 | break;
68 | }
69 |
70 | items.Add(new Span(p, cb).ToArray());
71 | p += cb;
72 | }
73 |
74 | return items;
75 | }
76 |
77 | public LinkIdListDescriptionId GetDescriptionId()
78 | {
79 | LinkIdListDescriptionId descriptionId = default;
80 | Interop.SHGetDataFromIDList(
81 | null,
82 | _list,
83 | SHGDFIL_FORMAT.SHGDFIL_DESCRIPTIONID,
84 | &descriptionId,
85 | sizeof(LinkIdListDescriptionId))
86 | .AssertSuccess();
87 |
88 | return descriptionId;
89 | }
90 |
91 | public string GetName(LinkSigDn dn = LinkSigDn.NormalDisplay)
92 | {
93 | PWSTR pName = default;
94 | try
95 | {
96 | Interop.SHGetNameFromIDList(
97 | _list,
98 | (SIGDN)dn,
99 | &pName)
100 | .AssertSuccess();
101 |
102 | return pName.ToString();
103 | }
104 | finally
105 | {
106 | if (pName.Value is not null)
107 | {
108 | Marshal.FreeCoTaskMem((nint)pName.Value);
109 | }
110 | }
111 | }
112 |
113 | [SkipLocalsInit]
114 | public string GetPath(GpfIdlFlags flags = GpfIdlFlags.Default)
115 | {
116 | const int MAX_PATH = 260;
117 | char* path = stackalloc char[MAX_PATH];
118 | Unsafe.InitBlock(path, 0, MAX_PATH * sizeof(char));
119 | if (!Interop.SHGetPathFromIDListEx(_list, path, MAX_PATH, (GPFIDL_FLAGS)flags))
120 | {
121 | throw new Win32Exception();
122 | }
123 |
124 | return new string(path);
125 | }
126 |
127 | public void Dispose()
128 | {
129 | if (_isDisposed || !_ownsList)
130 | {
131 | return;
132 | }
133 |
134 | Marshal.FreeCoTaskMem((nint)_list);
135 | _isDisposed = true;
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/LinkIdListDescriptionId.cs:
--------------------------------------------------------------------------------
1 | namespace Profile.Links;
2 |
3 | public struct LinkIdListDescriptionId
4 | {
5 | public uint dwDescriptionId;
6 |
7 | public Guid clsid;
8 | }
9 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/LinkSigDn.cs:
--------------------------------------------------------------------------------
1 | namespace Profile.Links;
2 |
3 | public enum LinkSigDn
4 | {
5 | NormalDisplay = 0,
6 | ParentRelativeParsing,
7 | DesktopAbsoluteParsing,
8 | ParentRelativeEditing,
9 | DesktopAbsoluteEditing,
10 | FileSysPath,
11 | Url,
12 | ParentRelativeForAddressBar,
13 | ParentRelative,
14 | ParentRelativeForUI,
15 | }
16 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/LinkSpecialFolder.cs:
--------------------------------------------------------------------------------
1 | namespace Profile.Links;
2 |
3 | public struct LinkSpecialFolder
4 | {
5 | public DataBlockHeader dbh;
6 |
7 | public uint idSpecialFolder;
8 |
9 | public uint cbOffset;
10 | }
11 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/LnkConsoleColorRef.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Management.Automation;
3 |
4 | namespace Profile.Links;
5 |
6 | public readonly struct LnkConsoleColorRef
7 | {
8 | private readonly uint _value;
9 |
10 | public int R => (int)((_value >> 0) & 0xFF);
11 |
12 | public int G => (int)((_value >> 8) & 0xFF);
13 |
14 | public int B => (int)((_value >> 16) & 0xFF);
15 |
16 | public LnkConsoleColorRef(uint value) => _value = value;
17 |
18 | public LnkConsoleColorRef(object[] args)
19 | {
20 | if (args is not [object r, object g, object b])
21 | {
22 | throw new ArgumentException(
23 | "Value must be three numbers, one for red, green and blue.",
24 | nameof(args));
25 | }
26 |
27 | _value = RgbToUInt(
28 | LanguagePrimitives.ConvertTo(r),
29 | LanguagePrimitives.ConvertTo(g),
30 | LanguagePrimitives.ConvertTo(b));
31 | }
32 |
33 | public static LnkConsoleColorRef FromRgb(byte r, byte g, byte b)
34 | {
35 | return new(RgbToUInt(r, g, b));
36 | }
37 |
38 | public static LnkConsoleColorRef Parse(string value)
39 | {
40 | ReadOnlySpan valueSpan = value;
41 | if (valueSpan is ['#', ..])
42 | {
43 | valueSpan = valueSpan[1..];
44 | }
45 |
46 | if (valueSpan.Length is not 6)
47 | {
48 | goto FAIL;
49 | }
50 |
51 | ReadOnlySpan color = valueSpan[..2];
52 | valueSpan = valueSpan[2..];
53 | if (!byte.TryParse(color, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out byte r))
54 | {
55 | goto FAIL;
56 | }
57 |
58 | color = valueSpan[..2];
59 | valueSpan = valueSpan[2..];
60 | if (!byte.TryParse(color, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out byte g))
61 | {
62 | goto FAIL;
63 | }
64 |
65 | if (!byte.TryParse(color, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out byte b))
66 | {
67 | goto FAIL;
68 | }
69 |
70 | throw null!;
71 |
72 | FAIL:
73 | throw new ArgumentException(
74 | "Expected string format of '#RRGGBB' where 'R', 'G' and 'B' are the numeric values of red, green and blue in hex notation.",
75 | nameof(value));
76 | }
77 |
78 | private static uint RgbToUInt(byte r, byte g, byte b)
79 | {
80 | return (uint)(b << 16) | (uint)(g << 8) | r;
81 | }
82 |
83 | public override string ToString()
84 | {
85 | return $"#{R:X2}{G:X2}{B:X2}";
86 | }
87 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/LnkConsoleColorTable.cs:
--------------------------------------------------------------------------------
1 | namespace Profile.Links;
2 |
3 | public sealed class LnkConsoleColorTable
4 | {
5 | private readonly Memory _colorTable;
6 |
7 | public LnkConsoleColorTable(Memory colorTable) => _colorTable = colorTable;
8 |
9 | public LnkConsoleColorRef this[int index]
10 | {
11 | get => Table[index];
12 | set => Table[index] = value;
13 | }
14 |
15 | private Span Table => _colorTable.Span;
16 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/LnkConsoleSettings.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.Versioning;
4 |
5 | namespace Profile.Links;
6 |
7 | [SupportedOSPlatform("windows6.0.6000")]
8 | public unsafe partial class LnkConsoleSettings
9 | {
10 | private readonly PinnedHeapRef _props;
11 |
12 | private LnkConsoleSettings(PinnedHeapRef props)
13 | {
14 | _props = props;
15 | }
16 |
17 | internal static LnkConsoleSettings Create(LnkFile shortcut)
18 | {
19 | PinnedHeapRef props = PinnedHeapRef.Alloc();
20 | LnkConsoleSettings result = new(props);
21 |
22 | shortcut.DataList->CopyDataBlock(
23 | (uint)LinkDataBlockSignature.Console,
24 | (void**)props.Ptr)
25 | .AssertSuccess();
26 |
27 | return result;
28 | }
29 |
30 | public ushort ForegroundColorIndex
31 | {
32 | get => _props.Ptr->wFillAttribute;
33 | set
34 | {
35 | Assert.IndexInRange(value < 16);
36 | _props.Ptr->wFillAttribute = value;
37 | }
38 | }
39 |
40 | public ushort PopupForegroundColorIndex
41 | {
42 | get => _props.Ptr->wPopupFillAttribute;
43 | set
44 | {
45 | Assert.IndexInRange(value < 16);
46 | _props.Ptr->wPopupFillAttribute = value;
47 | }
48 | }
49 |
50 | public LnkCoordProxy ScreenBufferSize => new(CreatePinnedHeapRef(&_props.Ptr->dwScreenBufferSize));
51 |
52 | public LnkCoordProxy WindowSize => new(CreatePinnedHeapRef(&_props.Ptr->dwWindowSize));
53 |
54 | public LnkCoordProxy WindowOrigin => new(CreatePinnedHeapRef(&_props.Ptr->dwWindowOrigin));
55 |
56 | public int FontIndex
57 | {
58 | get => (int)_props.Ptr->nFont;
59 | set
60 | {
61 | ArgumentOutOfRangeException.ThrowIfNegative(value);
62 | _props.Ptr->nFont = (uint)value;
63 | }
64 | }
65 |
66 | public int InputBufferSize
67 | {
68 | get => (int)_props.Ptr->nInputBufferSize;
69 | set
70 | {
71 | ArgumentOutOfRangeException.ThrowIfNegative(value);
72 | _props.Ptr->nInputBufferSize = (uint)value;
73 | }
74 | }
75 |
76 | public LnkCoordProxy FontSize => new(CreatePinnedHeapRef(&_props.Ptr->dwFontSize));
77 |
78 | public PitchAndFamily PitchAndFamily
79 | {
80 | get => (PitchAndFamily)_props.Ptr->uFontFamily;
81 | set => _props.Ptr->uFontFamily = (uint)value;
82 | }
83 |
84 | public int FontWeight
85 | {
86 | get => (int)_props.Ptr->uFontWeight;
87 | set
88 | {
89 | ArgumentOutOfRangeException.ThrowIfNegative(value);
90 | _props.Ptr->uFontWeight = (uint)value;
91 | }
92 | }
93 |
94 | public string FontFaceName
95 | {
96 | get => _props.Ptr->FaceName.Span.SliceToNull().ToString();
97 | set
98 | {
99 | ReadOnlySpan valueSpan = value.AsSpan();
100 | if (valueSpan.Length > FaceNameInlineArray.LF_FACESIZE)
101 | {
102 | valueSpan = valueSpan[..FaceNameInlineArray.LF_FACESIZE];
103 | }
104 |
105 | Span faceName = _props.Ptr->FaceName.Span;
106 | valueSpan.CopyTo(faceName);
107 | if (valueSpan.Length is not FaceNameInlineArray.LF_FACESIZE)
108 | {
109 | faceName[valueSpan.Length + 1] = '\0';
110 | }
111 | }
112 | }
113 |
114 | public int CursorSize
115 | {
116 | get => (int)_props.Ptr->uCursorSize;
117 | set
118 | {
119 | ArgumentOutOfRangeException.ThrowIfNegative(value);
120 | _props.Ptr->uCursorSize = (uint)value;
121 | }
122 | }
123 |
124 | public bool FullScreen
125 | {
126 | get => _props.Ptr->bFullScreen is not 0;
127 | set => _props.Ptr->bFullScreen = value ? 1 : 0;
128 | }
129 |
130 | public bool QuickEdit
131 | {
132 | get => _props.Ptr->bQuickEdit is not 0;
133 | set => _props.Ptr->bQuickEdit = value ? 1 : 0;
134 | }
135 |
136 | public bool InsertMode
137 | {
138 | get => _props.Ptr->bInsertMode is not 0;
139 | set => _props.Ptr->bInsertMode = value ? 1 : 0;
140 | }
141 |
142 | public bool AutoPosition
143 | {
144 | get => _props.Ptr->bAutoPosition is not 0;
145 | set => _props.Ptr->bAutoPosition = value ? 1 : 0;
146 | }
147 |
148 | public int HistoryBufferSize
149 | {
150 | get => (int)_props.Ptr->uHistoryBufferSize;
151 | set
152 | {
153 | ArgumentOutOfRangeException.ThrowIfNegative(value);
154 | _props.Ptr->uHistoryBufferSize = (uint)value;
155 | }
156 | }
157 |
158 | public int NumberOfHistoryBuffers
159 | {
160 | get => (int)_props.Ptr->uNumberOfHistoryBuffers;
161 | set
162 | {
163 | ArgumentOutOfRangeException.ThrowIfNegative(value);
164 | _props.Ptr->uNumberOfHistoryBuffers = (uint)value;
165 | }
166 | }
167 |
168 | public bool HistoryNoDuplicates
169 | {
170 | get => _props.Ptr->bHistoryNoDup is not 0;
171 | set => _props.Ptr->bHistoryNoDup = value ? 1 : 0;
172 | }
173 |
174 | internal void* Ptr => _props.Ptr;
175 |
176 | [field: MaybeNull]
177 | public LnkConsoleColorTable Colors =>
178 | field ??= new(
179 | CreateMemory(
180 | (LnkConsoleColorRef*)&_props.Ptr->ColorTable,
181 | LnkConsoleProps.ColorTableInlineArray.Length));
182 |
183 | internal Memory CreateMemory(T* ptr, int length)
184 | where T : unmanaged
185 | {
186 | return _props.CreateDerivedMemory(ptr, length).Memory;
187 | }
188 |
189 | internal PinnedHeapRef CreatePinnedHeapRef(T* ptr)
190 | where T : unmanaged
191 | {
192 | return _props.CreateDerivedRef(ptr);
193 | }
194 |
195 | public struct LnkCoordProxy
196 | {
197 | private readonly PinnedHeapRef _target;
198 |
199 | internal LnkCoordProxy(PinnedHeapRef target) => _target = target;
200 |
201 | public short X
202 | {
203 | get => _target.Value.X;
204 | set => _target.Value.X = value;
205 | }
206 |
207 | public short Y
208 | {
209 | get => _target.Value.Y;
210 | set => _target.Value.Y = value;
211 | }
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/PathInlineArray.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace Profile.Links;
5 |
6 | [InlineArray(MAX_PATH)]
7 | internal struct PathInlineArray where T : unmanaged
8 | {
9 | public const int MAX_PATH = 260;
10 |
11 | private T _element0;
12 |
13 | public Span Span => MemoryMarshal.CreateSpan(ref _element0, MAX_PATH);
14 | }
15 |
16 | internal static class FaceNameInlineArray
17 | {
18 | public const int LF_FACESIZE = 32;
19 | }
20 |
21 | [InlineArray(FaceNameInlineArray.LF_FACESIZE)]
22 | internal struct FaceNameInlineArray where T : unmanaged
23 | {
24 | private T _element0;
25 |
26 | public Span Span => MemoryMarshal.CreateSpan(ref _element0, FaceNameInlineArray.LF_FACESIZE);
27 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/PinnedArrayMemoryManager.cs:
--------------------------------------------------------------------------------
1 | using System.Buffers;
2 |
3 | namespace Profile;
4 |
5 | internal sealed unsafe class PinnedArrayMemoryManager : MemoryManager where T : unmanaged
6 | {
7 | #pragma warning disable IDE0052
8 | private readonly object _keepAlive;
9 | #pragma warning restore IDE0052
10 |
11 | private readonly T* _ptr;
12 |
13 | private readonly int _length;
14 |
15 | public PinnedArrayMemoryManager(object keepAlive, T* ptr, int length)
16 | {
17 | _keepAlive = keepAlive;
18 | _ptr = ptr;
19 | _length = length;
20 | }
21 |
22 | public override Span GetSpan()
23 | {
24 | return new Span(_ptr, _length);
25 | }
26 |
27 | public override MemoryHandle Pin(int elementIndex = 0)
28 | {
29 | return new MemoryHandle(_ptr);
30 | }
31 |
32 | public override void Unpin()
33 | {
34 | }
35 |
36 | protected override void Dispose(bool disposing)
37 | {
38 | }
39 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/PitchAndFamily.cs:
--------------------------------------------------------------------------------
1 | namespace Profile.Links;
2 |
3 | [Flags]
4 | public enum PitchAndFamily : uint
5 | {
6 | None = 0,
7 | FixedPitch = 1 << 0,
8 | Vector = 1 << 1,
9 | TrueType = 1 << 2,
10 | Device = 1 << 3,
11 | }
12 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/ShortcutFlags.cs:
--------------------------------------------------------------------------------
1 | namespace Profile.Links;
2 |
3 | [Flags]
4 | public enum ShortcutFlags
5 | {
6 | Default = 0x00000000,
7 | HasIdList = 0x00000001,
8 | HasLinkInfo = 0x00000002,
9 | HasName = 0x00000004,
10 | HasRelPath = 0x00000008,
11 | HasWorkingDir = 0x00000010,
12 | HasArgs = 0x00000020,
13 | HasIconLocation = 0x00000040,
14 | Unicode = 0x00000080,
15 | ForceNoLinkInfo = 0x00000100,
16 | HasExpSz = 0x00000200,
17 | RunInSeparate = 0x00000400,
18 | HasLogo3Id = 0x00000800,
19 | HasDarwinId = 0x00001000,
20 | RunAsUser = 0x00002000,
21 | HasExpIconSz = 0x00004000,
22 | NoPidlAlias = 0x00008000,
23 | ForceUncName = 0x00010000,
24 | RunWithShimLayer = 0x00020000,
25 | ForceNoLinkTrack = 0x00040000,
26 | EnableTargetMetadata = 0x00080000,
27 | DisableLinkPathTracking = 0x00100000,
28 | DisableKnownFolderRelativeTracking = 0x00200000,
29 | NoKfAlias = 0x00400000,
30 | AllowLinkToLink = 0x00800000,
31 | UnaliasOnSave = 0x01000000,
32 | PreferEnvironmentPath = 0x02000000,
33 | KeepLocalIdlistForUncTarget = 0x04000000,
34 | PersistVolumeIdRelative = 0x08000000,
35 | Valid = 0x003FF7FF,
36 | }
37 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Links/ShowWindowCmd.cs:
--------------------------------------------------------------------------------
1 | namespace Profile.Links;
2 |
3 | public enum ShowWindowCmd
4 | {
5 | Hide = 0,
6 | ShowNormal = 1,
7 | Normal = 1,
8 | ShowMinimized = 2,
9 | ShowMaximized = 3,
10 | Maximize = 3,
11 | ShowNoActivate = 4,
12 | Show = 5,
13 | Minimize = 6,
14 | ShowMinNoActive = 7,
15 | ShowNa = 8,
16 | Restore = 9,
17 | ShowDefault = 10,
18 | ForceMinimize = 11,
19 | Max = 11,
20 | }
21 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/LooseHandle.cs:
--------------------------------------------------------------------------------
1 | namespace Profile;
2 |
3 | internal readonly struct LooseHandle : IDisposable
4 | where T : IDisposable
5 | {
6 | public readonly T? Value;
7 |
8 | public LooseHandle(T? value = default) => Value = value;
9 |
10 | public void Dispose() => Value?.Dispose();
11 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/NativeMethods.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://aka.ms/CsWin32.schema.json",
3 | "emitSingleFile": true,
4 | "public": false,
5 | "useSafeHandles": false,
6 | "className": "Interop",
7 | "friendlyOverloads": {
8 | "enabled": false
9 | },
10 | "comInterop": {
11 | "preserveSigMethods": [
12 | "*"
13 | ]
14 | },
15 | "allowMarshaling": false
16 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/NativeMethods.txt:
--------------------------------------------------------------------------------
1 | GetWindowInfo
2 | GetWindowTextLengthW
3 | GetWindowTextW
4 | GetWindowThreadProcessId
5 | EnumWindows
6 | EnumChildWindows
7 | GetClassInfoExW
8 | GetClassNameW
9 | HINSTANCE
10 | FindWindowExW
11 | IShellLinkW
12 | CoCreateInstance
13 | IPersistFile
14 | ShellLink
15 | CLSID_ShellLink
16 | IPropertyStore
17 | PKEY_Link_Arguments
18 | INPLACE_S_TRUNCATED
19 | PropVariantToBSTR
20 | PropVariantClear
21 | SysFreeString
22 | IPersistFile
23 | PSGetPropertyDescription
24 | IPropertyDescription
25 | IShellLinkDataList
26 | SHGetPathFromIDListEx
27 | SHGetNameFromIDList
28 | SHGetDataFromIDListW
29 | SHGetPropertyStoreFromIDList
30 | GetErrorInfo
31 | IErrorInfo
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/PointerOps.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | namespace Profile;
4 |
5 | internal static class PointerOps
6 | {
7 | public static bool TryGetNativeInt(object? value, out nint result)
8 | {
9 | return value switch
10 | {
11 | nint v => Success(v, out result),
12 | nuint v => Success(unchecked((nint)v), out result),
13 | int v => Success(v, out result),
14 | uint v => Success(unchecked((int)v), out result),
15 | long v => nint.Size is sizeof(long) ? Success(Unsafe.As(ref v), out result) : Fail(out result),
16 | ulong v => nint.Size is sizeof(long) ? Success(Unsafe.As(ref v), out result) : Fail(out result),
17 | INativeIntWrapper v => Success(v.ToIntPtr(), out result),
18 | _ => Fail(out result),
19 | };
20 |
21 | static bool Success(nint value, out nint result)
22 | {
23 | result = value;
24 | return true;
25 | }
26 |
27 | static bool Fail(out nint result)
28 | {
29 | result = default;
30 | return false;
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/PooledConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.Linq.Expressions;
3 | using System.Management.Automation;
4 | using System.Management.Automation.Internal;
5 | using System.Reflection;
6 | using System.Reflection.Metadata;
7 |
8 | namespace Profile;
9 |
10 | public sealed class PooledConverter : PSTypeConverter
11 | {
12 | public override bool CanConvertFrom(object sourceValue, Type destinationType)
13 | {
14 | return sourceValue is pooled && destinationType.IsSubclassOf(typeof(Delegate));
15 | }
16 |
17 | public override bool CanConvertTo(object sourceValue, Type destinationType)
18 | {
19 | return sourceValue is pooled && destinationType.IsSubclassOf(typeof(Delegate));
20 | }
21 |
22 | public override object ConvertFrom(
23 | object sourceValue,
24 | Type destinationType,
25 | IFormatProvider formatProvider,
26 | bool ignoreCase)
27 | {
28 | return CreateDelegate(((pooled)sourceValue)._scriptBlock, destinationType);
29 | }
30 |
31 | public override object ConvertTo(object sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase)
32 | {
33 | return CreateDelegate(((pooled)sourceValue)._scriptBlock, destinationType);
34 | }
35 |
36 | private Delegate CreateDelegate(ScriptBlock scriptBlock, Type delegateType)
37 | {
38 | MethodInfo? invokeMethod = delegateType.GetMethod("Invoke");
39 | Debug.Assert(invokeMethod is not null);
40 |
41 | ParameterInfo[] parameters = invokeMethod.GetParameters();
42 | ParameterExpression[] paramExpr = new ParameterExpression[parameters.Length];
43 | Expression[] paramsAsArgs = new Expression[parameters.Length];
44 | for (int i = parameters.Length - 1; i >= 0; i--)
45 | {
46 | ParameterInfo p = parameters[i];
47 | ParameterExpression pExpr = Expression.Parameter(p.ParameterType, p.Name);
48 | paramExpr[i] = pExpr;
49 | if (p.ParameterType.IsValueType)
50 | {
51 | paramsAsArgs[i] = Expression.Convert(pExpr, typeof(object));
52 | continue;
53 | }
54 |
55 | paramsAsArgs[i] = pExpr;
56 | }
57 |
58 | ConstantExpression autoNull = Expression.Constant(AutomationNull.Value, typeof(object));
59 | Expression call = Expression.Call(
60 | null,
61 | ReflectionCache.PooledRunspaces.InvokeWithCachedRunspaceMethod,
62 | [
63 | Expression.Constant(ReflectionCache.ScriptBlock.Clone(scriptBlock)),
64 | Expression.Constant(PooledRunspaces.Instance),
65 | paramsAsArgs.Length is not 0 ? paramsAsArgs[0] : autoNull,
66 | autoNull,
67 | Expression.NewArrayInit(typeof(object), paramsAsArgs)
68 | ]);
69 |
70 | if (invokeMethod.ReturnType != typeof(void))
71 | {
72 | call = Expression.Dynamic(
73 | ReflectionCache.PSConvertBinder.Get(invokeMethod.ReturnType),
74 | invokeMethod.ReturnType,
75 | call);
76 | }
77 |
78 | return Expression.Lambda(delegateType, call, paramExpr).Compile();
79 | }
80 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/PooledRunspaces.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Concurrent;
2 | using System.Management.Automation;
3 | using System.Management.Automation.Runspaces;
4 |
5 | namespace Profile;
6 |
7 | internal sealed class PooledRunspaces
8 | {
9 | public static PooledRunspaces Instance { get; } = new();
10 |
11 | private readonly ConcurrentBag _runspaces = new();
12 |
13 | public Runspace Rent()
14 | {
15 | if (_runspaces.TryPeek(out Runspace? existing))
16 | {
17 | return existing;
18 | }
19 |
20 | return CreateRunspace();
21 | }
22 |
23 | public void Return(Runspace runspace)
24 | {
25 | runspace.ResetRunspaceState();
26 | _runspaces.Add(runspace);
27 | }
28 |
29 | private Runspace CreateRunspace()
30 | {
31 | Runspace rs = RunspaceFactory.CreateRunspace();
32 | rs.ThreadOptions = PSThreadOptions.UseCurrentThread;
33 | rs.Open();
34 | return rs;
35 | }
36 |
37 | internal static object? InvokeWithCachedRunspace(
38 | ScriptBlock scriptBlock,
39 | PooledRunspaces runspaces,
40 | object? dollarUnder,
41 | object? dollarThis,
42 | object?[]? args)
43 | {
44 | Runspace? previous = Runspace.DefaultRunspace;
45 | Runspace toReturn = runspaces.Rent();
46 | try
47 | {
48 | Runspace.DefaultRunspace = toReturn;
49 | return ReflectionCache.ScriptBlock.InvokeAsDelegateHelper(
50 | scriptBlock,
51 | dollarUnder,
52 | dollarThis,
53 | args);
54 | }
55 | finally
56 | {
57 | runspaces.Return(toReturn);
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Profile.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net9.0
5 | enable
6 | enable
7 | true
8 | true
9 | preview
10 | true
11 |
12 |
13 |
14 |
15 | runtime; build; native; contentfiles; analyzers; buildtransitive
16 | all
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/PropVariant.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 | using Windows.Win32.System.Com;
3 | using Windows.Win32.System.Com.StructuredStorage;
4 | using Windows.Win32.System.Variant;
5 | using Windows.Win32.Foundation;
6 | using System.Runtime.InteropServices.ComTypes;
7 | using IStream = Windows.Win32.System.Com.IStream;
8 | // using winmdroot = global::Windows.Win32;
9 |
10 | namespace Profile;
11 |
12 | internal struct PropVariant
13 | {
14 | private PROPVARIANT _var;
15 | internal ref VARENUM vt => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.vt);
16 | internal ref DECIMAL decVal => ref Unsafe.AsRef(ref _var.Anonymous.decVal);
17 | internal ref CHAR cVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cVal);
18 | internal ref byte bVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.bVal);
19 | internal ref short iVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.iVal);
20 | internal ref ushort uiVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.uiVal);
21 | internal ref int lVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.lVal);
22 | internal ref uint ulVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.ulVal);
23 | internal ref int intVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.intVal);
24 | internal ref uint uintVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.uintVal);
25 | internal ref long hVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.hVal);
26 | internal ref ulong uhVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.uhVal);
27 | internal ref float fltVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.fltVal);
28 | internal ref double dblVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.dblVal);
29 | internal ref VARIANT_BOOL boolVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.boolVal);
30 | internal ref int scode => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.scode);
31 | internal ref CY cyVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cyVal);
32 | internal ref double date => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.date);
33 | internal ref FILETIME filetime => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.filetime);
34 | internal unsafe ref global::System.Guid* puuid => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.puuid);
35 | internal unsafe ref CLIPDATA* pclipdata => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pclipdata);
36 | internal ref BSTR bstrVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.bstrVal);
37 | internal ref BSTRBLOB bstrblobVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.bstrblobVal);
38 | internal ref BLOB blob => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.blob);
39 | internal ref PSTR pszVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.pszVal);
40 | internal ref PWSTR pwszVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.pwszVal);
41 | internal unsafe ref IUnknown* punkVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.punkVal);
42 | internal unsafe ref IDispatch* pdispVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pdispVal);
43 | internal unsafe ref IStream* pStream => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pStream);
44 | internal unsafe ref IStorage* pStorage => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pStorage);
45 | internal unsafe ref VERSIONEDSTREAM* pVersionedStream => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pVersionedStream);
46 | internal unsafe ref SAFEARRAY* parray => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.parray);
47 | internal ref CAC cac => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cac);
48 | internal ref CAUB caub => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.caub);
49 | internal ref CAI cai => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cai);
50 | internal ref CAUI caui => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.caui);
51 | internal ref CAL cal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cal);
52 | internal ref CAUL caul => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.caul);
53 | internal ref CAH cah => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cah);
54 | internal ref CAUH cauh => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cauh);
55 | internal ref CAFLT caflt => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.caflt);
56 | internal ref CADBL cadbl => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cadbl);
57 | internal ref CABOOL cabool => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cabool);
58 | internal ref CASCODE cascode => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cascode);
59 | internal ref CACY cacy => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cacy);
60 | internal ref CADATE cadate => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cadate);
61 | internal ref CAFILETIME cafiletime => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cafiletime);
62 | internal ref CACLSID cauuid => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cauuid);
63 | internal ref CACLIPDATA caclipdata => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.caclipdata);
64 | internal ref CABSTR cabstr => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cabstr);
65 | internal ref CABSTRBLOB cabstrblob => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.cabstrblob);
66 | internal ref CALPSTR calpstr => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.calpstr);
67 | internal ref CALPWSTR calpwstr => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.calpwstr);
68 | internal ref CAPROPVARIANT capropvar => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.capropvar);
69 | internal ref PSTR pcVal => ref Unsafe.AsRef(ref _var.Anonymous.Anonymous.Anonymous.pcVal);
70 | internal unsafe ref byte* pbVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pbVal);
71 | internal unsafe ref short* piVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.piVal);
72 | internal unsafe ref ushort* puiVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.puiVal);
73 | internal unsafe ref int* plVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.plVal);
74 | internal unsafe ref uint* pulVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pulVal);
75 | internal unsafe ref int* pintVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pintVal);
76 | internal unsafe ref uint* puintVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.puintVal);
77 | internal unsafe ref float* pfltVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pfltVal);
78 | internal unsafe ref double* pdblVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pdblVal);
79 | internal unsafe ref VARIANT_BOOL* pboolVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pboolVal);
80 | internal unsafe ref DECIMAL* pdecVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pdecVal);
81 | internal unsafe ref int* pscode => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pscode);
82 | internal unsafe ref CY* pcyVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pcyVal);
83 | internal unsafe ref double* pdate => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pdate);
84 | internal unsafe ref BSTR* pbstrVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pbstrVal);
85 | internal unsafe ref IUnknown** ppunkVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.ppunkVal);
86 | internal unsafe ref IDispatch** ppdispVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.ppdispVal);
87 | internal unsafe ref SAFEARRAY** pparray => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pparray);
88 | internal unsafe ref PROPVARIANT* pvarVal => ref To.Ref(ref _var.Anonymous.Anonymous.Anonymous.pvarVal);
89 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Rect.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using System.Numerics;
3 |
4 | namespace Profile;
5 |
6 | public readonly struct Rect : IEquatable, IEqualityOperators
7 | {
8 | public int Left { get; }
9 |
10 | public int Top { get; }
11 |
12 | public int Right { get; }
13 |
14 | public int Bottom { get; }
15 |
16 | public int Width => Right - Left;
17 |
18 | public int Height => Bottom - Top;
19 |
20 | public static bool operator ==(Rect left, Rect right)
21 | {
22 | return left.Equals(right);
23 | }
24 |
25 | public static bool operator !=(Rect left, Rect right)
26 | {
27 | return !left.Equals(right);
28 | }
29 |
30 | public bool Equals(Rect other)
31 | {
32 | return Left == other.Left
33 | && Right == other.Right
34 | && Top == other.Top
35 | && Bottom == other.Bottom;
36 | }
37 |
38 | public override bool Equals([NotNullWhen(true)] object? obj)
39 | {
40 | return obj is Rect other && Equals(other);
41 | }
42 |
43 | public override string ToString()
44 | {
45 | return $"{Left},{Top} - {Width}x{Height}";
46 | }
47 |
48 | public override int GetHashCode()
49 | {
50 | return HashCode.Combine(Left, Right, Top, Bottom);
51 | }
52 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/Throw.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | namespace Profile;
4 |
5 | internal static class Throw
6 | {
7 | // public static TResult ThrowOutOfRange()
8 | // {
9 | // ArgumentException.
10 | // }
11 | public static TResult Unreachable()
12 | {
13 | throw new UnreachableException();
14 | }
15 | }
--------------------------------------------------------------------------------
/Documents/PowerShell/Profile/src/Profile/pooled.cs:
--------------------------------------------------------------------------------
1 |
2 | using System.Management.Automation;
3 |
4 | #pragma warning disable CS8981 // The type name only contains lower-cased ascii characters. Such names may become reserved for the language.
5 |
6 | public sealed class pooled
7 | {
8 | internal readonly ScriptBlock _scriptBlock;
9 |
10 | public pooled(ScriptBlock scriptBlock)
11 | {
12 | _scriptBlock = scriptBlock;
13 | }
14 |
15 | public override string ToString() => _scriptBlock.ToString();
16 |
17 | public override int GetHashCode() => _scriptBlock.GetHashCode();
18 | }
19 |
20 | #pragma warning restore CS8981 // The type name only contains lower-cased ascii characters. Such names may become reserved for the language.
21 |
--------------------------------------------------------------------------------
/Documents/PowerShell/SetConsoleFont.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | DESCRIPTION
3 | This script sets the current console font. The module WindowsConsoleFont by Jaykul
4 | could (and probably should) be used here instead. That's not currently published
5 | anywhere so I put together a minimal version to avoid needing to compile that project
6 | on every machine I use.
7 | #>
8 | [CmdletBinding()]
9 | param([string] $Family, [int] $Size)
10 | end {
11 | # If we're not in conhost don't try to set font family.
12 | if ($env:TERM_PROGRAM -match 'vscode' -or $env:WT_SESSION) {
13 | return
14 | }
15 |
16 | $assemblyPath = "$PSScriptRoot\FontSetter.dll"
17 | if (-not (Test-Path $assemblyPath)) {
18 | Add-Type -OutputType Library -OutputAssembly $assemblyPath -TypeDefinition '
19 | using System;
20 | using System.ComponentModel;
21 | using System.Management.Automation;
22 | using System.Runtime.InteropServices;
23 |
24 | namespace ProfileUtility
25 | {
26 | [EditorBrowsable(EditorBrowsableState.Never)]
27 | public static class FontSetter
28 | {
29 | private static IntPtr s_outputHandle;
30 |
31 | [Hidden, EditorBrowsable(EditorBrowsableState.Never)]
32 | public static void SetConsoleFont(string familyName, short size = 0)
33 | {
34 | var info = new Interop.CONSOLE_FONT_INFOEX();
35 | info.FaceName = new char[Interop.LF_FACESIZE];
36 | info.cbSize = (uint)Marshal.SizeOf();
37 | int result = Interop.GetCurrentConsoleFontEx(
38 | GetOutputHandle(),
39 | false,
40 | ref info);
41 |
42 | if (result == 0)
43 | {
44 | throw new Win32Exception(Marshal.GetLastWin32Error());
45 | }
46 |
47 | Array.Clear(info.FaceName, 0, info.FaceName.Length);
48 | familyName.CopyTo(0, info.FaceName, 0, Math.Min(familyName.Length, Interop.LF_FACESIZE));
49 | if (size > 0)
50 | {
51 | info.dwFontSize.Y = size;
52 | }
53 |
54 | result = Interop.SetCurrentConsoleFontEx(
55 | GetOutputHandle(),
56 | false,
57 | ref info);
58 |
59 | if (result == 0)
60 | {
61 | throw new Win32Exception(Marshal.GetLastWin32Error());
62 | }
63 | }
64 |
65 | private static IntPtr GetOutputHandle()
66 | {
67 | if (s_outputHandle != Interop.INVALID_HANDLE_VALUE && s_outputHandle != IntPtr.Zero)
68 | {
69 | return s_outputHandle;
70 | }
71 |
72 | IntPtr outputHandle = Interop.GetStdHandle(Interop.STD_OUTPUT_HANDLE);
73 | if (outputHandle == Interop.INVALID_HANDLE_VALUE)
74 | {
75 | throw new Win32Exception(Marshal.GetLastWin32Error());
76 | }
77 |
78 | return s_outputHandle = outputHandle;
79 | }
80 |
81 | private static class Interop
82 | {
83 | public const int LF_FACESIZE = 32;
84 |
85 | public const int STD_OUTPUT_HANDLE = -11;
86 |
87 | public static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
88 |
89 | private const string Kernel32DllName = "kernel32";
90 |
91 | [DllImport(Kernel32DllName, SetLastError = true)]
92 | public static extern IntPtr GetStdHandle(int nStdHandle);
93 |
94 |
95 | [DllImport(Kernel32DllName, SetLastError = true, CharSet = CharSet.Unicode)]
96 | public static extern int GetCurrentConsoleFontEx(
97 | IntPtr hConsoleOutput,
98 | bool bMaximumWindow,
99 | ref CONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
100 |
101 | [DllImport(Kernel32DllName, SetLastError = true, CharSet = CharSet.Unicode)]
102 | public static extern int SetCurrentConsoleFontEx(
103 | IntPtr hConsoleOutput,
104 | bool bMaximumWindow,
105 | ref CONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
106 |
107 | [StructLayout(LayoutKind.Sequential)]
108 | public struct COORD
109 | {
110 | public short X;
111 |
112 | public short Y;
113 | }
114 |
115 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
116 | public struct CONSOLE_FONT_INFOEX
117 | {
118 | public uint cbSize;
119 |
120 | public int nFont;
121 |
122 | public COORD dwFontSize;
123 |
124 | public uint FontFamily;
125 |
126 | public uint FontWeight;
127 |
128 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = LF_FACESIZE)]
129 | public char[] FaceName;
130 | }
131 | }
132 | }
133 | }'
134 | }
135 |
136 | Add-Type -Path $assemblyPath -ErrorAction Stop
137 | [ProfileUtility.FontSetter]::SetConsoleFont($Family, $Size)
138 | }
139 |
--------------------------------------------------------------------------------
/Documents/PowerShell/SetTypeCache.ps1:
--------------------------------------------------------------------------------
1 | using namespace System
2 | using namespace System.Collections.Generic
3 | using namespace System.Management.Automation
4 | using namespace System.Reflection
5 |
6 | <#
7 | SYNOPSIS
8 | Forcefully repopulates type tab completion cache. Useful when loading
9 | assemblies that cause Assembly.GetTypes() to throw in PowerShell 5.1.
10 | #>
11 | function global:Set-TypeCompletionCache {
12 | param()
13 | end {
14 | Import-Module PSLambda
15 | $types = [type[]] (& {
16 | Find-Type -Force TypeCompletionMapping
17 | Find-Type -Force TypeCompletion
18 | Find-Type -Force TypeAccelerators
19 | Find-Type -Force TypeCompletionBase
20 | Find-Type -Force TypeCompletionInStringFormat
21 | Find-Type -Force ClrFacade
22 | Find-Type -Force TypeResolver -Namespace System.Management.Automation.Language
23 | })
24 |
25 | Invoke-PSLambda -EnablePrivateBinding -ResolvablePrivateTypes $types {
26 | $entries = [Dictionary[string,TypeCompletionMapping]]::new([StringComparer]::OrdinalIgnoreCase)
27 | foreach ($type in [TypeAccelerators]::Get) {
28 | $entry = default([TypeCompletionMapping])
29 | $instance = [TypeCompletion]::new()
30 | $instance.Type = $type.Value
31 |
32 | if ($entries.TryGetValue($type.Key, $entry)) {
33 | $acceleratorType = $type.Value
34 | $alreadyIncluded = $entry.Completions.Any{ $item => {
35 | return $item -is [TypeCompletion] -and ([TypeCompletion]$item).Type -eq $acceleratorType
36 | }}
37 |
38 | if ($alreadyIncluded) {
39 | continue
40 | }
41 |
42 | $entry.Completions.Add($instance)
43 | } else {
44 | $entry = [TypeCompletionMapping]::new()
45 | $entry.Key = $type.Key
46 | $entry.Completions = [List[TypeCompletionBase]]::new()
47 | $entry.Completions.Add($instance)
48 | $entries.Add($type.Key, $entry)
49 | }
50 |
51 | $fullTypeName = $type.Value.FullName
52 | if ($entries.ContainsKey($fullTypeName)) {
53 | continue
54 | }
55 |
56 | $mapping = [TypeCompletionMapping]::new()
57 | $mapping.Key = $fullTypeName
58 | $mapping.Completions = [List[TypeCompletionBase]]::new()
59 | $mapping.Completions.Add($instance)
60 | $entries.Add($fullTypeName, $mapping)
61 |
62 | $shortTypeName = $type.Value.Name
63 | if ($type.Key.Equals($shortTypeName, [StringComparison]::OrdinalIgnoreCase)) {
64 | continue
65 | }
66 |
67 | if (-not $entries.TryGetValue($shortTypeName, $entry)) {
68 | $entry = [TypeCompletionMapping]::new()
69 | $entry.Key = $shortTypeName
70 | $entries.Add($shortTypeName, $entry)
71 | }
72 |
73 | $entry.Completions.Add($instance)
74 | }
75 |
76 | $availableTypes = [List[type]]::new()
77 | foreach ($assembly in [AppDomain]::CurrentDomain.GetAssemblies()) {
78 | $types = [type]::EmptyTypes
79 | try {
80 | $types = $assembly.GetTypes()
81 | } catch {
82 | continue
83 | }
84 |
85 | $availableTypes.AddRange($types)
86 | }
87 |
88 | foreach ($type in $availableTypes) {
89 | try {
90 | if (-not [TypeResolver]::IsPublic($type)) {
91 | continue
92 | }
93 |
94 | [CompletionCompleters]::HandleNamespace($entries, $type.Namespace)
95 | [CompletionCompleters]::HandleType($entries, $type.FullName, $type.Name, $type)
96 | } catch {
97 | continue
98 | }
99 | }
100 |
101 | $grouping = ([TypeCompletionMapping[]]$entries.Values).
102 | GroupBy{ $t => $t.Key.ToCharArray().Count{ $c => ($c -eq '.'[0]) }}.
103 | OrderBy{ $g => $g.Key }.
104 | ToArray()
105 |
106 | $localTypeCache = [TypeCompletionMapping[][]]::new($grouping.Last().Key + 1)
107 | foreach ($group in $grouping) {
108 | $localTypeCache.SetValue([TypeCompletionMapping[]]$group, $group.Key)
109 | }
110 |
111 | $cacheField = default([FieldInfo])
112 | $bindingFlags = [BindingFlags]'NonPublic, Static'
113 | if (([Version]$PSVersionTable['PSVersion']).Major -gt 5) {
114 | $cacheField = [CompletionCompleters].GetField('s_typeCache', $bindingFlags)
115 | } else {
116 | $cacheField = [CompletionCompleters].GetField('typeCache', $bindingFlags)
117 | }
118 |
119 | $cacheField.SetValue($null, $localTypeCache)
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/Documents/PowerShell/VT.ps1:
--------------------------------------------------------------------------------
1 | $IND = "`eD" # Index
2 | $NEL = "`eE" # Next line
3 | $HTS = "`eH" # Horizontal tab set
4 | $RI = "`eM" # Reverse index
5 | $SS2 = "`eN" # Single shift 2
6 | $SS3 = "`eO" # Single shift 3
7 | $DCS = "`eP" # Device control string
8 | $SOS = "`eX" # Start of string
9 | $CSI = "`e[" # Control sequence introducer
10 | $ST = "`e\" # String terminator
11 | $OSC = "`e]" # Operating system command
12 | $PM = "`e^" # Privacy message
13 | $APC = "`e_" # Application program
14 | $DECID = "`eZ" # VT identification
15 |
16 | $ALL_VT = @{
17 | IND = $IND
18 | NEL = $NEL
19 | HTS = $HTS
20 | RI = $RI
21 | SS2 = $SS2
22 | SS3 = $SS3
23 | DCS = $DCS
24 | SOS = $SOS
25 | CSI = $CSI
26 | ST = $ST
27 | OSC = $OSC
28 | PM = $PM
29 | APC = $APC
30 | DECID = $DECID
31 | }
32 |
33 | function Show-VT {
34 | param(
35 | [Parameter(ValueFromPipeline)]
36 | [string] $Sequence
37 | )
38 | process {
39 | foreach ($vt in $ALL_VT.GetEnumerator()) {
40 | $Sequence = $Sequence -replace [regex]::Escape($vt.Value), { " $($vt.Key) " }
41 | }
42 |
43 | $Sequence -replace '\p{Cc}', {
44 | $value = [int][char]$_.Value
45 | return [char]($value -lt 0x20 ? $value -bor 0x2400 : $value)
46 | }
47 | }
48 | }
49 |
50 | function Get-VTInfo {
51 | [CmdletBinding()]
52 | param(
53 | [Parameter(Mandatory)]
54 | [ValidateNotNullOrEmpty()]
55 | [string] $Name
56 | )
57 | end {
58 | $uri = 'https://vt100.net/docs/vt510-rm/{0}.html' -f $Name
59 | $html = (Invoke-WebRequest $uri -UseBasicParsing).ToString()
60 | $desc = $html | htmlq 'h2 + p' --text
61 | $seq = $html | htmlq .ctrlseq | htmlq 'span, var' --pretty | Out-String
62 | $seq = $seq.Trim()
63 | $seq = $seq `
64 | -replace '', ' ' `
65 | -replace '', ' ' `
66 | -replace 'n', '' `
67 | -replace '', " $($PSStyle.Italic)" `
68 | -replace '', "$($PSStyle.ItalicOff)" `
69 | -replace ' {1,}',' '
70 |
71 | [pscustomobject]@{
72 | PSTypeName = 'Utility.VTInfo'
73 | Name = $Name
74 | Description = $desc
75 | Sequence = $seq
76 | }
77 | }
78 | }
79 |
80 | $C0_NUL = "`u{0000}" # Null
81 | $C0_SOH = "`u{0001}" # Start of Heading
82 | $C0_STX = "`u{0002}" # Start of Text
83 | $C0_ETX = "`u{0003}" # End of Text
84 | $C0_EOT = "`u{0004}" # End of Transmission
85 | $C0_ENG = "`u{0005}" # Enquiry
86 | $C0_ACK = "`u{0006}" # Acknowledge
87 | $C0_BEL = "`u{0007}" # Bell
88 | $C0_BS = "`u{0008}" # Backspace
89 | $C0_HT = "`u{0009}" # Horizontal Tab
90 | $C0_LF = "`u{000A}" # Line Feed
91 | $C0_VT = "`u{000B}" # Vertical Tab
92 | $C0_FF = "`u{000C}" # Form Feed
93 | $C0_CR = "`u{000D}" # Carriage Return
94 | $C0_SO = "`u{000E}" # Shift Out
95 | $C0_SI = "`u{000F}" # Shift In
96 | $C0_DLE = "`u{0010}" # Data Link Escape
97 | $C0_DC1 = "`u{0011}" # Device Control 1 (XON)
98 | $C0_DC2 = "`u{0012}" # Device Control 2
99 | $C0_DC3 = "`u{0013}" # Device Control 3 (XOFF)
100 | $C0_DC4 = "`u{0014}" # Device Control 4
101 | $C0_NAK = "`u{0015}" # Negative Acknowledge
102 | $C0_SYN = "`u{0016}" # Synchronous Idle
103 | $C0_ETB = "`u{0017}" # End of Transmission Block
104 | $C0_CAN = "`u{0018}" # Cancel
105 | $C0_EM = "`u{0019}" # End of Medium
106 | $C0_SUB = "`u{001A}" # Substitute
107 | $C0_ESC = "`u{001B}" # Escape
108 | $C0_FS = "`u{001C}" # File Separator
109 | $C0_GS = "`u{001D}" # Group Separator
110 | $C0_RS = "`u{001E}" # Record Separator
111 | $C0_US = "`u{001F}" # Unit Separator
112 | $C0_DEL = "`u{007F}" # Delete
113 | $C1_SPA = "`u{0096}" # Start of guarded area
114 | $C1_EPA = "`u{0097}" # End of guarded area
115 |
--------------------------------------------------------------------------------
/Documents/PowerShell/consoleColors.reg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SeeminglyScience/dotfiles/f71ae620d7b30246c33dec8636a4a609c449d517/Documents/PowerShell/consoleColors.reg
--------------------------------------------------------------------------------
/Documents/PowerShell/gh.Completer.ps1:
--------------------------------------------------------------------------------
1 | using namespace System.Management.Automation
2 | using namespace System.Management.Automation.Language
3 |
4 | # A fixed version of the completion script generated by `gh`. It did
5 | # not seem to work at all for me.
6 | Register-ArgumentCompleter -Native -CommandName 'gh' -ScriptBlock {
7 | param(
8 | [string] $WordToComplete,
9 | [System.Management.Automation.Language.CommandAst] $CommandAst,
10 | [int] $CursorPosition
11 | )
12 | filter __gh_escapeStringWithSpecialChars {
13 | $_ -replace '\s|#|@|\$|;|,|''|\{|\}|\(|\)|"|`|\||<|>|&','`$&'
14 | }
15 |
16 | # Get the current command line and convert into a string
17 | # $Command = $CommandAst.CommandElements
18 | $Command = $CommandAst.Extent.Text
19 | $Command = "$Command"
20 |
21 | # We need to trigger completion from the $CursorPosition location, so we need
22 | # to truncate the command-line ($Command) up to the $CursorPosition location.
23 | # Make sure the $Command is longer then the $CursorPosition before we truncate.
24 | # This happens because the $Command does not include the last space.
25 | if ($Command.Length -gt $CursorPosition) {
26 | $Command=$Command.Substring(0,$CursorPosition)
27 | }
28 |
29 | $ShellCompDirectiveError=1
30 | $ShellCompDirectiveNoSpace=2
31 | $ShellCompDirectiveNoFileComp=4
32 | $ShellCompDirectiveFilterFileExt=8
33 | $ShellCompDirectiveFilterDirs=16
34 |
35 | # Prepare the command to request completions for the program.
36 | # Split the command at the first space to separate the program and arguments.
37 | $Program, $Arguments = $CommandAst.CommandElements
38 | if ($null -eq $Arguments) {
39 | $Arguments = @('')
40 | }
41 |
42 | $Arguments = @('__complete') + @($Arguments)
43 | if (-not $WordToComplete -and $Arguments[-1]) {
44 | $Arguments += ''
45 | }
46 |
47 | # we cannot use $WordToComplete because it
48 | # has the wrong values if the cursor was moved
49 | # so use the last argument
50 | # if ($WordToComplete) {
51 | # $WordToComplete = $Arguments.Split(" ")[-1]
52 | # }
53 |
54 |
55 | # Check for flag with equal sign
56 | $IsEqualFlag = ($WordToComplete -Like "--*=*" )
57 | if ( $IsEqualFlag ) {
58 | # Remove the flag part
59 | $Flag,$WordToComplete = $WordToComplete.Split("=",2)
60 | }
61 |
62 | #call the command store the output in $out and redirect stderr and stdout to null
63 | $out = & $Program @Arguments 2> $null
64 |
65 | # get directive from last line
66 | [int]$Directive = $Out[-1].TrimStart(':')
67 | if (-not $Directive) {
68 | # There is no directive specified
69 | $Directive = 0
70 | }
71 |
72 | # remove directive (last element) from out
73 | $Out = $Out | Where-Object { $_ -ne $Out[-1] }
74 |
75 | if (($Directive -band $ShellCompDirectiveError) -ne 0 ) {
76 | # Error code. No completion.
77 | return
78 | }
79 |
80 | $Longest = 0
81 | $Values = $Out | ForEach-Object {
82 | #Split the output in name and description
83 | $Name, $Description = $_.Split("`t",2)
84 |
85 | # Look for the longest completion so that we can format things nicely
86 | if ($Longest -lt $Name.Length) {
87 | $Longest = $Name.Length
88 | }
89 |
90 | # Set the description to a one space string if there is none set.
91 | # This is needed because the CompletionResult does not accept an empty string as argument
92 | if (-Not $Description) {
93 | $Description = " "
94 | }
95 | @{Name="$Name";Description="$Description"}
96 | }
97 |
98 |
99 | $Space = " "
100 | if (($Directive -band $ShellCompDirectiveNoSpace) -ne 0 ) {
101 | # remove the space here
102 | $Space = ""
103 | }
104 |
105 | if ((($Directive -band $ShellCompDirectiveFilterFileExt) -ne 0 ) -or
106 | (($Directive -band $ShellCompDirectiveFilterDirs) -ne 0 )) {
107 |
108 | # return here to prevent the completion of the extensions
109 | return
110 | }
111 |
112 | $Values = $Values | Where-Object {
113 | # filter the result
114 | $_.Name -like "$WordToComplete*"
115 |
116 | # Join the flag back if we have an equal sign flag
117 | if ( $IsEqualFlag ) {
118 | $_.Name = $Flag + "=" + $_.Name
119 | }
120 | }
121 |
122 | if (($Directive -band $ShellCompDirectiveNoFileComp) -ne 0 ) {
123 |
124 | if ($Values.Length -eq 0) {
125 | # Just print an empty string here so the
126 | # shell does not start to complete paths.
127 | # We cannot use CompletionResult here because
128 | # it does not accept an empty string as argument.
129 | ""
130 | return
131 | }
132 | }
133 |
134 | # Get the current mode
135 | $Mode = (Get-PSReadLineKeyHandler | Where-Object {$_.Key -eq "Tab" }).Function
136 |
137 | $Values | ForEach-Object {
138 |
139 | # store temporary because switch will overwrite $_
140 | $comp = $_
141 |
142 | # PowerShell supports three different completion modes
143 | # - TabCompleteNext (default windows style - on each key press the next option is displayed)
144 | # - Complete (works like bash)
145 | # - MenuComplete (works like zsh)
146 | # You set the mode with Set-PSReadLineKeyHandler -Key Tab -Function
147 |
148 | # CompletionResult Arguments:
149 | # 1) CompletionText text to be used as the auto completion result
150 | # 2) ListItemText text to be displayed in the suggestion list
151 | # 3) ResultType type of completion result
152 | # 4) ToolTip text for the tooltip with details about the object
153 |
154 | switch ($Mode) {
155 |
156 | # bash like
157 | "Complete" {
158 |
159 | if ($Values.Length -eq 1) {
160 | # insert space after value
161 | [System.Management.Automation.CompletionResult]::new($($comp.Name | __gh_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
162 |
163 | } else {
164 | # Add the proper number of spaces to align the descriptions
165 | while($comp.Name.Length -lt $Longest) {
166 | $comp.Name = $comp.Name + " "
167 | }
168 |
169 | # Check for empty description and only add parentheses if needed
170 | if ($($comp.Description) -eq " " ) {
171 | $Description = ""
172 | } else {
173 | $Description = " ($($comp.Description))"
174 | }
175 |
176 | [System.Management.Automation.CompletionResult]::new("$($comp.Name)$Description", "$($comp.Name)$Description", 'ParameterValue', "$($comp.Description)")
177 | }
178 | }
179 |
180 | # zsh like
181 | "MenuComplete" {
182 | # insert space after value
183 | # MenuComplete will automatically show the ToolTip of
184 | # the highlighted value at the bottom of the suggestions.
185 | [System.Management.Automation.CompletionResult]::new($($comp.Name | __gh_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
186 | }
187 |
188 | # TabCompleteNext and in case we get something unknown
189 | Default {
190 | # Like MenuComplete but we don't want to add a space here because
191 | # the user need to press space anyway to get the completion.
192 | # Description will not be shown because that's not possible with TabCompleteNext
193 | [System.Management.Automation.CompletionResult]::new($($comp.Name | __gh_escapeStringWithSpecialChars), "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
194 | }
195 | }
196 |
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/Documents/PowerShell/intrinsics.ps1:
--------------------------------------------------------------------------------
1 | using namespace System.Text.RegularExpressions
2 |
3 | $script:s_intrinsicsInitialized = $false
4 | $script:s_intrinsics = $null
5 | $script:s_intrinsicsDocs = $null
6 |
7 | function EnsureIntrinsicsInitialized {
8 | end {
9 | if ($script:s_intrinsicsInitialized) {
10 | return
11 | }
12 |
13 | $splat = @{
14 | MemberType = 'ScriptMethod'
15 | MemberName = 'ToString'
16 | Value = { $this.Name }
17 | Force = $true
18 | }
19 |
20 | Update-TypeData -TypeName 'Deserialized.IntrinsicInfo.Raw' @splat
21 | Update-TypeData -TypeName 'Deserialized.IntrinsicInfo.Method' @splat
22 | Update-TypeData -TypeName 'Deserialized.IntrinsicInfo.Friendly' @splat
23 |
24 | $splat = @{
25 | TypeName = 'Deserialized.IntrinsicInfo.Intrinsic'
26 | DefaultDisplayPropertySet = 'Group', 'Method', 'Raw', 'Description'
27 | Force = $true
28 | }
29 |
30 | Update-TypeData @splat
31 |
32 | Update-TypeData -TypeName 'Deserialized.IntrinsicInfo.Intrinsic' -MemberName Docs -MemberType ScriptProperty -Value {
33 | & (Get-Module Utility) {
34 | param($instance)
35 | if ($null -ne $script:s_intrinsicsDocs.intrinsics_list) {
36 | $script:s_intrinsicsDocs.intrinsics_list.SelectNodes("//intrinsic[@name='$($instance.Raw.Name)']")
37 | }
38 | } $this
39 | }
40 |
41 | Update-TypeData -TypeName 'Deserialized.IntrinsicInfo.Intrinsic' -MemberName Description -MemberType ScriptProperty -Value {
42 | return $this.Docs.description
43 | }
44 |
45 | $content = Get-Content $PSScriptRoot\intrinsics.ps1xml -ErrorAction Stop -Raw
46 | $script:s_intrinsics = [System.Management.Automation.PSSerializer]::Deserialize($content)
47 |
48 | $oldDefaults = $PSDefaultParameterValues
49 | $oldPref = $ProgressPreference
50 | try {
51 | $PSDefaultParameterValues = $global:PSDefaultParameterValues
52 | $ProgressPreference = [System.Management.Automation.ActionPreference]::Ignore
53 | $script:s_intrinsicsDocs = [xml](Invoke-WebRequest 'https://software.intel.com/sites/landingpage/IntrinsicsGuide/files/data-3.6.0.xml' -ErrorAction Stop).Content
54 | } finally {
55 | $PSDefaultParameterValues = $oldDefaults
56 | $ProgressPreference = $oldPref
57 | }
58 |
59 | $script:s_intrinsicsInitialized = $true
60 | }
61 | }
62 |
63 | function Get-Intrinsic {
64 | [CmdletBinding(PositionalBinding = $false)]
65 | param(
66 | [Parameter(ValueFromPipeline, Position = 0)]
67 | [SupportsWildcards()]
68 | [psobject] $Name,
69 |
70 | [Parameter()]
71 | [SupportsWildcards()]
72 | [string] $Group,
73 |
74 | [Parameter()]
75 | [SupportsWildcards()]
76 | [string] $RawInstruction
77 | )
78 | begin {
79 | EnsureIntrinsicsInitialized
80 | $intrinsics = $script:s_intrinsics
81 | }
82 | process {
83 | $notBound = -not $PSBoundParameters.ContainsKey((nameof{$Name})) -and
84 | -not $PSBoundParameters.ContainsKey((nameof{$Group})) -and
85 | -not $PSBoundParameters.ContainsKey((nameof{$RawInstruction}))
86 |
87 | if ($notBound -and -not $MyInvocation.ExpectingInput) {
88 | return $script:s_intrinsics
89 | }
90 |
91 | $string = $null
92 | if ($Name -is [string]) {
93 | $string = $Name
94 | } else {
95 | $methods = $null
96 | if ($Name -is [System.Management.Automation.PSMethod]) {
97 | $methods = $Name.ReflectionInfo
98 | if ($null -eq $methods) {
99 | throw 'Profile ETS member "ReflectionInfo" is missing.'
100 | }
101 | } elseif ($Name -is [System.Reflection.MethodInfo]) {
102 | $methods = $Name
103 | } else {
104 | $string = [string]$Name
105 | }
106 |
107 | if ($null -ne $methods) {
108 | $string = $methods[0].Name
109 | $parent = $methods[0].DeclaringType
110 | if ($parent.Name -eq 'X64') {
111 | $Group = $parent.DeclaringType.Name, $parent.Name -join '.'
112 | } else {
113 | $Group = $parent.Name
114 | }
115 | }
116 | }
117 |
118 | $options = [System.Management.Automation.WildcardOptions]::IgnoreCase -bor
119 | [System.Management.Automation.WildcardOptions]::CultureInvariant
120 | $namePattern = if ([string]::IsNullOrEmpty($string)) { $null } else { [WildcardPattern]::new($string, $options) }
121 | $groupPattern = if ([string]::IsNullOrEmpty($Group)) { $null } else { [WildcardPattern]::new($Group, $options) }
122 | $rawInstructionPattern = if ([string]::IsNullOrEmpty($RawInstruction)) { $null } else { [WildcardPattern]::new($RawInstruction, $options) }
123 |
124 | foreach ($intrinsic in $intrinsics) {
125 | if ($namePattern -and -not $namePattern.IsMatch($intrinsic.Method.Name)) {
126 | continue
127 | }
128 |
129 | if ($groupPattern -and -not $groupPattern.IsMatch($intrinsic.Group)) {
130 | continue
131 | }
132 |
133 | if ($rawInstructionPattern -and -not $rawInstructionPattern.IsMatch($intrinsic.Raw.Name)) {
134 | continue
135 | }
136 |
137 | # yield
138 | $intrinsic
139 | }
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/Documents/PowerShell/locationAliases.json:
--------------------------------------------------------------------------------
1 | {
2 | "Captures": "~/Videos/Captures",
3 | "ps": "~/Documents/PowerShell",
4 | "gpg": "~/scoop/persist/gpg/home",
5 | "chez": "~/.local/share/chezmoi",
6 | "pwsh": "{projects}/PowerShell",
7 | "pses": "{projects}/PowerShellEditorServices",
8 | "ce": "{projects}/ClassExplorer",
9 | "dl": "~/Downloads",
10 | "doc": "~/Documents",
11 | "vim": "~/.vimfiles",
12 | "r": "{projects}/releasing",
13 | "rpwsh": "{projects}/releasing/PowerShell"
14 | }
15 |
--------------------------------------------------------------------------------
/Documents/PowerShell/profile.types.ps1xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | UtilityProfile.InstalledSoftware
4 |
5 |
6 | Version
7 | DisplayVersion
8 |
9 |
10 |
11 |
12 | System.Management.Automation.PSMethod
13 |
14 |
15 | ReflectionInfo
16 |
17 | $adapterData = $this.GetType().GetField('adapterData', 60).GetValue($this)
18 | $methodInformationStructures = $adapterData.
19 | GetType().
20 | GetField('methodInformationStructures', 60).
21 | GetValue($adapterData)
22 |
23 | foreach ($structure in $methodInformationStructures) {
24 | $structure.GetType().GetField('method', 60).GetValue($structure)
25 | }
26 |
27 |
28 |
29 |
30 |
31 | System.Management.Automation.PSProperty
32 |
33 |
34 | ReflectionInfo
35 |
36 | $adapterData = $this.GetType().GetField('adapterData', 60).GetValue($this)
37 | return $adapterData.GetType().GetField('member', 60).GetValue($adapterData)
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Documents/symlink_WindowsPowerShell.tmpl:
--------------------------------------------------------------------------------
1 | {{ .chezmoi.homeDir }}\Documents\PowerShell
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Patrick Meinecke
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 | IMPORTANT NOTICE: THE SOFTWARE ALSO CONTAINS THIRD PARTY AND OTHER
24 | PROPRIETARY SOFTWARE THAT ARE GOVERNED BY SEPARATE LICENSE TERMS. BY ACCEPTING
25 | THE LICENSE TERMS ABOVE, YOU ALSO ACCEPT THE LICENSE TERMS GOVERNING THE
26 | THIRD PARTY AND OTHER SOFTWARE, WHICH ARE SET FORTH IN ThirdPartyNotices.txt
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SeeminglyScience's dot files
2 |
3 | This repo holds my PowerShell profile and various other configuration files. Some of these things I use every day, others may be unfinished or straight up broken. This isn't intended to be a supported product.
4 |
5 | Managed with [chezmoi](https://www.chezmoi.io/)
6 |
7 | This snippet is mainly for me:
8 |
9 | ```powershell
10 | (iwr -useb https://seemingly.dev/install-dots).Content | iex
11 | ```
12 |
13 | You'd need to (but probably shouldn't, just use this as reference) do:
14 |
15 | ```powershell
16 | $env:NO_SECRETS = 1;(iwr -useb https://seemingly.dev/install-dots).Content | iex
17 | ```
18 |
19 | ### PowerShell
20 |
21 | - [All profile files](./Documents/PowerShell)
22 | - [`Utility.psm1`](./Documents/PowerShell/Utility.psm1) (All the functions I use interactively that don't fit into something publishable)
23 | - [Module installs](./run_once_before_main.ps1#L58)
24 |
25 | ### VSCode
26 |
27 | VSCode settings are handled with settings sync, but a snapshot is included here for reference.
28 |
29 | - [`settings.json`](./VSCode/settings.json)
30 | - [`keybindings.json`](./VSCode/keybindings.json)
31 |
32 | Also here are my current extensions:
33 |
34 | - alefragnani.project-manager
35 | - bungcip.better-toml
36 | - DavidAnson.vscode-markdownlint
37 | - eamodio.gitlens
38 | - EditorConfig.EditorConfig
39 | - Fudge.auto-using
40 | - GitHub.vscode-pull-request-github
41 | - josefpihrt-vscode.roslynator
42 | - ms-azure-devops.azure-pipelines
43 | - ms-dotnettools.csharp
44 | - ms-vscode-remote.remote-containers
45 | - ms-vscode.azure-account
46 | - ms-vscode.cpptools
47 | - ms-vscode.hexeditor
48 | - ms-vscode.powershell-preview
49 | - ms-vscode.vscode-typescript-tslint-plugin
50 | - pascalsenn.keyboard-quickfix
51 | - redhat.vscode-xml
52 | - twxs.cmake
53 | - TylerLeonhardt.vscode-inline-values-powershell
54 | - usernamehw.errorlens
55 | - vitaliymaz.vscode-svg-previewer
56 | - vscodevim.vim
57 | - wwm.better-align
58 | - XadillaX.viml
59 |
60 | ### Vim
61 |
62 | The neovim [`init.vim`](./AppData/Local/nvim/init.vim) just points to `.vimrc` below.
63 |
64 | - [`.vimrc`](./dot_vimfiles/dot_vimrc)
65 | - [`plugins.vim`](./dot_vimfiles/plugins.vim)
66 | - [`theme.vim`](./dot_vimfiles/theme.vim)
67 | - [`settings.vim`](./dot_vimfiles/settings.vim)
68 | - [`maps.vim`](./dot_vimfiles/maps.vim)
69 | - [`auto.vim`](./dot_vimfiles/auto.vim)
70 | - [`coc-settings.json`](./AppData/Local/nvim/coc-settings.json)
71 |
72 | Only thing that isn't handled by chezmoi:
73 |
74 | - Install coc extensions with `:CocInstall extensionname`
75 | - coc-powershell
76 | - coc-marketplace
77 | - coc-omnisharp
78 | - coc-json
79 |
80 | ### Windows Terminal
81 |
82 | - [`settings.json`](./AppData/Local/Packages/Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe/LocalState/settings.json)
83 |
84 | ### Git
85 |
86 | - [`.gitconfig`](./dot_gitconfig.tmpl)
87 |
88 | ### Apex Legends
89 |
90 | For apex to execute a config it actually needs to be in `ApexInstallDir/cfg` but you can't really manage that well with chezmoi so I have a script to copy it.
91 |
92 | - [`autoexec.cfg`](./AppData/Roaming/apex-config/autoexec.cfg)
93 | - [`apex-config.cfg`](./AppData/Roaming/apex-config/apex-config.cfg)
94 | - [`CopyConfigs.ps1`](./AppData/Roaming/apex-config/CopyConfigs.ps1)
95 | - [Command line options](./AppData/Roaming/apex-config/apex-config.cfg#L14)
96 |
97 | ## Future
98 |
99 | In the future I'd like to:
100 |
101 | - Document the profile functions
102 | - Remove what doesn't work
103 |
--------------------------------------------------------------------------------
/VSCode/keybindings.json:
--------------------------------------------------------------------------------
1 | // Place your key bindings in this file to overwrite the defaults
2 | [
3 | {
4 | "key": "alt+n",
5 | "command": "workbench.action.compareEditor.nextChange",
6 | "when": "editorTextFocus && !suggestWidgetVisible && textCompareEditorActive",
7 | },
8 | {
9 | "key": "alt+shift+n",
10 | "command": "workbench.action.compareEditor.previousChange",
11 | "when": "editorTextFocus && !suggestWidgetVisible && textCompareEditorActive",
12 | },
13 | {
14 | "key": "alt+n",
15 | "command": "workbench.action.editor.nextChange",
16 | "when": "editorTextFocus && !suggestWidgetVisible && !textCompareEditorActive",
17 | },
18 | {
19 | "key": "alt+shift+n",
20 | "command": "workbench.action.editor.previousChange",
21 | "when": "editorTextFocus && !suggestWidgetVisible && !textCompareEditorActive",
22 | },
23 | {
24 | "key": "shift+enter",
25 | "command": "editor.action.insertSnippet",
26 | "args": {
27 | "snippet": "🔸 `${1:XX}:` $2",
28 | "langId": "markdown",
29 | "name": "Dialog",
30 | },
31 | "when": "editorTextFocus && editorLangId == 'markdown' && vim.mode == 'Insert'"
32 | },
33 | {
34 | "command": "workbench.action.findInFiles",
35 | "args": {
36 | "onlyOpenEditors": true,
37 | "triggerSearch": true,
38 | },
39 | "key": "ctrl+0"
40 | },
41 | {
42 | "command": "vscode-neovim.compositeEscape1",
43 | "key": "j",
44 | "when": "neovim.mode == insert && editorTextFocus",
45 | "args": "j",
46 | },
47 | {
48 | "command": "problems.action.openToSide",
49 | "key": "F1",
50 | },
51 | {
52 | "key": "ctrl+shift+r",
53 | "command": "PowerShell.RestartSession",
54 | "when": "editorTextFocus && editorLangId == 'powershell'"
55 | },
56 | {
57 | "key": "ctrl+`",
58 | "command": "workbench.action.focusActiveEditorGroup",
59 | "when": "!editorFocus"
60 | },
61 | {
62 | "key": "ctrl+`",
63 | "command": "workbench.action.terminal.focus",
64 | "when": "!terminalFocus"
65 | },
66 | {
67 | "key": "ctrl+shift+a",
68 | "command": "extension.align",
69 | "when": "editorTextFocus"
70 | },
71 | {
72 | "key": "alt+shift+s",
73 | "command": "PowerShell.InvokeRegisteredEditorCommand",
74 | "args": { "commandName": "ConvertTo-SplatExpression" },
75 | "when": "editorLangId == 'powershell'"
76 | },
77 | {
78 | "key": "alt+shift+n",
79 | "command": "PowerShell.InvokeRegisteredEditorCommand",
80 | "args": { "commandName": "Resolve-TypeExpression" },
81 | "when": "editorLangId == 'powershell'"
82 | },
83 | {
84 | "key": "alt+shift+m",
85 | "command": "PowerShell.InvokeRegisteredEditorCommand",
86 | "args": { "commandName": "Expand-MemberExpression" },
87 | "when": "editorLangId == 'powershell'"
88 | },
89 | {
90 | "key": "alt+shift+f",
91 | "command": "workbench.files.action.focusFilesExplorer"
92 | },
93 | {
94 | "key": "r",
95 | "command": "workbench.files.action.refreshFilesExplorer",
96 | "when": "explorerViewletVisible && filesExplorerFocus && !inputFocus"
97 | },
98 | {
99 | "key": "d",
100 | "command": "moveFileToTrash",
101 | "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !inputFocus"
102 | },
103 | {
104 | "key": "ctrl+n",
105 | "command": "explorer.newFile",
106 | "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !inputFocus && !inQuickOpen"
107 | },
108 | {
109 | "key": "alt+n",
110 | "command": "workbench.action.quickOpenNavigateNext",
111 | "when": "inQuickOpen"
112 | },
113 | {
114 | "key": "alt+p",
115 | "command": "workbench.action.quickOpenNavigatePrevious",
116 | "when": "inQuickOpen"
117 | },
118 | {
119 | "key": "alt+n",
120 | "command": "selectNextSuggestion",
121 | "when": "editorTextFocus && suggestWidgetVisible"
122 | },
123 | {
124 | "key": "alt+p",
125 | "command": "selectPrevSuggestion",
126 | "when": "editorTextFocus && suggestWidgetVisible"
127 | },
128 | {
129 | "key": "alt+n",
130 | "command": "showNextParameterHint",
131 | "when": "editorTextFocus && parameterHintsMultipleSignatures && parameterHintsVisible"
132 | },
133 | {
134 | "key": "alt+p",
135 | "command": "showPrevParameterHint",
136 | "when": "editorTextFocus && parameterHintsMultipleSignatures && parameterHintsVisible"
137 | },
138 | {
139 | "key": "k",
140 | "command": "list.focusUp",
141 | "when": "listFocus && listHasSelectionOrFocus && !inputFocus"
142 | },
143 | {
144 | "key": "j",
145 | "command": "list.focusDown",
146 | "when": "listFocus && listHasSelectionOrFocus && !inputFocus"
147 | },
148 | {
149 | "key": "ctrl+v",
150 | "command": "workbench.action.terminal.sendSequence",
151 | "args": { "text": "\u2714" },
152 | "when": "terminalFocus"
153 | },
154 | {
155 | "key": "shift+enter",
156 | "command": "workbench.action.terminal.sendSequence",
157 | "args": { "text": "\u2665" },
158 | "when": "terminalFocus",
159 | },
160 | {
161 | "key": "ctrl+shift+.",
162 | "command": "editor.action.quickFix",
163 | },
164 | { "key": "ctrl+r l", "command": "-npm-script.showOutput" },
165 | { "key": "ctrl+r t", "command": "-dotnet.test.runTestsInContext" },
166 | { "key": "ctrl+r shift+r", "command": "-npm-script.run" },
167 | { "key": "ctrl+r ctrl+t", "command": "-dotnet.test.debugTestsInContext" },
168 | { "key": "ctrl+r r", "command": "-npm-script.rerun-last-script" },
169 | { "key": "ctrl+r shift+x", "command": "-npm-script.terminate-script" },
170 | { "key": "ctrl+r t", "command": "-npm-script.test" },
171 | { "key": "ctrl+`", "command": "workbench.action.focusActiveEditorGroup",
172 | "when": "!editorFocus" },
173 | { "key": "ctrl+`", "command": "workbench.action.terminal.focus",
174 | "when": "!terminalFocus" },
175 | { "key": "ctrl+shift+r", "command": "PowerShell.RestartSession",
176 | "when": "editorLangId == 'powershell'" },
177 | { "key": "ctrl+shift+q", "command": "workbench.action.toggleMaximizedPanel" },
178 | { "key": "ctrl+shift+c", "command": "PowerShell.ShowAdditionalCommands",
179 | "when": "editorLangId == 'powershell'" },
180 | { "key": "ctrl+shift+a", "command": "extension.align",
181 | "when": "editorTextFocus" },
182 | {
183 | "key": "ctrl+shift+r",
184 | "command": "workbench.action.reloadWindow"
185 | },
186 | {
187 | "key": "ctrl+shift+j",
188 | "command": "PowerShell.InvokeRegisteredEditorCommand",
189 | "args": [{ "commandName": "FixAllPSSA" }],
190 | "when": "editorLangId == 'powershell'"
191 | },
192 | {
193 | "key": "shift+alt+s",
194 | "command": "PowerShell.InvokeRegisteredEditorCommand",
195 | "args": { "commandName": "ConvertTo-SplatExpression" },
196 | "when": "editorLangId == 'powershell'"
197 | },
198 | {
199 | "key": "alt+n",
200 | "command": "showNextParameterHint",
201 | "when": "editorTextFocus && parameterHintsMultipleSignatures && parameterHintsVisible",
202 | },
203 | {
204 | "key": "alt+p",
205 | "command": "showPrevParameterHint",
206 | "when": "editorTextFocus && parameterHintsMultipleSignatures && parameterHintsVisible",
207 | },
208 | {
209 | "key": "shift+enter",
210 | "command": "terminalInput.sendCustomInput",
211 | "args": [ "heartEmojiWithAlt" ],
212 | "when": "terminalFocus"
213 | },
214 | {
215 | "key": "ctrl+.",
216 | "command": "keyboard-quickfix.openQuickFix",
217 | },
218 | ]
219 |
--------------------------------------------------------------------------------
/admin_tasks.ps1:
--------------------------------------------------------------------------------
1 | [CmdletBinding()]
2 | param()
3 | begin {
4 | function ConfirmInstallScript {
5 | [CmdletBinding()]
6 | param([string] $Name, [string] $Script)
7 | end {
8 | # bat doesn't seem to work right away. Needs a restart or two
9 | # $bat = Get-Command bat -CommandType Application -ErrorAction Ignore
10 | # $batArgs = @('-l', 'powershell')
11 | $bat = $null
12 | if (-not $bat) {
13 | $bat = 'more'
14 | $batArgs = @()
15 | }
16 |
17 | $Script | & $bat @batArgs
18 | if (-not $PSCmdlet.ShouldContinue('Or is it bad now :o', "Install ${Name}?")) {
19 | throw 'it''s bad now :o'
20 | }
21 |
22 | & ([scriptblock]::Create($Script))
23 | }
24 | }
25 |
26 | function MaybeInstallChocoApp {
27 | [CmdletBinding()]
28 | param(
29 | [Parameter(ValueFromPipeline)]
30 | [ValidateNotNullOrEmpty()]
31 | [string] $Name,
32 |
33 | [Parameter()]
34 | [AllowNull()]
35 | [AllowEmptyString()]
36 | [string] $Application,
37 |
38 | [switch] $SkipExistingCheck
39 | )
40 | process {
41 | if (-not $SkipExistingCheck) {
42 | if (-not $Application) {
43 | $Application = $Name
44 | }
45 |
46 | if (Get-Command $Application -CommandType Application -ErrorAction Ignore) {
47 | return
48 | }
49 | }
50 |
51 | choco install $Name
52 | }
53 | }
54 | }
55 | end {
56 | DISM /Online /Enable-Feature /All /FeatureName:Microsoft-Hyper-V /NoRestart
57 | DISM /Online /Enable-Feature /FeatureName:Microsoft-Windows-Subsystem-Linux /NoRestart
58 | wsl --install
59 | DISM /Online /Add-Capability /CapabilityName:Tools.DeveloperMode.Core~~~~0.0.1.0 /NoRestart
60 | $null = REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"
61 |
62 |
63 | $trigger = New-ScheduledTaskTrigger -AtLogOn
64 |
65 | $wslSshPageant = "$env:USERPROFILE\scoop\apps\wsl-ssh-pageant\current\wsl-ssh-pageant-gui.exe"
66 | $action = New-ScheduledTaskAction -Execute $wslSshPageant -Argument '--systray --winssh ssh-pageant'
67 | New-ScheduledTask -Action $action -Trigger $trigger | Register-ScheduledTask 'Launch wsl-ssh-pageant' | Out-Null
68 |
69 | $gpgconf = "$env:USERPROFILE\scoop\apps\gpg\current\bin\gpgconf.exe"
70 | $action = New-ScheduledTaskAction -Execute $gpgconf -Argument '--launch gpg-agent'
71 | New-ScheduledTask -Action $action -Trigger $trigger | Register-ScheduledTask 'Launch gpg-agent' | Out-Null
72 |
73 | $oldProtocol = [System.Net.ServicePointManager]::SecurityProtocol
74 | $wc = $null
75 | try {
76 | [System.Net.ServicePointManager]::SecurityProtocol = $oldProtocol -bor 3072;
77 | $wc = [System.Net.WebClient]::new()
78 | if (-not (Get-Command choco -CommandType Application -ErrorAction Ignore)) {
79 | $chocoInstall = $wc.DownloadString('https://community.chocolatey.org/install.ps1')
80 | ConfirmInstallScript -Name choco -Script $chocoInstall
81 | }
82 |
83 | MaybeInstallChocoApp rustup.install rustup
84 | MaybeInstallChocoApp neovim nvim
85 | MaybeInstallChocoApp nodejs npm
86 | MaybeInstallChocoApp obs -SkipExistingCheck
87 | MaybeInstallChocoApp microsoft-windows-terminal wt
88 | MaybeInstallChocoApp powertoys -SkipExistingCheck
89 | MaybeInstallChocoApp cascadia-code-nerd-font -SkipExistingCheck
90 | MaybeInstallChocoApp pwsh
91 | MaybeInstallChocoApp bitwarden -SkipExistingCheck
92 | } finally {
93 | [System.Net.ServicePointManager]::SecurityProtocol = $oldProtocol
94 | if ($null -ne $wc) {
95 | $wc.Dispose()
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/chezmoi.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.31903.59
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documents", "Documents", "{ED60E4B3-1C3C-4B69-2451-DE8E1ACBF1DB}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PowerShell", "PowerShell", "{6203C810-F23F-292C-C35A-0B01854280C9}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Profile", "Profile", "{6121C78D-F49C-0D1A-4152-E48653EB22D6}"
11 | EndProject
12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F16CFDBD-6E5F-5768-5D7F-006ACFAE0E1E}"
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Profile", "Documents\PowerShell\Profile\src\Profile\Profile.csproj", "{9EB4A001-483C-473E-AE81-F17953225714}"
15 | EndProject
16 | Global
17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
18 | Debug|Any CPU = Debug|Any CPU
19 | Debug|x64 = Debug|x64
20 | Debug|x86 = Debug|x86
21 | Release|Any CPU = Release|Any CPU
22 | Release|x64 = Release|x64
23 | Release|x86 = Release|x86
24 | EndGlobalSection
25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
26 | {9EB4A001-483C-473E-AE81-F17953225714}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {9EB4A001-483C-473E-AE81-F17953225714}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {9EB4A001-483C-473E-AE81-F17953225714}.Debug|x64.ActiveCfg = Debug|Any CPU
29 | {9EB4A001-483C-473E-AE81-F17953225714}.Debug|x64.Build.0 = Debug|Any CPU
30 | {9EB4A001-483C-473E-AE81-F17953225714}.Debug|x86.ActiveCfg = Debug|Any CPU
31 | {9EB4A001-483C-473E-AE81-F17953225714}.Debug|x86.Build.0 = Debug|Any CPU
32 | {9EB4A001-483C-473E-AE81-F17953225714}.Release|Any CPU.ActiveCfg = Release|Any CPU
33 | {9EB4A001-483C-473E-AE81-F17953225714}.Release|Any CPU.Build.0 = Release|Any CPU
34 | {9EB4A001-483C-473E-AE81-F17953225714}.Release|x64.ActiveCfg = Release|Any CPU
35 | {9EB4A001-483C-473E-AE81-F17953225714}.Release|x64.Build.0 = Release|Any CPU
36 | {9EB4A001-483C-473E-AE81-F17953225714}.Release|x86.ActiveCfg = Release|Any CPU
37 | {9EB4A001-483C-473E-AE81-F17953225714}.Release|x86.Build.0 = Release|Any CPU
38 | EndGlobalSection
39 | GlobalSection(SolutionProperties) = preSolution
40 | HideSolutionNode = FALSE
41 | EndGlobalSection
42 | GlobalSection(NestedProjects) = preSolution
43 | {6203C810-F23F-292C-C35A-0B01854280C9} = {ED60E4B3-1C3C-4B69-2451-DE8E1ACBF1DB}
44 | {6121C78D-F49C-0D1A-4152-E48653EB22D6} = {6203C810-F23F-292C-C35A-0B01854280C9}
45 | {F16CFDBD-6E5F-5768-5D7F-006ACFAE0E1E} = {6121C78D-F49C-0D1A-4152-E48653EB22D6}
46 | {9EB4A001-483C-473E-AE81-F17953225714} = {F16CFDBD-6E5F-5768-5D7F-006ACFAE0E1E}
47 | EndGlobalSection
48 | EndGlobal
49 |
--------------------------------------------------------------------------------
/dot_gitconfig.tmpl:
--------------------------------------------------------------------------------
1 | [core]
2 | pager = delta
3 | [interactive]
4 | diffFilter = delta --color-only
5 | [delta]
6 | navigate = true
7 | line-numbers = true
8 | theme = Visual Studio Dark+
9 | [merge]
10 | conflictstyle = diff3
11 | [diff]
12 | colorMoved = default
13 | [init]
14 | defaultbranch = main
15 | [user]
16 | name = {{ .name }}
17 | email = {{ .email }}
18 | signingkey = {{ .gpgkey }}!
19 | [rebase]
20 | stat = true
21 | autoSquash = true
22 | autoStash = true
23 | [core]
24 | autocrlf = false
25 | [commit]
26 | gpgsign = true
27 | [gpg]
28 | program = {{ joinPath .chezmoi.homeDir "scoop/apps/gpg/current/bin/gpg.exe" | replace "\\" "/" | quote }}
29 | [alias]
30 | unstage = reset HEAD
31 | unst = reset HEAD
32 | stage = add
33 | st = add
34 | unci = reset --soft HEAD^
35 | undo-commit = reset --soft HEAD^
36 | ci = commit
37 | st = status
38 | co = checkout
39 | br = branch
40 | pick = cherry-pick
41 | last = log -1 HEAD
42 | ls = log --abbrev-commit --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'
43 | ll = log --pretty=format:"%C(yellow)%h%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate --numstat # List commits showing changed files
44 | lds = log --pretty=format:"%C(yellow)%h\\ %ad%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate --date=short # List oneline commits showing dates
45 | ld = log --pretty=format:"%C(yellow)%h\\ %ad%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate --date=relative # List oneline commits showing relative dates
46 | le = log --oneline --decorate #Default look for short git log
47 | logtree = "log --graph --oneline --decorate --all" # same as above, but with graph
48 | filelog = log -u # See all the commits related to a file, with the diff of the changes with git log -u
49 |
--------------------------------------------------------------------------------
/dot_vimfiles/auto.vim:
--------------------------------------------------------------------------------
1 | if !exists('g:vscode')
2 |
3 | if has("autocmd")
4 | autocmd BufWritePre *.ps1,*.psd1,*.psm1,*.ps1xml,*.js,*.jsx,*.ts,*.tsx,*.cs,*.csproj,*.xml,*.json,*.jsonc :call CleanExtraSpaces()
5 | endif
6 |
7 | " Fast editing and reloading of vimrc configs
8 | autocmd! BufWritePost MYVIMRC source MYVIMRC
9 |
10 | " Return to last edit position when opening files
11 | au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
12 |
13 | autocmd FileType html setlocal shiftwidth=2 tabstop=2 softtabstop=2
14 | autocmd FileType js setlocal shiftwidth=2 tabstop=2 softtabstop=2
15 | autocmd FileType jsx setlocal shiftwidth=2 tabstop=2 softtabstop=2
16 | autocmd FileType ts setlocal shiftwidth=2 tabstop=2 softtabstop=2
17 | autocmd FileType tsx setlocal shiftwidth=2 tabstop=2 softtabstop=2
18 | autocmd FileType json setlocal shiftwidth=2 tabstop=2 softtabstop=2
19 | autocmd FileType jsonc setlocal shiftwidth=2 tabstop=2 softtabstop=2
20 |
21 | autocmd FileType cs setlocal commentstring=//\ %s
22 |
23 | endif
24 |
--------------------------------------------------------------------------------
/dot_vimfiles/dot_vimrc:
--------------------------------------------------------------------------------
1 | let g:MYVIMRC = expand('')
2 |
3 | let thisDir = resolve(fnamemodify(MYVIMRC, ':h'))
4 | for i in ['plugins', 'theme', 'settings', 'maps', 'auto']
5 | let scriptPath = globpath(thisDir, i . '.vim')
6 | if filereadable(scriptPath)
7 | exec ('source ' . scriptPath)
8 | endif
9 | endfor
10 |
--------------------------------------------------------------------------------
/dot_vimfiles/maps.vim:
--------------------------------------------------------------------------------
1 | let mapleader = ','
2 |
3 | if exists('g:vscode')
4 | xmap gc VSCodeCommentary
5 | nmap gc VSCodeCommentary
6 | omap gc VSCodeCommentary
7 | nmap gcc VSCodeCommentaryLine
8 |
9 | function! s:runSelection()
10 | normal! gv
11 | let visualmode = visualmode()
12 | if visualmode == "V"
13 | let startLine = line("v")
14 | let endLine = line(".")
15 | call VSCodeNotifyRange("PowerShell.RunSelection", startLine, endLine, 1)
16 | else
17 | let startPos = getpos("v")
18 | let endPos = getpos(".")
19 | call VSCodeNotifyRangePos("PowerShell.RunSelection", startPos[1], endPos[1], startPos[2], endPos[2], 1)
20 | endif
21 | endfunction
22 |
23 | vmap :call runSelection()
24 | nmap gd :call VSCodeNotify('editor.action.revealDefinition')
25 | else
26 | " Use tab for trigger completion with characters ahead and navigate.
27 | " Use command ':verbose imap ' to make sure tab is not mapped by other plugin.
28 | inoremap
29 | \ pumvisible() ? "\" :
30 | \ CheckBackspace_maps_vim() ? "\" :
31 | \ coc#refresh()
32 | inoremap pumvisible() ? "\" : "\"
33 |
34 | function! CheckBackspace_maps_vim() abort
35 | let col = col('.') - 1
36 | return !col || getline('.')[col - 1] =~# '\s'
37 | endfunction
38 |
39 | " Use to trigger completion.
40 | inoremap coc#refresh()
41 | inoremap coc#refresh()
42 |
43 | " Use to confirm completion, `u` means break undo chain at current position.
44 | " Coc only does snippet and additional edit on confirm.
45 | inoremap pumvisible() ? "\" : "\u\"
46 |
47 | " Use `[c` and `]c` to navigate diagnostics
48 | nmap [c (coc-diagnostic-prev)
49 | nmap ]c (coc-diagnostic-next)
50 |
51 | " Remap keys for gotos
52 | nmap gd (coc-definition)
53 | nmap gy (coc-type-definition)
54 | nmap gi (coc-implementation)
55 | nmap gr (coc-references)
56 |
57 | " Use K to show documentation in preview window
58 | nnoremap K :call show_documentation()
59 |
60 | function! s:show_documentation()
61 | if (index(['vim','help'], &filetype) >= 0)
62 | execute 'h '.expand('')
63 | else
64 | call CocAction('doHover')
65 | endif
66 | endfunction
67 |
68 | " Highlight symbol under cursor on CursorHold
69 | autocmd CursorHold * silent call CocActionAsync('highlight')
70 |
71 | " Remap for rename current word
72 | nmap rn (coc-rename)
73 |
74 | " Remap for format selected region
75 | xmap f (coc-format-selected)
76 | nmap f (coc-format-selected)
77 |
78 | augroup mygroup
79 | autocmd!
80 | " Setup formatexpr specified filetype(s).
81 | autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
82 | " Update signature help on jump placeholder
83 | autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
84 | augroup end
85 |
86 | " Remap for do codeAction of selected region, ex: `aap` for current paragraph
87 | xmap a (coc-codeaction-selected)
88 | nmap a (coc-codeaction-selected)
89 |
90 | " Remap for do codeAction of current line
91 | nmap ac (coc-codeaction)
92 | " Fix autofix problem of current line
93 | nmap qf (coc-fix-current)
94 |
95 | " Use for select selections ranges, needs server support, like: coc-tsserver, coc-python
96 | nmap (coc-range-select)
97 | xmap (coc-range-select)
98 | xmap (coc-range-select-backword)
99 |
100 | " Use `:Format` to format current buffer
101 | command! -nargs=0 Format :call CocAction('format')
102 |
103 | " Use `:Fold` to fold current buffer
104 | command! -nargs=? Fold :call CocAction('fold', )
105 |
106 | " use `:OR` for organize import of current buffer
107 | command! -nargs=0 OR :call CocAction('runCommand', 'editor.action.organizeImport')
108 |
109 | " Add status line support, for integration with other plugin, checkout `:h coc-status`
110 | set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}
111 |
112 | " Using CocList
113 | " Show all diagnostics
114 | nnoremap a :CocList diagnostics
115 |
116 | " Manage extensions
117 | nnoremap e :CocList extensions
118 | " Show commands
119 | nnoremap c :CocList commands
120 | " Find symbol of current document
121 | nnoremap o :CocList outline
122 | " Search workspace symbols
123 | nnoremap s :CocList -I symbols
124 | " Do default action for next item.
125 | nnoremap j :CocNext
126 | " Do default action for previous item.
127 | nnoremap k :CocPrev
128 | " Resume latest coc list
129 | nnoremap p :CocListResume
130 |
131 | nmap :CocCommand
132 | xmap :CocCommand
133 |
134 | map nn :NERDTreeToggle
135 | map nb :NERDTreeFromBookmark
136 | map nf :NERDTreeFind
137 |
138 | endif
139 |
140 | " Start interactive EasyAlign in visual mode (e.g. vipga)
141 | xmap ga (EasyAlign)
142 |
143 | " Start interactive EasyAlign for a motion/text object (e.g. gaip)
144 | nmap ga (EasyAlign)
145 |
146 | imap jj
147 |
148 | " Move between windows
149 | map j
150 | map k
151 | map h
152 | map l
153 |
154 | " Remap VIM 0 to first non-blank character
155 | map 0 ^
156 |
157 | " Move a line of text using ALT+[jk] or Command+[jk] on mac
158 | nmap mz:m+`z
159 | nmap mz:m-2`z
160 | vmap :m'>+`mzgv`yo`z
161 | vmap :m'<-2`>my`e :exec(':e! ' . MYVIMRC)
174 |
175 | let g:multi_cursor_use_default_mapping=0
176 | let g:multi_cursor_start_word_key = ''
177 | let g:multi_cursor_select_all_word_key = ''
178 | let g:multi_cursor_start_key = 'g'
179 | let g:multi_cursor_select_all_key = 'g'
180 | let g:multi_cursor_next_key = ''
181 | let g:multi_cursor_prev_key = ''
182 | let g:multi_cursor_skip_key = ''
183 | let g:multi_cursor_quit_key = '