copy and paste in vi - bash

I don't have a huge amount of experience using VI. I am running it on Mac OSX.
I've copied and pasted text before in the editor using (when I say gui in the following I mean the Mac OSX gui)
Cursor to highlight and copy i using command C or the gui or the yy command in VI.
Entering insert mode where I want to paste the text and then pasting using command V or the gui
My problem is that a very long line that is split over multiple lines in the terminal becomes multiple lines as shown on the terminal when copied and pasted by any of the methods.
How do I get it to copy and paste excatly as is?

Move the cursor to the line from where you want to copy and paste contents at another place.
Hold the key v in press mode and press upper or lower arrow key according to requirements or up to lines that will be copied. you can press key V to select whole lines.
Press d to cut or y to copy.
Move the cursor to the place where you want to paste.
Press p to paste contents after the cursor or P to paste before the cursor.

You have
:set paste
Put Vim in Paste mode. This is useful if you want to cut or copy
some text from one window and paste it in Vim. This will avoid
unexpected effects.
Setting this option is useful when using Vim in a terminal, where Vim
cannot distinguish between typed text and pasted text.

Assuming your vi is actually vim, before pasting, do:
:set paste
That disables word wrapping and auto-indent and all similar things that modify typed text. After pasting, turn it off again with
:set nopaste
The reason is that while gvim can tell pasting from typing (so you don't need this when using gvim), the terminal version can't, because it's the terminal doing copy and paste and vim simply sees the text as typed. And therefore applies the transformation like it does for any other text.

Someone showed me a neat trick. In the vi editor, set to insert mode ("i"). Then middle-button click at the location where you would like to insert.

Well, if it is actually one long line the easiest way to do this is with a 'Y' in command mode. Just move to the line and do Y and then move to where you want to put the line and do a p (for paste).

After trying everything suggested here and in other answers including trying to format the file afterwards with vi(m) commands and seds, I got smart and just heredoc'd what I wanted to paste with redirection to the file. i.e.
cat << EOF > yourfile.txt
paste what you are trying to paste
another line of pasted text
yet another
foo > bar?
foo = bar??
end of the file(yay)
EOF
everything between the first line and the last line will be pasted to your file without those pesky newlines interpreted as many spaces/tabs. Just beware that what you are pasting might have its own heredoc(like mine did coincidently LOL). In that case would need to manually paste those lines in your editor which shouldn't be an issue.

Related

Shortcut to jump to the previous white space in a bash command line

To jump to the previous word in a command line, I use Alt + b.
However, the names of my files are pretty long and look like this:
2018_09_03_abcdef_ghijkl_mnopqr_stuvwx_yz.txt
When I want to change the name of these files, I use the command mv and a shortcut** that permits me to paste the first word/argument (the current name of the file). This gives me the following command:
$ mv 2018_09_03_abcdef_ghijkl_mnopqr_stuvwx_yz.txt 2018_09_03_abcdef_ghijkl_mnopqr_stuvwx_yz.txt
Then I either want to change the date of the day and/or the first letters of the file name to get for example the final command line:
$ mv 2018_09_03_abcdef_ghijkl_mnopqr_stuvwx_yz.txt 2018_09_04_ABcd1234_ghijkl_mnopqr_stuvwx_yz.txt
To make the change at the beginning of the file name, I have to type the shortcut Alt + b several times since this shortcut considers every letters separated by an underscore as a word.
I would like to be able to jump directly to the beginning of the name (not the beginning of the line) to modify it. A shortcut targeting the white space would be ideal.
I have not been able to find such a shortcut that would skip the underscores and go directly to the previous white space.
Did anyone already create a shortcut in bash that allows you to do this?
Would the only possible way to accomplish this be to switch from emacs mode to vi mode (set -o vi) and use the vi shortcut:
F + space
?
Thank you very much in advance!
** The shortcut I found to paste the previous word in the current command line and paste it in the same current command line uses Alt + j and has to be added in the '~/.inputrc' file (followed by bind -f ~/.inputrc):
"\ej":"!#:$\e^"
There are several shortcuts to navigate bash command line. Here's another list.
Assuming cursor is at the end of the line, it could jump to 03 (day part) by typing Meta+7 Meta+b (2 keystrokes without releasing Meta key).
Now, for the file name changes, brace expansion could be used to get a command like this that provides the second argument from expansion.
mv 2018_09_{03_abc,04_ABC}def_ghijkl_mnopqr_stuvwx_yz.txt

Disable delete key in terminal prompt

I modified my prompt in my .bashrc file using the following command:
PS1='\[$(tput bold)\e[1;34m\w\e[m$ '
Now my prompt shows the current directory in bold blue color followed by the $ sign. On a new prompt, if no other text has been entered, I press the delete key nothing happens.
However, if I enter any text, say cd, delete that and then press the delete key once more, it will delete my prompt. How can I change my .bashrc file so my prompt can never be deleted?
Bash is confused about how long your prompt actually is. You can tell bash by enclosing non-printable parts of the prompt with backslash-brackets: \[....\].
Your prompt, however only contains the opening bracket, making bash believe that the prompt is very short, so it happily removes almost all of it in some situations. A proper use of the bracketing would look like this:
PS1='\[$(tput bold)\e[1;34m\]\w\[\e[m\]$ '
That is, everything is in backslash-bracket except the working directory and the dollar sign, because those are the only parts that actually consume space on the terminal screen.

Bash Ctrl + R use current text

I use the reverse-i-search in Bash a lot. But I always type in the start of the command I'm about to use before I realise that I need to search for it.
Is there a way to make Ctrl + R use the input text, so that I don't have to type it again?
By input text, I mean text that I have typed in to the terminal before pressing Enter.
An example:
cd ~/some/folder/
cd some/subfolder/
I am about to go to a subfolder with cd. Before pressing Enter, I will type "cd some/subfolder". That is the input text.
You can use the CTRL-aryr command.
It looks worse than it is: for a half typed complex command it's quite helpful.
That's a compound command:
CTRL-a: home
-r: open reverse incremental history search and copy the text after the cursor position
-y: paste the text
-r: look for matching commands
It appears you can not do this. That is CTRL-R reads directly from the keyboard (at least on Linux) so you can't even paste into the buffer.
The best solution I can recommend is that you consider using Emacs Shell mode which will replace Bash's input with Emacs buffers.

In bash, how does one clear the current input?

Suppose in bash you start writing a command like:
$ rm -rf /foo/bar/really/long/path/here
and then realize you don't want to execute this after all. Is there a way to clear the input with one or two keystrokes?
What I have been doing lately is prepending echo and enclosing the input in quotes (Ctrl+A, echo ", Ctrl+E, ") then hitting enter. Is there a faster way?
Press Ctrl-U to delete everything before the cursor. The deleted command will be stored into a buffer. Press Ctrl-Y to paste the deleted command.
(Optional: Press End or Ctrl-E to jump to the end of the input first.)
Alternatively, press Ctrl-C to abort what you're typing.
Try Ctrl+U. That clears the input line.
Found a short reference at http://www.ice2o.com/bash_quick_ref.html while searching.
ctrl + e (if not at the end of the line) plus ctrl + u will do it.
Ctrl-U, Ctrl-K does the trick as well.
Ctrl-U deletes everything from the beginning of the line up to the cursor, Ctrl-K deletes everything from the cursor to the end of the line. (It is sometimes useful to use only one of them.)
There are two options to do this
ctrl+c - this clears the whole line, no matter where the cursor is.
ctrl+u - this clear the line from the position of the cursor until the beginning.
A nice shortcut is pressing Esc#. It will prepend a # character (thus making the line a comment) and then press enter. If you then decide that you still the need the command, you still have it in your history :)
Pressing Esc plus Backspace in bash will clear everything up to the cursor's position.
(In Cygwin, this will clear the input up to the next word. Words are separated by spaces, underscores, ...)
This is an expansion of knittl's answer that stores the line in the console history by prefixing with a hash. Overcoming drawbacks of the clipboard, such as accidental overwriting or being unable to view the cut line for reference.
Comment Line & Return New Prompt
Use either key shortcut:
Esc,#
Alt+#
A hash character # will be prepended to the line, thus turning the whole line into a comment. It will also return a new prompt, as if enter was pressed by the user. e.g.
$ #rm -rf /foo/bar/really/long/path/here
$
Retrieve Commented Line
To recover the old line from console history use one of the following shortcuts:
Up
Ctrl+p
Repeat key shortcut until the desired line appears.
Quick Hash Prefix Removal
To remove the line's hash # prefix there are a few different options available:
Remove first character and immediately execute command:
Esc,1,Esc,#
Alt+-, Alt+#
Move cursor to start and remove first character, without executing the command:
Home, Delete
Ctrl+a, Ctrl+d
Consider that using Ctrl-U (or Ctrl-E and then Ctrl-U) will store what you clear in a buffer so that you can then paste it later using Ctrl-Y.
If you are using Bash in vi mode (set it with set -o vi), then press Esc to switch to the normal mode of vi, and type dd to delete the current line!
To delete the current line, try:
Ctrl-X, Ctrl-U
As an alternative you may use:
Esc-D
which requires in ~/.inputrc:
"\ed": kill-whole-line
see: http://codesnippets.joyent.com/posts/show/1690

Pasting functions from system clipboard to gVIM

The following is the contents of the Windows System Clipboard
:function CurrentLineLength
: len = strlen(getline("."))
: return len
:endfunction
I hit the colon and then control r
I then hit shift 8 to paste the contents of the system clipboard.
I hit return and vim comes back with
E488: Trailing Characters
I see some ^M characters in there and removing them does not help. I do know that I can paste the functions into a .vim file and read them that way so its not crippling but as I work through some examples of vim script this would be nice to have.
Is there something special about how functions are entered in or is it possible to paste them from the system clipboard?
Thanks!
I'm not sure about pasting multiple lines to command mode, but you can achieve the same thing by simply putting the function in a register and executing the register (same as a macro).
Also, Vim doesn't seem to like that function as you've pasted it, I've made a couple of changes below. If you copy the below to the system clipboard and then press #* from normal mode, it works.
:function CurrentLineLength()
: let len = strlen(getline("."))
: return len
:endfunction
Vim should not have any problems with carriage returns in command mode (that's what the ^M characters are). I would guess that there are some other characters in the code you're pasting - this is quite possibly the problem if you're pasting from a web page. Try putting the contents of your clipboard into a file and see if it's really what you expect it to be (including all whitespace characters).

Resources