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

Buffer splitting/tiling #55

Open
dunkyp opened this issue Jan 10, 2018 · 25 comments
Open

Buffer splitting/tiling #55

dunkyp opened this issue Jan 10, 2018 · 25 comments
Labels
feature Feature requests. high ui/ux Nyxt User Interface: themes, appearance and usability.

Comments

@dunkyp
Copy link

dunkyp commented Jan 10, 2018

Is anyone else interested in splitting windows emacs style. I've implemented a super simple prototype in the cocoa version (splitting window in half horizonally and manually updating the window url from the repl) and it seems to work nicely.
Does anyone else like this idea. I've included a screenshot of the hack in action, just want to gather opinions on whether it's worth implementing this fully (horizonal and vertical splitting, resizing window switching etc.)

screenshot

@jmercouris
Copy link
Member

I for one am SUPER interested in this. How do you update the active buffer when splitting the window? Did you make a callback into the next package to set the active buffer?

Any more information on this would be greatly interested. Thank you so much! I have literally been dreaming about this feature for months.

@dunkyp
Copy link
Author

dunkyp commented Jan 10, 2018

Well, that's great news I have a weekend project sorted ;). The implementation is just the simplest possible but I'll push changes once I have them to a fork which I'll create now.

@jmercouris
Copy link
Member

Ok great, I'm so happy to hear this, you have no idea :)

@jmercouris
Copy link
Member

@dunkyp Could you please post the code you did to split the screen? Regardless of how incomplete it may be. I'm quite curious to see!

@shanemhansen
Copy link

@dunkyp Interested in the split screen as well.

@jmercouris
Copy link
Member

I'm afraid the implementation has changed so much since this RFC, that it is at the moment entirely impossible. We have to change a lot of things in the port architecture to support this. I would like window splitting myself as well. I don't like to say it, but this is probably something that will most likely have to wait for version 2.0.

@Ambrevar
Copy link
Member

Ambrevar commented Dec 5, 2018 via email

@jmercouris
Copy link
Member

jmercouris commented Dec 5, 2018

If you can think of a simple way to do this, I would be very happy as this is one feature I really would love to have!

I can't ever wrap my head around the tree structures and how to implement things though (with regards to tiling window managers) :\

@Ambrevar
Copy link
Member

We are very close to being able to have a vertical minibuffer.
A few FFI functions would be enough.

That said, it would be more interesting to implement full-fledged window-manager à-la Emacs. Then the vertical minibuffer would come for free.

Maybe have a look at Lem / StumpWM to avoid reinventing the wheel.

@Ambrevar Ambrevar added the high label Jun 1, 2020
@Ambrevar Ambrevar added the feature Feature requests. label Mar 24, 2021
@aartaka aartaka changed the title RFC window splitting Buffer splitting/tiling Jan 18, 2022
@aartaka aartaka added the ui/ux Nyxt User Interface: themes, appearance and usability. label Jan 18, 2022
@shaunsingh
Copy link
Contributor

Ran into this bug today, which i quite like
20230302_13h34m15s_grim

As #1604 has been fixed, is this possible to implement now? I'd be happy to work on it

@aadcg
Copy link
Member

aadcg commented Mar 2, 2023

Offtopic: That's a seriously customized status-buffer! Glad to see it :)

@shaunsingh
Copy link
Contributor

shaunsingh commented Mar 3, 2023

Glad to see it :)

Thank you for making it to easy to configure :)

Anyways, had a go at trying to implement a hacky version using the current panel-buffer functionality

20230303_01h37m53s_grim

From what I understand, the renderer has assigned containers for the panel buffers and prompt buffer. The hsplit code below doesn't work currently, but you could probably implement it using the prompt-buffers container.

