11

I have been using VI and VIM for years (30 or more) (in xterms, not its own window, gvim) and I have a huge library of vim commands that I give vim using the mouse middle button as a selection.

For example I would often do things like...

 vi {many_hundreds_of_files}
   paste vim commands using mouse - one paste per file.

The selection would include lots of VIM commands to do things things like replacing test, formatting, move lines around, etc., etc., etc., and typically ends with :w and :next VIM commands, at the end of the selection, so vim is ready for me to paste again into the next file. This lets me update huge numbers of files in VERY complex ways, without needing special scripts (such as perl in-place editing) to do it.

Some of these vim command pastes are 200+ lines long (stored in text files I pop-up on screen, and 'copy-all'! These make a LOT of changes to the set of thousands of files I am re-formatting. But only for the specific set of files, not for my day-to-day vim work. EG: Bulk re-formating for text/data files.

The Problem...

During my last system patch (Fedora 25) vim now pastes the mouse selection AS TEXT and not as vim commands, and I can't seem to stop it!

It still works fine on another system (Fedora 24).

If I want to paste as text, I enter insert mode before pasting! I don't want VIM automatically pasting selections AS text when it is not in insert mode. I understand this was meant as a security feature, but to me it is a MAJOR usability issue.

I have tried back dating terminfo entries (xterm-256color) from a machine that does not do this (especially the "kmous" terminfo entry). I have also looked at the vim ":set mouse=" setting (which is null!). I do not know if it is the xterm (doubtful), or something that changed in VIM (likely), and change logs and google have been unhelpful.

Nothing however seems to get me the old behaviour.

anthony
  • 610
  • Found another user with the same problem, less detail, no solution https://unix.stackexchange.com/questions/346293/cannot-paste-a-command-to-vim-8-0 – anthony May 10 '17 at 01:51
  • 1
    I doubt it's more likely a vim change: How can vim inside an xterm know something is entered through keyboard or pasted through mouse button? I don't know such a mechanism. On the other hand, xterm knows that it's executing vim so it could decide to surround the pasting with i and . Try (a) with a different kind of terminal window and (b) a copy of vim with a different name. This should help to narrow the cause of the problem. – Philippos May 10 '17 at 06:00
  • I agree with @philippos. Maybe something other than vim is hijacking your paste method. Maybe try ssh'ing or telneting into your machine and pasting that way. If you have a Windows box, use putty to ssh into your Fedora25 machine and paste that way. – Jim U May 10 '17 at 14:17
  • Not directly related, but gvim on windows has behaved this way for years. When you install gvim, you get two executables, gvim.exe (graphical-vim) and command-line vim.exe. Paste "itext" in gvim.exe and you get itext. Paste it in the vim.exe and you get text – Jim U May 10 '17 at 14:19
  • 1
    @Philippos That mechanism could be bracketed paste. I don't know how how Vim might support it, perhaps the pastetoggle option? – Gilles 'SO- stop being evil' May 10 '17 at 20:55
  • yes it was a bracketed paste. I finally got some info about it. The reason it did not click was it is a 'fake' termcap entry that VIM added internally... See the Answer below. – anthony May 11 '17 at 00:48
  • Thanks to those pointing out the paste exploit. Though I already know about it. My final solution however was to only disable bracketed-paste while I am normal-mode (commands), and not when I am pasting in insert-mode. I only paste vim commands I have written and collected into libraries. – anthony May 15 '17 at 00:17
  • Why not do it the Vim way and put them in as macros? – Wildcard May 15 '17 at 00:50
  • Some common ones are macros, (such as compress multiple blank lines to one blank line) But what I paste more typically depends on the files I am editing. It varies with the situation. I even call the macros I do have in the pasted commands as part of a larger set of commands. Basically so I can do a single paste per file over many many files, for that specific session. – anthony Sep 08 '17 at 02:26
  • Also I would like to not that some of my vim command pastes are 200+ lines long! Doing a LOT of changes to the thousands of files I am re-formatting. But only for the specific set of files, not for my day-to-day vim work. EG Bulk re-formating. – anthony Aug 06 '19 at 00:59

1 Answers1

14

Well after going through a LOT of web pages, many giving some hints that did not seem to work, I found a hint (extra text around a paste) that lead me to the cause and the solution to the problem.

It seems that vim has built into it a number of 'fake' termcap entries which it uses when it recognises specific terminals (and sometimes gets wrong, though it wasn't wrong in this case).

Termcap settings in vim are numerious add as such DOES NOT show up in a normal ":set all" setting list. To see them you need to use ":set termcap". The specific 'non-standard' termcap setting is "t_BE" (see vim ":help t_BE"). The built-in help "xterm-bracketed-paste" explains this internal-to-vim termcap setting.

Basically if this setting is defined (in this case by Vim not termcap/terminfo) then vim will send it to the xterm when it starts up, which tells xterm to add special codes around any text the user pastes from an external source. When vim sees these it automatically goes not only into insert-mode but also sets 'paste-mode' so as not to format the text.

The later (paste-mode) is I think VERY useful! The former is what has been giving me all the trouble.

The brute force solution is disable bracketed-paste by adding this to the ".vimrc"

:set t_BE=

An Alternative Solution....

Instead of disabling bracketed-paste completely, stop vim taking action when it sees the starting sequence of a terminal paste (from the mouse), while in command or normal-mode.

:nmap <PasteStart>  <NOP>
:nmap <PasteEnd>    <NOP>
:cmap <PasteStart>  <NOP>
:cmap <PasteEnd>    <NOP>

Using this means that if you do paste text while in insert-mode vim will not try to format (indent) text that is more than likely already indented.

This does not mean I no longer need to toggle paste-mode, as I also use the paste-mode toggle (mapped to F2) to disable "showbreak" and "listchars" (displaying wrapped lines, tabs, no-break spaces, and extra spaces at the end of lines). I would still need to put vim in that mode when I want to make mouse selections to paste elsewhere.

Comments and Suggestions on the solutions are welcome.

anthony
  • 610