Lock some text in vim to prevent modifications - vim

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

Related

Vim yank and paste non-standard characters

I have a document with a non-standard encoding. Some of them aren't valid UTF-8, etc. However, a lot of the starts/ends of sections etc still line up, so I would still like to do some basic things in vim with this document. One of those things is to copy and paste. However this seems to fail when my document isn't in a standard encoding.
I can't provide my original document, but one can easily experiment with this with other arbitrary files. For example, if you open a .jpg file in vim, and then (y)ank all of it and (P)aste it into a new file, and save that file as a .jpg, it won't open. Somewhere in the yank-paste pipeline stuff got lost. What is going on with my vim clipboard, and is there a way to work around this?

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.

Pasting text to a new buffer

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.

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.

What is a "buffer" in VIM?

When VIM refers to a file im editing as a "buffer"...what exactly does it mean? Whenever I edit the file in shell or in the application, it refers to the copy of the file as a buffer. I was curious as to what exactly this meant, but couldn't find anything on it. Any help would be appreciated.
From :help windows-intro, as linked by icktoofay in a comment:
A buffer is the in-memory text of a file ... [which is] loaded into memory for editing. The original file remains unchanged until you write the buffer to the file.
That is, a buffer represents the actual loaded/working data itself.
You can think of it as similar to the Windows clipboard. You can use it to cut, copy and paste text snippets.
But you can have multiple "buffers" open at the same time. And each buffer can have a name.
See VI Tutorial: Manipulating Text:
A named buffer is another method to move or duplicate text... first position the cursor at the material you want to copy. Next make a copy of the desired text by using the yank command. This places the copied text into a temporary buffer...

Resources