Giter Club home page Giter Club logo

Comments (7)

justinmk avatar justinmk commented on August 28, 2024

Mapping meta does not work in the terminal because Vim cannot tell the difference between meta and esc. Neovim in the terminal works fine with meta maps (as well as <esc> map), but it means that the opposite issue occurs: neovim/neovim#2017

from vim-sexp.

guns avatar guns commented on August 28, 2024

Hi @gsavovski,

I make Meta mappings work in my terminal by explicitly setting them on
startup.

For example, if your terminal sends \033a when you press <M-a> on your
keyboard, you can teach vim this keystroke with:

execute "set <M-a>=\<Esc>a"

Therefore, to make <M-…> work in a terminal that sends \033:

" Timeout quickly on key codes to differentiate from normal <Esc>
set ttimeout ttimeoutlen=0

" Special named keys that cause problems when used literally
let namedkeys = { ' ': 'Space', '\': 'Bslash', '|': 'Bar', '<': 'lt' }

" Map Alt + ASCII printable chars
for n in range(0x20, 0x7e)
    let char = nr2char(n)
    let key  = char

    if has_key(namedkeys, char)
        let char = namedkeys[char]
        let key  = '<' . char . '>'
    endif

    " Escaped Meta (i.e. not 8-bit mode)
    "  * Esc-[ is the CSI prefix (Control Sequence Introducer)
    "  * Esc-O is the SS3 prefix (Single Shift Select of G3 Character Set)
    if char !=# '[' && char !=# 'O'
        try
            execute 'set <M-' . char . ">=\<Esc>" . key
        catch
        endtry
    endif
endfor

unlet namedkeys n key char

I've always meant to package this bit of vim voodoo into a plugin, but never
got around to it. In fact, when I originally wrote vim-sexp, I had been using
this setup for so long that I forgot that <M-…> does not work in vim by
default.

Hence https://github.com/tpope/vim-sexp-mappings-for-regular-people

:)

EDIT (removed discussion of binding <4-…>, simplified code example):

@justinmk just brought up a good point: this will cause <Esc> to behave
badly unless we set ttimeout and ttimeoutlen:

set ttimeout ttimeoutlen=0

Setting ttimeout{,len} can have its own issues, but I don't find it to be a
problem in practice. You can increase ttimeoutlen if you are using Vim over
an especially slow network connection.

In truth, none of this has personally never bothered me as I use <C-c> in
place of <Esc>.

Hope this helps!

Thanks for the reminder @justinmk!

from vim-sexp.

guns avatar guns commented on August 28, 2024

@justinmk

Oops, forgot about that side effect. Appending my first post now...

from vim-sexp.

guns avatar guns commented on August 28, 2024

Okay, I've updated my comment with discussion of ttimeout{,len}.

It's surely a hack, but a serviceable one nonetheless.

from vim-sexp.

guns avatar guns commented on August 28, 2024

@gsavovski

One more thing I forgot to mention: Meta mappings work by default in vim if
you can configure your terminal to set the 8th bit on meta/alt.

Most terminals can be configured to do this, but often do not do it by
default. I imagine iTerm has this option as well. IIRC, the default OS X
Terminal also has this option.

from vim-sexp.

gsavovski avatar gsavovski commented on August 28, 2024

Hi @justinmk

Thanks for the kind explanation.

I actually remembered that I never could
use the Alt/Meta and Command keys since
I didn’t have any mappings for them in vimrc.

Hi @guns,

Thanks for opening this new door :-)

I already had set in my iTerm2 that the left option
acts as (+Esc).
When I press any of the combination
in terminal by catting the output I get:

