├── .gitattributes ├── .github └── workflows │ └── PushGitLogger.yml ├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── LICENSE ├── Ninmonkey.Console - module.code-workspace ├── Ninmonkey.Console.psd1 ├── Ninmonkey.Console.psm1 ├── PSScriptAnalyzerSettings.psd1 ├── README.md ├── Readme.Todo.Refactor.md ├── Todo.Next.md ├── beforeAll_autoloader ├── Compare-Char.ps1 ├── Compare-LongestSharedString.ps1 ├── Compare-LongestSharedString.tests.ps1 ├── Format-BasicShortStr.ps1 ├── Format-ShortStr.ps1 ├── Format-ShortStr.tests.ps1 ├── Test-PathsAreEqual.ps1 ├── __init__.ps1 └── executionContext-queryCommands-commands.ps1 ├── debug_harness.ps1 ├── disabled ├── Get-ObjectType-Old.ps1 ├── Testing-Get-FileInfo.ps1 ├── Testing-Get-FileInfo2.ps1 └── Testing-WrapStyle-Enum.ps1 ├── docs_static ├── changes.md ├── commands │ └── Format-NativeCommandArguments.md ├── data │ └── Start-LogTestNet.screenshot.png ├── ideas │ ├── code-references-todo-first.2022-09.efu │ └── ideas.experimental-native-commands.ps1.md └── img │ └── format-ul-completer.png ├── examples └── Inspect-Generic-Collections.ps1 ├── future_code └── original_complete.ps1 ├── help ├── Format-TypeName.md └── Get-NativeCommand.md ├── new -- summarize PSReadlineKey bindings.ps1 ├── next-pass.md ├── notebooks └── using_wrapText.ipynb ├── old - no formatter - Get-ObjectProperty.ps1 ├── prev - Get-ObjectProperty.ps1 ├── private ├── Format-ParameterTypeInfo.ps1 ├── Toast-LogTestNetResult.ps1 ├── config │ └── getDocs-Powerquery.json ├── metadata │ └── ExceptionTypes.metadata.ps1 ├── pester │ └── Test-PesterLinesAreEqual.ps1 ├── refactor to csharp │ └── EncodingCompletion.ps1 ├── safe_prompt.ps1 └── seeminglySci │ ├── NamespaceAwareCompletion.ps1.off │ └── seeminglySci_import.ps1.off ├── prompt_block └── prompt_blocks.ps1 ├── public ├── Compare-Directory.ps1 ├── ConvertTo-Base64String.ps1 ├── ConvertTo-BitString.ps1 ├── ConvertTo-HexString.ps1 ├── ConvertTo-Number.ps1 ├── ConvertTo-PropertyList.ps1 ├── ConvertTo-Timespan.ps1 ├── ConvertTo-Timespan.tests.ps1 ├── Edit-GitConfig.ps1 ├── Export-PlatformFolderPath.ps1 ├── Find-GitRepo.ps1 ├── Find-Hotkey.ps1 ├── Find-NinNativeCommand.ps1 ├── Find-TabExpansionCommand.ps1 ├── Find-VSCodeProject.ps1 ├── FindMyCommand..ps1 ├── Format-ControlChar.ps1 ├── Format-FileSize.ps1 ├── Format-GenericTypeName.ps1 ├── Format-HashTableList.ps1 ├── Format-Hashtable.ps1 ├── Format-History.ps1 ├── Format-MeasureCommand.ps1 ├── Format-NinChildItemDirectory.ps1 ├── Format-NullText.ps1 ├── Format-Predent.ps1 ├── Format-PrettyJson.ps1 ├── Format-TestConnection.ps1 ├── Format-TypeName.ps1 ├── Format-TypeName.tests.ps1 ├── FormatData │ ├── BuiltinTypes │ │ ├── nin-Microsoft.PowerShell.Commands.TestConnectionCommand.Format.ps1xml │ │ └── nin-System.RuntimeType.Format.ps1xml │ └── Nin.PropertyList.Format.ps1xml ├── Get-ConsoleEncoding.ps1 ├── Get-Docs.ps1 ├── Get-EnumInfo.ps1 ├── Get-NativeCommand.ps1 ├── Get-NinAlias.ps1 ├── Get-NinAppxPackage.ps1 ├── Get-NinChildItem.ps1 ├── Get-NinCommandProxy.ps1 ├── Get-NinCommandSyntax.ps1 ├── Get-NinModule.ps1 ├── Get-NinMyVSCode.ps1 ├── Get-NinNamedPath.ps1 ├── Get-NinTypeData.ps1 ├── Get-ObjectProperty.ps1 ├── Get-ObjectType.ps1 ├── Get-StaticProperty.ps1 ├── Get-StaticProperty.visual_tests.ps1 ├── Get-TerminalName.ps1 ├── Get-TextEncoding.ps1 ├── Get-TimeStuff.tests.ps1 ├── Get-UnicodeInfo.ps1 ├── Import-NinModule.ps1 ├── Import-NinPSReadLineKeyHandler.ps1 ├── Invoke-Explorer.ps1 ├── Invoke-NativeCommand.ps1 ├── Invoke-Wget.ps1 ├── Join-Regex.ps1 ├── Join-Regex.tests.ps1 ├── Out-Fzf.ps1 ├── PSReadLine │ ├── ExpandAliases.ps1 │ ├── IndentSelections_Jaykul.ps1 │ ├── ParenthesizeSelection.ps1 │ ├── ToggleQuoteArgument.ps1 │ ├── native-dotnet-completer.ps1 │ └── smart_brackets_braces.ps1 ├── Resolve-CommandName.ps1 ├── Resolve-CommandName.tests.ps1 ├── Select-NinProperty.ps1 ├── Set-ConsoleEncoding.ps1 ├── Set-FormattedClipboard.ps1 ├── Set-NinLocation.ps1 ├── Set-NinLocation.tests.ps1 ├── Sort-Hashtable.ps1 ├── Start-LogTestNet.ps1 ├── Test-Net.ps1 ├── Test-NullArg.ps1 ├── Test-NullArg.tests.ps1 ├── Test-UserIsAdmin.ps1 ├── Trace-NinCommand.ps1 ├── Write-AnsiHyperlink.ps1 ├── Write-ConsoleHeader.ps1 ├── Write-ConsoleHorizontalRule.ps1 ├── Write-ConsoleLabel.ps1 ├── Write-ConsoleNewline.ps1 ├── Write-ConsoleText.ps1 ├── Write-ConsoleText.tests.ps1 ├── _refactor-Get-NinModule.ps1 ├── alias │ └── SeeminglySci.ps1 ├── completer │ ├── Completer-Loader.ps1 │ ├── Readme.completer.md │ └── dotnet.ps1 ├── copy - Get-NinCommand.ps1 ├── data │ ├── unicode_docs.ps1 │ ├── unicode_metadata.ps1 │ └── unicode_web_query.ps1 ├── native_wrapper │ ├── Invoke-IPython.ps1 │ └── Invoke-RipGrepChildItem.ps1 └── seeminglySci │ ├── Get-ElementName.ps1 │ └── import_nin_sci.ps1 ├── public_autoloader ├── Add-ConsoleEnvVarPath.ps1 ├── Add-ConsoleEnvVarPath.tests.ps1 ├── Add-IndexProperty.ps1 ├── Ansi-Write-RandomColorEscape.ps1 ├── Assert-CommandType.ps1 ├── Assert-CommandType.tests.ps1 ├── Assert-HashTableEqual.tests.ps1 ├── Assert-HashtableEqual.ps1 ├── Compare-StringSet.ps1 ├── ConvertFrom-Base64String.ps1 ├── ConvertFrom-NumberedFilepath.ps1 ├── ConvertFrom-NumberedFilepath.tests.ps1 ├── ConvertTo-Base64String.tests.ps1 ├── ConvertTo-BreadCrumb.ps1 ├── ConvertTo-BreadCrumb.tests.ps1 ├── ConvertTo-RegexLiteral.ps1 ├── ConvertTo-RegexLiteral.tests.ps1 ├── ConvertTo-RegexLiteral.v1.tests.ps1 ├── ConvertTo-RelativePath.ps1 ├── ConvertTo-RelativePath.tests.ps1 ├── Copy-RelativeItemTree.ps1 ├── Debug-CompareVariablesInModule.ps1 ├── Debug-ExposeInternal.ps1 ├── Decode-url.ps1 ├── Edit-FunctionSource.ps1 ├── Enable-PSreadLineHistoryHandler.ps1 ├── ExecutionContext.Get-Command.ps1 ├── EyeInspect.ps1 ├── Filter-ChangedWithin.ps1 ├── Find-Exception.ps1 ├── Find-HistorySomething.ps1 ├── Find-PSReadLine.ps1 ├── Find-UnderlineMember.ps1 ├── Format-NativeCommandArguments.ps1 ├── Format-ObjectAsCulture.ps1 ├── Format-RemoveAnsiEscape.ps1 ├── Format-RemoveAnsiEscape.tests.ps1 ├── Format-UnicodeCodepoints.ps1 ├── Format-UnicodeCodepoints.tests.ps1 ├── Format-WrapText.ps1 ├── Format-WrapText.tests.ps1 ├── Get-CachedClipboardValue.ps1 ├── Get-CommandSummary.ps1 ├── Get-HelpFromType.2.ps1 ├── Get-NinCommand.ps1 ├── Get-NinPSReadlineHistory.ps1 ├── Get-NinVerb.ps1 ├── Get-ObjectTypeHelp.ps1 ├── Get-ObjectTypeHelp.tests.ps1 ├── Get-SemanticColor.ps1 ├── Get-SequentialRandomLines.ps1 ├── GetAndConvert_EnvVar_ToRelativePath.ps1 ├── Group-ObjectByCount.ps1 ├── Inspect-Get_TypeOfCollection.ps1 ├── Inspect-Get_TypeOfCollection.tests.ps1 ├── Inspect-ObjectProperty.ps1 ├── Inspect-PathInfoStack.ps1 ├── Invoke-FdFind.ps1 ├── Invoke-Formatting.ps1 ├── Invoke-GHRepoList.ps1 ├── Invoke-JsonJqQuery.ps1 ├── Invoke-NinFormatterFancy.ps1 ├── Invoke-NinFormatterFancy.tests.ps1 ├── Invoke-Pipescript.TranspileIfNew.ps1 ├── Invoke-Robocopy.Minimalism.ps1 ├── Invoke-WSL-OutString.ps1 ├── Join-Hashtable.ps1 ├── Join-Hashtable.tests.ps1 ├── Join-RegexFromPipe.ps1 ├── Measure-NinChildItem.ps1 ├── Measure-NinChildItem.tests.ps1 ├── Measure-ObjectCount.ps1 ├── New-NinStringComparer.ps1 ├── New-NinStringComparer.tests.ps1 ├── New-PSCustomObject.nin.ps1 ├── New-SafeFilename.ps1 ├── New-TextObject.ps1 ├── New-WindowsTerminal.ps1 ├── Out-NinGridView.ps1 ├── Out-ReversePipeline.ps1 ├── Out-ReversePipeline.tests.ps1 ├── Pop-NinLocation.ps1 ├── ProxyGet-Command.ps1 ├── Render-FormatShortTypeName.ps1 ├── Resolve-FilePath.ps1 ├── Resolve-ScriptBlockSource.ps1 ├── Select-ListSliceExpression.ps1 ├── Show-XmlPreview.ps1 ├── SortBy │ ├── SortBy-Get-Alias.ps1 │ └── __init__.ps1 ├── Test-CommandExist.ps1 ├── Test-ConsoleEnvVarPath.ps1 ├── Test-ConsoleEnvVarPath.tests.ps1 ├── Test-IsDirectory.ps1 ├── Test-IsDirectory.tests.ps1 ├── Test-IsSubDirectory.ps1 ├── Test-IsSubDirectory.tests.ps1 ├── Test-SameObjectType.ps1 ├── Test-WhichPwshAddon.ps1 ├── Text-IgnoreUntilMatch.ps1 ├── Text-IgnoreUntilMatch.tests.ps1 ├── VsCode-WriteConsoleSetMark.ps1 ├── Where-NonNullHashtableValue.tests.ps1 ├── __init__.ps1 ├── _enumerateMyCommand.tests.ps1 ├── _enumerateMyModule.ps1 ├── basicFormat-ControlChar.ps1 ├── cmd-git │ └── Getting.Resolve-Symbol.ps1 ├── inspection │ ├── FilterBy-MatchingAnyProperty.ps1 │ ├── FilterBy-MatchingAnyProperty.tests.ps1 │ ├── Find-FunctionInFile.ps1 │ ├── __init__.ps1 │ ├── __init__.py │ └── debug.TryHadException.ps1 ├── join.star │ ├── JoinStr.Format-Indent.ps1 │ ├── JoinStr.Format-Indent.tests.ps1 │ ├── JoinStr.Format-UnorderedList.ps1 │ └── __init__.ps1 ├── logging │ └── __init__.ps1 ├── nancy.Get-NinUnicodeSymbols.ps1 └── wt-SetWindowTabTitle.off ├── refs └── Strings.CheatSheet.md ├── root_autoloader.ps1 ├── test.txt ├── test ├── private │ ├── Test-PesterLinesAreEqual.tests.ps1 │ ├── run_temp_color_test.ps1 │ ├── run_temp_test-Get-NativeCommand.ps1 │ └── run_temp_test.ps1 ├── public │ ├── ConvertTo-BitString.tests.ps1 │ ├── ConvertTo-HexString.tests.ps1 │ ├── ConvertTo-Number.tests.ps1 │ ├── Format-ControlChar.tests.ps1 │ ├── Format-GenericTypeName.tests.ps1 │ ├── Format-HashTableList.visual_tests.ps1 │ ├── Format-Hashtable.visual_tests.ps1 │ ├── Format-NullText.tests.ps1 │ ├── Format-Predent.tests.ps1 │ ├── FormatControlChar.original.tests.ps1 │ ├── Get-EnumInfo.tests.ps1 │ ├── Get-ObjectProperty.tests.ps1 │ ├── Get-ObjectType.tests.ps1 │ ├── Get-ObjectType.visual_tests.ps1 │ ├── Sort-Hashtable.tests.ps1 │ ├── Test-NullArg.tests.ps1 │ ├── Write-ConsoleHeader.tests.ps1 │ ├── Write-ConsoleHeader.visual_tests.ps1 │ ├── Write-ConsoleLabel.visual_tests.ps1 │ ├── visual_test │ │ ├── Compare-Directory.visual_tests.ps1 │ │ └── Get-ObjectType.visual_tests.ps1 │ ├── wip - Get-EnumInfo.wip.ps1 │ ├── wip - Get-NinModule.wip.ps1 │ ├── wip - Get-PlatformFolderPath.ps1 │ └── wip - Invoke-Explorer.ps1 ├── test_Format.ps1xml.ps1 └── test_basic_import.ps1 ├── to cleanup -- function Invoke-BrowserItem.ps1 ├── to-investigate.md ├── todo_JoinOnNewLine-SplitNewline.ps1 ├── trash ├── Format-TypeName.old └── old-get-ninmodule.ps1 ├── zeroDepend_autoloader ├── ConvertTo-EnvVarPath.tests.ps1 ├── ConvertTo-EnvVarPathPath.ps1 ├── CurrentCulture.ps1 ├── Find-CommandHelpOnline.ps1 ├── Format-Join.Csv.ps1 ├── Format-ShortTypeName.ps1 ├── Format-ShortTypeName.tests.ps1 ├── GotoModule.ps1 ├── Import-NinPSReadlineConfig.ps1 ├── Invoke-VSCode.ps1 ├── Invoke-VsCodeProfileVenv.ps1 ├── Jsonify.tests.ps1 ├── Measure-ScriptBlockExecution.ps1 ├── New-RelativeDate.ps1 ├── New-StopWatch.ps1 ├── NewRegexLiteralOr.ps1 ├── Test-PathsAreEqual.ps1 ├── ZD-DecentPrompt.ps1 ├── ZD-Get-RuneInfo.ps1 ├── ZD-ToggleModule-Load.ps1 ├── __init__.ps1 ├── batPreview.ps1 ├── dump-VersionInfo.ps1 ├── invoke-wt-colors.ps1 ├── jaykul-formatwrap.ps1 ├── jsonify.ps1 ├── jsonify │ ├── Process.jsonify.ps1 │ ├── _renderPropertySample.ps1 │ └── readme.md ├── logging.Write-NinLogRecord.ps1 ├── mergeMe │ ├── Assert-IsNotBlank.ps1 │ ├── Assert-IsNotBlank.tests.ps1 │ ├── Test-IsNotBlank.ps1 │ ├── Test-IsNotBlank.tests.ps1 │ ├── Where-IsNotBlank.ps1 │ └── Where-IsNotBlank.tests.ps1 ├── newRegexLiteralOr.tests.ps1 ├── pansies-DumpColorspaceBlock.ps1 ├── prompt │ ├── customPrompt.ps1 │ └── root-prompts.ps1 ├── testPropertyIsJsonify.ps1 ├── url │ └── unescape-uri.ps1 ├── zeroDepend_GetPropertyEnumerator.ps1 ├── zeroDepend_WriteColor.ps1 └── zeroDependencies_Format-PropsAsPropTypeDefinition.ps1 └── 🐒 Ninmonkey.Console🖥️ .code-workspace /.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # binary files, custom handlers: https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes 3 | # Custom determining text diffs 4 | # https://www.git-scm.com/docs/gitattributes/2.18.0#_generating_diff_text 5 | # 6 | # [SO Examples diffing binary text files](https://superuser.com/a/706286) 7 | # Auto detect text files and perform LF normalization 8 | * text=auto 9 | 10 | # pwsh 11 | *.psd1 text=auto 12 | *.psm1 text=auto # fixes 13 | 14 | # Custom for Visual Studio 15 | *.cs diff=csharp 16 | # PowerShell 17 | #*.psd1 diff=astextplain 18 | #*.xml diff=astextplain 19 | -------------------------------------------------------------------------------- /.github/workflows/PushGitLogger.yml: -------------------------------------------------------------------------------- 1 | name: demo List Files 2 | run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 3 | on: [push] 4 | jobs: 5 | Explore-GitHub-Actions: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." 9 | - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" 10 | - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." 11 | - name: Check out repository code 12 | uses: actions/checkout@v3 13 | - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." 14 | - run: echo "🖥️ The workflow is now ready to test your code on the runner." 15 | - name: Run GitLogger 16 | uses: GitLogging/GitLoggerAction@main 17 | - name: List files in the repository 18 | run: | 19 | ls ${{ github.workspace }} 20 | - run: echo "🍏 This job's status is ${{ job.status }}." 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.zip 2 | *.exe 3 | *.lnk 4 | temp/ 5 | Todo_nocommit.md 6 | appveyor - random example.yml 7 | TestExplorerResults.xml 8 | debug.log 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.fontSize": 15, 3 | "editor.fontFamily": "'cascadia code pl', Consolas, 'Courier New', monospace" 4 | 5 | } 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 ninmonkey 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 | -------------------------------------------------------------------------------- /Readme.Todo.Refactor.md: -------------------------------------------------------------------------------- 1 | # Window API 2 | 3 | - [ ] include Indented's [Win32 api wrappers](https://gist.github.com/indented-automation/cbad4e0c7e059e0b16b4e42ba4be77a1) 4 | 5 | # Aliases 6 | 7 | | alias | Description | 8 | | ---------------- | ----------------------------- | 9 | | - [ ] h1, .., h6 | `Label` with padding | 10 | | - [ ] Pair | `Label -sep ': ' $Key $value` | 11 | 12 | ## JoinStr 13 | 14 | - [ ] `joinStrUl` # list item 15 | - [ ] `joinStrLine -sep '\n' ` 16 | - [ ] `joinStrCsv` 17 | - `-sep ', ' -op '\n'` 18 | 19 | # Minimum 20 | ## `Write-NinConsoleColor` 21 | 22 | Minimal, other commands all use this 23 | 24 | - [ ] `wcolor -fg -bg -Text ` 25 | 26 | ```ps1 27 | [h1 | h2] $Text 28 | 29 | # call signatures 30 | Label 'Key' -sep ' ' 31 | Label 'key' 'value' 32 | ``` 33 | ## `Label` 34 | 35 | ```ps1 36 | Pipe | Label 'Key' # invokes multiple key value pairs 37 | Pipe | JoinCsv | Label 'stuff' 38 | Label 'key' 'value' 39 | 40 | ``` -------------------------------------------------------------------------------- /Todo.Next.md: -------------------------------------------------------------------------------- 1 | - [ ] `Get-NinHelp` 2 | - [ ] lists important info, like `PSReadline` custom keybindings that are loaded like `alt+(`, `alt+%` 3 | - [ ] `Get-NinCommand` - `proxy` 4 | - [ ] `Get-NinModule` - `proxy` -------------------------------------------------------------------------------- /beforeAll_autoloader/Compare-LongestSharedString.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | Import-Module Ninmonkey.Console -Force 3 | } 4 | 5 | Describe 'Compare-LongestSharedString' { 6 | 7 | It '"" with "" matches anything"' -ForEach @( 8 | @{ 9 | A = 'abcd' ; Expected = $true 10 | B = 'abcde' 11 | } 12 | @{ 13 | A = 'abcd' ; Expected = $true 14 | B = 'abcd' 15 | } 16 | @{ 17 | A = 'bcd' ; Expected = $false 18 | B = 'abcd' 19 | } 20 | ) { 21 | Compare-LongestSharedPrefix -A $A -B $B 22 | | Should -Not -BeExactly [string]::Empty 23 | 24 | } 25 | Context 'Without PassThru' { 26 | Describe 'Using Codepoint Length Type' { 27 | It '"" with "" is "' -Foreach @() { 28 | Set-ItResult -Pending -Because 'unicode comparison not written yet' 29 | } 30 | } 31 | Describe 'Using Char Length Type' { 32 | It '"" with "" is "' -Foreach @( 33 | @{ 34 | A = 'abcd' 35 | B = 'abcde' 36 | Expected = 'abcd' 37 | } 38 | @{ 39 | A = 'abcde' 40 | B = 'abcd' 41 | Expected = 'abcd' 42 | } 43 | @{ 44 | A = 'abcd' 45 | B = 'bcd' 46 | Expected = '' 47 | } 48 | @{ 49 | A = 'bcd' 50 | B = 'abcd' 51 | Expected = '' 52 | } 53 | ) { 54 | Compare-LongestSharedPrefix -A $A -B $B 55 | | Should -BeExactly $Expected 56 | 57 | } 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /beforeAll_autoloader/__init__.ps1: -------------------------------------------------------------------------------- 1 | # This section is nearly no dependencies, 2 | # see also: git//zeroDepend_autoloader/__init__.ps1 3 | -------------------------------------------------------------------------------- /beforeAll_autoloader/executionContext-queryCommands-commands.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 7 2 | 3 | Write-Warning "still in debug mode $PSCommandPath" 4 | <# 5 | 6 | 7 | 8 | #> 9 | function _getNativeCommand { 10 | param( 11 | [Alias('LiteralName')] 12 | [string]$Name, 13 | 14 | [Alias('WildCard')] 15 | [switch]$UsingWildcard 16 | 17 | ) 18 | throw 'get below, or other ref' 19 | } 20 | # $sess.InvokeCommand.GetCommand('git', [CommandTypes]::Application ) 21 | 22 | # if ( $publicToExport ) { 23 | # $publicToExport.function += @( 24 | # 'Test-PathsAreEqual' 25 | # 'Ensure-CurWorkingDirectory' 26 | # ) 27 | # $publicToExport.alias += @( 28 | # '_ensureCwd' # 'Ensure-CurWorkingDirectory' 29 | # 'Ensure->Cwd' # 'Ensure-CurWorkingDirectory' 30 | # ) 31 | # } 32 | 33 | return 34 | 35 | $ExecutionContext.InvokeCommand.GetCommandName('gi*', $false, $true) 36 | # 63 0.051 $ExecutionContext.InvokeCommand.GetCommandName('gi*', $true, $true) 37 | # 62 0.028 $ExecutionContext.InvokeCommand.GetCommandName('gi', $true, $true) 38 | # 61 0.022 $ExecutionContext.InvokeCommand.GetCommandName('gi', $false, $true) 39 | # 60 0.021 $ExecutionContext.InvokeCommand.GetCommandName('git', $false, $true) 40 | # 59 0.026 $ExecutionContext.InvokeCommand.GetCommandName('git', $false) 41 | # 58 0.026 $ExecutionContext.InvokeCommand.GetCommandName('git', $false, $true) 42 | # 57 0.027 $ExecutionContext.InvokeCommand.GetCommandName('git', $true, $true) 43 | # 56 0.023 $ExecutionContext.InvokeCommand.GetCommandName('git', $true) 44 | # 55 0.027 $ExecutionContext.InvokeCommand.GetCommandName('git') 45 | # 54 0.018 $ExecutionContext.InvokeCommand.GetCommandName 46 | # 53 0.481 $sess.InvokeCommand.GetCommand('code.exe', [CommandTypes]::Application ) 47 | # 52 0.022 $sess.InvokeCommand.GetCommand('code.cmd', [CommandTypes]::Application ) 48 | # 51 0.034 $sess.InvokeCommand.GetCommand('code', [CommandTypes]::Application ) 49 | # 50 0.032 & $Null 50 | 51 | # 64 0.006 $ExecutionContext.InvokeCommand.GetCommandName('gi*', $false, $true) 52 | # 63 0.051 $ExecutionContext.InvokeCommand.GetCommandName('gi*', $true, $true) 53 | # 62 0.028 $ExecutionContext.InvokeCommand.GetCommandName('gi', $true, $true) -------------------------------------------------------------------------------- /debug_harness.ps1: -------------------------------------------------------------------------------- 1 | import-module './' -Force -Verbose -PassThru -------------------------------------------------------------------------------- /disabled/Testing-Get-FileInfo.ps1: -------------------------------------------------------------------------------- 1 | if (-not (Get-Command 'h1' -ea Ignore)) { 2 | function h9 { 3 | param( [string]$Text ) 4 | "`n`n ## $Text `n`n" 5 | } 6 | 7 | } 8 | $Error.clear() 9 | 10 | 11 | function _testIt { 12 | param( 13 | [ValidateNotNull()][Parameter()]$Obj, [string]$Label 14 | ) 15 | 16 | if ($Null -eq $Obj) { 17 | Write-Error 'Obj was null, requires value.' 18 | return 19 | } 20 | $dbg = [ordered]@{ 21 | 'Label' = $Label 22 | 'Exists?' = Test-Path $Obj 23 | 'Name' = $Obj.Name ?? '' 24 | 'FullName' = $Obj.FullName ?? '' 25 | 'Types?' = $Obj.PStypeNames | Csv2 26 | 'Length' = $Obj.Length ?? '' 27 | 'Content' = try { 28 | Get-Content $Obj -ea stop 29 | } catch { 30 | $_.Exception.Message 31 | } 32 | } 33 | return [pscustomobject]$dbg 34 | } 35 | 36 | 37 | 38 | $validPath = Get-ChildItem -Path '~' -File | Select-Object -First 1 39 | 40 | $existing = Resolve-FileInfo $ValidPath 41 | $existing.Length 42 | $notExisting = Resolve-FileInfo 'C:\nin_temp\does-not-exist.txt' 43 | $notExisting 44 | $notExistingSilent = Resolve-FileInfo 'C:\nin_temp\does-not-exist.txt' -ea Ignore 45 | $notExistingSilent 46 | $red = Resolve-FileInfo 'fg:\red' 47 | $red 48 | $greenLong = Resolve-FileInfo 'RgbColor::Foreground:\green' 49 | $greenLong 50 | 51 | # Test-Path -Path $existing, $notExisting 52 | $Tests = @( 53 | _TestIt $existing 'Existing' 54 | _TestIt $notExisting 'NotExisting' 55 | _TestIt $notExistingSilent 'NotExistingSilent' 56 | 57 | H1 'Color Fg:\red' 58 | _testIt 'Foreground:\red' 'Fg' 59 | ) 60 | 61 | Hr 62 | 63 | 64 | 65 | return 66 | # H1 'notExisting' 67 | # H1 'c' 68 | # H1 'd' 69 | 70 | 71 | # if ($false) { 72 | # 'text' | Set-Content $notExisting ; Get-Content $notExisting; 73 | # 'text' | Set-Content $notExisting ; Get-Item $notExisting 74 | # Remove-Item $notExisting 75 | # Remove-Item $notExisting 76 | # $notExisting 77 | # Get-Item $notExisting 78 | # Get-History 79 | # Get-History | ReverseIt 80 | # } -------------------------------------------------------------------------------- /docs_static/commands/Format-NativeCommandArguments.md: -------------------------------------------------------------------------------- 1 | ```ps1 2 | Format-NativeCommandArguments 'code' '--goto', 'someFile.log:242' 3 | 4 | $clargs = @('--goto', (gi '..\README.md')) 5 | $clargs | Format-NativeCommandArguments 'code' 6 | 7 | get-date | sc 'temp:\now.txt' 8 | sleep 0.01 9 | get-date | sc 'temp:\now with spaces.txt' 10 | 11 | $vscodeDiff = @( 12 | '--reuse-window' 13 | '--diff' 14 | gi 'temp:\now.txt' 15 | gi 'temp:\now with spaces.txt' 16 | ) 17 | 18 | Format-NativeCommandArguments 'code' $vscodeDiff 19 | ``` -------------------------------------------------------------------------------- /docs_static/data/Start-LogTestNet.screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninmonkey/Ninmonkey.Console/58bf5625e56fb178e5870a4d3bb06d112b39b458/docs_static/data/Start-LogTestNet.screenshot.png -------------------------------------------------------------------------------- /docs_static/ideas/ideas.experimental-native-commands.ps1.md: -------------------------------------------------------------------------------- 1 | ```ps1 2 | 'RoboCopy Copy' <# and #> 'RoboCopy Copy' 3 | 'Robo.Copy' <# and #> 'Robo.Mirror' 4 | 5 | # $NativeCmd▸$SubCommand 6 | 'Robo▸ -help' 7 | 'Robo▸Copy' <# and #> 'Robo▸Mirror' 8 | 'Robo▸Copy' -Help <# and #> 'Robo▸Mirror' -help 9 | 10 | # 11 | 'Robo⁞Copy' 'Robo🗄' 'RoboCopy' 12 | 'RoboCopy▸' 'RoboCopy📁' 'RoboCopy🗄' 13 | ``` -------------------------------------------------------------------------------- /docs_static/img/format-ul-completer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninmonkey/Ninmonkey.Console/58bf5625e56fb178e5870a4d3bb06d112b39b458/docs_static/img/format-ul-completer.png -------------------------------------------------------------------------------- /examples/Inspect-Generic-Collections.ps1: -------------------------------------------------------------------------------- 1 | function re { 2 | Import-Module Ninmonkey.Console -Dis -Force -Scope Global 1>$null 3 | } 4 | 5 | 6 | $manyEnv = Get-ChildItem env: 7 | $manyColor = Get-ChildItem env: 8 | $manyFile = Get-ChildItem .. -Depth 2 | Get-Unique -OnType | Select-Object -First 3 9 | 10 | $oneEnvRoot = Get-Item env:\ 11 | $oneEnvItem = Get-Item Env:\TEMP 12 | $oneColor = Get-Item Fg:\red 13 | $oneFile = Get-Item . 14 | 15 | hr 16 | Get-Collection $Obj 17 | hr 18 | return 19 | 20 | $params = (Get-Command Get-Culture).Parameters 21 | Get-Collection $params #| Format-List 22 | hr 23 | Get-Item env: | Get-Collection | Format-List 24 | 25 | 26 | h1 '1' 27 | $manyEnv = Get-ChildItem env: 28 | h1 '2' 29 | $manyColor = Get-ChildItem env: 30 | h1 '3' 31 | 32 | $envItem = Get-Item env:\ 33 | h1 '4' 34 | $colorItem = Get-Item Fg:\red 35 | $obj = Get-Item Env:\TEMP 36 | Get-Collection $Obj 37 | h1 '5' 38 | -------------------------------------------------------------------------------- /future_code/original_complete.ps1: -------------------------------------------------------------------------------- 1 | $ExecutionContext.InvokeCommand.GetCommand('TabExpansion2', 'All') 2 | 3 | $setAliasSplat = @{ 4 | Scope = 'global' 5 | Name = 'TabExpansion2_Original' 6 | Value = $ExecutionContext.InvokeCommand.GetCommand( 7 | 'TabExpansion2', 'Function' 8 | ) 9 | Description = 'Test out the vanilla completion' 10 | } 11 | 12 | Set-Alias @setAliasSplat -------------------------------------------------------------------------------- /help/Format-TypeName.md: -------------------------------------------------------------------------------- 1 | # Format-TypeName 2 | 3 | ## Make Generic types readable 4 | 5 | ```powershell 6 | # Often types are too specific by including assembly information 7 | PS> $params = (Get-Command Get-ChildItem).Parameters 8 | $params.GetType() 9 | 10 | Name FullName 11 | ---- -------- 12 | Dictionary`2 System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib, Version=5.0.0.0, 13 | Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Management.Automation.ParameterMetadata, 14 | System.Management.Automation, Version=7.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]] 15 | 16 | # Simplify Generic argument types using type names 17 | PS> $params | Format-TypeName 18 | 19 | Dictionary`2[System.String, System.Management.Automation.ParameterMetadata] 20 | ``` 21 | 22 | ## Examples 23 | 24 | ```powershell 25 | 🐒> [list[int]] 26 | 27 | 28 | Name FullName Base 29 | ---- -------- ---- 30 | List`1 System.Collections.Generic.List`1[[System.Int32, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]] System.Object 31 | 32 | 33 | 🐒> [list[int]] | format-typename 34 | 35 | List`1[Int32] 36 | 37 | 🐒> [list[int]] | % gettype | % fullname 38 | 39 | System.RuntimeType 40 | 41 | 🐒> [list[int]] | % gettypeinfo | % fullname 42 | 43 | System.Collections.Generic.List`1[[System.Int32, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]] 44 | 45 | 🐒> [list[int]] | % gettypeinfo | % fullname | format-typename 46 | 47 | List`1[[System.Int32, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]] 48 | ``` -------------------------------------------------------------------------------- /new -- summarize PSReadlineKey bindings.ps1: -------------------------------------------------------------------------------- 1 | 2 | 3 | function _summarizeKeybind { 4 | <# 5 | .synopsis 6 | make testing keybindings readable for the cli 7 | .example 8 | PS> _summarizeKeybind '^f\d$' 9 | 10 | F1 = ShowCommandHelp; F2 = SwitchPredictionView; F3 = CharacterSearch; F8 = HistorySearchBackward 11 | 12 | PS> _summarizeKeybind 'enter' 13 | 14 | Alt+Enter = InsertLineBelow; Ctrl+Enter = InsertLineAbove; Enter = AcceptLine; Shift+Ctrl+Enter = InsertLineBelow; Shift+Enter = AddLine 15 | #> 16 | [Alias('__Refactor.ForTypeWriter')] 17 | param( 18 | # Regex 19 | [Parameter(Position = 0)] 20 | [string]$PatternKeybind 21 | ) 22 | 23 | begin { 24 | $splat_JoinKeys = @{ 25 | Separator = '; ' 26 | OutputSuffix = "`n" 27 | Property = { $_.Key, $_.Function -join ' = ' } 28 | } 29 | } 30 | 31 | process { 32 | Label 'Pattern' $PatternKeybind | Write-Information 33 | Get-PSReadLineKeyHandler -Bound 34 | | Where-Object { $_.Key -match $PatternKeybind } 35 | | Sort-Object Key 36 | | Join-String @splat_JoinKeys 37 | } 38 | } 39 | 40 | _summarizeKeybind '^f\d$' -InformationAction Continue 41 | _summarizeKeybind 'enter' -InformationAction Continue 42 | 43 | # Get-PSReadLineKeyHandler -Bound | Where-Object { $_.Key -match 'f[12]' } 44 | # | Sort-Object Key 45 | # | Join-String -sep '; ' { $_.Key, $_.Function -join ' = ' } -os '' -------------------------------------------------------------------------------- /next-pass.md: -------------------------------------------------------------------------------- 1 | - [ ] `Invoke-GhRepoList` new dynamic completions 2 | - [ ] `Jsonify core` => FileInfo, Dates, ProcessListing, automatic nesting test 3 | - [ ] increment depth cost, unless, type is already directly handled by `Jsonify` 4 | - [ ] future: Jsonify using custom attributes for easier serialization 5 | - [ ] `Test-JsonifyPropertyIsOk` -------------------------------------------------------------------------------- /notebooks/using_wrapText.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "dotnet_interactive": { 8 | "language": "pwsh" 9 | }, 10 | "vscode": { 11 | "languageId": "polyglot-notebook" 12 | } 13 | }, 14 | "outputs": [], 15 | "source": [ 16 | "Import-Module Ninmonkey.Console *>$null" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "metadata": { 23 | "dotnet_interactive": { 24 | "language": "pwsh" 25 | }, 26 | "vscode": { 27 | "languageId": "polyglot-notebook" 28 | } 29 | }, 30 | "outputs": [], 31 | "source": [ 32 | "0..4\n", 33 | "| wrapText Dunder\n", 34 | "| wrapText PwshVariable\n", 35 | "| wrapText RegexNamedGroup -a 'Stuff'\n", 36 | "| wrapText PwshStaticMember -a 'Invoke()'" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": null, 42 | "metadata": { 43 | "dotnet_interactive": { 44 | "language": "pwsh" 45 | }, 46 | "vscode": { 47 | "languageId": "polyglot-notebook" 48 | } 49 | }, 50 | "outputs": [], 51 | "source": [ 52 | "0..4 | wrapText Dunder" 53 | ] 54 | } 55 | ], 56 | "metadata": { 57 | "kernelspec": { 58 | "display_name": ".NET (C#)", 59 | "language": "C#", 60 | "name": ".net-csharp" 61 | }, 62 | "language_info": { 63 | "file_extension": ".cs", 64 | "mimetype": "text/x-csharp", 65 | "name": "C#", 66 | "pygments_lexer": "csharp", 67 | "version": "9.0" 68 | }, 69 | "orig_nbformat": 4 70 | }, 71 | "nbformat": 4, 72 | "nbformat_minor": 2 73 | } 74 | -------------------------------------------------------------------------------- /private/Format-ParameterTypeInfo.ps1: -------------------------------------------------------------------------------- 1 | # using namespace System.Management.Automation 2 | 3 | 4 | # function _Format-ParameterTypeInfo { 5 | # <# 6 | # .description 7 | # formats [System.Management.Automation.ParameterMetadata] 8 | # #> 9 | # param( 10 | # # [ParameterMetadata] instance 11 | # [Parameter(Mandatory, Position = 0, ValueFromPipeline)] 12 | # $InputObject 13 | # ) 14 | 15 | # begin { 16 | # h2 'yay' 17 | # Write-Warning 'wip' 18 | # } 19 | # process { 20 | 21 | # $InputObject.GetEnumerator() | ForEach-Object { 22 | 23 | # # is a: [ParameterMetadata] 24 | # $curParam = $_ 25 | # $curName = $curParam.Key 26 | # $curValue = $curParam.Value 27 | # $hashParam = @{ 28 | # Name = $curName 29 | # Type = $curValue.ParameterType 30 | # ParamSets = $curValue.ParameterSets 31 | # IsDynamic = $curValue.IsDynamic 32 | # Aliases = $curValue.Aliases 33 | # Attributes = $curValue.Attributes 34 | # IsSwitch = $curVal.SwitchParameter 35 | 36 | # } 37 | # [pscustomobject]$hashParam 38 | # } 39 | # } 40 | # } 41 | # <# 42 | if ($false) { 43 | $Sample = @{ 44 | FunctionInfo_WithParam = Get-Command * | Where-Object { 45 | $_ -is 'FunctionInfo' -and $null -ne $_.Version -and $_.Parameters.PSBase.Count -gt 0 46 | } | Select-Object -First 1 -Wait 47 | } 48 | $g_paramDict = $Sample.FunctionInfo_WithParam.Parameters 49 | $g_paramSingle = $Sample.FunctionInfo_WithParam.Parameters.GetEnumerator() | Select-Object -First 1 -ExpandProperty Value 50 | 51 | _Format-ParameterTypeInfo $g_paramDict 52 | 53 | } 54 | #> 55 | -------------------------------------------------------------------------------- /private/config/getDocs-Powerquery.json: -------------------------------------------------------------------------------- 1 | /* 2 | powequery function + identifier names (for docs) 3 | 4 | https://raw.githubusercontent.com/ninmonkey/Ninmonkey.PowerQueryLib/master/Docs/List_Constants-All.csv 5 | https://raw.githubusercontent.com/ninmonkey/Ninmonkey.PowerQueryLib/master/Docs/List_Functions-All.csv 6 | https://raw.githubusercontent.com/ninmonkey/Ninmonkey.PowerQueryLib/master/Docs/List_Numbers-All.csv 7 | https://raw.githubusercontent.com/ninmonkey/Ninmonkey.PowerQueryLib/master/Docs/List_Text-All.csv 8 | https://raw.githubusercontent.com/ninmonkey/Ninmonkey.PowerQueryLib/master/Docs/List_Types-All.csv 9 | 10 | 11 | */ 12 | -------------------------------------------------------------------------------- /private/pester/Test-PesterLinesAreEqual.ps1: -------------------------------------------------------------------------------- 1 | function Test-PesterLinesAreEqual { 2 | <# 3 | .synopsis 4 | test if strings are equa 5 | l, regardless of line ending style 6 | .notes 7 | - Is it better to throw an exception or return a [bool] for [Pester] ? 8 | - if the text delim is '\r' with no '\n' then splitting on '\r?\n' fails 9 | #> 10 | param( 11 | # Expected Text 12 | [Parameter(Mandatory, Position = 0)] 13 | [string[]]$ExpectedText, 14 | 15 | # Comparison text 16 | [Parameter(Mandatory, Position = 1)] 17 | [string[]]$ActualText, 18 | 19 | # strict coompare: Treat different line endings as a failed match 20 | [Parameter()][switch]$PreserveLineEnding 21 | ) 22 | process { 23 | # H1 "_Pester-linesAreEqual" | Write-Information 24 | $Meta = @{ 25 | 'PreserveLineEndings?' = $PreserveLineEnding 26 | ExpectedLength = ($ExpectedText -join '' ).Length 27 | ActualLength = ($ActualText -join '' ).Length 28 | } 29 | 30 | $cleanExpected = $ExpectedText.Trim() 31 | if (! $PreserveLineEnding) { 32 | $cleanExpected = $cleanExpected -join "`n" -split '\r?\n' -join "`n" 33 | } 34 | $cleanActual = $ActualText.Trim() 35 | if (! $PreserveLineEnding) { 36 | $cleanActual = $cleanActual -join "`n" -split '\r?\n' -join "`n" 37 | } 38 | $Meta += @{ 39 | ExpectedLengthClean = ($cleanExpected -join '' ).Length 40 | ActualLengthClean = ($cleanActual -join '' ).Length 41 | } 42 | 43 | $Meta | Format-HashTable | Write-Debug 44 | $cleanActual | Should -Be $cleanExpected 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /public/Compare-Directory.ps1: -------------------------------------------------------------------------------- 1 | function Compare-Directory { 2 | <# 3 | .SYNOPSIS 4 | Compare Two directories using 'diff' 5 | 6 | .DESCRIPTION 7 | wrapper for 'diff' 8 | 9 | .PARAMETER Path1 10 | First Path 11 | 12 | .PARAMETER Path2 13 | Second Path 14 | 15 | .EXAMPLE 16 | Compare-Directory 'c:\foo' 'c:\bar\bat' 17 | #> 18 | [Alias('DiffDir')] 19 | param( 20 | # Path1 21 | [Parameter(Mandatory, Position = 0)] 22 | [string]$Path1, 23 | # Path2 24 | [Parameter(Mandatory, Position = 1)] 25 | [string]$Path2, 26 | 27 | # Output original raw text 28 | [Parameter()][switch]$OutputRaw 29 | ) 30 | 31 | $Base1 = $Path1 | Get-Item -ea Stop 32 | $Base2 = $Path2 | Get-Item -ea Stop 33 | $Label1 = $Base1 | Split-Path -Leaf | New-Text -fg 'green' 34 | $Label2 = $Base2 | Split-Path -Leaf | New-Text -fg 'yellow' 35 | 36 | "Comparing: 37 | Path: $Path1 38 | Path: $Path2 39 | " | Write-Information 40 | 41 | $stdout = Invoke-NativeCommand 'diff' -args @( 42 | '-q' 43 | $Base1 44 | $Base2 45 | ) 46 | 47 | $outColor = $stdout 48 | $outColor = $outColor -replace [regex]::Escape($path1), $Label1 49 | $outColor = $outColor -replace [regex]::Escape($path2), $Label2 50 | $outColor = $outColor -replace 'Only in', (New-Text 'Only In' -fg 'red') 51 | $outColor = $outColor -replace 'Differ', (New-Text 'Differ' -fg 'red') 52 | 53 | if ($OutputRaw) { 54 | h1 'Raw' | Write-Information 55 | $stdout 56 | return 57 | } 58 | 59 | $outColor 60 | } 61 | -------------------------------------------------------------------------------- /public/ConvertTo-Base64String.ps1: -------------------------------------------------------------------------------- 1 | using namespace System.Text 2 | 3 | 4 | 5 | # todo 6 | function ConvertTo-Base64String { 7 | <# 8 | .synopsis 9 | originally from: 10 | .notes 11 | currently the same, separate same. separate for dependency clarity 12 | .example 13 | # For more see: 14 | <./test/public/ConvertTo-Base64String.tests.ps1> 15 | .link 16 | Utility\ConvertTo-Base64String 17 | #> 18 | [Alias('Base64')] 19 | 20 | [OutputType([System.String])] 21 | [CmdletBinding(PositionalBinding = $false)] 22 | param( 23 | [Parameter(ValueFromPipeline, Position = 0)] 24 | [AllowEmptyString()] 25 | [AllowNull()] 26 | [string] $InputObject, 27 | 28 | [Parameter()] 29 | [ArgumentCompletions('UTF8', 'ASCII', 'Unicode', 'BigEndianUnicode', 'Default', 'UTF32', 'us-ascii')] 30 | # [ArgumentCompleter([EncodingArgumentCompleter])] 31 | [EncodingArgumentConverter()] 32 | [Encoding] $Encoding 33 | ) 34 | begin { 35 | if ($PSBoundParameters.ContainsKey((nameof { $Encoding }))) { 36 | $userEncoding = $Encoding 37 | return 38 | } 39 | 40 | $userEncoding = [System.Text.Encoding]::UTF8 41 | #used to be: [Encoding]::Unicode # ut8 42 | } 43 | process { 44 | if ([string]::IsNullOrEmpty($InputObject)) { 45 | return 46 | } 47 | 48 | return [convert]::ToBase64String($userEncoding.GetBytes($InputObject)) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /public/ConvertTo-HexString.ps1: -------------------------------------------------------------------------------- 1 | 2 | function ConvertTo-HexString { 3 | <# 4 | .synopsis 5 | convert [int] into '0xff' or 'ff f3' hex strings 6 | .notes 7 | originally based on 'SeeminglyScience\ConvertTo-HexString' 8 | #> 9 | [Alias('Hex')] 10 | [CmdletBinding(PositionalBinding = $false)] 11 | param( 12 | [Parameter(ValueFromPipeline)] 13 | [psobject[]] $InputObject, 14 | 15 | [Parameter(Position = 0)] 16 | [ValidateRange(1, [int]::MaxValue)] 17 | [Alias('Padding')] 18 | [int] $ZeroPadding, 19 | 20 | # NoPrefix as '0x' 21 | [Parameter()][switch]$NoPrefix 22 | ) 23 | process { 24 | foreach ($currentItem in $InputObject) { 25 | $numeric = Number $currentItem 26 | 27 | # difference between using $padding as non null? 28 | # PSBoundParameters means ignoring PSDefaultValues ? 29 | 30 | if ($PSBoundParameters.ContainsKey((nameof { $Padding }))) { 31 | "0x{0:x$ZeroPadding}" -f $numeric 32 | continue 33 | } 34 | 35 | '0x{0:x}' -f $numeric 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /public/ConvertTo-Number.ps1: -------------------------------------------------------------------------------- 1 |  2 | function ConvertTo-Number { 3 | <# 4 | .synopsis 5 | originally from: 6 | .notes 7 | currently the same, separate same. separate for dependency clarity 8 | .example| 9 | # For more see: 10 | <./test/public/ConvertTo-Number.ps1> 11 | #> 12 | [Alias('Number')] 13 | [CmdletBinding(PositionalBinding = $false)] 14 | param( 15 | [Parameter(ValueFromPipeline, Position = 0)] 16 | [psobject] $InputObject 17 | ) 18 | process { 19 | foreach ($currentItem in $InputObject) { 20 | if ($currentItem -is [Enum]) { 21 | # yield 22 | $currentItem.value__ 23 | continue 24 | } 25 | 26 | # see: 27 | if ($currentItem -isnot [ValueType]) { 28 | # yield 29 | $currentItem -as [int] 30 | continue 31 | } 32 | 33 | if ([array]::IndexOf($script:WellKnownNumericTypes, $currentItem.GetType()) -eq -1) { 34 | # yield 35 | $currentItem -as [int] 36 | continue 37 | } 38 | 39 | # yield 40 | $currentItem 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /public/ConvertTo-Timespan.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | # . $PSCommandPath.Replace('.Tests.ps1', '.ps1') 3 | Import-Module Ninmonkey.Console -Force 4 | 5 | } 6 | 7 | Describe 'ConvertTo-Timespan' { 8 | # BeforeAll { 9 | # $SampleData = @( 10 | # '3d1m' 11 | # '3d1a' 12 | # '-3d1m' 13 | # '-3d1a' 14 | # '1d3s' 15 | # '1d3-s' 16 | # '1d3h4m1s' 17 | # '3d' 18 | # ) 19 | # } 20 | BeforeAll { 21 | 22 | } 23 | Describe 'Empty Values' { 24 | It 'Zero is Valid' { 25 | { Ninmonkey.Console\ConvertTo-Timespan '0s' -ZeroIsValid -ea stop } 26 | | Should -Not -Throw 27 | } 28 | It 'Zero Should Throw' { 29 | { Ninmonkey.Console\ConvertTo-Timespan '0s' -ea stop } 30 | | Should -Throw 31 | } 32 | } 33 | <# 34 | once parsing is fixed: 35 | 36 | mixed decimal cases, before, after, empty, both 37 | 31s 38 | 3.s 39 | .3s 40 | .0s 41 | 42 | 0.3d0.2h0.4m1.45s93.4ms 43 | 0.3d-0.2h0.4m1.45s93.3ms 44 | 45 | all negatives 46 | 47 | -0.1d-0.1h-0.1m-0.1s-0.1ms 48 | 49 | regular enumeration 50 | 1.1s 51 | 0.1s 52 | 0342.234s 53 | -1.1s 54 | -0.1s 55 | -0342.234s 56 | 0.0s 57 | 0s 58 | 59 | 2d 60 | #> 61 | It 'Returns ()' -ForEach @( 62 | # I think some values go out of range or precision errors 63 | @{ Name = '0s'; Expected = ([timespan]::new(0, 0, 0, 0, 0)) } 64 | @{ Name = '3d1m'; Expected = ([timespan]::new(3, 0, 1, 0, 0)) } 65 | @{ Name = '9d3h'; Expected = ([timespan]::new(9, 3, 0, 0, 0)) } 66 | @{ Name = '9d3h1d'; Expected = ([timespan]::new(9, 3, 0, 0, 0)) } 67 | @{ Name = '9d1m3h'; Expected = ([timespan]::new(9, 0, 1, 0, 0)) } 68 | # @{ Name = '-4d2h9s299ms'; Expected = ([timespan]::new(9, 3, 0, 0, 0)) } 69 | 70 | ) { 71 | Ninmonkey.Console\ConvertTo-Timespan $name -ZeroIsValid 72 | | Should -Be $expected 73 | # Get-Emoji -Name $name | Should -Be $expected 74 | } 75 | 76 | 77 | } 78 | -------------------------------------------------------------------------------- /public/Edit-GitConfig.ps1: -------------------------------------------------------------------------------- 1 |  2 | function Edit-GitConfig { 3 | <# 4 | .description 5 | an alias to edit global git config 6 | .notes 7 | try: ~/.gitconfig 8 | see a ton of git utils in: 9 | #> 10 | git config --global -e 11 | } 12 | -------------------------------------------------------------------------------- /public/Export-PlatformFolderPath.ps1: -------------------------------------------------------------------------------- 1 | function Export-PlatformFolderPath { 2 | <# 3 | .description 4 | compare results of [Environment]::GetFolderPath() across different platforms and versions 5 | #> 6 | param( 7 | # Try both versions of powershell in a subprocess, otherwise defaults to using the current session 8 | [Parameter()] 9 | [switch]$TryAll, 10 | 11 | # return PSObject instead of Json ? 12 | [Parameter()][switch]$PassThru, 13 | 14 | # minify JSON ? 15 | [Parameter()][switch]$CompressJson 16 | ) 17 | 18 | $folderList = [enum]::GetNames( [System.Environment+SpecialFolder] ) | ForEach-Object { 19 | [pscustomobject]@{ 20 | Name = $_; 21 | Path = [Environment]::GetFolderPath( $_ ) 22 | } 23 | } 24 | $computerInfo = try { 25 | Get-ComputerInfo | Select-Object 'OsName', 'OSType', 'OSVersion', 'OsArchitecture' 26 | } catch { 27 | '' 28 | } 29 | 30 | $metaData = @{ 31 | 'PSVersion' = $PSVersionTable | Select-Object 'PSEdition', 'OS', 'Platform', @{ 32 | n = 'PSVersion'; e = { $_.PSVersion.tostring() } 33 | } 34 | 'SpecialFolders' = $folderList 35 | 'ComputerInfo' = $computerInfo 36 | } 37 | 38 | $Result = [pscustomobject]$metaData 39 | 40 | 'suggested name: ' | Write-Verbose 41 | if ($PassThru) { 42 | return $Result 43 | } 44 | 45 | $splat = @{ 46 | # = $CompressJson ? $true : $false # ps5 breaks 47 | # Compress = (if ($CompressJson) { $true } else { $false } ) 48 | } 49 | $Result | ConvertTo-Json @splat 50 | } 51 | -------------------------------------------------------------------------------- /public/Find-GitRepo.ps1: -------------------------------------------------------------------------------- 1 | 2 | function Find-GitRepo { 3 | <# 4 | .synopsis 5 | find folders with git repos, like 'Get-ChildItem' 6 | .notes 7 | or should it be named like get-childitem? 8 | future: 9 | a custom attribute for (filepath must exist) vs (filepath optionally exists) logic? 10 | 11 | future 12 | - [ ] performance: use 'fdfind' or 'everythingSearch' or even dotnet methods 13 | - [ ] return record with a custom view? 14 | 15 | .example 16 | PS> Find-GitRepo ~/documents/2021 17 | .example 18 | PS> LsGit 'c:\' -Depth 1 19 | | out-fzf | Goto 20 | 21 | #> 22 | [Alias('LsGit')] 23 | param( 24 | # root path to search 25 | [parameter(Position = 0)] 26 | [string]$Path = '.', 27 | 28 | # Max depth 29 | [parameter(Position = 1)] 30 | [uint]$Depth, 31 | 32 | # Max depth 33 | [parameter()][switch]$Detailed 34 | ) 35 | 36 | $RootPath = Get-Item -ea stop $Path 37 | $split_gciRepo = @{ 38 | Directory = $true 39 | Force = $true 40 | Recurse = $true 41 | Path = $RootPath 42 | Filter = '.git' 43 | } 44 | 45 | if ($Depth) { 46 | $split_gciRepo['Depth'] = $Depth 47 | } 48 | 49 | $dirs = Get-ChildItem @split_gciRepo 50 | # | Where-Object '.git' 51 | | ForEach-Object Parent 52 | | Sort-Object LastWriteTime -Descending 53 | 54 | if (!$Detailed) { 55 | $dirs 56 | return 57 | } 58 | 59 | $dirs | ForEach-Object { 60 | $meta = @{ 61 | Name = $_.Name 62 | Parent = $_.Parent.Name 63 | FullName = $_ # .FullName 64 | LastWriteTime = $_.LastWriteTime 65 | CreationTime = $_.CreationTime 66 | # "OtherInfoFrom" = 'Git-Posh' 67 | } 68 | [pscustomobject]$meta 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /public/Find-Hotkey.ps1: -------------------------------------------------------------------------------- 1 | 2 | 3 | function Get-Hotkeys { 4 | <# 5 | .synopsis 6 | ancient code, but the output is decent. 7 | .example 8 | PS> Get-Hotkeys alt, shift, enter, ctrl 9 | 10 | # these are both 11 | Get-PSReadLineKeyHandler -Bound | sort Group | rg 'alt|shift|enter|ctrl|$' 12 | Get-PSReadLineKeyHandler -Bound | sort Group | rg 'alt|shift|enter|ctrl|$' | measure 13 | 14 | # Simplified to: 15 | 16 | Get-Hotkeys alt, shift, enter, ctrl 17 | Get-Hotkeys alt, shift, enter, ctrl | measure 18 | 19 | .notes 20 | 21 | todo: 22 | - [ ] remove rg dependency for color 23 | - [ ] generate unique colors per key names 24 | - [ ] generate hotkey names autocompleted from parsed results of (get-psreadlinekeyhandler) 25 | so athat 26 | Get-Hotkeys al[tab] sh[tab] en[tab] 27 | As one long string? or as an array ? 28 | - [ ] arg passing, easy to allow 29 | $split = $line -match ',' ? ',' : '\s+' 30 | key1, key3 31 | key1 key3 32 | # highlights any matched words 33 | 34 | 35 | #> 36 | [CmdletBinding()] 37 | param ( 38 | [Parameter(, Position = 0, HelpMessage = "Keys to search for like: 'enter, ctrl'")] 39 | [string[]]$keys 40 | ) 41 | 42 | $items = $keys -split ',' 43 | "using: $( $items -join ', ' )" 44 | # Get-PSReadLineKeyHandler -Bound | sort Group | rg 'alt|shift|enter|ctrl|$' 45 | 46 | $regex = $keys 47 | | ForEach-Object { 48 | [regex]::Escape( $_.Trim() ) 49 | } | Join-String -Separator '|' 50 | 51 | $regex += '|$' 52 | Get-PSReadLineKeyHandler -Bound | Sort-Object Group | rg $regex 53 | 'hotkey regex: ', $regex -join '' | Write-Host -ForegroundColor Magenta 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /public/Find-NinNativeCommand.ps1: -------------------------------------------------------------------------------- 1 | function Find-NinNativeCommand { 2 | <# 3 | .synopsis 4 | ME FIRST 5 | .description 6 | . 7 | .example 8 | PS> 9 | .notes 10 | . 11 | #> 12 | [Alias('Find-NativeCommand')] 13 | [cmdletbinding(PositionalBinding = $false)] 14 | param ( 15 | # # Docstring 16 | # [Parameter(Mandatory, Position=0)] 17 | # [object]$ParameterName 18 | # # filter 19 | # [Alias('Type')] 20 | # [Parameter(Mandatory, Position = 0)] 21 | # [System.Management.Automation.CommandTypes]$CommandType 22 | 23 | ) 24 | begin {} 25 | process { 26 | # Write-Warning @' 27 | # nyi: 28 | # Start with: 29 | # ' 30 | # 31 | # '@ 32 | } 33 | end {} 34 | } -------------------------------------------------------------------------------- /public/Find-TabExpansionCommand.ps1: -------------------------------------------------------------------------------- 1 | function Find-TabExpansionCommand { 2 | <# 3 | .synopsis 4 | Find tab expansion hooks 5 | .description 6 | . 7 | 8 | .example 9 | PS> 10 | .notes 11 | . 12 | #> 13 | # [alias('Find-TabExpansion')] 14 | param ( 15 | [Parameter()][switch]$UseGrep 16 | ) 17 | begin { 18 | throw 'Obsolete' 19 | } 20 | process { 21 | # $Target = gi -ea stop $InputObject # Yes? No? 22 | $meta = @{ 23 | ChocolateyProfile = $ChocolateyProfile 24 | ChocolateyTabSettings = $ChocolateyTabSettings 25 | } 26 | $Found = Get-Command 'tab*' -All | Where-Object { 27 | $_.CommandType -ne 'Application' -and $_.Source -ne 'PSWriteHtml' 28 | } | Sort-Object Name 29 | $meta; 30 | Hr 4 31 | $found 32 | Hr 33 | 'next: search function:provider' 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /public/Find-VSCodeProject.ps1: -------------------------------------------------------------------------------- 1 | function Find-GitRepo { 2 | <# 3 | .synopsis 4 | find folders with git repos, like 'Get-ChildItem' 5 | .notes 6 | or should it be named like get-childitem? 7 | future: 8 | a custom attribute for (filepath must exist) vs (filepath optionally exists) logic? 9 | .example 10 | PS> LsGit 11 | .example 12 | PS> LsGit 'c:\' -Depth 1 13 | 14 | #> 15 | [Alias('LsGit')] 16 | param( 17 | # root path to search 18 | [parameter(Position = 0)] 19 | [string]$Path = '.', 20 | 21 | # Max depth 22 | [parameter(Position = 1)] 23 | [uint]$Depth 24 | 25 | 26 | 27 | ) 28 | 29 | $RootPath = Get-Item -ea stop $Path 30 | $split_gciRepo = @{ 31 | Directory = $true 32 | Force = $true 33 | Recurse = $true 34 | Path = $RootPath 35 | Filter = '.git' 36 | } 37 | 38 | if ($Depth) { 39 | $split_gciRepo['Depth'] = $Depth 40 | } 41 | 42 | Get-ChildItem @split_gciRepo -ov 'cache' | ForEach-Object Parent 43 | 44 | Write-Warning ' 45 | ask 46 | 1] why does path "c:" and "c:\" give different results 47 | 48 | 2] why does filter allow broken on ".git", dot should not allow the match 49 | 50 | 3] ***solution** just compare "name" -eq ".git" for a working hack, not worth filter. 51 | ' 52 | } 53 | 54 | 55 | if ($false) { 56 | # Find-GitRepo 'C:' -Depth 2 57 | h1 '..\..' 58 | Find-GitRepo '..\..' 59 | h1 'c:\' 60 | Find-GitRepo 'C:' 61 | # | Join-Path -ChildPath '.git' #| ? Test-Path 62 | } 63 | -------------------------------------------------------------------------------- /public/FindMyCommand..ps1: -------------------------------------------------------------------------------- 1 | function Find-MyCommand { 2 | <# 3 | .synopsis 4 | sketch, not ready. 5 | #> 6 | h1 'sketch' 7 | $queryTerm = '*prop*', '*object*', '*hashtable*' 8 | $query = Get-Command -m (_enumerateMyModule) $queryTerm 9 | 10 | 11 | 12 | h1 'details' 13 | $query 14 | | Where-Object { $_.CommandType -notin @('Alias', 'Application') } 15 | | Sort-Object Source, Name 16 | | Get-Random -Count 20 17 | | First 3 18 | | s -ExcludeProperty Definition, ScriptBlock 19 | | Out-Null 20 | 21 | h1 'sort types' 22 | $query | Get-Random -Count 40 23 | | Sort-Object Verb, Name 24 | | Out-Null 25 | 26 | 27 | & { 28 | $randTest1 = $query | Get-Random -Count 40 29 | h1 'type1: verb centric' 30 | $randTest1 | Sort-Object Verb, Name, Source 31 | | Format-Table Name, Source -GroupBy Verb -AutoSize 32 | 33 | h1 'type2: Source, name' 34 | $randTest1 35 | | Sort-Object Source, Name, Verb 36 | | Format-Table Name, Verb -GroupBy Source -AutoSize 37 | } 38 | 39 | '*filter->*', '*from->*', '*to->*' | ForEach-Object { 40 | Get-Command -m (_enumerateMyModule) $_ 41 | hr 42 | } 43 | 44 | 45 | } -------------------------------------------------------------------------------- /public/Format-FileSize.ps1: -------------------------------------------------------------------------------- 1 | Function Format-FileSize { 2 | <# 3 | .DESCRIPTION 4 | Formats bytes as humanized sizes 5 | .NOTES 6 | todo: 7 | - nicely handle null values (just ignore) 8 | - format table with align = right 9 | 10 | Original was based on: https://github.com/chocolatey/choco/blob/master/src/chocolatey.resources/helpers/functions/Format-FileSize.ps1 11 | #> 12 | [cmdletbinding()] 13 | param ( 14 | # size in Bytes 15 | [Parameter(Mandatory, Position = 0, ValueFromPipeline)] 16 | [int64] $Size, 17 | 18 | # future nin parameter type 19 | # [1] tooltip of format string show an actual usage of the template 20 | [Parameter()] 21 | [ArgumentCompletions( 22 | "'{0:n2} {1}'", 23 | "'{0:0.##} {1}'" 24 | )] 25 | [String]$FormatString = '{0:n2} {1}' 26 | ) 27 | 28 | begin { 29 | if ( [string]::IsNullOrWhiteSpace($FormatString) ) { 30 | $template = '{0:0.##} {1}' 31 | } else { 32 | $template = $FormatString 33 | } 34 | } 35 | process { 36 | 37 | 38 | Foreach ($unit in @('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB')) { 39 | If ($size -lt 1024) { 40 | return [string]::Format($template, $size, $unit) 41 | } 42 | $size /= 1024 43 | } 44 | [string]::Format('{0:0.##} YB', $size) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /public/Format-HashTableList.ps1: -------------------------------------------------------------------------------- 1 | 2 | function Format-HashTableList { 3 | <# 4 | .synopsis 5 | pretty prints a list of hashtables as single lines 6 | .description 7 | expects a [hashtable[]] 8 | .notes 9 | refactor to a list of any type with nested expansion ? 10 | .example 11 | 12 | PS> 13 | $SampleList = @( 14 | @{ expression = 'Name'; Descending = $true; cat = 4 } 15 | @{ expression = 'Id'; Descending = $true } 16 | ) 17 | , $SampleList | Format-HashTableList 18 | 19 | # Output: 20 | 21 | Hashtable[] = @( 22 | @{cat = 4; Descending = True; expression = Name } 23 | @{Descending = True; expression = Id } 24 | ) 25 | 26 | #> 27 | param( 28 | # List of [Hashtable] 29 | [Parameter(Mandatory, ValueFromPipeline)] 30 | # [hashtable[]]$InputList 31 | [hashtable[]]$InputList 32 | ) 33 | 34 | begin { 35 | $Depth = 1 36 | $SpacesPerIndent = 4 37 | $IndentString = (' ' * $SpacesPerIndent) -join '' 38 | } 39 | process { 40 | # foreach ($element in $InputList) { 41 | $NestedIndentString = $IndentString * $Depth 42 | $PrefixTypeName = TypeOf -InputObject $InputList 43 | $joinStringSplat = @{ 44 | OutputPrefix = "${PrefixTypeName} = @(`n${NestedIndentString}" 45 | Separator = "`n${NestedIndentString}" 46 | OutputSuffix = "`n)" 47 | } 48 | 49 | $InputList | ForEach-Object { 50 | $_ | Format-HashTable SingleLine 51 | } | Join-String @joinStringSplat 52 | # } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /public/Format-MeasureCommand.ps1: -------------------------------------------------------------------------------- 1 |  2 | function Format-MeasureCommand { 3 | <# 4 | .Synopsis 5 | Improves readability of multiple 'measure-command's 6 | 7 | .Description 8 | 9 | todo: 10 | - [ ] arg as array, or hashtable arg 11 | - [ ] show speedups as relative percents of best/worst 12 | - [ ] -retry count: measure scriptblock multiple times 13 | 14 | .example 15 | PS> $results = @( 16 | measure-command { 0.. 200 }, 17 | measure-command { 0.. 200 }, 18 | measure-command { 0.. 200 }, 19 | ) 20 | Format-MeasureResults $results 21 | 22 | .example 23 | PS> Format-MeasureResults -ScriptBlock { 0..300 | sort } 24 | .example 25 | PS> $results = [ordered]@{} 26 | 27 | $results['convert csv'] = measure-command { 28 | ls | ConvertTo-Csv 29 | } 30 | 31 | $results['convert json'] = measure-command { 32 | ls | ConvertTo-Json 33 | } 34 | 35 | Format-MeasureResults $results 36 | 37 | 38 | .example 39 | ps> Format-MeasureResults $results 40 | 41 | Id TotalMs Test 42 | -- ------- ---- 43 | 3 717.9803 2**16: out: join-stri 44 | 2 516.9105 2**16: out: -join '', 45 | 1 469.9436 2**16: out: pipeline, 46 | 0 3.4769 256: Naive string-joi 47 | 4 2.3224 c 48 | 49 | #> 50 | Param([hashtable]$results) 51 | $id = 0 52 | $results.Keys | ForEach-Object { 53 | $key = $_ 54 | [pscustomobject][ordered]@{ 55 | Test = $key 56 | Ms = $results.$key.Milliseconds 57 | MsConvert = $results.$key.Milliseconds -as 'int' 58 | TotalMs = $results.$key.TotalMilliseconds 59 | Id = $id++ 60 | } 61 | } | Sort-Object TotalMs -Descending 62 | | Format-Table Id, TotalMs, Test 63 | 64 | hr 65 | } 66 | -------------------------------------------------------------------------------- /public/Format-NullText.ps1: -------------------------------------------------------------------------------- 1 |  2 | function Format-NullText { 3 | <# 4 | .synopsis 5 | format null values to be human readable 6 | .description 7 | turns $null values, and null unicode in strings 8 | #> 9 | param( 10 | # piped objects, allows null 11 | # Not actually text, but, 12 | [Parameter(Mandatory, Position = 0, ValueFromPipeline)] 13 | [AllowNull()] 14 | [object]$InputObject, 15 | 16 | # safe String to use if not the default 17 | [Parameter(Position = 1)] 18 | [string]$ReplacementString = '␀' 19 | ) 20 | begin { 21 | $Uni = @{ 22 | Null = "`u{0}" 23 | NullSymbol = '␀' 24 | } 25 | 26 | } 27 | 28 | process { 29 | # Either symbol for null, if text then replace null values 30 | if ($null -eq $InputObject) { 31 | return $Uni.NullSymbol 32 | } 33 | 34 | if ($InputObject -is 'String') { 35 | $FilteredString = $InputObject -replace $uni.Null, $uni.NullSymbol 36 | $FilteredString 37 | return 38 | } 39 | 40 | return $InputObject 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /public/Format-PrettyJson.ps1: -------------------------------------------------------------------------------- 1 | 2 | function Format-PrettyJson { 3 | <# 4 | .synopsis 5 | piping objects will convert to Json with syntax highlighting and a label 6 | .description 7 | an easy way to visualise nested arrays (or to confirm they are not flat) 8 | .example 9 | PS> 10 | $Sample = @(1, 4, @(0..2)) 11 | $Sample | Format-PrettyJson 'Nested' 12 | .notes 13 | Should it be ConvertTo-PrettyJson ? 14 | #> 15 | 16 | [Alias('PrettyJson', 'Json🎨')] 17 | param( 18 | # input array 19 | [Parameter(Mandatory, ValueFromPipeline)] 20 | [AllowNull()] 21 | [object]$InputObject, 22 | 23 | # Name / description 24 | [Parameter(Position = 0)] 25 | [string]$Name = 'Json', 26 | 27 | # Do not colorize 28 | [Parameter()][switch]$NoColor 29 | ) 30 | begin { 31 | $objList = [list[object]]::new() 32 | $useColor = $true 33 | 34 | try { 35 | Get-NativeCommand pygmentize -ea Stop | Out-Null 36 | } catch { 37 | $useColor = $false 38 | } 39 | } 40 | process { 41 | $objList.Add( $InputObject ) 42 | } 43 | end { 44 | if (! $useColor) { 45 | $objList | ConvertTo-Json | Label $Name 46 | return 47 | } 48 | 49 | $objList | ConvertTo-Json 50 | | Join-String -sep "`n" # required for pygment 51 | # | pygmentize.exe -l json # update to use get-native 52 | | pygmentize.exe -l json # update to use get-native 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /public/FormatData/BuiltinTypes/nin-System.RuntimeType.Format.ps1xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | System.RuntimeType 10 | 11 | System.RuntimeType 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Left 23 | 24 | 25 | 26 | Left 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | FullName 40 | 41 | 42 | BaseType 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /public/Get-Docs.ps1: -------------------------------------------------------------------------------- 1 | function Get-Docs { 2 | throw "NYI" 3 | } -------------------------------------------------------------------------------- /public/Get-NinCommandSyntax.ps1: -------------------------------------------------------------------------------- 1 | function Get-NinCommandSyntax { 2 | <# 3 | .synopsis 4 | an easier to read version of Get-Command -Syntax 5 | .description 6 | Syntax is formatted using a regex, it does not use intraspection 7 | .notes 8 | the original was based on: 9 | 10 | .example 11 | PS> Get-NinCommandSyntax Select-String 12 | .example 13 | PS> Get-NinCommandSyntax 'ls' 14 | #> 15 | param ( 16 | # name of command 17 | [Parameter(Mandatory, Position = 0)] 18 | [string]$Name 19 | ) 20 | $cmd = (Get-Command $Name) 21 | if ( $cmd.CommandType -eq 'Alias' ) { 22 | $Name = $cmd.ResolvedCommandName 23 | } 24 | $acutalCmd = Get-Command -Syntax $Name 25 | $acutalCmd -split ' (?=\[*-)' -replace '^[\[-]', ' $0' 26 | } 27 | -------------------------------------------------------------------------------- /public/Get-NinNamedPath.ps1: -------------------------------------------------------------------------------- 1 | Write-Warning "nyi: implement: C:\Users\cppmo_000\Documents\2020\powershell\MyModules_Github\Ninmonkey.Console\public\Get-NinNamedPath.ps1" 2 | function Get-NinNamedDotfile { 3 | <# 4 | .description 5 | returns path to user specific paths and log files, to make cross-platform profile usage easier 6 | .notes 7 | the future will allow user/machine specific overrides when they vary from the default 8 | #> 9 | $DotfilePath = @{ 10 | <# 11 | (The path is the same for at least WPS5 and PS7) 12 | Join-Path $Env:APPDATA -ChildPath 'Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt' 13 | #> 14 | 'Powershell History' = (Get-PSReadLineOption).HistorySavePath 15 | 'bat' = "$Env:USERPROFILE\Documents\2020\dotfiles_git\bat\bat.config" 16 | 'ripgrep' = "$Env:USERPROFILE\Documents\2020\dotfiles_git\ripgrep\.ripgreprc" 17 | } 18 | 19 | } 20 | function Get-NinNamedPath { 21 | <# 22 | .description 23 | returns path to user specific paths and log files, to make cross-platform profile usage easier 24 | .notes 25 | the future will allow user/machine specific overrides when they vary from the default 26 | #> 27 | param() 28 | Write-Warning "Todo: Clone logic from 'Get-NinNamedDotfile'" 29 | 30 | $DotfilePath = @{ 31 | <# 32 | (The path is the same for at least WPS5 and PS7) 33 | Join-Path $Env:APPDATA -ChildPath 'Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt' 34 | #> 35 | 'Powershell History' = (Get-PSReadLineOption).HistorySavePath 36 | 37 | 38 | 39 | } 40 | 41 | } 42 | 43 | function Get-NinNamedLog { 44 | <# 45 | .description 46 | returns path to user specific paths and log files, to make cross-platform profile usage easier 47 | .notes 48 | the future will allow user/machine specific overrides when they vary from the default 49 | #> 50 | Write-Warning "Todo: Clone logic from 'Get-NinNamedDotfile'" 51 | 52 | } 53 | -------------------------------------------------------------------------------- /public/Get-StaticProperty.ps1: -------------------------------------------------------------------------------- 1 | 2 | function Get-StaticProperty { 3 | <# 4 | .synopsis 5 | **only** fetches psobject.properties. Helper function for that specific case 6 | .description 7 | sort of an internal func, sort of not. 8 | .example 9 | PS> ls . -Dir | Get-StaticProperty 10 | #> 11 | [cmdletbinding()] 12 | [alias('StaticMemberProp')] 13 | param( 14 | # NoColor 15 | [Parameter()][switch]$NoColor, 16 | 17 | # inputobject 18 | [Parameter(Mandatory, Position = 0, ValueFromPipeline)] 19 | [object]$InputObject 20 | ) 21 | process { 22 | $target = $InputObject 23 | $propNames = $target | Fm -MemberType Property -Force | ForEach-Object Name 24 | $strNull = "[`u{2400}]" 25 | if (!$NoColor) { 26 | $strNull = $strNull | New-Text -fg 'gray30' 27 | } 28 | $propNames | ForEach-Object { 29 | $propName = $_ 30 | $propVal = $target.$propName 31 | if ($null -eq $propVal) { 32 | $typeName = $strNull 33 | } 34 | else { 35 | $typeName = $propVal.GetType() | Format-TypeName 36 | } 37 | [pscustomobject]@{ 38 | TypeName = $typeName ?? '?' 39 | Name = $propName 40 | Value = $propVal ?? $strNull 41 | # ValMem = $target::$Prop ?? $strNull # Maybe redundant, at least for properties 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /public/Get-StaticProperty.visual_tests.ps1: -------------------------------------------------------------------------------- 1 | 2 | #visual test, not pester test. 3 | $NoColor = $false 4 | 5 | $sample = Get-Process | Select-Object -First 1 6 | $sample | Get-StaticProperty -NoColor:$NoColor 7 | | Sort-Object TypeName 8 | | Format-Table TypeName, Name, value -GroupBy TypeName 9 | 10 | Hr 4 11 | 12 | $sample | Get-StaticProperty -NoColor:$NoColor 13 | | Sort-Object Name 14 | | Format-Table TypeName, Name, value 15 | -------------------------------------------------------------------------------- /public/Get-TerminalName.ps1: -------------------------------------------------------------------------------- 1 | function Get-TerminalName { 2 | <# 3 | .description 4 | detect terminal type or user's config to override defaults 5 | .example 6 | 7 | PS> GezGet-TerminalName 8 | 9 | Name Value 10 | ---- ----- 11 | IsVSCode False 12 | IsWindowsTerminal True 13 | ParentName WindowsTerminal.exe 14 | .notes 15 | 16 | todo: 17 | - [ ] optional read user's profile to override guess 18 | 19 | 20 | powershell equivalent for "feature testing verses user agent sniffing" 21 | for (process.parent property) on 'WindowsPowershell' vs 'Powershell' 22 | 23 | thread: 24 | 1] 25 | $proc.psobject.Properties['Parent'] 26 | 2] 27 | if ($psSelf.PSObject.Properties.Name -contains 'Parent') { 28 | 3] 29 | # if ($PSVersionTable.PSVersion.Major -lt 6 ) { 30 | #> 31 | 32 | $psSelf = Get-Process -Id $pid 33 | 34 | if ($psSelf.PSObject.Properties.Name -contains 'Parent') { 35 | $ParentName = $psSelf.Parent.Name 36 | } else { 37 | # fallback behaviour 38 | $psCimSelf = (Get-CimInstance -Class Win32_Process -Filter "ProcessId = $Pid") 39 | $parentPid = $psCimSelf.ParentProcessId 40 | $psCimParent = (Get-CimInstance -Class Win32_Process -Filter "ProcessId = $parentPid") 41 | $ParentName = $psCimParent.ProcessName 42 | } 43 | 44 | $results = @{ 45 | IsVSCode = $ParentName -match 'Code' 46 | IsWindowsTerminal = $ParentName -match 'WindowsTerminal' 47 | ParentName = $ParentName 48 | } 49 | $results 50 | } 51 | -------------------------------------------------------------------------------- /public/Get-TimeStuff.tests.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Module @{ ModuleName = 'Pester'; ModuleVersion = '5.0' } 2 | #Requires -Version 7 3 | 4 | BeforeAll { 5 | Import-Module Ninmonkey.Console -Force 6 | Import-Module Dev.Nin -Force 7 | } 8 | 9 | Describe 'Get-TimeStuff' -Tag 'requiresDev.Nin' { 10 | It 'first' { 11 | $tslist = @( 12 | 2 | days 13 | 3 | hours 14 | ) 15 | 16 | $ts_sum = $tslist | Measure-Object TotalMilliSeconds -Sum | ForEach-Object Sum | ForEach-Object { 17 | [timespan]::new(0, 0, 0, 0, $_) 18 | } 19 | 20 | $ts_sum | Should -Be (RelativeTs 2d3h -Debug) 21 | 22 | $tslist = @( 23 | 2 | days 24 | 3 | hours 25 | ) 26 | 27 | $total_ms = $tslist | Measure-Object TotalMilliSeconds -Sum | ForEach-Object Sum 28 | 29 | $ts_sum = $total_ms | ForEach-Object { 30 | [timespan]::new(0, 0, 0, 0, $_) 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /public/Get-UnicodeInfo.ps1: -------------------------------------------------------------------------------- 1 | function Get-UnicodeInfo { 2 | <# 3 | .description 4 | Converts strings to codepoints, and display byte strings using common encodings 5 | .notes 6 | **enumerate codepoints**, not **graphemes** 7 | 'todo: add colors to default format-list' 8 | 9 | #> 10 | [Alias('Get-RuneInfo')] 11 | [CmdletBinding()] 12 | # -Basic could be a param that is faster, if operations are a bottlenetck 13 | 14 | param ( 15 | [Parameter(Mandatory, Position = 0, ValueFromPipeline)] 16 | [string[]]$Text 17 | ) 18 | 19 | begin { 20 | # 'todo: [1] props like categories, blocks, ranges [2] PSTypeName Custom View' 21 | # UnicodeCategory Enum 22 | } 23 | Process { 24 | $text.EnumerateRunes() | ForEach-Object { 25 | $Codepont = $_.Value 26 | $Rune = [char]::ConvertFromUtf32( $Codepoint ) 27 | 28 | Write-Verbose "Item: $Rune" 29 | $info = [ordered]@{ 30 | PSTypeName = 'Nin.RuneInfo' 31 | Hex = $Codepont.ToString('x').ToLower() # to: conversion should ber in view 32 | Dec = $Codepont 33 | Utf8 = ([System.Text.Encoding]::UTF8.GetBytes( $Rune ) | Format-Hex | Select-Object -exp HexBytes).tolower() 34 | Utf16LE = ([System.Text.Encoding]::Unicode.GetBytes( $Rune ) | Format-Hex | Select-Object -exp HexBytes).tolower() 35 | Utf16BE = ([System.Text.Encoding]::BigEndianUnicode.GetBytes( $Rune ) | Format-Hex | Select-Object -exp HexBytes).tolower() 36 | Utf8Length = $_.Utf8SequenceLength 37 | Utf16Length = $_.Utf16SequenceLength 38 | Rune = $Rune 39 | } 40 | return [pscustomobject]$info 41 | } 42 | } 43 | } 44 | 45 | 46 | if ($DebugTestMode) { 47 | $strList = @( 48 | '🐒' 49 | '[System.Text.StringBuilder]::new()' 50 | ) 51 | $strList | Get-RuneInfo 52 | | Format-Table * 53 | 54 | hr 1 55 | 56 | $strList | ForEach-Object { 57 | [System.Text.Encoding]::UTF8.WebName 58 | $byteStr = [System.Text.Encoding]::UTF8.GetBytes( $_ ) 59 | 60 | } 61 | # } | Join-String -sep "`n" -FormatString '0x{0:x} = {0}' -prop { $_ } 62 | } -------------------------------------------------------------------------------- /public/Import-NinModule.ps1: -------------------------------------------------------------------------------- 1 | function Import-NinModule { 2 | <# 3 | .synopsis 4 | Import -Force all my modules, one easy command. 5 | .description 6 | Maybe an option to dotsource the profile? 7 | PS> . $PROFILE.NinProfileMainEntryPoint 8 | .outputs 9 | 10 | #> 11 | [CmdletBinding(PositionalBinding = $false)] 12 | param( 13 | # List of modules, if not the default 14 | [Parameter(Position = 0)] 15 | [string[]]$ModuleNames 16 | ) 17 | 18 | begin {} 19 | process { 20 | $ModuleNames ??= @( 21 | _enumerateMyModule 22 | ) | Sort-Object -Unique 23 | 24 | $ModuleNames | Join-String -sep ', ' -SingleQuote -op 'Loading Modules: ' 25 | | Write-Debug 26 | Import-Module -Name $ModuleNames -Force -ea SilentlyContinue 27 | 28 | } 29 | end { 30 | write-warning 'the problem reloading scoping, not enumerating' 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /public/Import-NinPSReadLineKeyHandler.ps1: -------------------------------------------------------------------------------- 1 | function Import-NinPSReadLineKeyHandler { 2 | <# 3 | .synopsis 4 | opt-in to keybindings 5 | #> 6 | [Alias('Import-NinKeys')] 7 | [CmdletBinding()] 8 | param ( 9 | # docstring 10 | # [Parameter() 11 | # [TypeName]$ParameterName 12 | ) 13 | '::Import-NinPSReadLineKeyHandler => enter' | Write-Host -fg 'orange' 14 | 15 | foreach ($extension in $psreadline_extensions) { 16 | $src = Join-Path $PSScriptRoot "PSReadLine\${extension}.ps1" 17 | if (Test-Path $src) { 18 | . $src 19 | } 20 | else { 21 | Write-Error "Import failed: '$src'" 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /public/PSReadLine/ExpandAliases.ps1: -------------------------------------------------------------------------------- 1 | using namespace System.Management.Automation 2 | using namespace System.Management.Automation.Language 3 | 4 | # This example will replace any aliases on the command line with the resolved commands. 5 | $splatKeys = @{ 6 | Key = 'Alt+%' 7 | BriefDescription = 'Expands aliases' 8 | LongDescription = 'Replace all aliases with the full command' 9 | } 10 | 11 | Set-PSReadLineKeyHandler @splatKeys -ScriptBlock { 12 | param($key, $arg) 13 | 14 | $ast = $null 15 | $tokens = $null 16 | $errors = $null 17 | $cursor = $null 18 | [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$ast, [ref]$tokens, [ref]$errors, [ref]$cursor) 19 | 20 | $startAdjustment = 0 21 | foreach ($token in $tokens) { 22 | if ($token.TokenFlags -band [TokenFlags]::CommandName) { 23 | $alias = $ExecutionContext.InvokeCommand.GetCommand($token.Extent.Text, 'Alias') 24 | # edit: why did the original not compare with null on LHS ? Accident? error? 25 | if ($alias -ne $null) { 26 | $resolvedCommand = $alias.ResolvedCommandName 27 | if ($resolvedCommand -ne $null) { 28 | $extent = $token.Extent 29 | $length = $extent.EndOffset - $extent.StartOffset 30 | [Microsoft.PowerShell.PSConsoleReadLine]::Replace( 31 | $extent.StartOffset + $startAdjustment, 32 | $length, 33 | $resolvedCommand) 34 | 35 | # Our copy of the tokens won't have been updated, so we need to 36 | # adjust by the difference in length 37 | $startAdjustment += ($resolvedCommand.Length - $length) 38 | } 39 | } 40 | } 41 | } 42 | if ($ENV:NinEnableToastDebug) { 43 | New-BurntToastNotification -Text ($Tokens | Join-String -sep ' ' -SingleQuote ) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /public/PSReadLine/ParenthesizeSelection.ps1: -------------------------------------------------------------------------------- 1 | using namespace System.Management.Automation 2 | using namespace System.Management.Automation.Language 3 | 4 | # Sometimes you want to get a property of invoke a member on what you've entered so far 5 | # but you need parens to do that. This binding will help by putting parens around the current selection, 6 | # or if nothing is selected, the whole line. 7 | Set-PSReadLineKeyHandler -Key 'Alt+(' ` 8 | -BriefDescription ParenthesizeSelection ` 9 | -LongDescription 'Put parenthesis around the selection or entire line and move the cursor to after the closing parenthesis' ` 10 | -ScriptBlock { 11 | param($key, $arg) 12 | 13 | $selectionStart = $null 14 | $selectionLength = $null 15 | [Microsoft.PowerShell.PSConsoleReadLine]::GetSelectionState( 16 | [ref]$selectionStart, [ref]$selectionLength 17 | ) 18 | 19 | $line = $null 20 | $cursor = $null 21 | [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState( 22 | [ref]$line, [ref]$cursor 23 | ) 24 | 25 | if ($selectionStart -ne -1) { 26 | [Microsoft.PowerShell.PSConsoleReadLine]::Replace( 27 | $selectionStart, $selectionLength, 28 | '(' + $line.SubString($selectionStart, $selectionLength) + ')' 29 | ) 30 | [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition( 31 | $selectionStart + $selectionLength + 2 32 | ) 33 | } 34 | else { 35 | [Microsoft.PowerShell.PSConsoleReadLine]::Replace( 36 | 0, $line.Length, '(' + $line + ')' 37 | ) 38 | [Microsoft.PowerShell.PSConsoleReadLine]::EndOfLine() 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /public/PSReadLine/native-dotnet-completer.ps1: -------------------------------------------------------------------------------- 1 | <# from the docs #> 2 | # warning: not working correctly from auto import 3 | # manual pasting does. 4 | $scriptblock = { 5 | param($wordToComplete, $commandAst, $cursorPosition) 6 | dotnet complete --position $cursorPosition $commandAst.ToString() | ForEach-Object { 7 | [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) 8 | } 9 | } 10 | Register-ArgumentCompleter -Native -CommandName dotnet -ScriptBlock $scriptblock 11 | -------------------------------------------------------------------------------- /public/Set-NinLocation.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | Import-Module Ninmonkey.Console -Force 3 | } 4 | 5 | Describe 'Set-NinLocation' { 6 | It 'From $Profile' { 7 | Push-Location -StackName 'pest.nin' 8 | $Expected = (Get-Item $PROFILE).Directory.FullName 9 | $profile | Goto 10 | Get-Item . | ForEach-Object FullName | Should -Be $Expected 11 | Pop-Location -StackName 'pest.nin' 12 | } 13 | It 'From [IO.FileSystemInfo]' { 14 | Push-Location -StackName 'pest.nin' 15 | $Somefile = Get-Item .. -file | Select-Object -First 1 16 | 17 | $somefile | Goto 18 | 19 | Get-Location | ForEach-Object tostring 20 | | Should -Be $Somefile.Directory 21 | 22 | Pop-Location -StackName 'pest.nin' 23 | } 24 | # ($PROFILE | Split-Path -Parent) | Should -be (gi . | % fullname) 25 | 26 | } -------------------------------------------------------------------------------- /public/Sort-Hashtable.ps1: -------------------------------------------------------------------------------- 1 | function Sort-Hashtable { 2 | <# 3 | .synopsis 4 | return a new, sorted hash using Keys or Values 5 | .description 6 | basic hash sortingwrapper for re-use 7 | .example 8 | PS> # examples: 9 | $hash1 = @{ name = 'Jack'; species = 'Cat'; age = 12 } 10 | 11 | Sort-Hashtable $hash1 Key 12 | 13 | $hash1 | Sort-Hashtable -Descending 14 | $hash1 | Sort-Hashtable Value 15 | $hash1 | Sort-Hashtable Value -Descending 16 | .notes 17 | Does it ever make sense to return enumeration, not a non-ordered-hashtable ? 18 | 19 | see also: 20 | 21 | - [about_Hashtables](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_hash_tables) 22 | #> 23 | [CmdletBinding(DefaultParameterSetName = 'FromParam')] 24 | param ( 25 | # Hashtable to sort 26 | [Parameter(ParameterSetName = 'FromParam', Mandatory, Position = 0)] 27 | [Parameter(ParameterSetName = 'FromPipe', Mandatory, ValueFromPipeline)] 28 | [hashtable]$InputHash, 29 | 30 | # Sort by key or value? 31 | [Parameter(ParameterSetName = 'FromParam', Position = 1)] 32 | [Parameter(ParameterSetName = 'FromPipe', Position = 0)] 33 | [ValidateSet('Key', 'Value')] 34 | [String]$SortBy = 'Key', 35 | 36 | # Sort by Descending? 37 | [Parameter()][switch]$Descending 38 | 39 | # would it ever 40 | # [Parameter(HelpMessage = "return hash or ordered hash?")][switch]$NotOrdered 41 | # ? 42 | ) 43 | begin {} 44 | Process { 45 | $OrderedHash = [ordered]@{} 46 | 47 | $splatSort = @{ 48 | Descending = $Descending 49 | Property = $SortBy 50 | } 51 | 52 | $InputHash.GetEnumerator() | Sort-Object @splatSort 53 | | ForEach-Object { 54 | $OrderedHash.Add( $_.Key, $_.Value ) 55 | } 56 | $OrderedHash 57 | } 58 | end {} 59 | } 60 | -------------------------------------------------------------------------------- /public/Test-NullArg.ps1: -------------------------------------------------------------------------------- 1 |  2 | function Test-NullArg { 3 | <# 4 | .synopsis 5 | test if args are actually null 6 | .example 7 | PS> 10, '', " ", 0, $null, "`u{0}" | Test-NullArg | Format-Table 8 | #> 9 | param( 10 | [Parameter( 11 | Mandatory, Position = 0, 12 | ValueFromPipeline)] 13 | [AllowNull()] 14 | [object]$InputObject # Not actually text, but, 15 | ) 16 | begin { 17 | # finish mini pass over 18 | } 19 | 20 | process { 21 | $test_isTrue = $true -eq $InputObject 22 | $test_isFalse = $false -eq $InputObject 23 | 24 | 25 | $objIsNull = $null -eq $InputObject 26 | $meta = [ordered]@{ 27 | Value = $objIsNull ? '␀' : $InputObject # ␀ 28 | Type = $objIsNull ? '[Null]' : $InputObject.GetType().Name # ␀ 29 | IsNull = $null -eq $InputObject 30 | IsNullOrWhiteSpace = [string]::IsNullOrWhiteSpace( $InputObject ) 31 | IsNullOrEmpty = [string]::IsNullOrEmpty( $InputObject ) 32 | IsTrue = $test_isTrue 33 | IsFalse = $test_isFalse 34 | TrueFalse_AreOpposite = (! $test_isTrue) -eq $test_isFalse 35 | AsString = "'$InputObject'" 36 | ToString = $objIsNull ? '␀' : $InputObject.ToString() | Join-String -SingleQuote 37 | CastString = [string]$InputObject | Join-String -SingleQuote 38 | TestId = $i++ 39 | IsNullCodepoint = $objIsNull ? $false : "`u{0}" -eq $InputObject 40 | } 41 | 42 | <# 43 | strip control chars from all outputs to make it safe to print 44 | #> 45 | $meta.keys.clone() | ForEach-Object { 46 | $curKey = $_ 47 | if ( $meta[$curKey] -is 'String') { 48 | $meta[$curKey] = $meta[$curKey] | Format-ControlChar 49 | Write-Verbose "Value is a 'string' for $curKey" 50 | } 51 | } 52 | 53 | [pscustomobject]$Meta 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /public/Test-NullArg.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | Import-Module Ninmonkey.Console -Force 3 | } 4 | # $sc = { 5 | $sample = @( 6 | 40 7 | 'a' 8 | @(), 9 | , @(), 10 | 'aa' 11 | $null 12 | (, $null) 13 | '' 14 | ' ' 15 | 10, '', ' ', 0, $null, "`u{0}" 16 | ) 17 | # } 18 | 19 | $sample | ForEach-Object { 20 | $cur = $_ 21 | # $cuR ??= '$null' 22 | h1 'step' 23 | $cur | Format-Typename -WithBrackets | Write-Color pink | str prefix 'item: ' 24 | # $cur | Join-String -DoubleQuote | str prefix 'value: ' 25 | Test-NullArg -InputObject $cur 26 | 27 | 28 | } 29 | 30 | 31 | return 32 | 33 | # | Test-NullArg | Format-Table 34 | 35 | $sc | iterProp | Sort-Object MemberType, Name 36 | | Format-List Name, Value, TypeNameOfValue, ReflectionInfo 37 | 38 | h1 'part1' 39 | $scNew = $sc | iterProp | Sort-Object MemberType, Name 40 | | ForEach-Object { 41 | # ㏒ℹℹ️ 42 | $_ | Add-Member -NotePropertyName 'sTypeNameOfValue' -NotePropertyValue $($_ | Format-Typename -WithBrackets) -PassThru 43 | # $_.sTypeNameOfValue = $_ | Format-TypeName 44 | } | s Name, Value, sTypeNameOfValue 45 | 46 | h1 'part3' 47 | #| Format-List Name, Value, sTypeNameOfValue, TypeNameOfValue, ReflectionInfo 48 | 49 | hr 50 | $scNew 51 | | s #-ExcludeProperty 'TypeNameOfValue' * 52 | | s Name, Value, sTypeNameOfValue, ReflectionInfo 53 | # | s Value, sTypeNameOfValue, ReflectionInfo 54 | # $scNew | s Name, Value, sTypeNameOfValue 55 | | Format-List * 56 | 57 | 58 | h1 'part2' 59 | $scNew = $sc | iterProp | Sort-Object MemberType, Name 60 | | ForEach-Object { 61 | # ㏒ℹℹ️ 62 | $_ | Add-Member -NotePropertyName 'sTypeNameOfValue' -NotePropertyValue $($_ | Format-Typename -WithBrackets) -PassThru 63 | 64 | '{0}{1} 65 | {2} 66 | ' -f @( 67 | $_.sTypeNameOfValue | Write-Color gray80 68 | $_.Name 69 | $_.value 70 | ) 71 | # $_.sTypeNameOfValue = $_ | Format-TypeName 72 | } #| s Name, Value, sTypeNameOfValue 73 | -------------------------------------------------------------------------------- /public/Test-UserIsAdmin.ps1: -------------------------------------------------------------------------------- 1 | function Test-UserIsAdmin { 2 | <# 3 | .synopsis 4 | test if the current user in role: [Security.Principal.WindowsBuiltInRole]::Administrator 5 | .example 6 | PS> Test-UserIsAdmin 7 | #> 8 | $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) 9 | $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) 10 | } -------------------------------------------------------------------------------- /public/Write-ConsoleNewline.ps1: -------------------------------------------------------------------------------- 1 | function Write-ConsoleNewline { 2 | <# 3 | .synopsis 4 | minimal function to return variable numbers of newlines 5 | #> 6 | [Alias( 7 | 'Write.Br', 8 | 'Write.NL', # I don't want to collide NL, that's a step too far 9 | 'LF' 10 | )] 11 | param ( 12 | # how many lines? 13 | [Parameter(Position = 0)] 14 | [int]$Count = 1 15 | ) 16 | $Count-- # because '0' still returns a string which implicitly can write a line 17 | 18 | if ($Count -lt 0) { 19 | return 20 | } 21 | ("`n" * $Count) -join '' 22 | } 23 | 24 | if ($false) { 25 | Write-Warning '
todo: move to dynamic pester testing' 26 | & { 27 | 0..4 | ForEach-Object { 28 | $res = Br $_ 29 | [ordered]@{ 30 | # Id = $_ 31 | Count = $res.Count 32 | Length = $res.length 33 | } 34 | | Format-HashTable -Title $_ SingleLine 35 | 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /public/Write-ConsoleText.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | # Import-Module Ninmonkey.console -Force 3 | . $PSCommandPath.Replace('.Tests.ps1', '.ps1') 4 | $ErrorActionPreference = 'Break' 5 | } 6 | 7 | Describe 'Write-ConsoleText' -Tag 'ConvertTo' { 8 | It 'Text -Foreground as Hex Color #feaabb' { 9 | Write-ConsoleText 'foo' -fg '#feaabb' 10 | | ForEach-Object tostring 11 | | Should -Be 'foo' -Because 'Ansi Escaped FG Color #feaabb' 12 | } 13 | It 'Text -Foreground as Named Color "blue"' { 14 | $Expected = 'foo' 15 | Write-ConsoleText 'foo' -fg 'blue' 16 | | ForEach-Object tostring 17 | | Should -Be $Expected -Because 'Ansi Escaped FG Color "blue"' 18 | } 19 | 20 | Context 'Text with -Foreground' { 21 | It 'Text -Foreground ( )' -ForEach @( 22 | @{ Text = 'foo'; Fg = '#feaabb'; Expected = 'foo' } 23 | @{ Text = 'foo'; Fg = 'blue'; Expected = 'foo' } 24 | 25 | ) { 26 | Write-ConsoleText -Object $Text -ForegroundColor $fg 27 | } 28 | } 29 | } 30 | # It 'Joining Basic Text' { 31 | # $expected = ' 32 | # foo 33 | # cat 34 | # ' 35 | # @( 36 | # Write-ConsoleText 'foo' -fg '#feaabb' 37 | # Write-consoleText 'cat' -fg 'blue' 38 | # ) | ForEach-Object tostring 39 | # | Should -Be $expected -Because 'AnsiEscape merged by defaults' 40 | # } 41 | -------------------------------------------------------------------------------- /public/alias/SeeminglySci.ps1: -------------------------------------------------------------------------------- 1 | # (Recommended items are referenced in some way in this profile) 2 | # Recommend modules: 3 | # - ClassExplorer 4 | # - ImpliedReflection 5 | # - EditorServicesCommandSuite 6 | # - InvokeBuild 7 | 8 | # Recommended choco packages: 9 | # - dnSpy 10 | # - bat 11 | # - Neovim 12 | 13 | $alias:w = 'Where-Object' 14 | $alias:f = 'ForEach-Object' 15 | $alias:s = 'Select-Object' 16 | $alias:m = 'Measure-Object' 17 | $alias:a = 'Get-Assembly' 18 | $alias:n = 'New-Object' 19 | $alias:new = 'New-Object' 20 | $alias:ib = 'Invoke-Build' 21 | $alias:apm = 'Add-PrivateMember' 22 | $alias:fit = 'Find-Type' 23 | $alias:fime = 'Find-Member' 24 | $alias:fins = 'Find-Namespace' 25 | $alias:gpa = 'Get-Parameter' 26 | $alias:os = 'Out-String' 27 | $alias:string = 'Out-String' 28 | $alias:vim = 'nvim.exe' 29 | ${alias:vim.exe} = 'nvim.exe' 30 | 31 | # Aliases from Utility.psm1 32 | # number = ConvertTo-Number 33 | # base, base64 = ConvertTo-Base64String 34 | # hex = ConvertTo-HexString 35 | # char = ConvertTo-Char 36 | # convert = Convert-Object 37 | # bits = ConvertTo-BitString 38 | # first, top = Select-FirstObject 39 | # last = Select-LastObject 40 | # at = Select-ObjectIndex 41 | # skip = Skip-Object 42 | # default = Get-TypeDefaultValue 43 | # nameof = Get-ElementName 44 | # cast = ConvertTo-Array 45 | # append = Join-After 46 | # prepend = Join-Before 47 | # e = Get-BaseException 48 | # se = Show-Exception 49 | # show = Show-FullObject 50 | # tostring = ConvertTo-String 51 | # await = Wait-AsyncResult 52 | # ?? = Invoke-Conditional 53 | # code = Invoke-VSCode 54 | # ishim = Install-Shim 55 | # p = Set-AndPass 56 | # up = Start-ElevatedSession 57 | # sms = Show-MemberSource 58 | # emi = Expand-MemberInfo 59 | # pslambda = Invoke-PSLambda 60 | -------------------------------------------------------------------------------- /public/completer/Readme.completer.md: -------------------------------------------------------------------------------- 1 | # Completers / Autocomplete in Powershell 2 | 3 | ## docs 4 | 5 | ## References 6 | 7 | - [NewProxyTabExpansion2](https://github.com/SeeminglyScience/dotfiles/blob/c4fa75ceddbdb5d9b6d16b90428969cc1c37fbe7/PowerShell/NamespaceAwareCompletion.ps1#L1) 8 | - [CommandCompletion/CompletionResult.cs](https://github.com/PowerShell/PowerShell/blob/9212aac0fa020b657454ef4f9ff2fdd6fc6d759c/src/System.Management.Automation/engine/CommandCompletion/CompletionResult.cs#L198) 9 | -------------------------------------------------------------------------------- /public/data/unicode_docs.ps1: -------------------------------------------------------------------------------- 1 | $_unicode_docs = @{ 2 | Main = 'https://docs.microsoft.com/en-us/dotnet/standard/base-types/character-encoding-introduction' 3 | 4 | # counts [char]s, [rune]s, and [textElement] graphemes 5 | Counting_GraphemeRuneChar = 'https://docs.microsoft.com/en-us/dotnet/standard/base-types/character-encoding-introduction#grapheme-clusters' 6 | 7 | Surrogate_Pairs = 'https://docs.microsoft.com/en-us/dotnet/standard/base-types/character-encoding-introduction#surrogate-pairs' 8 | 9 | About_Rune = 'https://docs.microsoft.com/en-us/dotnet/api/system.text.rune?view=net-5.0' 10 | 11 | About_ControlCodes = 'https://en.wikipedia.org/wiki/C0_and_C1_control_codes' 12 | 13 | Unsorted_Docs = @{ 14 | StringInfo = 'https://docs.microsoft.com/en-us/dotnet/api/system.globalization.stringinfo?view=net-5.0' 15 | 16 | TextElement = 'https://docs.microsoft.com/en-us/dotnet/api/system.globalization.stringinfo.gettextelementenumerator?view=net-5.0' 17 | 18 | 'StringInfo.GetTextElementEnumerator' = 'https://docs.microsoft.com/en-us/dotnet/api/system.globalization.stringinfo.gettextelementenumerator?view=net-5.0' 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /public/data/unicode_metadata.ps1: -------------------------------------------------------------------------------- 1 |  2 | # missing (utfbom/non-bom and pwsh specific) 3 | 4 | 5 | <# 6 | this is not to replace unicode data and code ranges, 7 | rather to suppliment or summarize important info 8 | #> 9 | $_unicode_metadata = @{ 10 | Docs = @{ 11 | } 12 | 'MaxValue' = 0x10ffff 13 | 14 | 'Ranges' = @{ 15 | 'C0 Control Codes' = @{ 16 | First = 0x00 17 | Last = 0x1f 18 | } 19 | 'C1 Control Codes' = @{ 20 | First = 0x80 21 | Last = 0x9f 22 | } 23 | 'C0 Control Char Symbols' = @{ 24 | First = 0x2400 25 | # technically space isn't control, but the symbol exists 26 | #0x241f 27 | Last = 0x2f20 28 | } 29 | 30 | 'SurrogatePairs' = @{ 31 | First = 0xD800 32 | Last = 0xDFFF 33 | } 34 | } 35 | 36 | 'Named_Codepoint' = @{ 37 | 'Null' = 0x00 38 | 'Delete' = 0x1f 39 | 'Control Char Symbol' = @{ 40 | 'Null' = 0x2400 41 | 'Delete' = 0x2421 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /public/data/unicode_web_query.ps1: -------------------------------------------------------------------------------- 1 |  2 | $_unicode_web_query = @{ 3 | 4 | 'Fileformat.info' = @{ 5 | # ex: 2400 6 | 'Codepoint' = 'https://www.fileformat.info/info/unicode/char/{{codepoint_hex}}/index.htm' 7 | 8 | # ex: 'Cc' and 'index' 9 | # 'https://www.fileformat.info/info/unicode/category/Cc/index.htm' 10 | 'Category_Index' = 'https://www.fileformat.info/info/unicode/category/{{category}}/list.htm' 11 | 12 | # ex: 'Cc' and 'index' 13 | # 'https://www.fileformat.info/info/unicode/category/Cc/list.htm' } 14 | 'Category2_List' = 'https://www.fileformat.info/info/unicode/category/{{category}}/list.htm' 15 | } 16 | } -------------------------------------------------------------------------------- /public/native_wrapper/Invoke-RipGrepChildItem.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | see integration with 'Fzf' 3 | https://github.com/junegunn/fzf#3-interactive-ripgrep-integration> 4 | #> 5 | -------------------------------------------------------------------------------- /public/seeminglySci/Get-ElementName.ps1: -------------------------------------------------------------------------------- 1 | 2 | function Get-ElementName { 3 | <# 4 | .synopsis 5 | originally from: 6 | .notes 7 | currently the same, separate same. separate for dependency clarity 8 | .example 9 | # For more see: 10 | <./test/public/ConvertTo-Base64String.ps1> 11 | #> 12 | [Alias('NameOf')] 13 | [CmdletBinding()] 14 | param( 15 | [Parameter(Position = 0, Mandatory)] 16 | [ValidateNotNull()] 17 | [ScriptBlock] $Expression 18 | ) 19 | end { 20 | if ($Expression.Ast.EndBlock.Statements.Count -eq 0) { 21 | return 22 | } 23 | 24 | $firstElement = $Expression.Ast.EndBlock.Statements[0].PipelineElements[0] 25 | if ($firstElement.Expression.VariablePath.UserPath) { 26 | return $firstElement.Expression.VariablePath.UserPath 27 | } 28 | 29 | if ($firstElement.Expression.Member) { 30 | return $firstElement.Expression.Member.SafeGetValue() 31 | } 32 | 33 | if ($firstElement.GetCommandName) { 34 | return $firstElement.GetCommandName() 35 | } 36 | 37 | if ($firstElement.Expression.TypeName.FullName) { 38 | return $firstElement.Expression.TypeName.FullName 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /public/seeminglySci/import_nin_sci.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninmonkey/Ninmonkey.Console/58bf5625e56fb178e5870a4d3bb06d112b39b458/public/seeminglySci/import_nin_sci.ps1 -------------------------------------------------------------------------------- /public_autoloader/Add-ConsoleEnvVarPath.tests.ps1: -------------------------------------------------------------------------------- 1 | #requires -modules @{ModuleName='Pester';ModuleVersion='5.0.0'} 2 | $SCRIPT:__PesterFunctionName = $myinvocation.MyCommand.Name.split('.')[0] 3 | BeforeAll { 4 | # Import-Module Ninmonkey.Console -Force 5 | } 6 | 7 | Describe "$__PesterFunctionName" -Tag Unit { 8 | BeforeAll { 9 | Import-Module Ninmonkey.Console -Force 10 | # . $(Get-ChildItem -Path $PSScriptRoot/.. -Recurse -Filter "$__PesterFunctionName.ps1") 11 | # $Mocks = Resolve-Path "$PSScriptRoot/Mocks" 12 | $ErrorActionPreference = 'Stop' 13 | } 14 | It 'Runs without error' { 15 | # . $__PesterFunctionName 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /public_autoloader/Ansi-Write-RandomColorEscape.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 7 2 | 3 | if ( $publicToExport ) { 4 | $publicToExport.function += @( 5 | '_randColorEscape' 6 | ) 7 | $publicToExport.alias += @( 8 | 9 | ) 10 | } 11 | 12 | 13 | function _randColorEscape { 14 | # return either color or rendered escape 15 | [outputType( 16 | 'PoshCode.Pansies.RgbColor', 17 | 'system.string' 18 | )] 19 | param( 20 | # render includes rand FG 21 | [Alias('Fg')] 22 | [switch]$Foreground, 23 | 24 | # render includes rand BG 25 | [Alias('Bg')] 26 | [switch]$Background, 27 | 28 | # returns meta 29 | [switch]$PassTru 30 | ) 31 | 32 | $cfg = 0..255 | Get-Random -Count 3 33 | $cbg = 0..255 | Get-Random -Count 3 34 | 35 | $pansies = [rgbcolor]::FromRgb($cfg[0], $cfg[1], $cfg[2]) 36 | $render_fg = $PSStyle.Foreground.FromRgb( $cfg[0], $cfg[1], $Cfg[2]) 37 | $render_bg = $PSStyle.Background.FromRgb( $cbg[0], $cbg[1], $Cbg[2]) 38 | if (! $Foreground ) { 39 | $render_fg = '' 40 | } 41 | if (! $Background) { 42 | $render_bg = '' 43 | } 44 | 45 | $render_all = $render_fg + $render_bg 46 | 47 | $meta = @{ 48 | RandColors = $c 49 | RgbColor = $pansies 50 | FgColor = $render_fg 51 | BgColor = $render_bg 52 | AllColor = $render_all 53 | # FgColor = $Foreground ? $render_fg : '' 54 | # BgColor = $Background ? $render_bg : '' 55 | } 56 | if ($PassTru) { 57 | return [pscustomobject]$meta 58 | } 59 | return $render_all 60 | } 61 | 62 | -------------------------------------------------------------------------------- /public_autoloader/Assert-CommandType.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | Import-Module Ninmonkey.Profile -Force 3 | } 4 | 5 | Describe 'Assert-CommandType' { 6 | It 'hardcoded' { 7 | Get-Command Microsoft.PowerShell.Core\Get-Command 8 | $false | Should -Be $True 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /public_autoloader/Assert-HashTableEqual.tests.ps1: -------------------------------------------------------------------------------- 1 | using namespace System.Collections.Generic 2 | 3 | BeforeAll { 4 | # . "$PSScriptRoot/Assert-HashtableEqual.ps1" 5 | Import-Module Ninmonkey.Console -Force 6 | $ErrorActionPreference = 'Break' 7 | } 8 | 9 | 10 | Describe 'Assert-HashtableEqual' { 11 | 12 | BeforeAll { 13 | # $false | Should -Be $True -Because 'NYI' 14 | } 15 | 16 | Describe 'CaseSensitivity' { 17 | Context 'Insensitive' { 18 | BeforeAll { 19 | $h1 = @{ 'species' = 'dog' ; 'lives' = 1 } 20 | $h2 = @{ 'lives' = 1; 'Species' = 'dog' } 21 | $h2_lower = @{ 'lives' = 1; 'species' = 'dog' } 22 | $h_extraKeys = $h1 + @{ 'Extra' = 'Something' } 23 | } 24 | It 'Basic' { 25 | Assert-HashtableEqual @{'a' = 3 } @{'A' = 9 } 26 | | Should -Be $true 27 | } 28 | 29 | It 'Equal Keys' { 30 | Assert-HashtableEqual $h1 $h2 | Should -Be $True 31 | Assert-HashtableEqual $h1 $h2_lower | Should -Be $True 32 | } 33 | It 'Extra Values' { 34 | Assert-HashtableEqual $h1 $h_extraKeys | Should -Be $False 35 | } 36 | } 37 | Context 'Sensitive' { 38 | 39 | } 40 | 41 | } 42 | } -------------------------------------------------------------------------------- /public_autoloader/Assert-HashtableEqual.ps1: -------------------------------------------------------------------------------- 1 | using namespace System.Management.Automation 2 | $script:publicToExport.function += @( 3 | 'Assert-HashtableEqual' 4 | ) 5 | # $script:publicToExport.alias += @() 6 | 7 | 8 | function Assert-HashtableEqual { 9 | <# 10 | .synopsis 11 | Do two hashtables have the same number of keys, and the same names? 12 | .description 13 | This does not test values other than type compatability 14 | 15 | see also: 16 | Assert\Assert-All 17 | Assert\Assert-Contain 18 | .notes 19 | future: 20 | - [ ] extract function to not require lib 21 | - [ ] case-sensitive comparison 22 | - [ ] whether values are the same datattype 23 | #> 24 | [OutputType([bool])] 25 | [CmdletBinding()] 26 | param( 27 | # Left side 28 | [Alias('Hash1')] 29 | [parameter(Mandatory, Position = 0)] 30 | [hashtable]$InputHash, 31 | 32 | # Right Side 33 | [Alias('Hash2')] 34 | [parameter(Mandatory, Position = 1)] 35 | [hashtable]$OtherHash 36 | 37 | # Force Case Sensitivity 38 | # [Switch]$CaseSensitive 39 | ) 40 | end { 41 | $hash1 = [HashSet[string]]::new( 42 | [string[]]($InputHash.Keys), 43 | [System.StringComparer]::OrdinalIgnoreCase 44 | ) 45 | $hash2 = [HashSet[string]]::new( 46 | [string[]]($OtherHash.Keys), 47 | [System.StringComparer]::OrdinalIgnoreCase 48 | ) 49 | $hash1 | Join-String -sep ', ' -op 'set1: ' | Write-Debug 50 | $hash2 | Join-String -sep ', ' -op 'set2: ' | Write-Debug 51 | 52 | $AreEqual = $hash1.SetEquals( $hash2 ) 53 | Write-Debug "Result: $AreEqual" 54 | if (! $AreEqual ) { 55 | $false; return 56 | # I'm not sure if I want to throw 57 | # Write-Error -ea Stop -Message 'Keys do not match' -Category InvalidData -ErrorId 'HashtableEqualKeys' -TargetObject @( 58 | # $hash1 59 | # $hash2 60 | # ) 61 | } 62 | 63 | 64 | $true ; return 65 | } 66 | } -------------------------------------------------------------------------------- /public_autoloader/ConvertFrom-Base64String.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 7 2 | using namespace System.Text 3 | 4 | $script:publicToExport.function += @( 5 | 'ConvertFrom-Base64String' 6 | ) 7 | $script:publicToExport.alias += @( 8 | 'From->Base64' 9 | ) 10 | 11 | 12 | 13 | # todo 14 | function ConvertFrom-Base64String { 15 | <# 16 | .synopsis 17 | originally from: 18 | .notes 19 | currently the same, separate same. separate for dependency clarity 20 | .example 21 | # For more see: 22 | <./test/public/ConvertFrom-Base64String.tests.ps1> 23 | .link 24 | Utility\ConvertFrom-Base64String 25 | #> 26 | [Alias('From->Base64')] 27 | [OutputType([System.String])] 28 | [CmdletBinding(PositionalBinding = $false)] 29 | param( 30 | [Parameter(ValueFromPipeline, Position = 0)] 31 | [AllowEmptyString()] 32 | [AllowNull()] 33 | [string] $InputObject, 34 | 35 | [Parameter()] 36 | [ArgumentCompleter([EncodingArgumentCompleter])] 37 | [EncodingArgumentConverter()] 38 | [Encoding] $Encoding 39 | ) 40 | begin { 41 | if ($PSBoundParameters.ContainsKey((nameof { $Encoding }))) { 42 | $userEncoding = $Encoding 43 | return 44 | } 45 | 46 | $userEncoding = [System.Text.Encoding]::UTF8 47 | #used to be: [Encoding]::Unicode # ut8 48 | } 49 | process { 50 | if ([string]::IsNullOrEmpty($InputObject)) { 51 | return 52 | } 53 | 54 | Write-Warning "finish function: '$PSCommandPath' " 55 | $decoded_bytes = [convert]::FromBase64String($InputObject) 56 | return $userEncoding.GetString( $decoded_bytes ) 57 | return 58 | 59 | # see: $userEncoding.GetString | fm * -Force | Get-Parameter -ea Ignore | ft -AutoSize 60 | 61 | $byteStr = [convert]::FromBase64String($b64) 62 | [System.Text.UTF8Encoding]::UTF8.GetString( $byteStr ) 63 | $userEncoding.GetString( 64 | <# bytes: #> $byteStr) 65 | 66 | $userEncoding.GetString( 67 | $InputObject 68 | ) 69 | 70 | Write-Warning "finish function: '$PSCommandPath' " 71 | return 72 | return [convert]::ToBase64String($userEncoding.GetBytes($InputObject)) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /public_autoloader/ConvertFrom-NumberedFilepath.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | Import-Module Ninmonkey.Console -Force 3 | } 4 | 5 | Describe 'ConvertFrom-NumberedFilepath' -Skip { 6 | It 'Does not throw' { 7 | { 'adsfs' | ConvertFrom-NumberedFilepath } 8 | | Should -Not -Throw 9 | } 10 | 11 | Describe 'Format -As [VSCodeFilepath]' { 12 | It 'Text: Valid filepath' { 13 | Set-ItResult -Pending -Because 'needs to be created/merged / nyi' 14 | # '...' | Should -BeOfType ([VSCodeFilepath]) 15 | } 16 | # $result = 17 | } 18 | 19 | Describe 'AnsiEscapes' { 20 | It 'FromRipGrep' { 21 | Set-ItResult -Skipped -Because 'add handling piping from RipGrep using StripAnsi()' 22 | } 23 | } 24 | 25 | It 'DefaultArgs: "" = ""' -ForEach @( 26 | @{ 27 | Text = 'foo:bar:cat.ps1:345:4' 28 | Expected = 'foo:bar:cat.ps1' 29 | } 30 | @{ 31 | Text = 'foo:bar:cat.ps1:345' 32 | Expected = 'foo:bar:cat.ps1' 33 | } 34 | @{ 35 | Text = 'foo:bar:cat.ps1' 36 | Expected = 'foo:bar:cat.ps1' 37 | } 38 | ) { 39 | $Text | ConvertFrom-NumberedFilepath -StripLastOnly:$False 40 | | Should -Be $Expected 41 | } 42 | It 'StripLastOnly: "" = ""' -ForEach @( 43 | @{ 44 | Text = 'foo:bar:cat.PS1:345:4' 45 | Expected = 'foo:bar:cat.PS1:345' 46 | ShouldThrow = $False 47 | } 48 | @{ 49 | Text = 'foo:bar:cat.PS1:345:4' 50 | Expected = 'foo:bar:cat.PS1:345' 51 | ShouldThrow = $False 52 | } 53 | ) { 54 | if ($ShouldThrow ?? $false) { 55 | { $Text | ConvertFrom-NumberedFilepath -StripLastOnly } 56 | | Should -Throw -Because 'Invalid result' 57 | 58 | } 59 | 60 | $Text | ConvertFrom-NumberedFilepath -StripLastOnly 61 | | Should -Be $Expected 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /public_autoloader/ConvertTo-Base64String.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | Import-Module Ninmonkey.Console -Force 3 | } 4 | 5 | Describe 'ConvertToAndFrom-Base64String' { 6 | Describe 'Round Trip' { 7 | BeforeAll { 8 | $original_string = @' 9 | 0..4 10 | | Str csv sep ' ' 11 | 12 | h1 'someheader' 13 | '@ 14 | } 15 | It 'utf8' { 16 | 17 | #'future' add non-utf8 enocdings as tests 18 | $b64_str = $original_string | To->Base64 -Encoding utf8 19 | $final_string = $b64_str | From->Base64 -encoding Utf8 20 | $final_string | Should -Be $original_string -Because 'round trip of encode->decode' 21 | } 22 | It 'Utf16LE' { 23 | $original_string = @' 24 | 0..4 25 | | Str csv sep ' ' 26 | 27 | h1 'someheader' 28 | '@ 29 | $b64_str = $original_string | To->Base64 -Encoding Unicode 30 | $final_string = $b64_str | From->Base64 -encoding Unicode 31 | $final_string | Should -Be $original_string -Because 'round trip of encode->decode' 32 | 33 | } 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /public_autoloader/ConvertTo-BreadCrumb.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | Import-Module Ninmoonkey.Console -Force 3 | } 4 | 5 | 6 | # $samplePath = Get-Item .\public_autoloader\Measure-NinChildItem.ps1 7 | # ConvertTo-BreadCrumb $SamplePath 8 | # ConvertTo-BreadCrumb $SamplePath.FullName 9 | 10 | Describe 'ConvertTo-BreadCrumb' { 11 | It 'Detect DoubleBackslash' { 12 | 'foo\\bar\\cat' | ConvertTo-BreadCrumb 13 | | Should -BeExactly @('foo', 'bar', 'cat') 14 | } 15 | It 'Detect Backslash' { 16 | 'foo\bar\cat' | ConvertTo-BreadCrumb 17 | | Should -BeExactly @('foo', 'bar', 'cat') 18 | } 19 | It 'Detect Forward Slash' { 20 | 'foo/bar/cat' | ConvertTo-BreadCrumb 21 | | Should -BeExactly @('foo', 'bar', 'cat') 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /public_autoloader/ConvertTo-RegexLiteral.v1.tests.ps1: -------------------------------------------------------------------------------- 1 | #requires -modules @{ModuleName='Pester';ModuleVersion='5.0.0'} 2 | 3 | Describe 'ConvertTo-RegexLiteral.v1' -Tag Unit { 4 | BeforeAll { 5 | Import-Module Ninmonkey.Console -Force 6 | $ErrorActionPreference = 'Stop' 7 | $Sample = @{ 8 | Spaces = 'hi! # world' 9 | } 10 | } 11 | It 'Runs without error' { 12 | { ConvertTo-RegexLiteral.v1 'stuff', 'other' } 13 | | Should -Not -Throw 14 | } 15 | Describe 'Verify Patterns for Dotnet are still valid' { 16 | 17 | It 'Whether Escaped braces match - hardcoded' { 18 | ('sdjf}dfsd' -match 'sdjf\}dfsd') -and ('sdjf}dfsd' -match 'sdjf}dfsd') 19 | | Should -Be $True 20 | } 21 | It 'Whether Escaped braces match - Convert to Foreach' { 22 | # $EscapeBasic = $RawInput | ConvertTo-RegexLiteral.v1 23 | $RawInput = 'sdjf}dfsd' 24 | $EscapeBasic = $RawInput | ConvertTo-RegexLiteral.v1 25 | $EscapeVS = $RawInput | ConvertTo-RegexLiteral.v1 -AsVSCode 26 | $EscapeRg = $RawInput | ConvertTo-RegexLiteral.v1 -AsRipgrepPattern 27 | 28 | ($RawInput -match $EscapeBasic) | Should -Be $True 29 | ($RawInput -match $EscapeVS) | Should -Be $True 30 | ($RawInput -match $EscapeRg) | Should -Be $True 31 | # ('sdjf}dfsd' -match 'sdjf\}dfsd') -and ('sdjf}dfsd' -match 'sdjf}dfsd') 32 | # | Should -be $True 33 | } 34 | 35 | } 36 | It 'Whitespace for "