Vim yank and paste non-standard characters - vim

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?

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.

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.

Saving a flat-file through Vim add an invisible byte to the file that creates a new line

The title is not really specific, but I have trouble identifying the correct key words as I'm not sure what is going on here. For the same reason, it is possible that my question has a duplicate, as . If that's the case: sorry!
I have a Linux application that receive data via flat files. I don't know exactly how those files are generated, but I can read them without any problem. Those are short files, only a line each.
For test purpose, I tried to modify one of those files and reinjected it again in the application. But when I do that I can see in the log that it added a mysterious page break at the end of the message (resulting in the application not recognising the message)...
For the sake of example, let's say I receive a flat file, named original, that contains the following:
ABCDEF
I make a copy of this file and named it copy.
If I compare those two files using the "diff" command, it says they are identical (as I expect them to be)
If I open copy via Vi and then quit without changing nor saving anything and then use the "diff" command, it says they are identical (as I also expect them to be)
If I open copy via Vi and then save it without changing anything and then use the "diff" command, I have the following (I added the dot for layout purpose):
diff original copy
1c1
< ABCDEF
\ No newline at end of file
---
.> ABCDEF
And if I compare the size of my two files, I can see that original is 71 bytes when copy is 72.
It seems that the format of the file change when I save the file. I first thought of an encoding problem, so I used the ":set list" command on Vim to see the invisible characters. But for both files, I can see the following:
ABCDEF$
I have found other ways to do my test, But this problem still bugged me and I would really like to understand it. So, my two questions are:
What is happening here?
How can I modify a file like that without creating this mysterious page break?
Thank you for your help!
What happens is that Vim is set by default to assume that the files you edit end with a "newline" character. That's normal behavior in UNIX-land. But the "files" your program is reading look more like "streams" to me because they don't end with a newline character.
To ensure that those "files" are written without a newline character, set the following options before writing:
:set binary noeol
See :help 'eol'.

How does vim know encoding of my files? When even I don't

I have been in charset-hell for days and vim somehow always shows the right charset for my file when even I'm not sure what they are (I'm dealing with files with identical content encoded in both charsets, mixed together)
I can see from inspecting the ΓΌ (u-umlaut) character in UTF-8 vs ISO-8859-1 which encoding I'm in, but I don't understand how vim figured it out - in those character-sets only the 'special characters' really look any different
If there is some other recording of the encoding/charset information I would love to know it
The explanation can be found under :help 'fileencodings':
This is a list of character encodings considered when starting to edit
an existing file. When a file is read, Vim tries to use the first
mentioned character encoding. If an error is detected, the next one
in the list is tried. When an encoding is found that works,
'fileencoding' is set to it. If all fail, 'fileencoding' is set to
an empty string, which means the value of 'encoding' is used.
So, there's no magic involved. When there's a Byte Order Mark in the file, that's easy. Else, Vim tries some other common encodings (which you can influence with that option; e.g. Japanese people will probably include something like sjis if they frequently edit such encoded files).
If you want a more intelligent detection, there are plugins for that, e.g. AutoFenc - Tries to automatically detect and set file encoding.

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

Resources