Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "text object" support for Vi mode #584

Open
gwojan opened this issue Nov 14, 2017 · 4 comments
Open

Add "text object" support for Vi mode #584

gwojan opened this issue Nov 14, 2017 · 4 comments
Labels
Issue-Enhancement It's a feature request. VI-Mode

Comments

@gwojan
Copy link

gwojan commented Nov 14, 2017

It would be really nice if Vi mode supported text objects so things like:

ci{
da{
ci[
ci"
ci'
etc...

were possible.

@lzybkr
Copy link
Member

lzybkr commented Nov 14, 2017

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.)

@lzybkr lzybkr added Issue-Enhancement It's a feature request. VI-Mode labels Nov 14, 2017
@gwojan
Copy link
Author

gwojan commented Nov 14, 2017

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... 😉

@springcomp
Copy link
Contributor

springcomp commented Dec 18, 2020

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:

  • n diw: deletes inner words. [vi-mode] Supports 'diw' text-object command. #2059. 🍾

  • n ciw: changes inner words.

  • n diW: deletes inner WORDs.

  • n ciW: changes inner WORDs.

  • di [ " | ' ]: deletes inner strings. [Vi-Mode] Supports di' and di" commands (quoted text objects) #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 😄.

@belotn
Copy link

belotn commented Dec 29, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Enhancement It's a feature request. VI-Mode
Projects
None yet
Development

No branches or pull requests

4 participants