Skip to content

inkarkat/vim-KeepText

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

248 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

KEEP TEXT

by Ingo Karkat

DESCRIPTION

It is easy to delete some text: By {motion}, visual selection, with :substitute. The opposite (keeping some text while removing the rest) isn't so easy: You have to yank to a temporary register, delete the remainder, and then paste again. You also cannot simply invert a selection; with :substitute, the match has to be captured and referenced in the replacement.

This plugin adds commands for normal, visual, and command-line mode that let you easily specify text (by {motion}, selection, [range], or {pattern}), and then removes everything else in the command's scope (line, buffer, last selection, [range]). It basically offers delete commands that operate on an inverted target. Like normal delete, the removed text is properly stored in a register.

USAGE

["x]<Leader>k{motion}   Delete any text in the line(s) covered by {motion}
                        except for the text that {motion} moves over itself,
                        and any indent (including a potential comment prefix).
                        Register x contains the deleted text (and the indent,
                        too).
                        When this is repeated (.) on a linewise selection,
                        the text covered by the previous {motion}, starting
                        from the current column, is kept in each line. For
                        characterwise and blockwise selections, it works like
                        a repeat of the following visual mode mapping,
                        deleting any text in the selected lines except the
                        selected text itself.
{Visual}["x]<Leader>k   Delete any text in the selected line(s) except the
                        selected text itself, and any indent / comment prefix.

["x]<Leader>kkn         Within the current line / [count] / selected lines,
{Visual}["x]<Leader>kkn delete any text that does not match the last search
                        pattern, and also keep any indent (including a
                        potential comment prefix).
["x]<Leader>kkN         Same as the above <Leader>kkn, but query whether to
{Visual}["x]<Leader>kkN keep each match.

["x]<Leader>kk/         Same as <Leader>kkN, but query a search pattern (and
{Visual}["x]<Leader>kk/ also query whether to keep each match).
["x]<Leader>kk?         Same as <Leader>kkN, but reuse the previously queried
{Visual}["x]<Leader>kk? search pattern from <Leader>kk/ (and also query
                        whether to keep each match).

["x]g<Leader>k{motion}  Delete any text in the entire buffer except for the
                        text that {motion} moves over itself.
                        Register x contains the deleted text.
{Visual}["x]g<Leader>k  Delete any text in the entire buffer except the
                        selected text itself.

["x]<Leader>zk{motion}  Delete any text in the last selection except for the
                        text that {motion} moves over itself. {motion} must be
                        (at least partially) inside the selection.
                        Register x contains the deleted text.

:[range]KeepRange [{register}] {range}
                        Delete any lines of the buffer / within [range] except
                        those that are covered by {range} into the unnamed
                        register / [{register}].
:[range]KeepRange! [{register}] {range}
                        Delete any lines of the buffer / within [range] that
                        are covered by {range} into the unnamed register /
                        [{register}].

:[range]KeepMatch [{register}] /{pattern}/[flags]
                        Within the current line / [range], delete any text
                        that does not match {pattern} into the unnamed
                        register / [{register}]. Only match(es) are kept.
                        Pass the special [<] flag to also keep any indent
                        (including a potential comment prefix), both in the
                        line and as part of the deleted text.
:[range]KeepMatch [{register}] /{pattern}/{string}/[flags]
                        Like above, but keep {string} (which can refer to the
                        match via &, \1, etc.)

:[range]KeepMatch! [{register}] /{pattern}/[flags]
                        Within the current line / [range], delete any text
                        that matches {pattern} into the unnamed
                        register / [{register}]. Only text that does not match
                        is kept. This is like
                            :[range]substitute/{pattern}//[flags]
                        but it stores the deleted text in a register.
:[range]KeepMatch! [{register}] /{pattern}/{string}/[flags]
                        Like above, but store {string} (which can refer to the
                        match via &, \1, etc.) in a register.

:[range]KeepMatchAndNewline [{register}] /{pattern}/[flags]
                        Within the current line / [range], delete any text
                        that does not match {pattern} into the unnamed
                        register / [{register}]. Only match(es) and newline
                        characters are kept; i.e. in contrast to :KeepMatch,
                        this variant does not join lines if the newline is not
                        included in {pattern}.
                        Pass the special [<] flag to also keep any indent
                        (including a potential comment prefix), both in the
                        line and as part of the deleted text.
                        This command is similar to
                            :[range]global/^/KeepMatch ...
                        but with correct register contents.
                        Note: When executed on a single line, it's the same as
                        a :KeepMatch command.
:[range]KeepMatchAndNewline [{register}] /{pattern}/{string}/[flags]
                        Like above, but keep {string} (which can refer to the
                        match via &, \1, etc.)
:[range]KeepMatchAndNewline! [{register}] /{pattern}/[flags]
:[range]KeepMatchAndNewline! [{register}] /{pattern}/{string}/[flags]
                        Within the current line / [range], delete any text
                        that matches {pattern} and newlines into the unnamed
                        register / [{register}]. Only text that does not match
                        and newlines are kept. This is like
                            :[range]substitute/{pattern}//[flags]
                        but it stores the deleted text in a register.

EXAMPLE

We want to keep just the quoted text: Hello, world!

He said: "Hello, world!" and then left.

Instead of yi"0_Dp or yi"Vp, we can now simply do <Leader>ki", or vi"<Leader>k.

Instead of

:substitute/.*"\(.*\)".*/\1/

use:

:KeepMatch/"\zs.*\ze"/

INSTALLATION

The code is hosted in a Git repo at https://github.com/inkarkat/vim-KeepText You can use your favorite plugin manager, or "git clone" into a directory used for Vim packages. Releases are on the "stable" branch, the latest unstable development snapshot on "master".

This script is also packaged as a vimball. If you have the "gunzip" decompressor in your PATH, simply edit the *.vmb.gz package in Vim; otherwise, decompress the archive first, e.g. using WinZip. Inside Vim, install by sourcing the vimball or via the :UseVimball command.

vim KeepText*.vmb.gz
:so %

To uninstall, use the :RmVimball command.

DEPENDENCIES

CONFIGURATION

For a permanent configuration, put the following commands into your vimrc:

If you want to use different mappings, map your keys to the <Plug>(KeepText...) mapping targets before sourcing the script (e.g. in your vimrc):

nmap <Leader>k <Plug>(KeepTextLineOperator)
xmap <Leader>k <Plug>(KeepTextLineVisual)
nmap g<Leader>k <Plug>(KeepTextBufferOperator)
xmap g<Leader>k <Plug>(KeepTextBufferVisual)
nmap <Leader>zk <Plug>(KeepTextSelectionOperator)
nmap <Leader>kkn <Plug>(KeepTextAllMatchesLine)
xmap <Leader>kkn <Plug>(KeepTextAllMatchesVisual)
nmap <Leader>kkN <Plug>(KeepTextQueriedMatchesLine)
xmap <Leader>kkN <Plug>(KeepTextQueriedMatchesVisual)
nmap <Leader>kk/ <Plug>(KeepTextQueriedQueriedPatternMatchesLine)
xmap <Leader>kk/ <Plug>(KeepTextQueriedQueriedPatternMatchesVisual)
nmap <Leader>kk? <Plug>(KeepTextQueriedRecalledPatternMatchesLine)
xmap <Leader>kk? <Plug>(KeepTextQueriedRecalledPatternMatchesVisual)

CONTRIBUTING

Report any bugs, send patches, or suggest features via the issue tracker at https://github.com/inkarkat/vim-KeepText/issues or email (address below).

HISTORY

1.00 11-Feb-2025
  • First published version.
0.01 01-Feb-2013
  • Started development.

Copyright: (C) 2013-2025 Ingo Karkat - The VIM LICENSE applies to this plugin.

Maintainer: Ingo Karkat <ingo@karkat.de>

About

Keep only {motion} text in lines or the buffer.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors