AutoHotKey w PowerShellu

HotSpaceBarDziś nieco o lenistwie i wszelkich jego konsekwencjach. O tym, jak korzystając nieustannie z konsoli – pisać (paradoksalnie) jak najmniej. Dlaczego? Otóż wszyscy, którzy mnie znają wiedzą, że marny ze mnie pisarczyk. I nie chodzi tu o poziom moich wypocin na blogu czy w innych mediach (tu chyba mimo wszystko wychodzę obronną ręką, głównie dzięki sprawdzaniu pisowni w Wordzie i Live Writerze) – raczej o literówki, którymi strzelam na lewo i prawo w konsoli. W PowerShellu na ogół ratuje mnie tabulator, ale…

Tuż przed świętami wykupiłem kurs gita od Maćka Aniserowicza. Niby gita znam dość dobrze, ale stwierdziłem, że nie zaszkodzi wiedzę nieco uporządkować i rozszerzyć. Kurs okazał się strzałem w dziesiątkę z różnych względów, ale jednym z nich było ukłucie zazdrości, gdy zobaczyłem jak Maciek pisze „gc” a jego konsola uczynnie zamienia to na soczyste „git commit”. Od razu nabrałem przekonania, że PowerShella też powinno się dać do tego zmusić. Ale najpierw przyszły święta, potem wakacje z rodzinką i na eksperymenty zabrakło czasu. Dopiero wczoraj wieczorem mnie olśniło. Oczywiście, rozwiązanie nasuwa się samo – PSReadLine! Smile

Możliwości implementacji tego rozwiązania jest kilka. W końcu zdecydowałem się na najprostszy: odtworzenie działania AutoHotKey bez żadnych kompromisów. Chcę napisać „ad”, nacisnąć spację i zobaczyć „git add „, znak zachęty i – hulaj dusza, piekła nie ma. Listę makr ograniczyłem do kilku zaledwie poleceń, ale myślę, że każdy „dośpiewa” sobie resztę.

Zanim przedstawię sam kod, składniki:

  • tablica skrótów, w której kluczami będą nasze makra, a odpowiadające im wartości użyte będą w czasie „podmianki”
  • metoda GetBufferState pobierającą aktualną zawartość linii
  • metoda Replace, która podmieni to, co wpisałem na to, co chcę zobaczyć
  • metoda SetCursorPosition, która przesunie kursor na koniec tego, co właśnie „wkleiła” metoda uprzednia

Cały kod:

Set-PSReadlineKeyHandler -Chord Spacebar -ScriptBlock {
param ($key, $arg)
$psReadLine = [Microsoft.PowerShell.PSConsoleReadLine]
$convert = @{
'co' = 'git commit '
'ad' = 'git add '
'pu' = 'git push '
'me' = 'git merge '
}
$line = $null
$cursor = $null
$psReadLine::GetBufferState(
[ref]$line, [ref]$cursor
)
if ($convert.ContainsKey($line)) {
$psReadLine::Replace(
0,
$line.Length,
$convert.$line
)
$psReadLine::SetCursorPosition($convert.$line.Length)
} else {
$psReadLine::Insert(' ')
}
}
view raw AutoHotKey.ps1 hosted with ❤ by GitHub

Przy okazji: to nie jest pierwsze podejście do problemu: jak gitować bez pisania. Już jakiś czas temu zaimplementowałem w swoim profilu mechanizm, który sprawiał, że aliasy w gicie stawały się niemal pełnoprawnymi komendami w PowerShellu. Jak? Wykorzystując CommandNotFoundAction. Od wersji trzeciej sami możemy obsłużyć sytuację, gdy PowerShell nie znajdzie wpisanej przez nas komendy. Wystarczy więc pobrać listę aliasów, sprawdzić czy wpisana komenda się pokrywa z jednym z nich, przekazać pozostałe parametry i już:

$gitAliases =
(git config --global -l).Where{
$_ -match '^alias\.'
}.ForEach{
$_ -replace '^alias\.(\w+).*', '$1'
}
$ExecutionContext.InvokeCommand.CommandNotFoundAction = {
param ($name, $eventArgs)
if ($name -in $gitAliases) {
$alias = $name
} elseif ($aliases = $gitAliases -match [regex]::Escape($name)) {
$alias = $aliases |
Sort-Object -Property Length |
Select-Object -First 1
}
if ($alias) {
$eventArgs.CommandScriptBlock = { git $alias @args }.GetNewClosure()
}
}
view raw ReplaceGitAlias.ps1 hosted with ❤ by GitHub

Biorąc pod uwagę, że mam wiele aliasów opartych o LOLCODE, moja historia poleceń wygląda dość komicznie:

moja-historia-LOLCODE

Wcześniej próbowałem podobnego rozwiązania z innym zestawem aliasów, ale historia wygląda z nim mało cenzuralnie, uznałem więc, że to jednak troszkę nierozsądne. Winking smile

~ - autor: Bartek Bielawski w dniu 6 Maj, 2019.

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj /  Zmień )

Zdjęcie na Google

Komentujesz korzystając z konta Google. Wyloguj /  Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj /  Zmień )

Zdjęcie na Facebooku

Komentujesz korzystając z konta Facebook. Wyloguj /  Zmień )

Połączenie z %s

 
%d blogerów lubi to: