append to end of visible line with wrapped vim - vim

I've got a file with some rather long lines, which is a pain.
I'm using :set wrap and :set linebreak, which is nice, and I've rebound a few keys from this page so that I can move up and down a visible line (rather than a physical line which has now been wrapped over 10-12 visible lines).
I use A quite a bit (append at the end of the line), but this appends at the end of the physical line, not the visible - is there a keymapping (or alternative keystroke) I can use to append to the end of the visibly wrapped line?

You could try with g$a. g$puts you on the end of the current 'screen line' and a will leave you on insert mode.
Maybe a mapping:
nnoremap <leader>a g$a

g$a - Go to the last character of the screen line, then append.
Want a mapping?
:nnoremap gA g$a

Type g$ to go to the end of visible line and a to enter insert mode. I guess you could create a custom mapping for that.

Related

Move to the last character of previous line vim

I have started using vim recently and was wondering if there's any keyboard shortcut to move the the last character of previous line( line number l-1 if I am currently on line number l) ?
One of the ways is to use the up arrow to move to the same column of previous line and then use $ to move to the end of the line.
I am looking for some shortcut to do that in one command.
UPDATE:
Here's also another solution to move to the beginning of the next line / the end of the previous line without the need to set any mappings. Add these three to your .vimrc:
set whichwrap+=<,h
set whichwrap+=>,l
set whichwrap+=[,]
(Credit to: Kevin H. Lin and garyjohn)
Original Answer:
I've not memorized all Vim shortcut combinations, so there might be one shortcut for what you're asking for, but I usually define a mapping whenever I need something I don't know how to do.
For what you need, you can simply define it with this:
nnoremap <S-L> <Up><S-4>
Just add it to your ~/.vimrc(if this file doesn't exist yet, create it yourself), then restart vim. Then the next time you open up your Vim, the "Shift-L" shortcut will do the job.
You can go straight into the insert mode as well and append characters after the last character of the previous line with this rule instead:
nnoremap <S-L> <Up><S-A>
Also in case you don't understand the structure of the above rules, you can read more about it here:
Understand Vim Mappings and Create Your Own Shortcuts.
There is a corner case: If your cursor is on the first line, pressing this mapping should not move the cursor.
Therefore, we can use the <expr> mapping:
nnoremap <expr> <F6> line('.')==1?'\<F6>':'k$'
In the example above, I used <F6>, you can choose the short-cut key you like.

How can I move the cursor to the end of the line in insert mode?

Is there an existing command or a configuration for my .vimrc that will make CTRL+right arrow go to the end of the line in insert mode instead of going to the next line? Like in most common editors, that shortcut jumps word by word, but in vim it goes to the next line when the cursor is at the last word in the line.
If there is a different fast way to jump to the end of the line in insert mode, that would also be useful.
In general, the best way to navigate in vim is in normal mode, and not in insert mode. I suggest that instead of finding ways to navigate in insert mode, you use the power of normal mode as intended. There are many ways to do this, but here are a couple of suggestions:
Use CTRL+o while in insert mode to temporarily enter normal mode for the next command, and then $ to go to the end of the line (after which you will be returned to insert mode)
Use ESC to return to normal mode, and then A which both moves the cursor to the end of the line and enters insert mode
If you want to navigate word by word (in normal mode), you can use w to move to the next word, or e to move to the end of the next word.
The Home and End keys are usually interpreted by vim in insert-mode as beginning and end of line (like 0 and $), respectively.
This is documented in the ins-special-special topic, e.g.,
:h ins-special-special

Delete backwards from cursor to the end of the previous line in Vim?

Say I want to edit the following line:
var myVar =
"I am a string!";
So that it looks like this:
var myVar = "I am a string!";
Is there a movement that goes to the end of the previous line?
What you want is the line join command, J.
In normal mode, put your cursor anywhere on the var myVar = line and type J (capital j).
Direction-wise motions work with J - 5J indents 5 lines below the cursor, etc. You can also select a range of lines using visual mode (v to start visual mode selection) and join them all into one using J.
The &joinspaces option affects this behavior as well. When it's "on" (set joinspaces or set js) it adds two spaces after a sentence-ending mark (i.e. '.', '?', or '!') when joining lines. set nojoinspaces or set nojs to turn that off and insert only one space.
Also,
:set backspace=indent,eol,start
The backspace option determines the behavior of pressing the backspace key (). By default, Vim’s backspace option is set to an empty list. There are three values that can be added that each independently alter the behavior of the backspace key. These are indent, eol, and start.
When indent is included, you can backspace over indentation from autoindent. Without it, Vim will not allow you to backspace over indentation.
When eol is included, you can backspace over an end of line (eol) character. If the cursor is at the first position of a line and you hit backspace, it will essentially be joined with the line above it. Without eol, this won’t happen.
When start is included, you can backspace past the position where you started Insert mode. Without start, you can enter Insert mode, type a bit, and then when backspacing, only delete back as far as the start of Insert mode.
The backspace default is absurd, you are going to want to add all of the above to your Vim settings.
See :h 'backspace' for more details.
kJ will do what you want and is probably what you should be using, however if you want to do exactly what you've asked for Delete backwards from cursor to the end of the previous line then you can do the following:
:set virtualedit+=onemore
^ " go to the start of the line
d?$<cr>
?$<cr> is a movement that goes to the end of the previous line.
:set virtualedit+=onemore allows the cursor to move just past the end of the line, without which we would end up deleting the last character of the line, which in the example you have given would be the trailing space.
You could then create a mapping to do this (:nohl just clears the search highlighting):
:nnoremap <leader>J ^d?$<cr>:nohl<cr>
Although a simpler mapping to achieve the same thing would be:
:nnoremap <leader>J kJ

Alternate to using backspace in vim

When I do a mistake in vim, I use backspace, because changing to command mode and use 'x' is longer, but maybe is other way to do it vim-way?
ctrl-w to erase the last word, ctrl-u to erase the entire line you're on.
In insert mode ctrl+h does the same thing as the backspace key (i.e. deletes one character backwards).
You can use u to undo. However it tends to erase the whole last line you typed...
Depending on the situation you can use the following text objects :
ciw to erase and rewrite the current word
c$ to erase and rewrite everything to the end of the line
c^ to erase and rewrite everything to the beginning of the line
ci) to change the content of parentheses
See :help text-objects for more.
If you need to change a single letter, the Vim way could be to use r to replace the wrong letter.
type tje home
Put your cursor on j using fj or Fj depending if your cursor is after or before j
Type r and then h