(define-class gtk-window ()

I think the way to go is give prompt-buffer, status-buffer, and message-buffer their own containers, since those are always going to be static on the page (assuming you have one status/message/prompt for the whole window, which is what I prefer)

Then we should be able to spawn new containers for each buffer. This will deprecate the need for panel buffers, and will allow us to create multiple regular buffers of various sizes, enabling emacs/stumpwm-like manipulation and management of windows.

After that its just a matter of modifying the code to take multiple buffers into account, and respond better to mouse actions (e.g. resizing windows). A lot of this is already semi-implemented with panel-buffer's, so shouldn't be too bad

Of course I'd be more than happy to just limit it to one horizontal split and one vertical split, definining static containers for each, but I think it would be much more powerful to enable infinite buffers.

Code for the "poor mans split" below (my enable-modes code clearly doesn't work, although I believe it should?)

(defun open-split (type panel-buffer)
  "a poor mans split"
  (let* ((url (quri:render-uri (url (current-buffer))))
         (modes (mapcar #'serapeum:class-name-of
                  (modes (current-buffer)))))
    (cond 
      ((string= type "horizontal")
       (setf (ffi-width panel-buffer) (ffi-width (current-window)))
       (setf (ffi-height panel-buffer) (round (/ (ffi-height (current-window)) 2))))
      ((string= type "vertical")
       (setf (ffi-width panel-buffer) (round (/ (ffi-width (current-window)) 2)))))
    (buffer-load (quri:uri url) :buffer panel-buffer)
    (enable-modes* modes (buffer panel-buffer))))

(define-panel-command-global vsplit ()
    (panel-buffer "*vsplit*" :right)
  "open current buffer with modes in a knockoff vertical split"
  (open-split "vertical" panel-buffer))

(define-panel-command-global hsplit ()
    (panel-buffer "*split*")
  "open current buffer with modes in a knockoff horizontal split"
  (open-split "horizontal" panel-buffer))

(define-command-global split ()
  "alias to `hsplit`"
  (hsplit))

@jmercouris
Copy link
Member

I think the way to go is give prompt-buffer, status-buffer, and message-buffer their own containers, since those are always going to be static on the page (assuming you have one status/message/prompt for the whole window, which is what I prefer)

(define-class gtk-window ()
  ((gtk-object)
   (handler-ids
    :documentation "See `gtk-buffer' slot of the same name.")
   (root-box-layout)
   (horizontal-box-layout)
   (panel-buffer-container-left)
   (panel-buffer-container-right)
   (panel-buffers-left)
   (panel-buffers-right)
   (main-buffer-container)
   (prompt-buffer-container)
   (prompt-buffer-view
    :documentation "Shared web view between all prompt buffers of this window.")
   (status-container)
   (message-container)
   (message-view)
   (key-string-buffer))
  (:export-class-name-p t)
  (:export-accessor-names-p t)          ; TODO: Unexport?
  (:accessor-name-transformer (class*:make-name-transformer name)))

Very close :-). So the prompt-buffer has a container, the message buffer has a container (message-container), and the status buffer has a container (status-container). The reason for this inconsistent naming is because we actually refer to them as the "status area" and "message area".

I too would like infinite buffers tiling. I have thought about how to do this. From what I have figured it would look like this.

We have a root container, it doesn't matter what this is. With a single buffer it looks like this:

Root -> Horizontal Box -> Webview

if the user splits vertically, we will get:

Root -> Horizontal Box -> Horizontal Box -> Webview, Horizontal Box -> Webview

if the user splits horizontally we will get:

Root -> Vertical Box -> Horizontal Box -> Webview, Horizontal Box -> Webview

so we always wrap a Webview in a container that we can then swap out for a horizontal or vertical container. It would be even easier if we can dynamically assign box layouts to being horizontal or vertical.

In any case, after a lot of consideration and deliberation, I think the best way to do this would be to only allow vertical splits, and then implement horizontal scrolling. This will be the easiest way to present lots of information, and the aspect ratio of all monitors these days is basically wide screen.

If you are interested in implementing this idea, I will champion it to completion :-D

@jmercouris
Copy link
Member

I think it also fits well with people's mental model of "tabs".

@aartaka
Copy link
Contributor

aartaka commented Mar 3, 2023

Anyways, had a go at trying to implement a hacky version using the current panel-buffer functionality

Yeah, I had one too :D

@shaunsingh
Copy link
Contributor

Your config inspired me to have a go at this issue in the first place :p

In any case, after a lot of consideration and deliberation, I think the best way to do this would be to only allow vertical splits, and then implement horizontal scrolling. This will be the easiest way to present lots of information, and the aspect ratio of all monitors these days is basically wide screen.

I actually use a vertical monitor, so I primarily use horizontal splits in vim/emacs, and I'd like to add it sometime. I agree that starting off with horizontal splits for now is a good idea.

If you are interested in implementing this idea, I will champion it to completion :-D

Sure! I'm not the best at CL, I'm only proficient in fennel which is quite a different implementation, so I apologize in advance if it might take a while

Regarding the status-buffer/message-buffer/prompt-buffer, are we having one of each "globally" for the window? Or are we aiming it to handle it like emacs, with one status per split.

I feel like web-pages are generally a lot bigger than text, and our status-buffer is quite crowded already, so we should stick with one globally

@aartaka
Copy link
Contributor

aartaka commented Mar 3, 2023

Regarding the status-buffer/message-buffer/prompt-buffer, are we having one of each "globally" for the window? Or are we aiming it to handle it like emacs, with one status per split.

I feel like web-pages are generally a lot bigger than text, and our status-buffer is quite crowded already, so we should stick with one globally

Yes, that'd be my intuition too!

@jmercouris
Copy link
Member

Yes, we can stick with one globally that updates when you select different buffers.

@tekakutli
Copy link

tekakutli commented Apr 19, 2023

This would be cool, that said:

I did this too, but it wasnt intentional, it has happened a couple of times and I dont know what I did or how to fix it other than by restarting nyxt
https://files.catbox.moe/df07y0.png
do anyone knows how to close it?

@jmercouris
Copy link
Member

I have no idea how you did that. Presumably two views got added to the current buffer view and it stacked them on top. Perhaps some race condition?

@shaunsingh
Copy link
Contributor

Indeed, sometimes the view bugs out and puts a web buffer in place of the prompt buffer.

I've been quite busy with personal and work projects, but I still plan to work on this soon-ish ™️

@MaxGyver83
Copy link
Contributor

Today (running the master branch's version), I also ran into an unintentional split:

2023-09-30 10 48 02 2560x1412 Window

I tried Ctrl-Alt-h (jump-to-heading-buffers) and browsed through the result list and then aborted with Esc.

@shaunsingh
Copy link
Contributor

A small update to the above: I did have a badly broken but slightly functional PoC with gtk, but had to switch back to macOS for work and, despite my best efforts, couldn't compile webkitGTK using nix. In the meantime, I'd be happy to work on the electron port (#2989) and attack this in the future

cc @aartaka

@aartaka
Copy link
Contributor

aartaka commented Oct 1, 2023

No worries, we're not hurrying with it anyway (I myself in particular — I already have what I need with the panel buffer hack 😅)

@teutonicjoe
Copy link

@MaxGyver83 I have also run into this strange vertical split thing unintentionally! Seems like Nyxt wants to have Emacs like buffer management hahah

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Feature requests. high ui/ux Nyxt User Interface: themes, appearance and usability.
Development

No branches or pull requests

10 participants