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

Integrate with external window manager #130

Open
memeplex opened this issue Jan 1, 2016 · 20 comments
Open

Integrate with external window manager #130

memeplex opened this issue Jan 1, 2016 · 20 comments

Comments

@memeplex
Copy link

memeplex commented Jan 1, 2016

The current state of affairs for the tiling/terminal crew is a mess of window management layers: vim splits inside dvtm/tmux panes inside dwm/i3 clients...

From the do one thing well perspective, and for the sake of the user mental health, it would be good to strive to delegate window management to dvtm, tmux, dwm, i3, etc. as much as possible, the way kakoune is leading.

I know this is in your todo list, I just want to remark as a potential user (I long for the day you finally free me for vim/neovim! ) that I find this one of the weakest areas of vis, currently.

@memeplex
Copy link
Author

memeplex commented Jan 1, 2016

Thinking about it a bit more, maybe I'm not understanding you. There is this client/server rpc thing in your plans, so I expected the clients would eventually access a list of open buffers kept in the server. But there is no "hidden buffer" feature a la vim, no way to get a list of open buffers even inside the same instance, afaics. So maybe your intention is to be old school: to avoid this kind of buffer management at all, force the user to save the changes and delegate file selection to external tools (dmenu, the shell, etc.). I'm really interested in hearing about your perspective here.

@martanne
Copy link
Owner

martanne commented Jan 2, 2016

I agree it is a worthwhile goal to let the window manager deal with editor windows.

And yes I personally don't need the "hidden buffer" feature. In principle the window manager should be able to "hide" currently unused windows (e.g. a tilling window manager could move them to different tags). But I understand some people like opening a lot of files and then switch between them using :prev/:next etc.

As for the client/server architecture, the main design decision is to figure out what kind of interface to expose. For example kakoune seems to be sending key strokes to the server? Depending on what you want to achieve it might be better to provide a more low level interface.

At the other end of the spectrum one could just expose the text.h API meaning the server would only take care file content changes. However things like register contents, macros, key bindings etc should probably be shared too? Does this mean the complete vi logic should be server side? What kind of API would be useful for plugins etc ...

@ghost
Copy link

ghost commented Jul 21, 2016

Rather than a "hidden buffer" feature, there could be "recent files" list, stored as plain text to be persistent across reboots:

$ vis "`vis-menu -l 10 < $HOME/.cache/vis/recent-files`"

# ~/bin/scripts/rss2txt.awk ######################################################
  ~/.config/vis/visrc
  ~/.profile
  ~/git/project/README
  ~/git/project/prj.1

This would make no distinction between closed files, and buffers put to the background.

@ghost
Copy link

ghost commented Dec 21, 2016

I implemented this "recent files" in a script, for iomenu.

Here is how I maintain a list of the most recently used files:

sort "$CACHE/vis/recent-files" | uniq -d | while IFS='' read -r f
do
        printf '%s\n' "$(grep -Fxv "$f" "$CACHE/vis/recent-files")" "$f" \
                > "$CACHE/vis/recent-files"
done
printf %s "$(tail "$CACHE/vis/recent-files")" > "$CACHE/vis/recent-files"

This de-duplicates the entries but without sorting it, for latest file to be kept at the end. It keeps only the 10 latests entries using tail.

@halfwit
Copy link

halfwit commented Aug 29, 2018

I want server/client more and more as I move on in my computing world. My initial thoughts here are, the server houses file changes without much more - which would mean that Vis client could be substituted with other mechanisms, should one desire such a thing. (Think, streaming to a limited client when doing presentations, collaborating with people who prefer different interfaces to editing, etc). The client would have a ctl interface to write to for redo/undo, for example and watch the underlying file for changes.

@halfwit
Copy link

halfwit commented Aug 29, 2018

...maybe on the wrong issue, whatever. This one is about buffers - my biggest actual gripe right now is that I can be editing multiple instances of the same file. (It happens!) What I'd like most of all is that the program caches changes to files until they're :w to disk, (or the program closes) and any subsequent opening or closing of files continues, sessioned and based on the file name called on opening. This, as far as I can tell is only really expressible through a client/server, or daemonized interface

