Windows 10 replaced the Command Prompt (cmd.exe) with Windows PowerShell (powershell.exe) as the default command-line interpreter (CLI). PowerShell Core (pwsh.exe) is the successor to Windows PowerShell. Until recently, I had used the Command Prompt through the Windows Terminal with the DejaVu Sans Mono font and the Solarized Dark colour scheme. What would be required to move to PowerShell Core?
Colours
Solarized provides the accent colours yellow (mapped to the terminal colour DarkYellow), orange (Red), red (DarkRed), magenta (DarkMagenta), violet (Magenta), blue (DarkBlue), cyan (DarkCyan) and green (DarkGreen).
$Host.PrivateData specifies colours for Error, Warning, Debug, Verbose and Progress (the progress bar). For example: $Host.PrivateData.ErrorForegroundColor.
I set Error red and Warning yellow (orange seemed too close to red). I set Debug green (like the colour often used for comments) and Verbose cyan. For Progress, I referenced Solarized Light and set base00 (mapped to terminal colour Yellow) on base3 (White).
Get-PSReadLineOption returns an object that can be used to specify colours for:
- a
Comment - a
Keyword - a
Commandand itsParameter - a
Member(property or method) of an object - an
Operator - a
DefaultToken - a
Type - a
Number(integer or real) - a
String(delimited by single or double quotation marks) - a
Variable - a
ContinuationPrompt Emphasisor anError.
For example: (Get-PSReadlineOption).ErrorColor = 'DarkRed'.
PowerShell comments run from # to the end of the line or are delimited by <# #>. I set them green.
The PowerShell language has a number of keywords. I set them magenta.
I set commands and members of objects yellow and their parameters violet (a colour I had not used elsewhere).
I set operators base0 (Blue), the body text in Solarized Dark.
I set default tokens blue. Default tokens include the names of functions, braces delimiting a script block ({}), the redirection operators, the grouping operator (()), the subexpression operator ($()), the array subexpression operator (@()), the cast operator ([]), the dot sourcing operator (. ), the index operator (also []), the call operator (&), the background operator (also &), the pipeline operator (|), the member access operator (.) and the static member operator (::).
I set types to yellow, as it contrasted with the colour used for the delimiting (default) tokens [].
I set numbers base01 (mapped to terminal colour Green), the secondary content in Solarized Dark, and strings orange (as close to brown).
PowerShell variable names start with $. I set them to cyan.
I set the continuation prompt to blue, emphasis to cyan (to follow my choice for Verbose) and errors to red.
The colours are set in a PowerShell script (Set-Colours.ps1), invoked in $PROFILE:
|
1 2 |
& (Join-Path -Path (Split-Path -Parent -Path $PROFILE) ` -ChildPath 'Set-Colours.ps1') |
Fonts
Windows Terminal ships with computer font Cascadia Code, a font with programming ligatures. Since version 1911.20, another version of the font, Cascadia Code PL, also includes powerline symbols (see tooling below). Font Hasklig provides powerline symbols too but its coverage of programming ligatures is more limited. I switched from DejaVu Sans Mono to Cascadia Code PL.
Tooling
The PowerShell module posh-git provides an environment for using Git on PowerShell, including Git summary status information in the PowerShell prompt.
The PowerShell module oh-my-posh builds on posh-git to provide prompt themes, making use of powerline fonts.
Aliases
PowerShell’s command names are structured (as Verb-Noun) but that structure means that frequently used commands are verbose. However, shorter aliases exist, or can be created, for such commands. For example dir (Get-Children), cd (Set-Location), copy (Copy-Item), move (Move-Item), and del or rmdir (Remove-Item).
Shortcuts
In the Command Prompt, I set environment variables to be able to change quickly to the directory for my Haskell projects or my local GitHub repositories (eg cd %Haskell%). PowerShell allowed for more powerful shortcuts. I created a module script Set-Shortcuts.psm1 that exported functions Set-Haskell and Set-GitHub:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
<# .SYNOPSIS Wraps a string or an array of strings at the console width without breaking within a word. .PARAMETER linesIn A string or an array of strings. .EXAMPLE Wrap-Item -LinesIn $string .EXAMPLE $string | Wrap-Item #> function Wrap-Item { Param( [Parameter(Mandatory = $True, ValueFromPipeline = $True)] [String[]] $linesIn ) Process { $linesOut = @() $width = $Host.UI.RawUI.BufferSize.Width ForEach ($lineIn In $linesIn) { $lineOut = '' $counter = 0 $lineIn -split '\s+' | ForEach-Object { $len = $_.Length While ($len -gt $width) { $head = $_.Substring(0, $width - $counter - 1) If ($head) { $lineOut = "$lineOut$head`u{23ce}" } $_ = $_.Substring($width - $counter - 1) $linesOut += $lineOut $lineOut = '' $counter = 0 $len = $_.Length } $counter += $len + 1 If ($counter -gt $width + 1) { $linesOut += $lineOut.trim() $lineOut = '' $counter = $_.Length + 1 } $lineOut = "$lineOut$_ " } $linesOut += $lineOut.trim() } $linesOut } } function Set-Shortcut { Param ([String]$shortcutPath, [String]$shortcutType, [String]$shortcut) If (-not $shortcut) { Set-Location $shortcutPath $True } Else { $filePath=Join-Path -Path $shortcutPath -ChildPath $shortcut If (Test-Path $filePath) { Set-Location $filePath $True } Else { Set-Location $shortcutPath (Split-Path (Get-ChildItem -Directory) -Leaf) -Join " " | Wrap-Item | ` Write-Host | Out-Null $False } } } <# .Description Set the location for GitHub repositories or an identified repository. #> function Set-GitHub { Param ([String]$repository) $gitHub='C:\Users\mikep\Documents\Code\GitHub' $gitHubType='repository' If (-not (Set-Shortcut $gitHub $gitHubType $repository)) { Write-Error "$gitHubType not found: $repository" ` -Category ObjectNotFound } } <# .Description Set the location for Haskell projects or an identified project. #> function Set-Haskell { Param ([String]$project) $haskell='C:\Users\mikep\Documents\Code\Haskell' $haskellType='project' If (-not (Set-Shortcut $haskell $haskellType $project)) { Write-Error "$haskellType not found: $project" ` -Category ObjectNotFound } } Export-ModuleMember -Function Set-Haskell, Set-GitHub |