Pasting text to a new buffer - vim

I've found questions that are similar, but don't really address what I'm trying to learn. I want to yank or delete text and append it to a new (or existing) buffer without changing buffers. I want to basically redirect the pasted text to its destination at the end of a separate buffer without leaving the original one, similar to what you might do with shell file redirection. I have a hard time believing vim/nvim can't do this, but haven't found an appropriate answer anywhere as of yet.
:'a, 'bw ~/path/to/file.txt
This will copy the text between the two marks 'a and 'b, and write it to a file in the filesystem. This is good, but the file can't be appended to... and it doesn't get opened in a buffer.

There is a :w >> {file} variant that lets you append to a file (:help :write_a).
As #Matt already commented, the usual way would involve switching buffers. Vimscript usage is closely aligned with (mostly Ex-) commands that the user would interactively use. With recent Vim versions, you can alternatively call the low-level appendbufline() function, though. This would bypass any autocmds, buffer setttings, etc. Depending on your use case, this can be desirable or not.
If the target buffer is already visible or can be kept visible as a side effect, temporarily switching to it is easy (mostly involving :sbuffer). My ingo-library plugin has a function ingo#buffer#visible#Execute() that also handles hidden buffers transparently.

Related

How to save buffer (preferably if changed) and then close the buffer but not VIM?