@sh4r1k7
Copy link
Contributor

sh4r1k7 commented Oct 8, 2019

@halfwit you can probably implement buffer caching as a simple lua extension listening for Esc key as the event trigger which would be almost identical to https://github.com/roguh/vis-backup

@nmeum
Copy link

nmeum commented Jan 24, 2020

As a radical alternative proposal to implementing some kind of client-server architecture in vis: Why even support "window management", i.e. multiple splits in a text editor in the first place? Why not recommended using one of the excellent terminal multiplexer such as dvtm or tmux where users can create multiple vis splits according to their needs.

@sh4r1k7
Copy link
Contributor

sh4r1k7 commented Jan 25, 2020

I'd say that's the final destination but you still need a client server design to support that otherwise you'd just have multiple independent instances of vis in different terminal windows, which you can already do now.

@tmccombs
Copy link

Why even support "window management", i.e. multiple splits in a text editor in the first place?

Without having splits, a lot of functionality wouldn't be possible even with plugins. Things like diff mode, sidebars for file navigation or git log/blame, etc. Although, currently, diff mode would probably be pretty difficult to implement, and sidebars aren't really doable in a usable way, given how limiting the window system is.

@thyssentishman
Copy link

Is there any progress on this? I'd love to help...

@mralusw
Copy link

mralusw commented Feb 1, 2024

So let me get this straight: because vis is (not) going to have a client/server architecture sometime soon, it's impossible to use tmux panes for windows. Meanwhile, a change as simple as adding support for resizing splits is rejected, because supposedly someday there will be a client/server architecture. Which is not going to happen.

Sounds like a great plan.

@mcepl
Copy link
Contributor

mcepl commented Feb 14, 2024

Sounds like a great plan.

No need to be sarcastic. Of course, those patches you have prepared for us would be considered. Where are they?

@dther
Copy link
Contributor

dther commented Apr 13, 2024

I'm currently working on implementing a working prototype for mouse support that covers all of the usecases in #666, and, in the process, have learned a lot about how the problem of window management was approached by Acme and Sam. I would like to propose an alternative to the client/server model which, theoretically, would require less changes to the current codebase, while simultaneously being better suited to vis' role (in my eyes, at least) as an excellent embedded editor.

Rather than having a "vis server" keeping track of every vis client, we ought to take a page from Acme, and have each vis process maintain a file system interface. A set of named pipes/unix sockets/watched tmp files that allow for executing commands and reliably querying the internal state.

What I'm suggesting is somewhat touched upon in #535, but I think that the suggestion there (of a single endpoint for running commands and receiving outputs) isn't strong enough. Rather, I'm suggesting we attempt something resembling acme's file system interface. Sockets created on demand by and for interacting with the Lua API, FIFOs for simulating keypresses and reading debug messages, tempfiles that are synchronised with internal buffers, leveraging file locking to prevent invalid states, things like that.

As an example for how this can be useful for this issue, in particular: For me, the absolute key feature for working across multiple editors is the ability to yank from one file and put into another, and to be able to jump to the appropriate editor based on file. Anything else, in my opinion, is second. For this minimal proof of concept, I'd need the following capabilities:

  • synchronise the contents of the unnamed register across two or more vis processes
  • read the file path for the currently opened file, and map it to the relevant pane containing its editor

In a server/client model, there are all sorts of questions raised as to how much of this logic should be inside the server, and how much of it is the responsibility of the window manager, and how much external user scripting is needed... And, thus, has lead to the deadlock in which no one is sure how to even start.

Within a file system interface, the delineation of responsibility is clear.

  • Each vis process should maintain a set of tmpfiles in /tmp/vis/processid/ (or some other similarly findable directory) which are synchronised to the registers and to important variables (e.g., absolute file path), and obtains a file lock whenever events are being processed
  • An external process will wait until this file is unlocked (signalling that vis is not currently executing any code), and then read/write to the file as needed to synchronise each processes' internal state

