18

I sometimes need to write Greek words, but when I am using the Greek keyboard, hitting, say, <C-p> will be understood as <C-π> and not as the command I intend. This can be fixed with :map <C-p> <C-π>. Can I do this for all letters without making a list of all?

PS. Making a list of all does not produce a perfect result. E.g., q is ; on the Gr. keyboard, but we don’t want to map ; to q. Also, for some reason, ΖΖ (zeta zeta) does not work after :map Ζ Z. And a command I defined, \lw, does not work as \λς.

  • 2
    I think that mapping is not the good way to go: maybe what you're looking for is the langmap option (see the doc which includes an example for greek layout). This option was actually made to help dealing with non latin keyboards like greek or cyrilic. It allows you to define pairs of symbols which will be interpreted normally in insert mode but will be replaced in other modes, maybe this will help you. – statox Sep 18 '15 at 17:20
  • @statox: Thanks! I tried using the ex. but nothing happened. The help says vim had to be complied with the +langmap option. Is there an easy way to check if it was? I’m using the version that comes with Mac OS. – Toothrot Sep 18 '15 at 17:42
  • 1
    You can use :echo has('langmap') if you get a 1 you have it if you get a 0 you don't. – statox Sep 18 '15 at 17:44
  • @statox: Thanks! I updated with brew install vim --override-system-vi and :echo has &c now returns 1. ZZ works. The problem with \lv &c remains. – Toothrot Sep 18 '15 at 19:17
  • I don't understand the :echo has &c part, I don't see how it is related to langmap also once you have vim compiled with langmap you have to specify the mappings with :set langmap=ΑA,ΒB,ΨC [...] in your vimrc. – statox Sep 18 '15 at 20:00
6

I would recommend keymap, which can solve your trouble. Put these in your vimrc

" set keymap=greek_utf-8
set iminsert=0
set imsearch=-1

