Vim, do an operation after going to a specific line - command-line

In Vim you can travel to a given line by entering vim's command mode and enter that given line's number there.
I want a specific operation to always take place after moving to a line number in that way.
How do I do that?
This is intended to adjust the screen, by the way.

Normally you enter either of the following in order to jump to line #123 in command mode:
123G
123gg
You just need to find a key to map your new command to (I would recommend using the leader key, which was created for exactly this purpose):
noremap <LEADER>G G:YourCommand<CR>
noremap <LEADER>gg gg:YourCommand<CR>
" Now you can type 123\G instead (assuming you
" have not changed your default leader key)
Or, you can overwrite the existing key (not recommended, as it might mess up other scripts):
noremap G G:YourCommand<CR>
noremap gg gg:YourCommand<CR>

Related

Move to specific line and column in one command

Let's say we have a text file that is very long and has many lines. I want to move to 30th line and 15th column in this file.
Are there any VIM commands that could be used to move to mentioned line number and column in one command? Thanks.
Please, do not suggest to use smt like :30 command and after 15| this is NOT an option.
May VIM has an option to input smt like: :30,15, just in another syntax?
The only option I found is to use :call cursor(30,15) but it looks little bit too long, as I need to type it each time I want to jump to the another position.
You can define your own command-line command. Define it in ~/.vimrc and it will be available everywhere. Define:
:command -nargs=* Go call cursor(<f-args>)
Run:
:Go 30 15
Well, you want to move across two dimensions but Vim commands are limited to one dimension, therefore you can't move to line 30 and column 15 with a single built-in command.
Here are the shortest key sequences to move to column 15 of line 30:
" in normal mode
30G15|
" in command-line mode and normal mode
:30<CR>15|<CR>
" in command-line mode
:30norm15|<CR>
" from the shell
$ vim foo.txt +norm30G15\|<CR>
Note that the first suggestion above is already the shortest theoretically possible sequence because you would need:
at least one key for the command itself,
at least one key to separate the two coordinates,
the vertical coordinate (can't be shortened),
and the horizontal coordinate (can't be shortened).
The only improvement I can think of to 30G15| would be to use keys that don't require a modifier but, frankly, I am not sure that it is worth the hassle.

Does `evil-mode` have vim like `changes` function?

As per vim wiki:
Vim remembers the locations where changes occurred. Each position
(column number, line number) is recorded in a change list, and each
buffer has a separate change list that records the last 100 positions
where an undo-able change occurred.
One can then use g; to move to the last change in the change list. This list survives through different sessions. This means, that even if one did not make any change to the file after opening it in a new session, g; will move the cursor/point to the line where the latest change occurred in previous session.
From what I can tell, evil-mode does not have the change list per buffer which survives session. Or does it?
You probably want to have a look at Undo Tree, which is used by evil-mode if undo-tree is installed. I do not think that it has the g; functionality that you describe though. It can, however, maintain undo history between sessions.
Take a look at goto-last-change on melpa. Evil has default integration through g;.

Is there a way to make regions in term modes respect line wrapping?

When using a term mode derivative (like ansi-term or multi-term), I often want to select a region and copy it someplace else. If that region includes a line which wraps at the edge of the terminal window, pasting that region in another buffer always inserts a hard newline at the place where term wrapped the line. This means I often have to go back and clean up pasted text. Is there a way to avoid doing this? I tried both term-line-mode and term-char-mode; both do the same thing.
I do not want to write a yank hook which strips out all newlines, since I want to preserve existing hard newlines in the original content.
This works for me:
(setq term-suppress-hard-newline t)

ISPF Editor: Changing characters to upper case?

I am fairly new to working in a z\OS environment, I've tried Googling this but found no result.
I'm creating a data set member in the ISPF edit window. However, every time I exit out of the file, save it, try to submit it as a JCL job, it will convert all the characters to upper case.
How can I stop this happening?
While in ISPF Edit on a member, if you type PROFILE on the "Command===>" line and press Enter, you will likely see CAPS ON included in your current options. You can change this by doing the following...
PROFILE UNLOCK
CAPS OFF
PROFILE LOCK
...on the Command===> line, pressing Enter after each.
The ISPF documentation is quite extensive. The above are what ISPF calls primary commands. The ISPF editor is quite powerful, there are SHARE presentations on its features.
ISPF Edit also has line commands, entered by overtyping the line number for a given line. Two such are UC and LC, which correspond to Upper Case and Lower Case respectively. They do just what you'd think, the former folds all text to upper case and the latter folds all text to lower case. Numbers and special characters are unaffected.

How can I script vim to run perltidy on a buffer?

At my current job, we have coding-style standards that are different from the ones I normally follow. Fortunately, we have a canned RC file for perltidy that I can apply to reformat files before I submit them to our review process.
I have code for emacs that I use to run a command over a buffer and replace the buffer with the output, which I have adapted for this. But I sometimes alternate between emacs and vim, and would like to have the same capabilities there. I'm sure that this or something similar is simple and had been done and re-done many times over. But I've not had much luck finding any examples of vim-script that seem to do what I need. Which is, in essence, to be able to hit a key combo (like Ctrl-F6, what I use in emacs) and have the buffer be reformatted in-place by perltidy. While I'm a comfortable vim-user, I'm completely clueless at writing this sort of thing for vim.
After trying #hobbs answer I noticed that when filtering the entire buffer through perltidy the cursor returned to byte 1, and I had to make a mental note of the original line number so I could go back after :Tidy completed.
So building on #hobbs' and #Ignacio's answers, I added the following to my .vimrc:
"define :Tidy command to run perltidy on visual selection || entire buffer"
command -range=% -nargs=* Tidy <line1>,<line2>!perltidy
"run :Tidy on entire buffer and return cursor to (approximate) original position"
fun DoTidy()
let l = line(".")
let c = col(".")
:Tidy
call cursor(l, c)
endfun
"shortcut for normal mode to run on entire buffer then return to current line"
au Filetype perl nmap <F2> :call DoTidy()<CR>
"shortcut for visual mode to run on the current visual selection"
au Filetype perl vmap <F2> :Tidy<CR>
(closing " added to comments for SO syntax highlighting purposes (not required, but valid vim syntax))
DoTidy() will return the cursor to its original position plus or minus at most X bytes, where X is the number of bytes added/removed by perltidy relative to the original cursor position. But this is fairly trivial as long as you keep things tidy :).
[Vim version: 7.2]
EDIT: Updated DoTidy() to incorporate #mikew's comment for readability and for compatibility with Vim 7.0
My tidy command:
command -range=% -nargs=* Tidy <line1>,<line2>!
\perltidy (your default options go here) <args>
If you use a visual selection or provide a range then it will tidy the selected range, otherwise it will use the whole file. You can put a set of default options (if you have any) at the point where I wrote (your default options go here), but any arguments that you provide to :Tidy will be appended to the perltidy commandline, overriding your defaults. (If you use a .perltidyrc you might not have default args -- that's fine -- but then again you might want to have a default like --profile=vim that sets up defaults only for when you're working in vim. Whatever works.)
The command to filter the entire buffer through an external program is:
:%!command
Put the following in ~/.vimrc to bind it to Ctrl-F6 in normal mode:
:nmap <C-F6> :%!command<CR>
For added fun:
:au Filetype perl nmap <C-F6> :%!command<CR>
This will only map the filter if editing a Perl file.
Taking hobbs' answer a step further, you can map that command to a shortcut key:
command -range=% -nargs=* Tidy <line1>,<line2>!perltidy -q
noremap <C-F6> :Tidy<CR>
And another step further: Only map the command when you're in a Perl buffer (since you probably wouldn't want to run perltidy on any other language):
autocmd BufRead,BufNewFile *.pl,*.plx,*.pm command! -range=% -nargs=* Tidy <line1>,<line2>!perltidy -q
autocmd BufRead,BufNewFile *.pl,*.plx,*.pm noremap <C-F6> :Tidy<CR>
Now you can press Ctrl-F6 without an active selection to format the whole file, or with an active selection to format just that section.
Instead of creating a new keyboard shortcut, how about replacing the meaning of the = command which is already in people's finger memory for indenting stuff? Yes, perlcritic does more than just indent but when you use perlcritic anyways, then you probably don't want to go back to the inferior "just indent" = command. So lets overwrite it!
filetype plugin indent on
autocmd FileType perl setlocal equalprg=perltidy
And now we can use = just like before but with the added functionality of perlcritic that goes beyond just indenting lines:
== run perlcritic on the current line
5== run perlcritic on five lines
=i{ Re-indent the 'inner block', i.e. the contents of the block
=a{ Re-indent 'a block', i.e. block and containing braces
=2a{ Re-indent '2 blocks', i.e. this block and containing block
gg=G run perlcritic on the entire buffer
And the best part is, that you don't have to learn any new shortcuts but can continue using the ones you already used with more power. :)
I'm used to select text using line oriented visual Shift+V and then I press : an I have !perltidy -pbp -et4 somewhere in history so I hit once or more up arrow ⇧.