As a bonus, the lack of a separate server also means that vis remains totally usable even in situations where resources are severely limited, such as in early boot or high security file editing. In my understanding, adapting a server/client model to this situation means either duplicating logic between the server and client, or compiling a special "restricted" vis that needs to be maintained separately from the "complete system" vis. Both of these options I consider inferior to simply disabling the file system API if resources are restricted.

The weakness of this system is that it'll create a secondary API that's just as, if not more complex than, the Lua API. However, I believe this to still be less complex than the work needed to implement an abstract server/client model. We have a pattern of how effective file system APIs for editors tend to look like (see acme(4)), and retaining the "each vis process handles its own file" would be less disruptive to the way vis is currently used by many- as an executable binary that can be used wherever a terminal with raw input and stderr is available.

Well, this ended up longer than I hoped. I'd like feedback (from the current maintainers and the userbase that cares enough to be subscribed to this issue) as to whether what I'm describing sounds plausible and desirable. In my eyes, I think this concept is more tangible and ripe for prototyping than a theoretical server/client model for which, as far as I can tell, no one has pinned down in an actionable form.

@halfwit
Copy link

halfwit commented Apr 13, 2024 via email

@whiteinge
Copy link

@dther fascinating idea! You're right about the deadlock on how to even start to tackle this issue, and your proposal sounds like a much simpler approach.

In your opinion, would this approach preclude the ability to have the same file open in separate instances at the same time? One of my more frequent (Vim) use-cases is to have multiple windows on the same buffer so I can see/edit different parts of the file at the same time. Each instance would maintain its own cursor/window position, which seems straightforward, however showing the real-time, unsaved edits in each instance would be much harder.

Perhaps a copy of the file could be stored in the temp directory that could be written to for any "unsaved" changes, and then watched/reloaded by other instances as changes are made, though (without testing) it feels like that might have notable performance implications, possibly in general, but certainly for large files.

@dther
Copy link
Contributor

dther commented Apr 14, 2024

(@whiteinge) In your opinion, would this approach preclude the ability to have the same file open in separate instances at the same time? One of my more frequent (Vim) use-cases is to have multiple windows on the same buffer so I can see/edit different parts of the file at the same time. Each instance would maintain its own cursor/window position, which seems straightforward, however showing the real-time, unsaved edits in each instance would be much harder.

Oh, wow, this is an excellent usecase that I hadn't even considered! Taking into account @halfwit's observation that Unix, unfortunately, doesn't have a portable mechanism for serving shared memory as a file reliable method of coordinating file changes between non-parent/child processes, I'd like to present another alternative arrangement for use in addition to 9-esque file system api: A peer-to-peer model, primarily for editors which are linked to the same file.

The concept is this: each vis process that wishes to allow multi-editor operations on its file has, at bare minimum, a file system API which serves up the absolute path of the file they are editing. Before opening a new file, every vis process checks its fellow peers to see if the file is already open. If it is, then it sends a signal to the vis process, indicating a request for a file synchronisation socket. From this point onwards, the first vis process to open the file becomes the ad-hoc server responsible for tracking this particular file, and any further vis processes will only connect to the ad-hoc server, with any "client" peers rejecting requests for new sockets.

Should the vis peer acting as the server shut down, it will pass its ad-hoc status to the next oldest peer, and send a special signal indicating that this peer must take responsibility for tracking all further edits and opening connections, then finally gracefully exiting after informing all the younger vis peers of the change in server.

As an added bonus, the client peers need not necessarily be vis editors! They could be specially designed processes that translate the state-change messages into, say, IDE autocomplete suggestion requests! If a non-vis client peer is asked to become a server, it can simply "pass it on" to the first process that is a vis editor, or, if no real editors remain, inform the ad-hoc server that it is time to close all connections and finish editing.

