Skip to content

Add "text object" support for Vi mode #584

Open

Description

@gwojan

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

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

were possible.

Activity

  1. lzybkr commented on Nov 14, 2017

    @lzybkr
    Contributor

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

  2. gwojan commented on Nov 14, 2017

    @gwojan
    Author

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

  3. springcomp commented on Dec 18, 2020

    @springcomp
    Contributor

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

  4. belotn commented on Dec 29, 2021

    @belotn

    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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions