PSReadLine
PSReadLine copied to clipboard
Add "text object" support for Vi mode
It would be really nice if Vi mode supported text objects so things like:
ci{
da{
ci[
ci"
ci'
etc...
were possible.
Indeed - I might have mentioned this to @srdubya a long time ago. I might even switch to vi mode if this was implemented. (I use vim or vim bindings in my editors.)
Yeah, my workaround when I really want to get nasty is set $env:VISUAL = 'vim.exe'
and then edit the whole thing inside vim proper...
I'm even using the wasavi
extension for chrome and editing this comment inside a vim-like editor. Yes, I'm sad... 😉
I’m working on this issue.
This will probably need to be broken up into several pull requests. This is how I see tackling this subject in order:
-
[x] n diw: deletes inner words. #2059. 🍾
-
[ ] n ciw: changes inner words.
-
[ ] n diW: deletes inner WORDs.
-
[ ] n ciW: changes inner WORDs.
-
[x] di [ " | ' ]: deletes inner strings. #3791.
-
[ ] ci [ " | ' ]: changes inner strings.
-
[ ] di [ ( | { | [ ]: deletes inner parentheses.
-
[ ] ci [ ( | { | [ ]: changes inner parentheses.
-
[ ] n daw: deletes outer words.
-
[ ] n caw: changes outer words.
-
[ ] n daW: deletes outer WORDs.
-
[ ] n caW: changes outer WORDs.
-
[ ] da [ " | ' ]: deletes outer strings.
-
[ ] ca [ " | ' ]: changes outer strings.
-
[ ] n da [ ( | { | [ ]: deletes outer parentheses.
-
[ ] n ca [ ( | { | [ ]: changes outer parentheses.
I don’t see the immediate value for other more arcane text objects 😄.
Hello,
I worked on some custom key handler for ci, ca, di and da as it really make editing more fluent. At the moment I only address ' " ( [ {
https://gist.github.com/belotn/538be5504b858c95890893b189720592
`Set-PSReadLineKeyHandler -Chord "c,i" -ViMode Command -ScriptBlock { VIChangeInnerBlock } Set-PSReadLineKeyHandler -Chord "c,a" -ViMode Command -ScriptBlock { VIChangeOuterBlock } Set-PSReadLineKeyHandler -Chord "d,i" -ViMode Command -ScriptBlock { VIDeleteInnerBlock } Set-PSReadLineKeyHandler -Chord "d,a" -ViMode Command -ScriptBlock { VIDeleteOuterBlock }
######################################################################
Section Function
######################################################################
function VIChangeInnerBlock(){
$quotes = @{
"'" = @("'","'");
'"'= @('"','"');
"(" = @('(',')');
"{" = @('{','}');
"[" = @('[',']')
}
$quote = ([Console]::ReadKey($true)).KeyChar
if( $quotes.ContainsKey($quote.toString())){
$Line = $Null
$Cursor = $Null
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$Line, [ref]$Cursor) $OpeningQuotes = $quotes[$quote.ToString()][0] $ClosingQuotes = $quotes[$quote.ToString()][1] $EndChar=$Line.indexOf($ClosingQuotes, $Cursor) $StartChar=$Line.LastIndexOf($OpeningQuotes, $Cursor) + 1 if($StartChar -eq 0 -or $EndChar -eq -1){ Return } [Microsoft.PowerShell.PSConsoleReadLine]::Replace($StartChar,
$EndChar - $StartChar, '')
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($StartChar)
[Microsoft.PowerShell.PSConsoleReadLine]::ViInsertMode()
}
}
function VIDeleteInnerBlock(){
$quotes = @{
"'" = @("'","'");
'"'= @('"','"');
"(" = @('(',')');
"{" = @('{','}');
"[" = @('[',']')
}
$quote = ([Console]::ReadKey($true)).KeyChar
if( $quotes.ContainsKey($quote.toString())){
$Line = $Null
$Cursor = $Null
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$Line, [ref]$Cursor) $OpeningQuotes = $quotes[$quote.ToString()][0] $ClosingQuotes = $quotes[$quote.ToString()][1] $EndChar=$Line.indexOf($ClosingQuotes, $Cursor) $StartChar=$Line.LastIndexOf($OpeningQuotes, $Cursor) + 1 if($StartChar -eq 0 -or $EndChar -eq -1){ Return } [Microsoft.PowerShell.PSConsoleReadLine]::Replace($StartChar,
$EndChar - $StartChar, '')
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($StartChar)
}
}
function VIChangeOuterBlock(){
$quotes = @{
"'" = @("'","'");
'"'= @('"','"');
"(" = @('(',')');
"{" = @('{','}');
"[" = @('[',']')
}
$quote = ([Console]::ReadKey($true)).KeyChar
if( $quotes.ContainsKey($quote.toString())){
$Line = $Null
$Cursor = $Null
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$Line,[ref]$Cursor) $OpeningQuotes = $quotes[$quote.ToString()][0] $ClosingQuotes = $quotes[$quote.ToString()][1] $EndChar=$Line.indexOf($ClosingQuotes, $Cursor) + 1 $StartChar=$Line.LastIndexOf($OpeningQuotes, $Cursor) if($StartChar -eq -1 -or $EndChar -eq -1){ Return } [Microsoft.PowerShell.PSConsoleReadLine]::Replace($StartChar,
$EndChar - $StartChar, '')
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($StartChar)
[Microsoft.PowerShell.PSConsoleReadLine]::ViInsertMode()
}
}
function VIDeleteOuterBlock(){
$quotes = @{
"'" = @("'","'");
'"'= @('"','"');
"(" = @('(',')');
"{" = @('{','}');
"[" = @('[',']')
}
$quote = ([Console]::ReadKey($true)).KeyChar
if( $quotes.ContainsKey($quote.toString())){
$Line = $Null
$Cursor = $Null
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$Line,[ref]$Cursor) $OpeningQuotes = $quotes[$quote.ToString()][0] $ClosingQuotes = $quotes[$quote.ToString()][1] $EndChar=$Line.indexOf($ClosingQuotes, $Cursor) + 1 $StartChar=$Line.LastIndexOf($OpeningQuotes, $Cursor) if($StartChar -eq -1 -or $EndChar -eq -1){ Return } [Microsoft.PowerShell.PSConsoleReadLine]::Replace($StartChar,
$EndChar - $StartChar, '')
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($StartChar)
}
}`
Regards, Nicolas