Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keymap Override #31

Open
MonaMayrhofer opened this issue Mar 30, 2023 · 2 comments
Open

Keymap Override #31

MonaMayrhofer opened this issue Mar 30, 2023 · 2 comments

Comments

@MonaMayrhofer
Copy link
Contributor

As far as I could discern there is currently no way to override the default keymap (Only extending them).

Is there a way that I have missed?

If implemented - my first idea would be to simply add some sort of "customKeymap" attrset option to each module, that if given replaces the default keymap. Is this or something similar be something that would be welcomed as a PR?

@jordanisaacs
Copy link
Owner

Yes, configurable keymaps are something that is on my to do list. Its in a bad situation right now with some being end user configurable and others being hardcoded. Additionally, some are using the module system for mappings, while others are literal lua/vim code. This is due to plugins all have different ways to handle keymappings (generic lua, vim, or inside plugin setup). And it is a legacy of this project evolving form a single personal configuration.

I want something standardized (hides the underlying mapping implementation) and can be overridable (ideally from the use of default). The hard part is designing the API for that and then creating all the mapping functions.

I am open to PRs, but I recommend staritng with a small POC so we can iterate.

@MonaMayrhofer
Copy link
Contributor Author

MonaMayrhofer commented Apr 5, 2023

Some thoughts:

In order to cater to the plugins that have a really non-trivial mapping api (e.g nvim-cmp, where one has to use cmp.mapping(blabla...), I immediately think of some sort of "Action"-Api:

  • Each module has some "Actions" it exposes to the end-user (e.g "CmpConfirm").
  • The user in their configuration can then define mappings for each action (e.g "{<CR>" = "CmpConfirm";};)
  • Additionally there should be a way for the user to also define plain old vim mappings

This could take shape in several forms:

Define the keymap close to the plugin - mappings for each plugin are given within their respective configuration:

{
autocomplete = {
  enable = true;
  foo = bar;
  mappings = {
    "<CR>" = "CmpConfirm";
   "<leader>h" = "CmpDoSomethingElse";
  };
};
}

Maybe we could even do the actions a bit more staticaly, by making mappings be a function, that takes an attrset of actions. Something like:

{
autocomplete = {
  enable = true;
  foo = bar;
  mappings = actions: {
    "<CR>" = actions.confirm;
   "<leader>h" = actions.doSomethingElse;
   "<leader>s" = someUserDefinedHack actions.insufficientlyPredefinedAction;
  };
};
}

where actions is something like

{
  confirm = "cmp.mapping.confirm({select=true})";
  doSomethingElse = "cmp.config.abort()";
  ...
}

Each module calls its respective config.mappings function and then does whatever it needs to do with the returned keymappings.

Problems that i can see immediately:

  • How to disambiguate between an Action and a custom binding. (hmm.. maybe we can solve that by allowing something like actions.executeLua "require'foo'.customCode()
  • We would probably not simply have the mappings sit directly inside the mappings option of a module, but have them nested in mappings.normal, mappings.visual etc. and then we have a problem with e.g the nvim-cmp mappings which afaik don't really care about the modes...
  • Having the plugins colocated with the configuration of each plugin might make the configuration somewhat cluttered, as the mappings are all around the place and not neat and tidy on one place together.

Having the keymap on one central option

Something like

keymap = {
  "<CR>" = "CmpConfirm";
  "<leader>e" = "FileTreeOpen";
};

I personally think we should not handle actions via strings... that just doesn't feel right. I believe we could manage to get a similar actions api going like i described above:

keymap = actions: {
  "<CR>" = actions.cmp.confirm;
  "<leader>e" = acitons.filetree.open;
};

where each module defines something like this in their config

{
  config = {
    actions = {
      confirm = "cmp.mapping.confirm({select=true})";
      doSomethingElse = "cmp.config.abort()";
     ...
    };
  };
}

and then we have a seperate keymappings.nix module that aggregates all the actions into a single big attrset and then calls the config.keymap function with it.
And then we do some magic to get these infos back to the modules that need to actually do something with the mappings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants