You can use the mapcheck()
function to check if the user mapped a key to something:
:echo json_encode(mapcheck('<F1>', 'n'))
""
:echo mapcheck('<F11>', 'n')
:set cursorcolumn!<CR>:set cursorcolumn?<CR>
So in your mapping, you can do:
if !hasmapto('<Plug>MyFunction', 'n') && mapcheck('<Leader>f', 'n') is# ''
nmap <buffer> <Leader>f <Plug>MyFunction
endif
Personally, I'm not completely convinced this is actually a good approach though. While it does prevent overriding user mappings, it's also very "magic" and may be surprising.
An approach that I often use is to make a single setting to disable all mappings:
if get(g:, 'myplugin_map_keys', 1)
nmap <buffer> <Leader>f <Plug>MyFunction
endif
This way users have a reasonable set of mappings by default, but can disable mappings and do their own thing if they want something custom.
Another option is to map from a variable:
exe printf('nmap <buffer> %s <Plug>MyFunction',
\ get(g:, 'myplugin_map_foo', '<Leader>f')
This way users can set their own keys for a specific mapping, without having to remap everything.
I don't think there is "one right way". Aside from personal preference, it also depends on the kind of plugin you're working on. For some plugins a key mapping is just an "extra bonus", whereas it's critical for others. Some plugins map just one or two keys, others dozens or even hundreds.
For smaller plugins with just one or two mappings, the first method will usually be better; for larger plugins with a lot of mappings, the second is often better. Of course, you can also do both.