1
command! -nargs=0 -bar UpdateBuff if empty(bufname('%'))
                           \|        browse confirm write
                           \|    else
                           \|        confirm write
                           \|    endif
nnoremap <silent> <A-s> :<C-u>UpdateBuff<CR>
nnoremap <silent> <A-q> :wqa<CR>
nnoremap <A-h> :SidewaysLeft<cr>
nnoremap <A-l> :SidewaysRight<cr>

I have mapped some of the useful commands to Alt key, because it's easy to reach on my Windows keyboard on Linux. Macs, however, have Command on this position, so on Mac I'd like to use Command instead of Alt in this mappings. I know that I probably can configure it manually for each mapping, with has('mac'), but this would be tedious and stupid. Is there a better way?

  • 2
    How about creating a function that create both mapping, and wrap them with has('mac')? – nobe4 Apr 29 '16 at 20:39
  • Probably a good idea, but I don't know vimscript that well right now. For example such function should take a keys that one should press after alt/cmd (or with it) and and action. I have no idea how to pass this to a function in vim. – user1685095 Apr 29 '16 at 20:49
  • Have a look at: learnvimscriptthehardway.stevelosh.com – nobe4 Apr 29 '16 at 20:50
2

The following function is a start; it will probably fail on a number of cases. You can build off it:

function! MyMap (...)
    let l:i = 0
    if a:0 > 2
        let l:opt = a:1
        let l:i += 1
    endif
    let l:key = a:000[i]
    let l:action = a:000[i+1]

    let l:mod = 'A'
    if has('mac')
        let l:mod = 'D'
    endif
    echo 'nnoremap' l:opt printf('<%s-%s>', l:mod, l:key) l:action
    exe 'nnoremap' l:opt printf('<%s-%s>', l:mod, l:key) l:action
endfunction

command! -na=+ MyMap call MyMap(<f-args>)

A break down:

  • function! MyMap (...) defines a function that takes a variable number of arguments. From :h ...:

                                            a:0 a:1 a:000 E740 ...
    Up to 20 arguments can be given, separated by commas.  After the named
    arguments an argument "..." can be specified, which means that more arguments
    may optionally be following.  In the function the extra arguments can be used
    as "a:1", "a:2", etc.  "a:0" is set to the number of extra arguments (which
    can be 0).  "a:000" is set to a List that contains these arguments.  Note
    that "a:1" is the same as "a:000[0]".
    
  • Next we check if we have more than two arguments, and if so, use the first one as special arguments to nnoremap. The other arguments are the key and the action.
  • Next, we set the modifier used to be A (or Alt) as a default, and change it to D (or Command) if has('mac').
  • Then we use execute to create and run the nnoremap command. printf('<%s-%s>', l:mod, l:key) will give <A-x> or <D-x> accordingly.
  • Finally we define a command to wrap the function. <f-args> splits the arguments on spaces and tabs, so be careful about those.

You can run the command like so:

MyMap <silent> q :wqa<cr>:H

Or, if additional special arguments are used:

MyMap <silent>\ <buffer> q :wqa<cr>:H

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.