<br><br><div class="gmail_quote">On Sat, Feb 26, 2011 at 9:26 AM, Vegard Øye <span dir="ltr">&lt;<a href="mailto:vegard_oye@hotmail.com">vegard_oye@hotmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

On 2011-02-25 22:20 +0100, Frank Fischer wrote:<br>
<br>
&gt; Gitorious should be okay.<br>
<br>
Then Gitorious it is! :)<br>
<div class="im"><br>
&gt; - repeating. Vim-mode uses keyboard-macro and those have to be<br>
&gt;   recorded. Recording them can be tricky if one keyboard macro calls<br>
&gt;   another one. Furthermore insert-mode is different because it<br>
&gt;   contains of several independent key-sequences. Using key-sequences<br>
&gt;   has some benefits but also some downsides, e.g., when lazy<br>
&gt;   completion packages are used<br>
<br>
</div>A big benefit of recording the keys is that it removes the need for<br>
repeat code in the commands themselves. For example, I have written<br>
some custom insertion commands for dealing with Lisp code (e.g.,<br>
&quot;Insert after S-exp&quot;); if I want them to repeat correctly under Viper,<br>
I have to edit the repeat history from within the commands, which is<br>
/extremely/ cumbersome. By contrast, a repeat system which monitors<br>
keystrokes and the current state would simply take note that I have<br>
entered Insert state, and update the repeat history accordingly.<br>
<br>
As you point out, some keystrokes are troublesome: &quot;M-/&quot;, which calls<br>
`dabbrev-expand&#39;, may expand to different words in different places in<br>
the buffer. One solution may be to define the repeat history as a<br>
collection of keystrokes and buffer insertions, e.g.,<br>
<br>
    ([a b c] &quot;inserted text&quot; [d e])<br>
<br>
Most commands are remembered as keystrokes (vectors), but certain<br>
ones, like `dabbrev-expand&#39;, are remembered as insertions (strings)<br>
instead. The repeat system would use a &quot;blacklist&quot; of unsafe commands<br>
like `dabbrev-expand&#39;; if the current command is listed, the system<br>
creates a marker at point (in `pre-command-hook&#39;), lets the command<br>
execute, and then (in `post-command-hook&#39;) extracts the text between<br>
point and the marker, which goes into the repeat history like above.<br>
<div class="im"><br>
&gt; - undo, vim usually undos everything done in insert-mode at once while<br>
&gt;   emacs undos insertion in steps.<br>
<br>
</div>This is not that difficult in itself, but becomes more complex when<br>
loading a custom undo package like undo-tree.el. (I would really like<br>
to use undo-tree.el in place of redo.el; it features a graphical<br>
interface which totally outclasses Vim&#39;s :undolist.)<br>
<br>
There is a case for making Vim-like &quot;bulk undoing&quot; toggleable:<br>
Emacs&#39; fine-grained undoing can be valuable in some circumstances.<br>
The default should be Vim-like behavior, of course.<br>
<div class="im"><br>
&gt; - catching of commands and motions. In each state the execution of<br>
&gt;   commands and motions has different effects and therefore some<br>
&gt;   special function has to be executed in each mode to deal with<br>
&gt;   commands and motions. In general I see two possibilities how this<br>
&gt;   special function can be executed. Either one hooks into pre- and/or<br>
&gt;   post-command hooks and checks whether the command/motion about to be<br>
&gt;   executed is a Vim operator and in this case do whatever is required<br>
&gt;   according to the current state. Or each command and motion is<br>
&gt;   defined in a special way in order to call the state specific handler<br>
&gt;   when it is executed. vim-mode uses the latter one because I try to<br>
&gt;   avoid pre- and post-command hooks if possible.<br>
<br>
</div>Ah, the relationship between operators and motions. This is an area<br>
where Vimpulse and vim-mode differ somewhat. In vim-mode, as I<br>
understand it, motions are passed to operators by parameter (or the<br>
operator reads a motion from the keyboard when called interactively).<br>
The operator executes the received motion to determine what text to<br>
act on. The resulting pair of buffer positions is used internally.<br>
<br>
In Vimpulse, the buffer positions /are/ the parameters (BEG and END).<br>
Operators work like region commands (i.e., (interactive &quot;r&quot;)) in that<br>
they either receive the positions from the caller, or figure them out<br>
for themselves when called interactively. (Vimpulse also possesses<br>
some facilities for &quot;passing a motion to an operator&quot;, which executes<br>
the specified motion and feeds its range to the operator. This is only<br>
used by the repeat system, though, and it would be totally superfluous<br>
if a keystroke-based system was in place.)<br>
<br>
For the sake of reusability, I recommend defining operator commands in<br>
the same way as region commands: with two parameters, BEG and END, and<br>
an `interactive&#39; specification for determining their values by reading<br>
a motion from the keyboard.<br>
<div class="im"><br>
&gt; - What to do with non-vim commands and motions? There should be a<br>
&gt;   simple rule so they work with vim in most cases as expected, but if<br>
&gt;   no meta-information is provided a non-vim command may always be<br>
&gt;   problematic (e.g., in operator-pending mode).<br>
<br>
</div>Well, we will likely have one macro for defining operators, and<br>
another for defining motions. Both can be set up to index all defined<br>
operators/motions for later lookup, which will give us some<br>
information to go on. By the way, I also think that all of Emacs&#39;<br>
standard movement commands should be regarded as motions.<br>
<br>
We thus get a large list of commands which move the cursor, and can<br>
restrict Operator-Pending state to those commands. Alternatively, we<br>
can maintain a &quot;blacklist&quot; of Emacs commands which should /not/ be<br>
executed. In any case, I don&#39;t think it&#39;s overly problematic if a<br>
nonsensical command should get called; any damage will be undoable,<br>
after all. It&#39;s probably better to err on the side of allowing too<br>
many commands than too few.<br>
<div class="im"><br>
&gt; - What to do with commands that change the current buffer? This is<br>
&gt;   problematic if some buffer-local variables are involved.<br>
<br>
</div>Right, which means that the repeat system cannot be buffer-local.<br>
I think it would just be confusing if it was, anyway.<br>
<div class="im"><br>
&gt; - How to switch states and how to represent states (usually as<br>
&gt;   minor-modes, perhaps with some further meta-data like cursor,<br>
&gt;   info-message, ...)<br>
<br>
</div>We&#39;ll have a macro for defining those too, of course. :)<br>
<br>
I suggest that each state&#39;s toggle function be a command; e.g., in<br>
Vimpulse&#39;s development code, vi state defines the command<br>
`vimpulse-vi-state&#39; for entering that state, emacs state defines<br>
`vimpulse-emacs-state&#39;, and so on. The command also has an optional<br>
argument which, if negative, disables the state; this is used<br>
internally when switching from one state to another.<br>
<div class="im"><br>
&gt; - What is a motion? There are a few fundamental differences between<br>
&gt;   buffer-coordinates of Vim and Emacs. Vim known line/column, Emacs<br>
&gt;   knows just the offset. The choice how to represent coordinates can<br>
&gt;   be crucial. And of course there is that funny newline character,<br>
&gt;   which is usually invisible in Vim except for empty lines. Because a<br>
&gt;   motion is a important concept for many parts including operators and<br>
&gt;   visual-mode.<br>
<br>
</div>I think all of Emacs&#39; regular movement commands should be valid<br>
motions. Furthermore, all of Emacs&#39; selection commands should be valid<br>
text objects. In Vimpulse, &quot;y C-x h&quot; and &quot;C-x h y&quot; are equally valid<br>
ways of copying the whole buffer, and &quot;d M-e&quot; works just as well for<br>
deleting a sentence as does &quot;d)&quot;.<br>
<br>
Given the above, the only thing which separates Emacs&#39; movement<br>
commands from the other motions is their lack of a /type/. For<br>
example, the motion &quot;j&quot; has a type of `line&#39;, which means that &quot;dj&quot;<br>
deletes two whole lines. What a type is, then, is a way to transform<br>
two buffer positions to two other positions -- in this case, to two<br>
whole lines.<br>
<div class="im"><br>
&gt;   Probably a motion is represented by some abstract data<br>
&gt;   type and this data-type is an important part of the interface a user<br>
&gt;   must understand in order to write new motions and commands.<br>
&gt;   Therefore it should be well-defined from the beginning because it<br>
&gt;   cannot be changed easily afterwards.<br>
<br>
</div>I don&#39;t think it needs to be very abstract. I would rather try to keep<br>
things from getting too abstract, actually. One of the design rules I<br>
laid down in Vimpulse&#39;s new &quot;TODO&quot; list was that it should require as<br>
few packages as possible, and not invent new stuff unless it&#39;s<br>
absolutely necessary.<br>
<br>
The way I understand motions, they are just regular movement command<br>
plus a type. The type can be stored as a symbol property, e.g.,<br>
(put &#39;motion &#39;type &#39;line). The type itself, of course, must also be<br>
defined; for this, a minimal system may be warranted, since both<br>
Operator-Pending state and Visual state use types. I&#39;ve pushed a<br>
currently unused &quot;type system&quot; to &quot;development&quot;:<br>
<br>
<a href="http://gitorious.org/vimpulse/vimpulse/blobs/development/vimpulse-types.el" target="_blank">http://gitorious.org/vimpulse/vimpulse/blobs/development/vimpulse-types.el</a><br>
<br>
Now, it&#39;s a bit more involved than it has to be; the routines for<br>
reselecting (e.g., two lines anywhere in the buffer) are unnecessary<br>
given a keystroke-based repeat system. The advantages of a systematic<br>
approach is that it can be reused by Operator-Pending state and Visual<br>
state, making the overall code simpler. The only heavy lifting Visual<br>
state ends up doing (once initialized) is highlight the different<br>
types, which is rather trivial (with the exception of `block&#39; ...).<br>
<div class="im"><br>
&gt; In fact, there are only two (or three) difficult commands: yank,<br>
&gt; delete and paste, but I hope the implementation in vim-mode is quite<br>
&gt; good know (it uses yank-handlers for all three kinds of yanking and<br>
&gt; also provides &quot;yank-pop&quot; stuff).<br>
<br>
</div>Yes, this is exactly the right way to do it. I think the actual yank<br>
handlers should be specified by the type system, so that `line&#39; has<br>
one handler, `block&#39; has another, and so on. That way, we avoid<br>
hard-coding these associations into the &quot;yank&quot; command.<br>
<div class="im"><br>
&gt; What could be useful are frameworks or perhaps only some functions<br>
&gt; which help defining more involved motions like text-objects. We should<br>
&gt; provide helper-functions for typical text-objects like parentheses,<br>
&gt; blocks, whatever. vim-mode (and vimpulse, too) contains a few of those<br>
&gt; functions which are again independent.<br>
<br>
</div>Agreed; we should have a macro for defining text objects, too.<br>
<br>
To recap, we now have the following define macros:<br>
<br>
    * `define-state&#39;<br>
    * `define-type&#39;<br>
    * `define-motion&#39;<br>
    * `define-text-object&#39;<br>
    * `define-operator&#39;<br>
<br>
Do we need more than these?<br>
<div class="im"><br>
&gt;&gt; <a href="http://gitorious.org/vimpulse/vimpulse/blobs/development/vimpulse-states.el" target="_blank">http://gitorious.org/vimpulse/vimpulse/blobs/development/vimpulse-states.el</a><br>
&gt;<br>
</div><div class="im">&gt; I read your comments and they sound reasonable. Adding auxiliary<br>
&gt; keymaps should not be that difficult. As I remember correctly, local<br>
&gt; keymaps were the biggest problem in vim-mode, but major and minor-mode<br>
&gt; specific should be relatively easy. Of course this is very important<br>
&gt; and should be done as one of the first things.<br>
<br>
</div>Actually, the current code already implements auxiliary keymaps,<br>
although I&#39;ve not tested it thoroughly.<br>
<div class="im"><br>
&gt; Note that vim-mode arranges keymaps in another hierarchy, too, which<br>
&gt; allows to enable only few keybindings in certain major modes, e.g.,<br>
&gt; only movement and window-commands in info-mode (somehow like<br>
&gt; viper-on-more-modes I think). The difference is that many<br>
&gt; standard-keybindings are not available in this case, e.g.,<br>
&gt; insert-mode.<br>
<br>
</div>Yes, this is very sensible. Motions and text objects can be bound in<br>
their own keymap (or state), and that keymap is inherited by vi state,<br>
Visual state, and so on. Modes which do not work well in vi state, can<br>
come up in the motion state instead. Any shortcomings can be<br>
alleviated on a per-mode basis with mode-specific state bindings.<br>
<div class="im"><br>
&gt;&gt; Regarding test frameworks, I hear Christian Ohler&#39;s ert.el is now<br>
&gt;&gt; included with Emacs trunk, so we could go with that:<br>
&gt;<br>
</div><div class="im">&gt; I never used any of those libraries but we should try. The main<br>
&gt; problem is to cover all those funny special cases that arise (what<br>
&gt; happens at the end of the buffer, on empty lines, ...) - most bugs<br>
&gt; found in vim-mode are of this kind.<br>
<br>
</div>This can be tested by executing a keyboard macro in a temporary<br>
buffer. A lot of Vimpulse&#39;s early tests do this, e.g.,<br>
<br>
    (deftest test-change-undo<br>
      &quot;Change a word and undo.&quot;<br>
      (execute-kbd-macro &quot;wcwfoo^[u&quot;)<br>
      (assert-string=<br>
        (buffer-substring 1 51)<br>
        &quot;;; This buffer is for notes you don&#39;t want to save&quot;))<br>
<div class="im"><br>
&gt; This is another point which is currently very bad in vim-mode. How to<br>
&gt; deal with errors, should there be a unique signalling scheme, where to<br>
&gt; handle them, ...<br>
<br>
</div>In &quot;indirect&quot; cases, like when executing a motion to get a text range,<br>
I think any errors should be suppressed. When executing the motions by<br>
themselves, however, we should signal any problems with `error&#39;.<br>
<div class="im"><br>
&gt; Btw, Emacs 23 contains visual-line-mode which is quite useful. But<br>
&gt; most commands work on buffer lines not on screen lines. Should we try<br>
&gt; to support visual-lines, too (optionally)? If yes this has to be<br>
&gt; considered for motions and commands, especially for operator-stuff,<br>
&gt; too, and we should think of it from the beginning, because many<br>
&gt; commands have to be implemented differently for visual-lines.<br>
<br>
</div>Yes, we should definitely support screen lines; I have &quot;j&quot; and &quot;k&quot;<br>
bound to `next-line&#39; and `previous-line&#39; because they work better in<br>
visual-line-mode. In Vim, one uses &quot;gj&quot; and &quot;gk&quot; to move by screen<br>
lines. I think this is very inefficient and would prefer an option for<br>
the regular commands. It may of course be disabled by default.<br>
<div class="im"><br>
&gt; Another thing somehow related to tests is documentation. We should not<br>
&gt; only write developer-documentation but also user-documentation right<br>
&gt; from the start. This should contain instructions for all important<br>
&gt; concepts and also examples for new motions and commands of all kind.<br>
&gt; Where should we put this documentation? EmacsWiki? Hosting site?<br>
&gt; Perhaps as tex-info?<br>
<br>
</div>Texinfo, definitely. I&#39;ve had my share of arbitrary wiki syntax and<br>
never-ending comment blocks. A text file under version control is<br>
wiki-like enough for me.<br>
<div class="im"><br>
&gt; Hm, I think a new cool name would be good. I prefer short names or at<br>
&gt; least names that allow short prefixes for function names ;)<br>
<br>
</div>For the sake of brainstorming, I&#39;ve grepped through /usr/share/dict<br>
for anything containing &quot;vi&quot;. There isn&#39;t much, unfortunately, so I&#39;ll<br>
start with some acronyms comprising three letters:<br>
<br>
    * avi, evi (augmented/extensible vi)<br>
    * via, vie (vi augmented/extended)<br>
    * vil (vi layer)<br>
    * xvi (vi plus a cool letter)<br>
    * yvi (yet a(nother) vi)</blockquote><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Things get slightly more descriptive when we allow four letters:<br>
