I'm completely new to Vim and finding that most users assume that everyone instinctively knows how to use it ;)
I'm using it with Git and trying to figure out how to move a line up or down in a rebase command.
This answer says that I can do the following
ddkP
but I don't understand what to do. If I just type it in, how will Vim know which line I want to move?
Clarification appreciated!
ddkP
is actually three low-level commands put together into a single high-level one, performed in normal mode (the mode you are in by default):
dd cuts the current line,
k moves the cursor up by one line,
P puts the line that was cut above the current line.
So, you have done $ git rebase -i, which opened Vim with something like the following, in normal mode:
pick 07c5abd Introduce OpenPGP and teach basic usage <-- current line
pick de9b1eb Fix PostChecker::Post#urls
pick 3e7ee36 Hey kids, stop all the highlighting
pick fa20af3 git interactive rebase, squash, amend
and you want to move 3e7ee36 up.
This is done by moving the cursor down two times with jj, making 3e7ee36 the current line:
pick 07c5abd Introduce OpenPGP and teach basic usage
pick de9b1eb Fix PostChecker::Post#urls
pick 3e7ee36 Hey kids, stop all the highlighting <-- current line
pick fa20af3 git interactive rebase, squash, amend
then cutting the line with dd, making fa20af3 the current line:
pick 07c5abd Introduce OpenPGP and teach basic usage
pick de9b1eb Fix PostChecker::Post#urls
pick fa20af3 git interactive rebase, squash, amend <-- current line
then moving the line up with k, making de9b1eb the current line:
pick 07c5abd Introduce OpenPGP and teach basic usage
pick de9b1eb Fix PostChecker::Post#urls <-- current line
pick fa20af3 git interactive rebase, squash, amend
then putting the previously cut line above the current line with P, effectively switching the two lines and thus moving 3e7ee36 up:
pick 07c5abd Introduce OpenPGP and teach basic usage
pick 3e7ee36 Hey kids, stop all the highlighting <-- current line
pick de9b1eb Fix PostChecker::Post#urls
pick fa20af3 git interactive rebase, squash, amend
And that's about it.
Vim is no different than other professional tools like Photoshop or Blender or what have you. Anyone can start them and poke around without any prior experience but there is some learning and training necessary to extract the most value from them.
In Vim's case, you have two invaluable built-in resources at your disposal:
If you only use Vim casually, for quick edits like $ git commit or $ rebase -i, then going through $ vimtutor at least one time is pretty much required. Case in point, the command that is giving you trouble is explained under lesson 3.1.
If you plan to use Vim as your main editor, then the most sensible thing to do is to start an active reading of the user manual, :help user-manual. It is actually a thorough tutorial that takes you from "noob" to "advanced" in a very approchable, iterative manner.
If you think all of this is too much work for too little gain, then I would suggest you stick to nano or some similar, more comfortable, editor. There is no point picking up a notoriously weird and complex tool if you don't want to put in the required effort.
Sample rebase taken from this article.
These are Normal mode commands. Normal mode is what makes Vim different from other editors.
Say, in a "regular" editor if you press d you type "d" letter; so to delete the current line you need some special key combination, e.g. Ctrl-Y.
In Vim you press simply dd (without any controls, alts or such) to delete the current line. The drawback is that you have to switch to special Insert mode to be able to type letters. (And hence at some point also to switch from Insert back to Normal). So using Vim effectively implies "mode switch optimization", that is, a vimmer should have a few dozen of (Normal mode) tricks at his "fingertips". In fact, this is not so uncommon for an experienced user of any application, but in Vim beginners really suffer until they are able to type ddkP and other simple stuff without even thinking.
So typing ddkP in Normal mode means: "delete (cut) current line" (dd); then "move cursor up" (k); then "put (paste) the (last cut) line before current cursor (line)" (P).
Please, also note that complete beginners are strongly encouraged to go through vimtutor.
Related
My Rails production.log has 2000000 lines. How can I scroll down to the last line with Vim?
I scroll down with Ctrl+F and Ctrl+D but it's not fast enough.
Alternative motions
Note that you can prefix motions like j or Ctrl + F with a number (multiplier), called [count] in the (excellent) :help. That gets you around a large buffer fast.
Another beneficial, but less known command is N%, to jump to a percentage in the file, e.g. the middle with 50%.
Best solution
But your particular problem is indeed best addressed by G, or :$ followed by Enter.
Additional help
With such a large file, navigation in Vim may be sluggish. Have a look at the LargeFile - Edit large files quickly plugin, which changes some options to speed up Vim.
Tips
If you're new to Vim (and its navigation and editing commands), you should spend 30 minutes on the vimtutor that comes with it (see :help vimtutor inside Vim). Then, there are several good resources, cheatsheets, and vi / Vim tutorials out there on the net. http://vimcasts.org/ has several short entertaining episodes that go beyond the basics.
Learn how to look up commands and navigate the built-in :help; it is comprehensive and offers many tips. You won't learn Vim as fast as other editors, but if you commit to continuous learning, it'll prove a very powerful and efficient editor.
According to this article:
To move to end of file just type G (press ESC and type capital G):
You can also go to a specific line with the line number followed by G, for example to go to line 123 you would do
123G
G is the key. if you want to open the file with cursor positioning on the last line, you can:
vim + foo.log
Further to the other answers, if the first thing you do when you open the logfile is jump to the end, have vim open the file straight at the end with:
vim /path/to/logfile +
Alternatively, as in my comment above, try opening it in a pager such as less if you're not actually editing the file. Again, you can jump straight to the end of the file from the command line:
less +G /path/to/logfile
More generally, both these forms (with the + argument) allow you to specify a command to run on startup.
vim defaults to jumping to the end of the file if no command is given, whereas less requires you to specify the G command. Both less and vim support searching for a specific string (e.g. a date) on opening the file with:
vim +/2014-02-28 /path/to/logfile
less +/2014-02-28 /path/to/logfile
I often work with files next to one another, in a :vsplit. Moving a line, or any obj from the file in one window to another is suboptimal. I was wondering if there is a movement I am missing.
What I do now: 3dd[ctrl]wwP[ctrl]ww. Roughly:
Remove a bunch of lines (could be anything from a line to any text-obj to a visual selection)
Move custor to other window.
Paste
Move cursor back to other window.
Vim in vimdiff mode allows :diffput and :diffpull to move lines in a diff between the two splits. Is there something similar for any two files in any two splits?
No, there is no such generic command.
:diffput and :diffget are possible because the origin and target are known: the location of your cursor corresponds to a specific range in both buffers so it's "easy" for Vim to know what to do with what and where.
A generic "take this, put it over there and come back" command is harder to design because not much is known about the target and a lot of things must be infered from the context of the command, your window layout or even the kind (linewise, characterwise, blockwise) of the text you are moving around. An important thing to decide, for example is "how to paste": p, P, :put or even if we need to re-indent. A very simplistic implementation would look like this:
:command! To :wincmd w|put|wincmd w
but it's obviously not smart enough to be really generic. I'm afraid what you want requires quite a bit of thinking and vimscript.
I'm new to vim (for the seventh time) so this may not be something that makes sense for vim style but:
The command history in the command window has up-arrow mapped to history and this has been very helpful in learning, except that it does not seem to store commands that fail to execute in the history. Obviously, this is a bad configuration choice for someone trying to learn from mistakes. Is there a way to force it to remember the failed commands, in the sense that they can be recalled with the up-arrow?
FYI, I am using MacVim with Janus extensions.
What kind of error are you talking about? :s/foo/bar is always recorded into history, even if there was no foo on the current line and you get E486.
As a side note, if you use Ex commands a lot you might be interested in the Command line window, invoked by q:, that you can navigate and edit just like any other window. It's really great.
Also, drop Janus as soon as possible! That pile of crap is the absolute worst thing to install when learning to use Vim. Seriously.
Sometimes I hit the wrong keys on my laptop's small keyboard, and odd navigation or editing occurs (sometimes a feature that's new to me).
Although I can undo the editing (u) or navigation (control-o), I don't know what I did wrong, so it's difficult to avoid it in future. It's also frustrating to not know what just happened. So, I would like to be able to see my last few keystrokes.
A bit like :set showcmd, but to show the literal keystrokes, and (ideally) a short history of them.
I've only found commandline and navigation history in help/google.
To clarify: I'm not looking for commandline history, but keystroke history. e.g. did I press ) accidentally and go to the next sentence? Did I press dd and delete a line? I guess it's similar to a keystroke logger.
Commandline history (:history) only shows commands entered at the : prompt.
A bit old, but I've just found this on reddit:
You can start vim with the -w flag to write all keystrokes in a file. See :h -w
vim -w filename
To my knowledge, the closest you can get is the q command, which records your keystrokes into a register of your choice. Obviously, that has to be set up a priori as it's intended for complex repeats, although you could probably hack something to start recording on every file open. There's the matter of memory usage and that annoying "recording" prompt though.
Probably the most straightforward way would be to install keylogging software. I don't have any personal experience with these, but the security implications are probably mild if you get it from a trustworthy source or build it yourself, set it to only log to memory not a disk, only have a buffer the size of a sentence or so, or only log for vim windows.
More recently I came across a logging plugin for Vim and it reminded me of this question:
http://wolever.net/~wolever/wiki/vim-logging
It basically records everything you do for later analysis, it was intended for getting statistics about command usage but should work perfectly for finding what those magic commands you accidentally entered were.
:history will show your command history - that should help you uncover the new features that we all uncover in vim with misplaced keystrokes.
Gundo - Is probably worth a look, whilst perhaps not exactly what you are looking it will help slightly.
It lets you visualise the Vim undo tree, this means you will be able to see the last edits that happened. For example if you accidentally deleted a line or some such this will show up in the tree, however, it doesn't show you the actual keystrokes that were pushed and will not show things such as cursor movements.
I've used vi for decades, and am now practicing using vim, expecting
eventually to switch to it entirely.
I have a number of questions, but I'll start with the one that
troubles me most. Something I have long done in vi is to type
a bottom-line command into the file I am editing, yank it to a named buffer
(e.g., using the keystrokes "ayy) and execute that buffer (using
:#a^M). This allows me to edit complicated commands till they
work right, and to keep commands that I will use many times as I
work in a file. (I have
in my .exrc file a mapping that reduces this yank-and-execute to a
single keystroke; but that isn't relevant to my question.)
I find that in vim, I need a lot more ^Vs than in vi. This
means, on the one hand, that when I have some command-line in a file
that I expect to use this way, I now need to keep it in two
versions, one for vi and one for vim. Also, the requirement of the
extra ^Vs seems inelegant: evidently various special characters
that are interpreted once when the named buffer is executed in vi
are interpreted twice when its is executed in vim -- but why?
As an example, a command of the form
map =f :w^V|e foo^M
(mapping the keystroke-sequence =f to write the current file
and go to the file foo) works this way in vi, but has to have the form
map =f :w^V^V|e foo^V^M
in vim. (Here in both commands, ^V is gotten by typing ^V^V,
and ^M is gotten by typing ^V^M; so typing the first version
involves typing three ^Vs, and the second, seven.) To be
exact: the first version does work in vim if one actually
types it into the bottom line (with the indicated extra ^Vs);
but the latter is required in an executed named buffer.
Any explanation? Anything I can set to fix this? ("compatible"
doesn't seem to do it.) Any hope that it will be fixed in a future
release? (The system I am on uses version 7.0.)
(I should confess that I'm not a programmer; just a user who has
become proficient in vi.)
Personally, I'd stop using ^V completely. In Vim (I've no idea about Vi), there are various key notations that get round the problems you're having. For your specific example, I'd recommend:
map =f :w<bar>e foo<CR>
where <bar> means 'insert the vertical bar here' and <CR> means 'insert a carriage return here'. See:
:help key-notation
for more information. I find the <CR> much easier to understand than ^V^M.
That's an interesting way of using :#, which I hadn't thought of before. I generally just use the command line history when I need to edit complicated commands, and I tend to save common or complicated commands as mappings or commands in my .vimrc (of course, I have a mapping that will pop open my .vimrc in a new tab). But there are certainly benefits to using vim's normal mode rather than command line mode for editing a complicated command.
As I understand it, you not only want to avoid so many <C-V> characters, you would also like to be able to use the same commands in vim and vi. Unfortunately, that would preclude you from using the (preferred in vim) key-notation. I think that you should be able to use the cmdline mode's Ctrl-R Ctrl-R register to help you out (:help c_<C-R>_<C-R>). E.g.
map <Leader>e mm^"ay$`m:<C-R><C-R>a<CR>
mm - mark cursor location so we can return later
^"ay$ - yank current line into register a (ignoring whitespace at beginning and newline at end)
``m` - return cursor to start position
: - enter command line mode
<C-R><C-R>a - place the literal contents of register a onto the command line, which seems to be where your problem with vim versus vi was coming to into play. I think that <C-R>a would give you the same behaviour you are seeing now with :#a.
- execute the whole thing
Using that mapping, I then typed your example of map =f :w^V|e foo^M into a file, placed my cursor on that line, ran my <Leader>e mapping, verified that your =f mapping had loaded correctly, and then ran it. Obviously you'll want to customize it to fit your needs, but I think that playing around with <C-R><C-R> will basically get you what you want.
All of that said, if you can, I'd strongly recommend taking the plunge and forgetting about compatibility with vi. Then you can use the much simpler key-notation and a host of other vim features. :-)