2017-05-27 12:45 GMT+03:00 Bram Moolenaar <[email protected]>: > > Nikolay Pavlov wrote: > >> 2017-05-26 20:43 GMT+03:00 Bram Moolenaar <[email protected]>: >> > >> > Brett Stahlman wrote: >> > >> >> >> On Tuesday, May 23, 2017 at 8:25:33 AM UTC-5, Brett Stahlman wrote: >> >> >> > On Tue, May 23, 2017 at 4:35 AM, Bram Moolenaar <[email protected]> >> >> >> > wrote: >> >> >> > > >> >> >> > > Brett Stahlman wrote: >> >> >> > > >> >> >> %--snip--% >> >> >> > > >> >> >> > > The best solution is probably to also add the raw rhs, with the >> >> >> > > terminal >> >> >> > > codes replaced. This won't work when changing the terminal type, >> >> >> > > but >> >> >> > > that is very unlikely to happen. >> >> >> > >> >> >> > You mean adding a key such as "raw_rhs" to the dictionary returned by >> >> >> > maparg()? If so, then yes this would help, but there would still >> >> >> > need to >> >> >> > be a way to determine lhs, which is currently even more ambiguous >> >> >> > than >> >> >> > rhs. While it's true that I probably already have lhs if I'm calling >> >> >> > maparg(), I need a way to determine which lhs(s) is/are ambiguous >> >> >> > with a >> >> >> > given lhs. Mapcheck() gives me only the rhs of the conflicting map. >> >> >> > To >> >> >> > save and restore, I'd need to know the lhs in canonical form as well. >> >> >> >> >> >> Perhaps mapcheck() could take an optional arg requesting something >> >> >> more than a simple boolean return. When called with this extra arg, >> >> >> mapcheck() could return a conflicting/ambiguous lhs (or list thereof) >> >> >> in some canonical format (possibly determined by the value of the >> >> >> extra arg itself). As long as the format returned could be fed to >> >> >> maparg(), it would be possible to find conflicting mappings, remove >> >> >> them temporarily, and subsequently restore them... >> >> > >> >> > If you define a mapping you will want to know whether the mapping >> >> > already exists and needs to be restored. For that you can use maparg(), >> >> > no need to use mapcheck(). >> >> > >> >> > Not sure why you would want to remove "conflicting" mappings. Perhaps >> >> > when you map the ; key, and the user has ;x mapped? Then you would need >> >> > a list. Adding a maplist() function would be better than adding >> >> > arguments to mapcheck(). >> >> >> >> Yes. Very much like that. I'm implementing a sort of transient mode, in >> >> which I'll "shadow" existing maps with very short (generally single >> >> character) mappings, which are expected to be ambiguous/conflicting with >> >> existing maps, and even builtin operators. Of course, when I exit the >> >> transient mode, I'd need to restore the mappings that were shadowed. >> >> >> >> The global and builtin maps are not a problem, since the transient maps >> >> use >> >> <buffer> and <nowait>; however, without parsing the output of one of the >> >> :map >> >> functions, I have no way of knowing which buf-local mappings will be >> >> ambiguous >> >> with the transient maps I'm defining. And parsing the :map output is >> >> problematic for the reasons already mentioned: e.g., no way to tell the >> >> difference between function key <F8> and the corresponding 4 characters. >> >> I'd >> >> actually considered taking some sort of iterative approach: e.g., trying >> >> all >> >> possible permutations of lhs as input to maparg() and testing the >> >> results, in >> >> an attempt to deduce the canonical form, but this would be extremely >> >> messy, >> >> and I don't even know whether it would be deterministic... The maplist() >> >> function you mentioned, if it returned all ambiguous left hand sides in >> >> canonical form, or even a list of the corresponding maparg()-style >> >> dictionaries, would be perfect. Of course, there would also need to be a >> >> way >> >> to get the rhs's canonical form: e.g., the extra "raw_rhs" key in the >> >> maparg() >> >> or maplist() dictionary. >> > >> > OK, so for this you would use maplist() to get the list of mappings to >> > disable, use maparg() to get the current mapping, clear the mapping, do >> > your stuff, then restore the cleared mappings. You then need to make >> > sure you restore the mappings exactly as they were, even when your >> > "stuff" fails miserably. >> > >> > It's a lot easier if we would have a way to temporarily disable >> > mappings. It's mostly the same as above, but you won't need to use >> > maparg() to get the current mapping and the restore operation. Instead >> > you would disable instead of clear, and later re-enable instead of >> > restore. Still need to make sure the re-enbling does happen, no change >> > in that part. >> >> Not sure I understood what exactly you suggest to disable/restore. All >> mappings at once with one command? I would actually disagree here: I >> need something similar for translit3, but it only remaps >> single-character mappings, leaving most of other user mappings alone. >> One mapping at a time? It would be good, but given that request is >> temporary remapping naming the functionality enable/disable looks >> strange. And there are still issues with determining {lhs}. > > Let's use an example: Suppose a plugin has a special mode for entering > data (e.g. chemical formulas). It would then map some keys, e.g. "a". > If the user already has a mapping for "a" it needs to be restored when > leaving the special mode. If the user has mappings starting with "a" we > would like to disable those, to avoid the timeout waiting for the next > character. > > We do not want to disable mappings that don't interfere, to maximise the > freedom for the user to use other mappings at the same time. > >> One of the logical variants would be `:map <push> {lhs} >> {new-rhs}`/`:unmap <push> {lhs}`+`:map <pop> {lhs}`, but this is hard >> to implement and is rather limited, though less limited then >> enable/disable everything variant. > > This quickly gets complicated if we need to take into account all the > possible modes a mapping can be used in. > >> I would instead suggest a function mappings_dump()/mappings_add(): >> first is similar to `nvim[_buf]_get_keymap` and should dump all >> mappings as a list of maparg()-like dictionaries. Second should define >> mappings being given a list of them. Of course, this means that >> dictionaries need to be fixed to allow correctly saving/restoring. >> >> The advantages: >> >> 1. Easier to implement. Code for creating a maparg() dictionary is >> already there, iterating over all mappings is not a problem. Results >> needs to be incompatible with maparg() or use additional keys though: >> e.g. Neovim altered the contents of `noremap` and `buffer` keys: first >> is now 0, 1 or 2 (you can’t correctly restore a mapping if you can’t >> distinguish `map <script>` and `noremap`) and second is a buffer >> number or zero. >> 2. More flexible: you can save and restore everything, push or pop >> individual mappings, create a temporary mapping which is just like >> mapping X, but has `<Plug>(Translit3TemporaryMap)` lhs instead (to be >> returned from `<expr>` mappings in order to select either plugin >> behaviour or fall back to previously present user mapping instead). >> >> I can imagine other usages enable/disable or push/pop could not >> achieve: generating configuration with mappings like :mkvimrc, but >> allows doing adjustments (parsing `:mkvimrc` output is not fun, >> especially if you want to be forward compatible), creating a plugin >> which analyses how often different mappings are used (need to copy all >> mappings to temporary then replace existing mappings with plugin >> ones). >> 3. This is also forward compatible: just need to state in the >> documentation that new significant keys may be added in the future to >> the dictionaries so they should be preserved. > > I don't see much use for this. I can't think of a practical example how > a plugin manipulates mappings it didn't create itself or even knows what > they are for.
Still Vim has :mkvimrc which does manipulate (dump) mappings from third-party plugins. Also I need this functionality for some <expr> mappings: if some condition is true (e.g. `>` is preceded by `-` (C, completion) or transliteration mode was enabled, or transliteration mode is enabled *and* character that does not start a new transliteration sequence is a continuation of previous one) use plugin mapping. If it is false, fall back to whatever was there previously, including falling back to whatever mapping was there previously. Also check https://github.com/neovim/neovim/issues/6123, this is the issue backing Neovim nvim_get_keymap() API function. > > Another complication is that mappings can be added/removed by other > mappings and by autocommands. I do not see how this complication is relevant to the discussion. I.e. I do not see how this complication should affect usage or implementation of both proposed changes. > > Disabling and re-enabling mappings is definitely more efficient than > removing and adding-back mappings. And it is also definitely both harder to implement and less flexible. > > -- > BLACK KNIGHT: I'm invincible! > ARTHUR: You're a looney. > "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD > > /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\ > /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ > \\\ an exciting new programming language -- http://www.Zimbu.org /// > \\\ help me help AIDS victims -- http://ICCF-Holland.org /// -- -- You received this message from the "vim_use" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_use" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