<br>
    * evil (extensible vi layer; this almost works too well)<br>
    * nuvi (new (unlimited) vi)<br>
    * vibe (vi is beautiful?)<br>
    * vici (veni, vidi ...)<br>
    * vimu (vi(m) emulation; vim unlimited; vi made usable)<br>
    * vini (vi new and improved)<br>
    * viva (viva la vi!)<br>
    * yavi (yet another vi)<br></blockquote><div><br></div><div>evil is almost too perfect of a name for it.  That gets my vote!</div><div><br></div><div>My next favorites:</div><div>* vimu</div><div>* viva</div><div><br>

</div><div>I think in terms of search-ability, vimu is likely to get a #1 hit in search engines. viva and evil are going to be hard terms to compete with.  So, I might choose vimu over evil if practicality is the primary priority.</div>

<div><br></div><div>However... if people search for &quot;emacs evil&quot;, they could probably find it in the first couple of hits... so it may not be so bad :)</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">


With five letters or more, there are many proper names to choose from<br>
(elvis is the name of a vi clone): alvin, levi, david, vidal, vince.<br>
And we have:<br>
<br>
    * anvil (a new vi layer; doesn&#39;t sound very light, though)<br>
    * vibrant (the soothing, relaxing, vibrating editor)<br>
    * vigil (vi greatly improved layer-something)<br>
    * vital (vi is vital to, say, avoiding RSI ...)<br></blockquote><div><br></div><div>None of these resonate with me.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">


More letters would be inconvenient; I want the name and code prefix to<br>
be one and the same. (I use an abbreviated prefix in<br>
viper-in-more-modes.el, and I hate the sight of it.)<br>
<br>
Of the above, I rather like &quot;vimu&quot;. It&#39;s short, it&#39;s sweet, and it can<br>
be read as both &quot;vi emulation&quot; and &quot;Vim emulation&quot;. Although I think<br>
Vim sets the baseline for what a modal editor should support, it&#39;s not<br>
the end of the road for me. A sufficiently extensible implementation<br>
will enable the user to explore uncharted territory.<br>
<br>
--<br>
<font color="#888888">Vegard<br>
</font><div><div></div><div class="h5"><br>
_______________________________________________<br>
implementations-list mailing list<br>
<a href="mailto:implementations-list@lists.ourproject.org">implementations-list@lists.ourproject.org</a><br>
<a href="https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list" target="_blank">https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list</a><br>
</div></div></blockquote></div><br>