Hello On Mon, Feb 15, 2016 at 05:34:58PM +0100, Marc André Tanner wrote: > In general what kind of data structure do you use to keep track of cursors > when the buffer changes? That is when something is inserted/deleted at a > cursor location, do you need to update the location of all subsequent > cursors?
Kakoune uses an array of line representation of buffers, so quite naturally selections are represented as a pair of (line, column) coordinates. Selections are kept sorted, so when inserting/deleting we keep track of the actual position change before processing the next selection. A list of buffer modifications is kept as well (separate from the undo list, this is an append only list of (position, length, insert/erase) data. Selections keep a timestamp so that when they are accessed and they are not up to date (that can happen when we have two windows on the same buffer) we can update them by applying all the modifications from last timestamp. That update is accelerated by batching the consecutive modifications that are either forward or backward sorted. For more details, I recommend taking a look at SelectionList::update :) > If you don't mind I would also like to discuss different approaches > to a client/server design. What kind of protocol do you use? Am I right > that the clients are rather "dumb" i.e. they just forward keyboard input > and display stuff rendered by the server process? Yep, the client server design has very dumb clients. A client only provides an user interface, it sends events (keys, mouse events, resize events) and recieve display commands. An important thing is that its totally asynchrounous, a command never recieve an answer, so we cannot by design be waiting on a client. The protocol is ad-hoc, sending directly the binary data of most structures, its actually something i'd like to improve as at the moment you cannot have a 32bit client connect to a 64bit server. > In Kakoune external programs/plugins talk to the editor via a bunch > of built in commands, manipulating the buffer content through regular > keyboard shortcuts, right? Do you feel this is flexible enough? Doesn't > this completely break if the user decides to change some keyboard mappings? Yep thats basically the case, external program can send commands in the same command language the user uses to open files, save, jump to tags... Buffer modification is the role of the normal/insert mode so scripts have to use that as well. It does work well enough although it has some limitations, expressing complex logic is tricky but works, it is an interesting design challenge to try to find a solution for script use cases that makes sense for interactive edition as well. One important design choice here is that the key mapping *is* the editing language, and not a binding of keystrokes to underlying commands. That means that, by default, the :exec command (that sends keystrokes as-if typed) will ignore user key mappings. > For vis I'm wondering what kind of RPC interface to expose. As an extreme > example should it be possible to connect with both a vim like and an > Emacs like interface to the same session/buffer? That is should the main > editor logic be client side and the server would only propagate buffer > changes and keep some shared state (e.g. registers, marks, macros ...)? I guess that really depends on what your goal is for vis. I am very happy with the asynchrounous nature of Kakoune's protocol, which I think works well because clients are very simple. The more you put in the client, the more complex you communication needs to be (for example you will need to access the buffer change history to update selections in your client if the buffer gets modified by another client, especially as with multi selection you can get a huge set of modifications in one go). > Looking forward to your comments and thanks for Kakoune it has some nice > ideas! Thanks, good luck with vis, I am happy to see it evolve on its own path rather than as just a vi clone. Cheers, Maxime.