I believe this would solve any issues with concurrent same-file management, but it comes with, of course, another set of drawbacks (which I still believe to be more acceptable than a purely theoretical server-client model, of course!)

  • given the number of moving parts needed to implement this, this is less an extension API model and more like three APIs in a trenchcoat. We'd need to figure out a usable (if minimal) Unix file system API, a communication protocol over a socket for transmitting the internal Sam buffer information, as well as determine how the Lua API fits in to all of this. (does the Lua API have special control over server functions? Can the API send messages to client peers? Is the Lua API informed as to whether changes in the file are from the server, or from another client?)
  • it requires we actually pin down a server-client model... But, thankfully, one that is conceptually simpler than what has already been discussed- It doesn't need to handle event processing, edit session management or viewport calculations, as each client that needs to do so can handle that itself- the server can focus entirely on merely keeping files synchronised for vis editors that have the same file open. All the other window manager integrations can be delegated to the file-system API, which (...theoretically) is easier to implement and functions (almost) independently of the peer-to-peer sychrony.
  • Each opened client must keep its own copy of the file buffer in memory. I imagine this is a problem for large files... Or, maybe not, if clients are smart enough to discard messages that are irrelevant to "their" part of the file. I'd need to look at the current large-file-handling code.
  • To my knowledge, this has never been done before. We're breaking new ground. That's odd to me, since, surely, Unix's history with abstracting IPC as server-client networks would have inspired someone to attempt a peer-to-peer network. I can't be the first person to have this idea, right?

Thanks for the words so far! I'll definitely put the file system API on my list of fun vis projects to try, once I polish off my raw mouse event patch into something I consider presentable. I'm close to my first release.

Edit: I forgot mmap exists. I don't know enough about mmap jank to use it. What I do know is that Vis' internal OT-based data structure means that serving up the file buffer as a memory file would require more logical complexity than I'm willing to even attempt.

@mralusw
Copy link

mralusw commented Apr 14, 2024

Reminds me of all the papers about collaborative editing, OT/CRDT (e.g. https://arxiv.org/abs/1810.02137). And to think that vis criticizes vim for offering merely window manager / IDE functions that "don't belong in an editor"... Otherwise, kak seemed to get it just right back when I played with it.

@dther
Copy link
Contributor

dther commented Apr 14, 2024

Reminds me of all the papers about collaborative editing, OT/CRDT (e.g. https://arxiv.org/abs/1810.02137). And to think that vis criticizes vim for offering merely window manager / IDE functions that "don't belong in an editor"...

I don't think that's a fair assessment. Vis doesn't do away with those functions merely for "not belonging", but rather to keep the codebase hackable and with as little backwards-compatible cruft as possible. In my experience trying to add mouse support, it has executed that goal perfectly. Working with its codebase and Lua API has been an absolute dream, and for my uses it has exceeded all expectations. The current windowing capabilities are weak, but good enough that I haven't touched vim after almost a year of use. Though, admittedly, I'm more of a sysop than a programmer these days.

The reason why the server/client model has been in the design philosophy for so long is because it's conducive to vis' internal data structure, which stores changes as a series of OT operations. It's practically begging to be turned into a IPC-local collaborative editor! Vis is much closer to that, structurally, than it is to an IDE.

@mralusw
Copy link

mralusw commented May 2, 2024

I don't think that's a fair assessment. Vis doesn't do away with those functions merely for "not belonging", but rather to keep the codebase hackable and with as little backwards-compatible

Perfectly commendable, but screen-estate management does seem like a core editor feature. In particular, would making the existing splits (panes) resizable reduce hack-ability? I can see how that might be the case for going from a single pane to multiple panes, but once those are in...

The reason why the server/client model has been in the design philosophy for so long is because it's conducive to vis' internal data structure, which stores changes as a series of OT operations. It's practically begging to be turned into a IPC-local collaborative editor! Vis is much closer to that, structurally, than it is to an IDE.

That's interesting. So it should also be possible to save an undo log / journal, and implement crash recovery (e.g. for power outages etc) by replaying the undo log?

Also, adding distributed computing of any kind usually introduces CAP-related limitations ("can't do X because we need to sync to other clients" etc), not to mention bugs (of the hard-to-reproduce kind); would this not also be the case here?

This is not to say it's not a worthwhile idea — just that it might also complicate the existing codebase and the potential to extend it (just like what you said above about other feautres).

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

No branches or pull requests