to disable Greek as a default.You can toggle the option on (Greek) and off (English) using <ctrl>+^ (you can also use <ctrl>+6, it is mapped on key, not on symbol) in insert mode and Replace mode (doesn't work in Normal mode). To automatically disable when leaving insert mode you can use

inoremap <ESC> <ESC>:set iminsert=0<CR>

More on these

:h iminsert :h keymap :h imsearch :h i_CTRL-^


EDIT to second comment:

You can try this to switch Greek on automatically, if entering insert mode (and replace mode), and to switch off automatically, if leaving (then you don't need mapping mentioned before).

augroup Greek
    au InsertEnter * set iminsert=1
    au InsertLeave * set iminsert=0
augroup END
  • Is it really necessary to use polytonic Greek? It seems to me that only right encoding is needed, and then to use built-in MacOS X input. But this is probably just my wrong impression. You can also switch to polytonic Greek keyboard in MacOS X (and learn it, but I guess it is not what you seek :-) About the lag of ἀ, there can be some mapping, try to find out by :map >a, and if there is, unmap it by :unmap >a. As a non-Greek and non-MacOs user I am already at my wits end. Sorry and good luck! – ryuichiro Sep 20 '15 at 13:31
10

As I said in the comments, mappings in are not designed to do what you want to do. An interesting option for this use case is langmap.

This option allows to keep the behavior or your keyboard in insert mode and change its behavior in the other modes.

To use it Vim has to be compiled with +langmap, you can check that this option is enabled with echo has('langmap'): if the command returns 1 the option is enabled else you'll have to get a setup with this option enabled (to know how to do that, it is another question).

When it is enabled, the option takes pairs of characters for example set langmap += à@ will allow you to add a à in your buffer when you're in insert mode and you type a à but typing à in normal mode will actually trigger a @ (this example can be useful on azerty keyboards to ease work with macros).

To use langmap in greek you can follow the example given in :h 'langmap' adding this line to your vimrc (Copying this line from here may not be a good idea since I'm really not sure of the encoding, yanking the line directly from the help file is probably safer):

:set langmap=ΑA,ΒB,ΨC,ΔD,ΕE,ΦF,ΓG,ΗH,ΙI,ΞJ,ΚK,ΛL,ΜM,ΝN,ΟO,ΠP,QQ,ΡR,ΣS,ΤT,ΘU,ΩV,WW,ΧX,ΥY,ΖZ,αa,βb,ψc,δd,εe,φf,γg,ηh,ιi,ξj,κk,λl,μm,νn,οo,πp,qq,ρr,σs,τt,θu,ωv,ςw,χx,υy,ζz

Now from what I understand in your comments it remains an issue when you try to use predefined commands: when you type a command, the insert mode behavior will be triggered instead of the langmap defined behavior. Unfortunately I'm not sure I have a good solution for that. One idea could be to redefine commands for example like that:

command λς lw

This way when you'll type the command λς Vim will execute lw but I see several drawbacks to this method:

  • It might be a huge pain in the butt to redefine all the commands you want to use.
  • User-defined commands have to start with a capital letter, and I have now idea how convenient it is to do that in greek.

So maybe a plugin suggested by @Alexander Myshov in his answer to this question could be useful (as I never tried any of these I don't know if they solve the problem but it seems like they do).

1

I type regularly in English and Swedish. Swedish is a smaller problem to solve than Greek because it only expands the English alphabet with a few characters, but I think my solution is transferable to Greek.

I used to switch using my OS's system keyboard switch. The problem with this is, as the OP noted, that it breaks a whole bunch of commands, since in normal mode, each key sends another signal to Vim with the non-English keyboard. In the Swedish keyboard layout, moreover, a whole bunch of non-alphabetical characters are moved to make way for the new characters å, ä, and ö. For example, } is typed with Alt-Shift-9 (matching the opening parenthesis on the English keyboard), and backslash is typed with Alt-Shift-7. Switching to a vanilla Swedish keyboard layout for insertmode thus causes a whole bunch of headaches.

My solution was to remap the relevant keys in insertmode only and wrap these mappings in a function so that I can switch easily back and forth. The code below is how I did this in my .vimrc. This only adds the characters I need to the position they have in the Swedish keyboard layout, leaving everything else. To type the characters that are masked by them (;, :, [, {, ", and '), I simply hit the key twice. Luckily, only silly people even need to type two äs in a row. (If this double hitting is not suitable, you could map them to Ctrl or something like that. The basic principle is that characters that are masked remain in their place on the keyboard but are one keystroke removed from being realized. I find this much easier than moving them around.) What means is that when I want to type in Swedish, I hit <Leader>s, which switches to these mappings and apply Swedish spellchecking. To switch back I do <Leader>e.

Now, for Greek, this would involve doing mappings for the whole alphabet, which is actually less of a hassle than it sounds like once you got the principle down. The tricky part then would be to unmap all those changes when switching to English. Perhaps someone can come up with a nifty way to do that.

I am planning on doing a insert function like those below for Arabic, the other language I often type in. I might come back here to report on the process.

" Switch to Swedish
function! SweType()
  set spelllang=sv
  inoremap ; ö
  inoremap ;; ;
  inoremap : Ö
  inoremap :: :
  inoremap [ å
  inoremap { Å
  inoremap ' ä
  inoremap '' '
  inoremap " Ä
  inoremap "" "
  inoremap [[ [
  inoremap {{ {
endfunction
nmap <Leader>s :<C-U>call SweType()<CR>


" Switch to English
function! EngType()
  set spelllang=en_us
  inoremap ; ;
  iunmap ;;
  inoremap : :
  iunmap ::
  inoremap [ [
  iunmap [[
  inoremap { {
  iunmap {{
  inoremap ' '
  iunmap ''
  inoremap " "
  iunmap ""
endfunction
nmap <Leader>e :<C-U>call EngType()<CR>
  • 1
    I might be wrong but I think that your answer allows to easily get non-English characters in insert mode while OP's problem was to easily get English characters in other modes than insert mode. I'm not sure your answer adresses the initial problem. Still the idea of function enabling/disabling mappings is quite interesting. – statox Sep 19 '15 at 13:49
  • @statox Well, I might have misunderstood the question, but if the problem is to easily insert non-english characters in insertmode while maintaining normalmode functions, I believe my question at least attemps to address that problem. – Andreas Sep 19 '15 at 15:59
  • I'm sorry I didn't meant to be offending: I was pointing out that there was maybe a gap between the question and your answer but of course you attempt to address the problem and as I said I really like the idea of functions enabling and disabling mappings. I really wasn't denying your answer and I'm really sorry of that's what it sounded like. – statox Sep 19 '15 at 16:05
  • 1
    @statox No offense taken. And if you had denied my answer that would all be in good order. – Andreas Sep 19 '15 at 16:24
0

I type in two languages too: Russian and English. And now I use this plugin https://github.com/lyokha/vim-xkbswitch. This plugin has a dependency on the native keyboard layout switcher, for Mac OS X you can use mine one https://github.com/myshov/xkbswitch-macosx.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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