1

So, I recently tried switching my keybinds over to using the Leader key, which I've decided to make the space key, but that doesn't matter that much.

I've adapted to it pretty much instantly and I liked it much more than my old keybinds that were using the Alt key, but this really soon showed its problems: the Leader key, whatever it is set to, is a key that corresponds to a typable character.

Why's that a problem? While it isn't in stuff like my keybinds to switch buffers, for example, it is a problem if such a keybinding is used in order to toggle something that accepts inputting text, like the FTerm plugin, which allows you to run a terminal inside a floating window:

vim.api.nvim_set_keymap('n', '<leader>t', ':lua require("FTerm").toggle()<CR>', { noremap = true, silent = true })
vim.api.nvim_set_keymap('t', '<leader>t', '<C-\\><C-n>:lua require("FTerm").toggle()<CR>', { noremap = true, silent = true })

These sorts of keybinds aren't an issue if they're created with a modifier key since keybindings created like that don't result in something getting typed on the screen, but like this they create annoying edge cases like if you'd like to write some text that includes the Leader key in that terminal, it could actually turn on the keybind.

This isn't a technical problem. But since (N)Vim can't detect modifier key presses (being able to do stuff like :map <Alt>t action), and detecting only modifier key combinations (like :map <A-t> action), all Leader key keybindings are doomed to be normal mode-only keybinds. So, what I'm asking for is, how would you manage your keybindings for this, but still revolving around using the Leader key?

3
  • I'm not sure if this is quite on-topic as-is (perhaps the real issue is that FTerm captures <space> and translates it through the mapping?), but: in all the "input" contexts I get in regular vim (including :terminal and terminals in vim's popups), normal-mode mappings don't apply.
    – D. Ben Knoble
    Commented Jun 9, 2022 at 20:00
  • @D.BenKnoble It's not the issue that it captures, and then translates it. It's basically the same issue you would get if you use ; as your Leader key (which is a popular option) and then want to run your last f or t command (which is done with the same key). Vim will take a 1 second delay for a Leader keybind to be pressed, and then press the actual key once that delay is over with no registered key.
    – Andy3153
    Commented Jun 9, 2022 at 21:05
  • @D.BenKnoble ((continuation of first comment)) Same with this case, but it's worse, because if you type fast something that contains your leader key and then immediately a character that'd trigger the keybind, instead of typing that in the floating terminal, it'll execute the keybind (ex: typing sudo<space>touch will execute a <Leader>t keybind). What I'm asking for is: I'm out of ideas, how would a person comfortably create a keybind that works well around this?
    – Andy3153
    Commented Jun 9, 2022 at 21:05

1 Answer 1

2

This does look like a bug in FTerm. As mentioned in the comments, usually in situations like this, normal mode mappings should not apply. This is usually achieved by setting the buftype to terminal. However, this is apparently not done in FTerm, resulting in the behaviour you describe. I would propose to open an issue asking the maintainers if it would be possible to change the buftype to terminal. In the meantime, a workaround like the one sketched below should work, as they seem to set the filetype to FTerm. (Note: The l:condition1 and the tnoremap line are just for for testing/illustration since I don't use FTerm. This also adds a mapping for <leader>xx in terminal mode and then never uses is, since in terminal mode the buftype is terminal).

Instead of directly mapping nnoremap <leader>xx 3j, you now have to remap using the WrapMapExpr function, which will fall back to the original characters of the mapping if one of the conditions specified at the top of the function are met.

function! WrapMapExpr(expr,keys)
    let l:condition1 = &buftype == "terminal"
    let l:condition2 = &filetype == "FTerm"
    if (l:condition1 || l:condition2)
        call feedkeys(a:keys, 'n')
        return ""
    else
        return a:expr
    endif
endfunction

nnoremap <expr> <leader>xx WrapMapExpr("3j", mapleader . "xx")
tnoremap <expr> <leader>xx WrapMapExpr("3j", mapleader . "xx")
3
  • FTerm correctly assigns the buftype and filetype though: :echo &buftype -> terminal, :echo &filetype -> FTerm (on my system anyways). What I asked for was just how would someone else make their keybindings in case they use a leader key for keybinds that open windows that accept input, as I said it's inevitable when using keys that type characters. Also, this happens in more plugins: Jaq, Rnvimr (they all open floating windows). Plus, the code I included shows that I have manually created a terminal mode keybind too anyway.
    – Andy3153
    Commented Jun 12, 2022 at 12:24
  • Right, I did not see the tmap there. If I understand you correctly now, my workaround actually sounds like a possible solution to your problem: You want <leader>t to open FTerm in a regular terminal, but not in FTerm (and potentially other apps with buftype=terminal). Thus I would suggest removing condition1 and adding further conditions for all the other apps. You might also get away with keeping condition1 and changing condition2 to &filetype == ''.
    – Ingo
    Commented Jun 13, 2022 at 13:21
  • My problem is not really about that. It's more about trying to find convenient to use keybinds for situations like this, using the leader key. Maybe a better leader key I haven't found out about, or a way to use a leader key that doesn't type out a character to avoid all this, or some sort of rarely used key that's placed conveniently enough, or, the best thing, but currently impossible, a way to use a modifier key as a leader key.
    – Andy3153
    Commented Jun 16, 2022 at 9:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.