sponsor Vim development Vim logo Vim Book Ad

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

 script karma  Rating 4/1, Downloaded by 29  Comments, bugs, improvements  Vim wiki

created by
Ingo Karkat
 
script type
utility
 
description
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"/
 
install details
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
- Requires Vim 7.0 or higher.
- Requires the ingo-library.vim plugin (vimscript #4433), version 1.044 or
  higher.
- repeat.vim (vimscript #2136) plugin (optional)
- visualrepeat.vim (vimscript #3848) plugin (optional)

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)
 

rate this script Life Changing Helpful Unfulfilling 
script versions (upload new version)

Click on the package to download.

package script version date Vim version user release notes
KeepText-1.00.vmb.gz 1.00 2025-02-11 7.0 Ingo Karkat Initial upload
ip used for rating: 142.132.191.50

If you have questions or remarks about this site, visit the vimonline development pages. Please use this site responsibly.
Questions about Vim should go to the maillist. Help Bram help Uganda.
   
Vim at Github