How do I insert a linebreak where the cursor is without entering into insert mode in Vim?

Is possible to insert a line break where the cursor is in Vim without entering into insert mode? Here's an example ([x] means cursor is on x):
if (some_condition) {[ ]return; }
Occasionally, I might want to enter some more code. So I'd press i to get into insert mode, press Enter to insert the line break and then delete the extra space. Next, I'd enter normal mode and position the cursor before the closing brace and then do the same thing to get it on its own line.
I've been doing this a while, but there's surely a better way to do it?
For the example you've given, you could use rEnter to replace a single character (the space) with Enter. Then, fspace. to move forward to the next space and repeat the last command.
Depending on your autoindent settings, the above may or may not indent the return statement properly. If not, then use sEnterTabEsc instead to replace the space with a newline, indent the line, and exit insert mode. You would have to replace the second space with a different command so you couldn't use '.' in this case.
A simple mapping to break the line at the cursor by pressing Ctrl+Enter:
:nmap <c-cr> i<cr><Esc>
essentially enters 'insert' mode, inserts a line break and goes back to normal mode.
put it in your .vimrc file for future use.
Here's how to create a macro that inserts a newline at the cursor whenever you press 'g' while not in insert mode:
From within vim, type:
:map g i[Ctrl+V][Enter][Ctrl+V][Esc][Enter]
Where:
[Ctrl+V] means hold the Ctrl key and press 'v'
[Enter] means press the Enter key
[Esc] means press the Esc key
You'll see the following at the bottom of your vim window until you press the final Enter:
:map g i^M^[
Explanation:
[Ctrl+V] means "quote the following character" -- it allows you to embed the newline and escape characters in the command.
So you're mapping the 'g' key to the sequence: i [Enter] [Escape]
This is vim for insert a newline before the cursor, then exit insert mode.
Tweaks:
You can replace the 'g' with any character that's not already linked to a command you use.
Add more to the command, e.g. f}i^M^[O -- This will find the } and insert another newline, then escape from insert mode and Open an empty line for you to enter more code.
You can add the command to your .vimrc or .exrc file to make it permanent. Just omit the colon from the beginning, so the command starts with "map"
Enjoy!
If you're usually expanding a one line block to three lines, try substitution. Change the opening bracket into bracket/return, and the closing bracket into return/bracket.
The command for substituting bracket/return for bracket looks like this:
:s/{/{\r/
Since you want to use this often, you could map the full sequence to an unused keystroke like this:
:map <F7> :s/{/{\r/ ^M :s/}/\r}/ ^M
Where you see ^M in the sequence, type [Ctrl-V], then press enter.
Now with your cursor anywhere on your sample line, press the mapped key, and the carriage returns are added.
Check :help map-which-keys for advice on selecting unused keystrokes to map.
Assuming you're okay with mapping K to something else (choose a different key of your liking), and using marker ' as a temporary marker is okay why not do this?
:nmap K m'a<CR><Esc>`'
now pressing K in normal mode over the character after which you want the line break to occur will split the line and leave the cursor where it was.
Basically, when you split a line you either want to just insert a carriage return, or in the case that you're on a space, replace that with a carriage return. Well, why settle for one or the other? Here's my mapping for K:
"Have K split lines the way J joins lines
nnoremap <expr>K getline('.')[col('.')-1]==' ' ? "r<CR>" : "i<CR><Esc>"
I use the ternary operator to condense the two actions into one key map. Breaking it down, <expr> means the key map's output can dynamic and in this case hinges on the condition getline('.')[col('.')-1]==' ' which is the long winded way to ask vim if the character under the cursor is a space. Finally, the familiar ternary operator ? : either replaces the space with linebreak (r<CR>) or inserts a new one (i<CR><Esc>)
Now you have a lovely sister key map to the J command.
Vim will automatically kill any whitespace to the right of the cursor if you break a line in two while autoindent (or any other indentation aid) is enabled.
If you do not want to use any of those settings, use s instead of i in order to substitute your new text for the blank rather than just inserting. (If there are multiple blanks, put the cursor on the leftmost and use cw instead.)
In fact you need the following combined operations:
Press v to enter Visual Mode
Select the line you want to split
Press : to enter in Command Mode
s/\s/\r/g
Done
If you have the input:
aaa bbb ccc ddd
and want to output
aaa
bbb
ccc
ddd
You can use the command
f r<ENTER>;.;.
o ESC command will do it for you.
Set this key mapping in your vimrc
:map <C-m> i<CR><Esc>h
Then press Ctrl+m if you want to use it in your vim.
IMHO, the built-in mapping gs is not a useful mapping (put vim to sleep), one could use this for splitting:
nmap gs i<CR><ESC>
In Vrapper you can use gql which will split a line without entering insert mode, but may not always maintain indentation.
I found this to be the most faithful implementation of what I'd expect the opposite behaviour to J
nnoremap S i<cr><esc>^mwgk:silent! s/\v +$//<cr>:noh<cr>`w
It does the simplistic new line at cursor, takes care of any trailing whitespace on the previous line if there are any present and then returns the cursor to the correct position.
i <cr> <esc> - this is one of the most common solutions suggested, it doesn't delete non-whitespace characters under your cursor but it also leaves you with trailing whitespace
^mw - goto start of new line and create a mark under w
gk - go up one line
:silent! s/\v +$//<cr> - regex replace any whitespace at the end of the line
:noh<cr> - Clear any search highlighting that the regex might have turned on
`w - return the the mark under w
Essentially combines the best of both r<esc><cr> and i<cr><esc>
Note: I have this bound to S which potentially overwrites a useful key but it is a synonym for cc and since I don't use it as often as I do splits I am okay with overwriting it.
This mapping will break up any one-line function you have. Simply put your cursor on the line and hit 'g' in normal mode:
:map g ^f{malr<CR>`a%hr<CR>`a
This assumes that you have a space after the opening brace and a space before the closing brace. See if that works for you.

Resources