Escape command in a vimscrimpt - command

Can anyone help me how to put an <esc> command in a vimscript in order to switch from a insert visual mode (selection mode) to the visual mode?
This is my script:
if a:type == "'<,'>"
normal! "\<esc>\<esc>"
normal gvy
let myvariable= #+
endif
explication:
I have selected a piece of text. (I'm now in insert visual mode (=selection mode))
I have to select the same text in visual mode.
Without vimscript I just have to push 2 times the <esc> command and the command gv in normal mode to reselect the selection again and this time I'm in visual mode.
I tried to put the <esc> commands as in above script but it doesn't work.

You have completely wrong syntax for invocation of :normal.
normal! "\<Esc>\<Esc>"
will execute 14 characters in normal mode, none of them will be escape character: normal does not accept expressions. You have to use
execute "normal! \e\e"
(\<Esc> also works, but \e is faster to type). I see no reason in having two normal commands here so
execute "normal! \e\egvy"
. But I am still wondering what you do to invoke this script? Without this information the above is likely to prove being completely useless.
PS: I completely agree with #romainl that using easy mode and, more, using mouse in easy mode is completely wrong way of using vim.

What are you doing in insert visual mode in the first place? Are you using GVim in "easy" mode and using the mouse? There are better ways…
Anyway, instead of <Esc><Esc> you can use <C-g> to go from select mode to visual mode.
Without more background on your goal I can't be sure but I think that you are doing something unnecessarily complicated.

Related

Neovim: Change Cursor Type for Insert Mode

I'm new to (Neo) Vim and I'm trying to find configurations that I like and learn from them.
Whenever I watch people code in vim/neovim, I notice that their cursor a thick box, same as when they're outside of Insert mode.
Basically, while in insert mode, my cursor is thin like this |, but I want to change it so that it's thick like it is when you're outside of insert mode.
I'm on the latest version of Neovim and I use Windows 10 if that's useful information.
Yes, that is possible with guicursor option, but whether what option takes effect also depends on your terminal, for example, using Windows Termianl.
This is a working setting to make cursor shape block in insert mode:
set guicursor=n-v-c-i:block
which means to make cursor shape block in normal, visual, command, and insert mode. For more details, please use :h 'guicursor'.
You should be able to change that setting with guicursor. (For NeoVim there is termcap-cursor-shape.)
But note that the two different cursor actually make sense: In normal mode you are always on a character (i.e. you can use i and a to produce different results), while in insert mode the curor must be between two characters.
Personally I think that it would just get confusing to have a blocky cursor in insert mode due to the reason above, but furthermore it would make it harder to distinguish the two modes too!
And for future reference, there is a dedicated stackexchange for vi and vim!

Tab completion, rlcompleter in Emacs

I have a Python program which uses rlcompleter to provide custom Tab-completion. The completion works when it is run under a bash terminal. However, it does not work under emacs, in shell mode, nor in eshell mode.
I noticed that Tab is really bound to completion-at-point, eshell-pcomplete, and so on, so I tried an (insert "\t"), supposing that this would trigger the completion, which I understand happens when the child process reads a "\t" character. But this does not work either. Perhaps input is buffered until a "RET"?
Completion for commands like service, which define their own candidates, does not work as expected either.
How can I access these candidates within Emacs?
Try using M-x ansi-term. I find it behaves a bit more like what I have come to expect from a *nix terminal.

Would it be possible to jump between prev/next Terminal command prompts?

I'm using zsh in OS X Terminal.app and for quite a while, I've been longing for a way to jump back and forth between prev/next prompts in the terminal's output.
One convenience with this would be to be able to review (and track errors at) the end of each command's output; eg. when you building stuff from source with ./configure; make; make install. Note: I'm obviously not referring to jumping back and forth in the command-history, but for a way to take a peek at the endings of each command's output.
Has anyone heard of such functionality in the *nix (preferrably also Mac) world? Would it require some sort of OS-centric Terminal plugin, or can it be programmatically done via a shell script which can be tied to a keyboard shortcut? Maybe I'm the only one thinking about this? :)
Edit: Here's an example scenario: Let's say I want to compile and install some program (using standard ./configure && make && make install procedure) and after the make command, I run into some errors. Now, the way I understand it (I may be completely wrong), the crucial error causing the make command to fail usually shows up in the last line(s) in the output, no? Anyway, at this point, I might do something like cat INSTALL to read up on the INSTALL document to check whether there's something I've missed. NOW, if I want to go back to see what the error was, that caused my initial make command to fail, I then have to manually scroll up to that position again, since my cat INSTALL command printed a ton of text after it.
I don't know if this scenario is the most elucidative – but there are many other situations where I wish I could just "jump" back to previous prompt lines and check up on previous command output; whether it was a simple ls command, make, git status, or whatever it was – swapping positions in the window by means of using prompt lines as "bookmark" positions seems an interesting idea to me.
command + left or right goes between tabs in iterm. is this what you are asking?
Emacs has a shell-mode that runs a shell inside the Emacs editor, providing a rich environment of additional commands for navigating and working with shell commands. This includes commands for going to the previous/next prompt, and deleting the output from commands so you can "clean up" and issue another command.
If you aren't familiar with Emacs: to start a shell inside Emacs, run emacs from the shell, then type Esc-x (or Meta-x, if you have "Use option as meta key" enabled in Terminal > Preferences > Settings > [profile] > Keyboard). This will ask for a command to execute. Enter shell.
To see a list of commands you can use in Shell Mode, enter Control-h m. Here are the ones for moving the cursor to the previous/next prompt:
C-c C-n comint-next-prompt
C-c C-p comint-previous-prompt
These commands would also be useful:
C-c C-r comint-show-output
C-c C-o comint-delete-output

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 ⇧.

Is there any way to enable code completion for Perl in vim?

Surprisingly as you get good at vim, you can code even faster than standard IDEs such as Eclipse. But one thing I really miss is code completion, especially for long variable names and functions.
Is there any way to enable code completion for Perl in vim?
Ctrl-P (Get Previous Match) and Ctrl-N (Get Next Match) are kind of pseudo code completion. They basically search the file (Backwards for Ctrl-P, Forwards for Ctrl-N) you are editing (and any open buffers, and if you are using TAGS anything in your TAG file) for words that start with what you are typing and add a drop down list. It works surprisingly well for variables and function names, even if it isn't intellisense. Generally I use Ctrl-P as the variable or function I am looking for is usually behind in the code. Also if you keep the same copy of Vim open, it will search the files you have previously opened.
Vim 7 supports omni completion.
For example, I have this in my vimrc
autocmd FileType php set omnifunc=phpcomplete#CompletePHP
and then, when I press Ctrl-X Ctrl-O in Insert mode, I get a dropdown list of autocomplete possibilities.
Here's an omnicfunc for perl. No idea how well it works though.
Well, Vim's generic completion mechanism is surprisingly good, just using Ctrl-N in insert mode. Also, line completion is very handy, using C-x C-l.
Also check out this vim script for perl.
The standard Ctrl+N and Ctrl+P works even better if you add the following to your ~/.vim/ftplugin/perl.vim file:
set iskeyword+=:
Then it will autocomplete module names, etc.
The .vimrc clip in one of the other answers is slightly wrong. To turn your tab key into an auto-complete key, use this code:
inoremap <tab> <c-r>=InsertTabWrapper()<cr>
function! InsertTabWrapper()
let col = col('.') - 1
if !col || getline('.')[col - 1] !~ '\k'
return "\<tab>"
else
return "\<c-p>"
endif
endfunction
You can find this, and tons of other vim tricks in this thread at Perlmonks--which links to even more threads with lots more customizations.
You should look at the SuperTab plugin:
http://www.vim.org/scripts/script.php?script_id=1643
It let's you do completion (either the OmniCompletion or the regular completion) using tab and shift-tab instead of ^N and ^P.
https://github.com/c9s/perlomni.vim
Ctrl+N
This is explained in the Perl Hacks book, along with how to do Package completion. Highly recommended.