Skip to content

Instantly share code, notes, and snippets.

@kieronlanning
Created December 26, 2024 17:32
Show Gist options
  • Save kieronlanning/186670a08342a69c59696f1b30e1b193 to your computer and use it in GitHub Desktop.
Save kieronlanning/186670a08342a69c59696f1b30e1b193 to your computer and use it in GitHub Desktop.
Makefile auto-completer for PowerShell
function Register-MakeCompleter {
# This scriptblock is called each time tab-completion occurs for `make` or `m`
$ScriptBlock = {
param(
$wordToComplete
)
# If no Makefile exists in the current directory, return no completions
if (-not (Test-Path "./Makefile")) {
return
}
# Parse the Makefile, looking for targets and their descriptions.
# The regex looks for a line starting with a target name, followed by ':',
# and optionally a comment starting with '##'.
# Example line: "build: ## This command builds the project"
$content = Get-Content "./Makefile"
$targets = $content | ForEach-Object {
# Try capturing target and description
if ($_ -match '^\s*([A-Za-z0-9._-]+):.*?\#\#\s*(.*)$') {
[PSCustomObject]@{
Name = $matches[1]
Description = $matches[2].Trim()
}
}
elseif ($_ -match '^\s*([A-Za-z0-9._-]+):') {
# Target without a description
[PSCustomObject]@{
Name = $matches[1]
Description = ''
}
}
} #| Sort-Object Name -Unique
$maxNameLength = ($targets | ForEach-Object { $_.Name.Length } | Measure-Object -Maximum).Maximum
$blue = $PSStyle.Foreground.Blue
$bold = $PSStyle.Bold
$reset = $PSStyle.Reset # Reset color
# Filter and return the completion results
$targets | Where-Object { $_.Name -like "$wordToComplete*" } | ForEach-Object {
# Incorporate description into the display text for visibility
$paddedName = $_.Name.PadRight($maxNameLength + 2)
$displayText = if ([string]::IsNullOrWhiteSpace($_.Description)) {
$_.Name
} else {
"$($blue)$($bold)$($paddedName)$($reset)$($_.Description)"
}
# Even though we still pass the description as tooltip,
# it's mainly for completeness. The $displayText ensures
# visibility in the suggestion list.
New-Object -Type System.Management.Automation.CompletionResult -ArgumentList @(
$_.Name # completionText
$displayText # listItemText
'ParameterValue' # resultType
$displayText # toolTip
)
}
}
# I alias make as m on my pc, hence the m too.
Register-ArgumentCompleter -Native -CommandName @("make", "m") -ScriptBlock $ScriptBlock
}
# Call 'Register-MakeCompleter' in your Powershell Profile for auto-completions on your Makefiles.
# If you include a description for you target, it'll use that too:
# target: ## This target does a thing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment