36

I often find myself typing commands like gg"+yG or ggdG and would like a more efficient way to do this without having to move the cursor twice. Is there any command that I can use e.g. y[movement] to copy the entire buffer without moving the cursor?

5 Answers 5

46

Since vim uses the percent sign to reference the current buffer, you can use it to get everything quickly.

:%y will yank the entire buffer :%y+ will yank it to the + register (and presumably the clipboard, provided vim was compiled with the proper options).

:%d and :%d+ will do the same for deletion.

In each of these cases, the cursor remains in place.

2
  • Wow, all this time I was using mmgg"+yG`m and never thought of this. Thanks, this is going right in the .vimrc.
    – Doorknob
    Commented Mar 3, 2015 at 14:01
  • 1
    @Doorknob instead of setting and using marks you could just use C-o twice to go back.
    – Ruslan
    Commented Jan 3, 2018 at 16:48
17

Another solution is to use a plugin called vim-textobj-entire. By default, this plugin provides the text object ae for the entire buffer, ie for the entire buffer except leading and trailing empty lines.

This plugin depends on vim-textobj-user by the same author, which lets users define any text objects comfortably. There are many plugins that make good use of this.

10

There is no text object for the whole file by default, but it is possible to create them using omap. In this case, it would look something like this:

onoremap f :<c-u>normal! mzggVG<cr>`z

Here is a breakdown of how it works:

onoremap f " make 'f' the text object name
:<c-u> " use <c-u> to prevent vim from inserting visual selection marker at the beginning of the command automatically.
normal! " use normal to make key presses ignoring any user mappings
mzggVG<cr>`z " make a marker in register z, select the entire file in visual line mode and enter the normal command, and go back to the z marker

Notes:

Ctrlu can be used in the command line mode to delete everything to the left of the cursor position. The reason why this is done is because if you enter the command line straight from visual mode, it will automatically insert '<,'> on the command line, and that isn't what we want. I would also suggest you use something other than f, because f is normally used to move to the next searched character on the line. For example, fi will go to the next i on the current line.

Relevant help topics:

:help omap-info
:help :normal
:help c_CTRL-U
:help v_:
4
  • Is there a way to do this while leaving the cursor alone?
    – Random832
    Commented Mar 2, 2015 at 20:17
  • @Random832 Adding a `` to the end will return the cursor to the previous location. Commented Mar 2, 2015 at 20:22
  • I'm concerned that this will make it not apply the selection to the yank command. I'll experiment some today.
    – Random832
    Commented Mar 2, 2015 at 20:24
  • 1
    I added a marker command to the mapping, it should leave the cursor where it is now. Commented Mar 2, 2015 at 20:42
4

Here are some quick n' dirty mappings to accomplish the task:

nnoremap yY :%yank <c-r>=v:register<cr><cr>
nnoremap dD :%delete <c-r>=v:register<cr><cr>

Now you can use yY and dD to yank/delete respectively. It's not as nice as using a full blown text object, but sometimes the simplest solutions are best.

For more help see:

:h :y
:h :d
:h [range]
:h v:register
:h c_ctrl-r
:h @=
3

Recommended Solution

Created by @filbranden in response to my question here

" Create text-object `A` which operates on the whole buffer (i.e. All)
" Keeps the cursor position in the same position
function TextObjectAll()
    let g:restore_position = winsaveview()
    normal! ggVG
    " For delete/change ALL, we don't wish to restore cursor position.
    if index(['c','d'], v:operator) == -1
        call feedkeys("\<Plug>(RestoreView)")
    end
endfunction
onoremap A :<C-U>call TextObjectAll()<CR>
nnoremap <silent> <Plug>(RestoreView) :call winrestview(g:restore_position)<CR>

1 Liner Solution

" Use operator pending mode to visually select the whole buffer
" e.g. dA = delete buffer ALL, yA = copy whole buffer ALL
onoremap <silent> A :<C-u>normal! ggVG<CR>

Visual mode

I used to have this, but when in visual mode, if you press A to append at the end of the lines, it override it with select ALL. You could map it to something else:

" Allow one to press A in visual mode to select the whole buffer (ALL)
xnoremap <silent> A :<C-U>normal! ggVG<CR>
3
  • 1
    Thanks for sharing this answer here!
    – filbranden
    Commented Apr 29, 2020 at 20:10
  • 2
    Very minor nitpick: vnoremap maps in visual and select mode, which probably isn't what you want, in this context. For a visual mode mapping, use xnoremap.
    – Rich
    Commented Apr 30, 2020 at 10:51
  • 1
    I dont use select mode, but for the benefit of other I changed it. Commented Apr 30, 2020 at 11:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.