dog.ps1 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. # Note: This works for both Windows PowerShell 5.1 and also PowerShell 7 (Core).
  2. # But beware that in Windows PowerShell 5.1, it has issues with completing args if they start with '-'.
  3. # For more information about the bug, see: https://github.com/PowerShell/PowerShell/issues/2912
  4. # In PowerShell 7+, it should work correctly.
  5. Register-ArgumentCompleter -Native -CommandName 'dog' -ScriptBlock {
  6. param($wordToComplete, $commandAst, $cursorPosition)
  7. [string]$argsString = $commandAst.ToString()
  8. # skip the "dog", split the args afterwards as array
  9. [string[]]$argsArray = $argsString.Split([char[]]@(' ', '=')) | Select-Object -Skip 1
  10. if ($argsArray -eq $null) { $argsArray = @() }
  11. # detect if starting a new arg (aka ending with space and asking for a completion)
  12. [bool]$isNewArg = $cursorPosition -gt $argsString.Length
  13. if ($isNewArg) {
  14. # if writing a new arg, add empty arg so that current and previous would be shifted
  15. $argsArray += ''
  16. }
  17. # get current arg (empty if starting new)
  18. [string]$currentArg = $argsArray[-1]
  19. if ([string]::IsNullOrEmpty($currentArg)) {
  20. $currentArg = ''
  21. }
  22. # get previous arg
  23. [string]$previousArg = $argsArray[-2]
  24. if ([string]::IsNullOrEmpty($previousArg)) {
  25. $previousArg = ''
  26. }
  27. [string[]]$dnsTypeValues = @('A', 'AAAA', 'CAA', 'CNAME', 'HINFO', 'MX', 'NS', 'PTR', 'SOA', 'SRV', 'TXT')
  28. [string[]]$completions = @()
  29. [bool]$isOptionValue = $argsString.EndsWith('=')
  30. # complete option value
  31. switch -Regex ($previousArg) {
  32. '^(-q|--query)' { $isOptionValue = $true }
  33. '^(-t|--type)' { $isOptionValue = $true; $completions += $dnsTypeValues }
  34. '^(-n|--nameserver)' { $isOptionValue = $true }
  35. '^(--class)' { $isOptionValue = $true; $completions += @('IN', 'CH', 'HS') }
  36. '^(--edns)' { $isOptionValue = $true; $completions += @('disable', 'hide', 'show') }
  37. '^(--txid)' { $isOptionValue = $true }
  38. '^(-Z)' { $isOptionValue = $true; $completions += @('aa', 'ad', 'bufsize=', 'cd') }
  39. '^(--color|--colour)' { $isOptionValue = $true; $completions += @('always', 'automatic', 'never') }
  40. }
  41. # detect whether to complete option value
  42. if ($isOptionValue) {
  43. if (!$isNewArg) {
  44. # if using =, complete including the option name and =
  45. $completions = $completions | ForEach-Object { "$previousArg=$_" }
  46. }
  47. }
  48. else {
  49. # if not completing option value, offer DNS type values first
  50. $completions += $dnsTypeValues
  51. # complete option name
  52. [string[]]$allOptions = @(
  53. '-q', '--query',
  54. '-t', '--type',
  55. '-n', '--nameserver',
  56. '--class',
  57. '--edns',
  58. '--txid',
  59. '-Z',
  60. '-U', '--udp',
  61. '-T', '--tcp',
  62. '-S', '--tls',
  63. '-H', '--https',
  64. '-1', '--short',
  65. '-J', '--json',
  66. '--color', '--colour',
  67. '--seconds',
  68. '--time',
  69. '-?', '--help',
  70. '-v', '--version'
  71. ) | Sort-Object
  72. $completions += $allOptions
  73. }
  74. if ($completions.Count -gt 0) {
  75. # narrow down completions by like* matching
  76. return $completions -like "$currentArg*"
  77. }
  78. }