So, I just realized I could use marks with capital letters to go to different files. That's great! However, I'm trying to find a way to close the buffer and return to the previous one. Say I go to my header file to change or add the declaration of the function I'm writing, and then I'd like to save the file, but only if there's changes to it, to go back to working on the contents of the function. How can I do this?
There's :x, but it also quits VIM
There's :bd!, but it doesnt save the changes
There's :bw, but that's even worse (unfortunately that's w[ipeout], not w[rite]...)
There's ctrl+O, but it doesnt seem to work when I edit the file (also, it doesnt actually close the buffer)
There's :up followed by :bd, but that's two commands and VIM's about efficiency, so I'd prefer a single command if it exists
There's a few other options and variants, but none that do what I wanted, afaik
It feels like this should be simple enough to do with one command, preferably without macros/plugins/functions/snippets/etc; as close to vanilla as possible. I get the feeling I'm missing something obvious.
You could concatenate commands like so:
:w|bd
I'd like to save the file, but only if there's changes to it
:up[date]
to go back to working on the contents of the function
Press Ctrl^, or enter the command :e[dit] #
I'd prefer a single command if it exists
Set an option :set autowrite and then Vim will save the current buffer on pressing Ctrl^ automatically.

Save Changes to a Vim Buffer Without Switching to That Buffer

How can I save the changes to a modified Vim buffer without switching to that buffer? I am trying to write a function that saves and closes all the buffers in a project.
Apart from the :wqall command, there's no command that writes a buffer other than the current one.
So you do have to switch to the buffer in order to write it. You could use :noautocmd to avoid the associated events (but that may have adverse side effects!).
The only alternative would be to use low-level functions like getbufline() and writefile(), but then you would have to deal with encoding conversions, fileformat, etc. on your own.
You can use :wqa[ll] to write and close all changed buffers. :wa will write without closing.
You can use the argument list, see :help argument-list.
Supposing you are working with three files foo, bar, baz, and want to only write foo and baz:
:args foo baz
:argdo w
You'll obviously need additional logic to determine which buffers to put in the arglist in the first place but it sounds like you already have that.

How to automatically name a file when saving in vim

I'm trying to emulate in vim a behaviour similar to that of TextEdit.app.
As I work I often open a lot of files to take notes, and keep them there without saving them. When I restart the laptop, the TextEdit files will still be there and open thanks to AutoSave. If I do the same thing with vim (specifically MacVim) the files are (as expected) not saved and I lose their content.
My recipe for solving this problem has two bits. The first one is to automatically save the files when I'm not using them, so using a command like:
autocmd BufLeave,FocusLost * silent! wall
This works fine with files that have already been saved, but it ignores ones that have not yet been saved. This is where the second bit comes into play, I would like vim to automatically give these files a default name if it tries to save them and they don't already have a name. Possibly I would also like there to be a default save directory.
The ideal solution would be that when an unnamed file/buffer loses focus it gets saved as ~/Documents/notes/note_1.txt, the second one note_2.txt, etc etc.
I did look around for any pointers that could help in either direction (default name and default directory - the latter is not fundamental though), but couldn't find anything.
Can anybody help?
I don't like your idea, but it is doable.
You need a function:
function! SaveIt()
if bufname("%")==''
exec 'w /path/note_'.localtime()
else
w
endif
endfunction
and in your autocommand, just call the function. Some points you need to note:
the filename would be /path/note_( ms since 1970). your 1,2,3.. index will make vim check filesystem to find out the index. It could be a better name, e.g note_2013-09-11_11:11:11.233 You just change the localtime()
this may throw exception when you try to save a readonly buffer. (help, qf ...) You could check for them though.
Note that I didn't add the ! in w cmd.
it may not work for your autocmd wall. if you want to do it, you have to loop through all buffers, and for each buffer call the function.
after all the function shows the direction how it could be done, it (the quality) is still very far away from "production" level.

Lock some text in vim to prevent modifications

I'm looking for a way to prevent the modification of a part of a vim buffer. I know it is possible to lock buffer to prevent all modifications inside, but I would like to do the same for just a few lines, or a paragraph.
Any idea if this is possible ?
Cheers,
V
Well, as I know, vim can not do that. The text in vim buffer is just a "string" without any property can be attached to them. So "readonly" can be only to whole buffer, but not specific characters, although emacs is able to add text properties to let some characters in buffer readonly.
On the other handle, if you really want to edit something and make it not affect the other buffer content. There should be an alternate way, although is not elegant.
1.create a temp buffer with "setlocal buftype=nofile", insert the text you want to edit into that buffer.
2.show that buffer on other window(need split firstly)
3.edit the temp buffer.
4.when you close that buffer, "merge" the result in the real buffer, and replace the text you want to edit.
So, you need to do that via some key binding and vim scripting, not an easy way.
If the "protected" region of text is readily defined (i.e. by its position in the file, or a regular expression) you could try writing a BufWritePre function that checks this region and throws an error if it has been modified. I resorted to this when I wanted to prevent saving a file with an invalid fold structure.
Presumably this would involve saving the original text in a variable when the file is loaded, and this may have performance implications.
Hope this helps.
There is a plugin called narrow region that edits selected text leaving intact the rest

In Vim, what is the "alternate file"?

I just ran :help registers in Vim and noticed that # 'contains the name of the alternate file'.
I have seen an example for renaming files that goes like this:
" Save the current file, foo.txt, as bar.txt
:w bar.txt
" Start editing bar.txt
:e#
So apparently in that case, the file you just saved out is the "alternate file."
Can someone give me a more general definition for the "alternate file" and what else you might use it for?
The alternate file is the file that was last edited in the current window. Actually when you use some command to open a new buffer, if the buffer that was displayed had a filename associated with it, that filename is recorded as alternate file name.
See :help alternate-file.
Very useful for...
Pasting in the name of a file I've just been looking at into the current file.
You can use <C-R># for this in insert mode or "#p in normal mode.
Not that useful for...
Jumping back and forth between two files. It does the job very well, but this is just something I don't generally need to do.
Even in the example given, I'd probably use:saveas bar.txt instead.
An Example:
Say if you're doing a bit of C programming and want to call some function. You can't remember the name of the function, so you place a mark on your current location mA and jump into several different files using tags or grep to find out where the function is declared and what it's actually called.
Ah - found it. You can copy the name and return to the mark yiw'A
Uh-oh - we also need to #include the file! Easy - just use the alternate file name register to paste the file name in... Gi#include"<C-R>#"
Be pleased that you've avoided the distraction of having to go back to the function's declaration and copy out the file name via :let #"=#% or something similar.
What I'd rather do when jumping between files:
When editing two files, it's probably easier to split them, so you can keep both on screen at the same time. If I'm editing 2 files I'll usually be comparing them in some way.
Usually I'm interested in 1-3 files (any more and I get confused). I'll often jump into or directly open many other files. Marking the interesting files, or traversing the jump list is usually the way to get around in this case.
If you're editing C/C++ where you're switching between a file and it's header, use a plugin! It will be much more convenient.
I use it in the buffer context to return to the last buffer that I was editing
vim foo bar
:n
:e#
will take you back to foo in that case
I 've always interpreted the "alternate file" as being the "previous file", so it is an handy way to jump back to the buffer you were editing.

Resources