adsr / mle

flexible terminal-based text editor (C)
Apache License 2.0
827 stars 53 forks source link

Key binding questions around making a complete Vim-like interface #39

Closed whiteinge closed 2 years ago

whiteinge commented 4 years ago

Hello. I've been playing with mle on and off for a few days and I just love the simplicity of the code and the minimal philosophy of leaning on external tools as much as possible. I'm an old Vim user so I've started hacking around a .mlerc with an eye toward how Vim-like I can make it (ala Emacs and Evil) and I was hoping you could field a few questions around what's possible and what you'd be interested in adding or not.

General questions:

Vim-specific questions:

I understand if the above is beyond the scope of your project but I'm excited about it and at least wanted to raise the questions. Thanks for your time!

adsr commented 4 years ago

Hello @whiteinge, glad to hear you like it.

Is it possible to bind the escape key? -kcmd_pop_kmap,escape, doesn't seem to work.

Not currently. mle uses termbox which supports two input modes, TB_INPUT_ESC which emits escape inputs but sacrifices meta inputs (alt+...), and TB_INPUT_ALT which is the opposite. mle hardcodes TB_INPUT_ALT. It would be nice if there was a third mode that would emit escape inputs if there is nothing left in the input buffer.

https://github.com/termbox/termbox/blob/8dc56647b963768cec4e8b0ff1350055d54fc9e3/termbox.c#L650

I think (inputmode & TB_INPUT_ESC || len == 1) would handle this in the nominal case. I'm sure there are edge cases with slow inputs or large / full buffers. It is a good feature request.

Would you be interested to enable the wiki on this repo so people can share tips, configs, and lua scripts?

Sure, I'll enable it.

Can kdef/kbind be done from Lua? I spent some time poking through the source, my C knowledge is limited, but it looks like not. Is that something you'd be interested to add? Asking because it would be nice to put everything in one -x mlevil.lua file. :-) Vim-specific questions: ...

Binding keys from Lua is not supported but it is easy to add. A long while ago I was working on built-in basic vim support https://github.com/adsr/mle/blob/6a7f9c10083c0c48046688cf403aa9a6bb6c8973/cmd_vim.c I removed it because I'm a pretty basic vim user and realized I was not a good judge of how accurate the emulation was. Let me know if you'd like to collaborate on resurrecting it.

whiteinge commented 4 years ago

Thanks for the replies. I'll play with TB_INPUT_ESC this weekend to see how it feels.

I am interested to collaborate on Vim support! Although I'm not sold on baking it directly into mle via C for a few reasons:

Thoughts, rebuttals, counterpoints very welcome.

hovsater commented 4 years ago

[...] Let me know if you'd like to collaborate on resurrecting it.

Just want to chime in here and say it's be happy to help out wherever I can. 🙂

adsr commented 4 years ago

Good points @whiteinge. I tend to agree overall.

The bulk of Evil clocks in at 541 lines

Impressive. Very curious to see it. I didn't realize you were already working on one.

Thoughts on multiple key presses for one command? E.g., Vim's gg. Possible API - notice overlapping kbinds and wait for another keypress: -kcmd_move_beginning,gg,

By the way, this should already be supported, e.g.:

mle -K kmap,,1 -k 'cmd_move_beginning,g g,' -k 'cmd_move_end,g G,' -n kmap

Maybe that helps you.

What are your thoughts on multiple commands in one mapping?

Interesting idea. I agree the current kbinding format is limiting. It would be nice if commands were more composable. There used to be an 'editing language' feature that attempted to address this: https://github.com/adsr/mle/blob/adf11c6f266fcb7f41ef395662fc50c271c25461/README.lel.md The idea was you could write a tiny program to do a more complex action and kbind it as usual. It was cool but I never used it and also overlapped with user scripts. But the idea of being able to express a little bit of logic inside a kbinding is still appealing to me.

For kmaps, I imagine it'd help if they had callbacks and/or some sort of internal state. Might help in implementing things like Vim's undo in normal mode or visual mode.

whiteinge commented 4 years ago

I didn't realize you were already working on one.

A little, yeah. I started porting this file from the Evil project over to mle to see how far I could get with push/pop kmaps. That file is 541 lines, my port is just 35 lines so far. You can view it here and I'd like to move it into the wiki once it's farther along. There's a few things that I think are possible with mle as-is (such as chording like cw to change word) that I haven't gotten to yet; there's a few things that probably aren't possible yet; and there's a few things that aren't applicable to mle (tabs, windows). I haven't tried yet but I was hoping to get some :ex-like behavior from mle_prompt_input and Lua.

That file is only part of what makes Evil Vim-like but it's a substantial part. There's also a nice similarity between Emacs command names and mle command names.

By the way, this should already be supported [...] Maybe that helps you.

Oh! Space-separated keys. Yes that helps, thanks.

Is it possible to map the two mle commands that accept ** arguments?

echo '-kcmd_move_until_forward,f,**'
echo '-kcmd_move_until_back,F,**'

For kmaps, I imagine it'd help if they had callbacks and/or some sort of internal state. Might help in implementing things like Vim's undo in normal mode or visual mode.

This is a good example of where I think trying to emulate Vim too much (or too early) could potentially send mle down a bloat-y path. -k 'cmd_undo,u,' doesn't work like Vim's undo but I think that's ok -- and it's particularly ok as a first-pass for Vim-like. IMO, it would be a bigger initial impact to get things like counts, movements, chording, and text objects as close as possible. There will inevitably be mle-isms (multiple cursors, save dialogs, copy & paste semantics) that will differ from Vim and I think that's probably ok forever, but certainly ok for now.

adsr commented 4 years ago

Excellent! Please let me know when it gets to a steady state. I'd like to add a link to it in the readme at least if that is ok by you.

Is it possible to map the two mle commands that accept ** arguments?

Yes, what you have should work (with space-separated keys):

echo '-kcmd_move_until_forward,f **'
echo '-kcmd_move_until_back,F **'

Fully agree re: avoiding bloat. I've wanted to rewrite the kmap code for a long while because it's hard to follow. I'd only consider the rewrite successful if the code ended up simpler. Bonus if the features are more flexible.

adsr commented 2 years ago

Feel free to re-open