-=} cat
^[H^[J^[K^[L

So I tried explicitly setting:

execute "set =^[J"
execute "set =^[K"
execute "set =^[H"
execute "set =^[L”

The ASCII code for ‘^[‘ is ‘\094 \091’.

Then I just put your code snippet in my vimrc and
it really worked. I can not even believe it :-)
Thank you so much!

Few more questions bug me..

Why did the explicit setting I mention above didn’t work?
Out of curiosity looking at your modifiers.vim code you have a lots
of mappings using the arrow keys, what do you accomplish doing that?
And lastly what do you mean by rarely used <4-…> mapping to be used as super?
Is that the actual number 4?

Thanks again this is great :-)

By the way the plugin already worked great in MacVim but
I'm much more of terminal user, therefore this is super exciting..

from vim-sexp.

guns avatar guns commented on August 28, 2024

I already had set in my iTerm2 that the left option acts as (+Esc).

Sounds like turning this off might enable meta-sets-top-bit mode, which is
really the best no-hack option if you just want to enable meta keys in your
terminal. You should give it a try!

So I tried explicitly setting:

execute "set =^[J"
execute "set =^[K"
execute "set =^[H"
execute "set =^[L”

The ASCII code for ‘^[‘ is ‘\094 \091’.

Why did the explicit setting I mention above didn’t work?

The ^[ is actually the standard printable representation for ASCII 033
(Escape). This character can be produced with the Escape key, or by pressing
<C-[>. Actually, the first 32 unprintable ASCII control characters can be
produced by pressing Ctrl and the corresponding ASCII equivalent 0x40 up the
table:

Ctrl + @ (0x40) -> 0x00 (Other keys can send NUL; I like Ctrl + Space)
Ctrl + A (0x41) -> 0x01
Ctrl + B (0x42) -> 0x02
Ctrl + C (0x43) -> 0x03
…
Ctrl + _ (0x5f) -> 0x1f

Of course, we don't type Ctrl-Shift-C when we want to send interrupt
through a terminal, so the actual key sent is upper cased when the Control
modifier is active. This convenience is why Ctrl-a and Ctrl-Shift-a
are indistinguishable in most terminal programs. Lots of people find this
annoying, but I personally enjoy this feature.

Here is the relevant bit in vim:

https://github.com/vim/vim/blob/60cce2f/src/ascii.h#L40-L41

#define Ctrl_chr(x) (TOUPPER_ASC(x) ^ 0x40) /* '?' -> DEL, '@' -> ^@, etc. */
#define Meta(x)     ((x) | 0x80)

Here we can also see why configuring your terminal to set the top bit when
Meta is active makes Meta mappings work out of the box.

Then I just put your code snippet in my vimrc and
it really worked. I can not even believe it :-)

I've edited my comment again to remove an errant debugging echo string(), so
you may want to remove that from your vimrc.

You've convinced me to start work on packaging this up as a plugin since it
does not seem to be common knowledge. It is in the documentation, but it's
easy to miss: :help :set-termcap.

Out of curiosity looking at your modifiers.vim code you have a lots of
mappings using the arrow keys, what do you accomplish doing that?

It allows mapping Modifier + Arrow keys. I don't ever find myself touching the
arrow keys, so it was mostly a way to experiment with setting key codes.

And lastly what do you mean by rarely used <4-…> mapping to be used as super?
Is that the actual number 4?

Yes, the <4- modifier is actually a mouse event modifier, but you can
bind it in regular mappings. For example, I configure my terminal to send
\033\007… when I type Super + …, then I map this sequence to produce the
corresponding <4-…>:

execute "map  <special> \<Esc>\<C-g>… <4-…>"
execute "map! <special> \<Esc>\<C-g>… <4-…>"

Now this <4-…> key can represent Super + … in your vimrc:

map <4-s> :<C-u>update<CR>

This is my favorite Vim hack, but it has the nasty side effect of borking
<Esc>, which is why I retracted my discussion of it.

Like I mentioned before, I use Ctrl-C as my escape anyway, so this does not
bother me.

I suspect there is a way to abuse the termcap key code system to accomplish
the same without this downside. If I find one I'll report back here.

By the way the plugin already worked great in MacVim but I'm much more of
terminal user, therefore this is super exciting..

Good to know. I compile vim with --disable-gui, so I am very unfamiliar with
GUI vim builds.

from vim-sexp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.