How to customize editor hotkeys in vim? - vim

I am using vim on a browser-based RDP session. Unfortunately, my browser is realllllly particular about capturing the "ctrl-w" key combo, because of unrelated-to-my-specific-use-case security reasons. This prevents me from using the pane feature of vim, because when I try to switch panes, my tab closes (!!!). Is there a way to change the "pane switch" hotkey to something besides "ctrl-w" in vim?

There is no "pane switch" "hotkey" in Vim. If you want to change <C-w> to something else you will have to do it for every single <C-w><something> command:
nnoremap <key>w <C-w>w
nnoremap <key>T <C-w>T
...
Now, what <key> to use is left as an exercise for you.

Related

Use AHK to detect the "Vim Mode" for GUI windows and configure conditional mappings of keys

The motivating story (TL;DR)
Terminals, due to historical reasons, won't distinguish tab from Ctrl+I. This makes quite a mess when I use Vim: my muscle memory tells me that Ctrl+I shall advance me forward to the next position in the "Jumplist", but some Vim-plugins do remap the tab key to do other good stuffs.
Better defined task
Can I make a "conditional mapping" for active windows from ahk_process gvim.exe when no "special characters" are shown at the bottom left corner of the active Window?
For the window on the left, the Vim session is in "Normal-mode"
For the window on the right, the Vim session is in "Insert-mode".
Other modes do exist, like Visual-mode
At the end of the days, I would like to map the tab key only in "Normal-mode". The best that I can come up with is to OCR a fixed region of pixels at the buttom-left corner, and make it a conditional. Yet, I am inexperienced for getting OCR jobs done in AHK.
Sidenote: I am asking for help from the Vim community the flipside of the same question: https://vi.stackexchange.com/questions/18796/may-i-have-a-vim-session-report-its-mode-in-its-window-title
No need for OCR/AHK hacks.
:nmap (and :nnoremap) maps only in normal mode.
:imap (and :inoremap) maps only in insert mode.
etc.
See :help :map-commands for the variety of different mapping commands for variety of modes.
If a plugin is overwriting a normal-mode mapping for Tab, see who the offender is by using :verbose nmap <Tab> (or its equivalent, :verbose nmap <C-I>), then look at its documentation to see how to rebind it (or in the worst case, eliminate the culprit).
There's no need to grab Vim's current mode to make it available to another application; that would be really cumbersome. If your eventual goal is to send different keys for <Tab> / <C-i> to Vim (e.g. <F13> instead of <Tab>), and you only want Vim to react differently in certain modes (e.g. normal mode), you can just map the other modes to again unify both keys:
:nnoremap <F13> ... " Functionality A
:nnoremap <C-i> ... " Functionality B
:map! <F13> <C-i> " Both keys continue to do the same in insert and command-line mode.

Key mapping confusion in VIM,How to make vim works in a smart way?

I want to bind Ctrl-w with :q command in vim That is to say, I want to use Ctrl-w to close the current window of vim,
So I add this to my ~/.vimrc :
nmap <C-W> :q<cr>
When I use this to close a window that has something unsaved,this command cannot work.
So I want to make it works in a smart way: When the content is saved, just close the window. When the content remains unsaved, ask me whether to close the window directly like this command
:0,$s/a/b/gc
I don't know if this is clear enough for you, but thanks in advance.
There's the :confirm command for that. Just put it in front of :quit:
:nmap <C-W> :confirm q<cr>
The simplest thing to do would be to set confirm in your vimrc - this will prompt you before closing without saving (and a few other things, too; see :help confirm).
Otherwise, you could write a little vim script which uses &modified and confirm() (see :help confirm()).

Netrw open files into tabs in opposite vertical window

Imagine I have :Vex after starting vim. I want to be able to press t and have the tabs appended to the opposite window rather than the Netrw window. Is this possible?
If I press P I can open the file into the split window but I would like to be able to tab through the files in the vertical split whilst having my Netrw window visible - just like Sublime or Komodo.
Possible?
And yes, I've scoured :h netrw!
Almost got it with some .vimrc remaps and options.
It looks like this http://i.imgur.com/rUf19SF.png
Usage:
run vim.
hit shift enter. this will open netrw as a sidebar (a small split window to the right) and focus it.
browse as usual and hit enter to open a file. this will open it in the left window by default and focus it.
hit control-w control-w. this will focus netrw again.
browse as usual but this time hit control-enter to open a file. this will open it in a new tab that also contains the netrw sidebar.
The .vimrc config:
" netrw magic
" enable mouse usage. makes it easier to browse multiple tabs
set mouse=a
" hide netrw top message
let g:netrw_banner=0
" tree listing by default
let g:netrw_liststyle=3
" hide vim swap files
let g:netrw_list_hide='.*\.swp$'
" open files in left window by default
let g:netrw_chgwin=1
" remap shift-enter to fire up the sidebar
nnoremap <silent> <S-CR> :rightbelow 20vs<CR>:e .<CR>
" the same remap as above - may be necessary in some distros
nnoremap <silent> <C-M> :rightbelow 20vs<CR>:e .<CR>
" remap control-enter to open files in new tab
nmap <silent> <C-CR> t :rightbelow 20vs<CR>:e .<CR>:wincmd h<CR>
" the same remap as above - may be necessary in some distros
nmap <silent> <NL> t :rightbelow 20vs<CR>:e .<CR>:wincmd h<CR>
Caveats:
The netrw "sidebar" in each tab is independent, meaning the current directory in a tab may not be the same in another tab. Suggestions? Thought of using the netrw buffer in every "sidebar" window, but netrw uses a new buffer whenever changing directories.
You seem to be confusing Vim's "tabs" with the "tabs" you can find in virtually every other program.
Unlike other implementations, Vim's tabs are not tied to a buffer. In Vim, "tabs" behave like what you would call "workspaces": they are meant to keep together one or more windows. Those windows could display any buffer and you can very well end up with the same buffer displayed in multiple windows in multiple tabs!
With that in mind, it would be very wrong to use them like you want. "Tabs" don't represent files and jumping to another "tab" is not equivalent to jumping to another file at all.
The window created by :Vex is a normal window. Like all the other windows, it is contained in a "tab" and can't live outside of a "tab". And you can't have "tabs" inside of windows.
So, basically, what you ask is impossible.
If you are on a Mac and this "other-editor-like feature" is really important for you (more important than, say, embrace the Vim way), you could try this MacVim fork that adds a "regular" file explorer outside of the buffer/window/tab trio. You could also try PIDA which tries to build an IDE around Vim; including a separate file explorer.
As romainl said, tabs are not files (or buffers). So, if I re-interpret your question to mean: "I want to press t and have files appear in the opposite window...". Then I suggest reading :help netrw-C. If you really do mean "append" and not "appear", then that's more involved and before I expend the effort to figure out how to do so I'd like to know that that's what you really meant. The latest netrw (as of today, that's v153f) has additional options which are mentioned in that help reference I gave above.

How do I remap control-shift-leftmouse in gvim?

I'd like to remap a modified click in gvim (and also MacVim), but certain combinations of modifiers work while others do not. In gvim on a Linux box, I would like to insert "hello" anywhere I type:
:noremap <C-S-LeftMouse> <LeftMouse>ihello<ESC>
However, that command does not work: control-shift-click retains its original behavior. Yet I can remap control-click in gvim:
:noremap <C-LeftMouse> <LeftMouse>ihello<ESC>
In MacVim, command-shift-click <D-S-LeftMouse> is likewise unresponsive, as are most other modified clicks.
How can I actually remap the modified mouse clicks?
To remap the <C-LeftMouse> in MacVim, you should first disable the contextual menu:
defaults write org.vim.MacVim MMTranslateCtrlClick 0
Double modifier keys don't work in MacVim. It's a known limitation/bug.
:nnoremap <M-LeftMouse> <LeftMouse>ihello<Esc>
seems to work, though, but neither <C-LeftMouse> nor <D-LeftMouse> do.
<C-LeftMouse> brings the normal contextual menu everyone expects, I wouldn't count on it being easily changed.
<D-LeftMouse> does nothing at all. I wonder if it's even registered.

Map shift-tab in vim to inverse tab in Vim

I've done some searching and found a wealth of information on binding keys in vim, but I can't find out, for sure, how to map shift-tab. Or what command I need to map it to for it to "tab backwards".
This is what I have at the moment:
map <S-tab> <S-,><S-,>
Possibly Relevant Information:
I'm running Debian with Terminal 2.22.3. with VIM - Vi IMproved 7.1
Vim already has built-in key commands for insert mode to shift the current line left or right one &shiftwidth. They are (in insert mode):
Ctrl-t : shift right (mnemonic "tab")
Ctrl-d : shift left (mnemonic "de-tab")
If you still want to use shift-tab, this is how you do it:
" for command mode
nnoremap <S-Tab> <<
" for insert mode
inoremap <S-Tab> <C-d>
Debugging why shift-tab in vim isn't performing an inverse tab in Vim
If you placed the code inoremap <S-Tab> <C-d> into your .vimrc and vim still isn't responding in insert mode, then that means your Shift-tab is being intercepted, gobbled, and ignored somewhere in the perilous 4-part journey between your keyboard and vim. You need to figure out where your Shift-Tab is getting silently orphaned.
Four stage journey of Shift+Tab between keyboard and vim
Keyboard -> Operating System
The first step of a keystroke's journey is the operating system that intercepts all keys and stops some of them to perform a behaviors for the Operating system. For example Alt+Tab which often means "change focus of current window to the next". If you send Alt+Tab into vim, vim will not respond because the operating system gobbled it. You have to find this keymapping area on your operating system. Windows, Mac and Linux are all different, and they have different programs that manage which keys are intercepted and which pass through to applications. Find this area and make sure your Shift+tab is set to pass-though to the Terminal you use.
Operating System -> Terminal Application
Step 2 assumes the OS allowed your Shift+Tab to pass through to your terminal Application that has focus. Your terminal application should have a configuration menu option (Most have more than one, that fight each other) under Settings -> shortcuts, or settings -> keymaps. There are hundreds of terminal apps out there and each have different ideologies for which keystrokes to trap and gobble and perform some action native to the app, or which to pass through to the shell. Find this area and make sure your Shift+tab is allowed to pass through and is passing through.
Terminal Application -> your Shell
Step 3 assumes your Terminal application allowed Shift+Tab to pass through to the shell. There is an area that defines which key combos are intercepted to perform an action on the shell, which pass through to the application that is on the front. For me this is inputrc but mac and Windows have different areas. You'll have to find this file and clear out anything that may be gobbling your Shift+Tab and erase that, or add a rule that says pass through.
Shell -> vim
Now we're at the level of Vim where the .vimrc can hear, trap and or rebroadcast the Shift+Tab to the next step in the command chain, and do whatever you want while it does so. Vim has the map keyword that controls this.
There's even a 5th step in the journey if we're talking about Browsers or webpages, who have interpreter engines that allow client side code to remap keys. But that's for a different post.
Debug chain instructions to isolate where your Shift+Tab is orphaned:
Make sure your OS isn't gobbling your Shift+tab and performing no-action. Try a different application like Eclipse, Browser or Notepad, and see if Shift+Tab performs any action. If it does then The OS is likely passing through your Shift+tab unaffected to applications.
Make sure your terminal app can receive and is receiving the Shift+Tab. Verify this by going to settings -> Shortcuts and erase any keymap that has Shift, or Tab in the name, then make a new keymapping that intercepts Shift+tab and performs some simple action like new tab doesn't matter. Save it, put focus in the terminal and press it, if a new tab appears then Terminal can hear and respond.
Make sure your terminal is passing through Shift+Tab to shell. Erase anything smelling of Tab or Shift in Settings -> keymaps and Settings -> Shortcuts. The default action (should be) do nothing and pass through.
Open any other shell program like nano, ed, or emacs. If any of these perform any action when you press Shift+Tab, then it's likely that the terminal is passing through Shift+tab to vim.
At this point we know vi/vim is receiving Shift+Tab, but not responding to it. To isolate the problem, blow away all your vim config files like .vimrc, .profile and anything under .vim. The problem could even be with vim or under /etc You run vanilla vim using vim -u NONE and make sure you're running vim. Vim's default behavior is straight pass through. So if Shift+Tab isn't doing something, then vi is bugged.
Uninstall vim with a blank config files/directories and re-install. If this doesn't work, then your operating system is bugged. Reinstall the operating system. If this doesn't work, throw the computer in the trash.
To test if vim actually gets your shift+tab go into insert mode
ctrl+v then tab and it should create a tab character
ctrl+v then shift+tab and it should create an inverse tab character (which appears as ^[[Z)
If it does not, then vim is not receiving the shift+tab input
In my case it was my terminal.
In the terminal window -> settings -> shortcuts
search shift+tab and unmap
OP's question specifies map, which applies to normal, visual, select, and operator-pending modes (see :h mapmode-nvo). I'm not sure such a mapping makes any sense in operator-pending mode, but it's very useful in visual and select modes. I'll also add forward indentation for completeness:
" both visual and select modes at once. gv means reselect the last selection
vnoremap <Tab> >gv
vnoremap <S-Tab> <gv
" just visual mode. this is unsurprisingly the same as vnoremap
xnoremap <Tab> >gv
xnoremap <S-Tab> <gv
" just select mode. <C-o> leaves select mode for visual mode, where the
" command is performed, and <C-g> reenters select mode from visual mode
snoremap <Tab> <C-o>>gv<C-g>
snoremap <S-Tab> <C-o><gv<C-g>
Please do note that Tab and CTRL-i map to each other in most terminal emulators, so mapping Tab can have unexpected results. See this question for more.
The following can be used with Vim tabs:
map <TAB> <ESC>gt<CR>
map <S-TAB> <ESC>gT<CR>

Resources