-
-
Notifications
You must be signed in to change notification settings - Fork 424
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
WIP: Persist buffer state to history (for modes, tags and more) #2627
Conversation
@Ambrevar Could you please re-word the discussion section? It seems off. |
Could you please explain the concept of a |
source/history.lisp
Outdated
@@ -344,7 +352,8 @@ Return non-NIL of history was restored, NIL otherwise." | |||
:url (url (htree:data current-node)) | |||
:load-url-p nil))) | |||
(setf (gethash owner-id old-id->new-id) (id new-buffer)) | |||
(setf (gethash (id new-buffer) new-owners) owner)))))) | |||
(setf (gethash (id new-buffer) new-owners) owner) | |||
(enable-modes (modes (htree:data owner)) new-buffer)))))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit confused by this. Could you explain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be more precise: htree:data
can be whatever, so it feels a bit arbitrary to use it to restore the modes that were active in a buffer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
htree:data
is an accessor for the arbitrarily-typed payload inside the owner/node. This is a design decision that we made to not tie ourselves to any particular design of histoy nodes and to make htree
more reusable.
Thought more about it: manually serializing modes and tags might be a bit shortsighted. Instead, we should probably add a For instance, create buffer B, serialize it with the new method, kill the buffer, then deserialize the serialized content to recreate the buffer. |
That sounds better to me @Ambrevar! |
By the way, this would address the long-standing issue of how to abstract "dead buffers". Two (or three?) birds with one stone. |
Yes, serializing buffers to history was the initial solution I thought of for buffer tagging :D |
2b6e80d
to
95064a1
Compare
@aartaka It seems that auto-rules are broken. For instance reloading a page disables the manually enabled modes, which is wrong. (See the original post for an example). Can you have a look? |
Good news! I'm able to serialize and restore buffers with all their modes! |
Ahhhhhh, I might know the reason—I've removed the handler from |
Thanks! |
Before going further we need to merge #2654 and 40ants/cl-prevalence#22. |
d53b60f
to
e285ec0
Compare
I've rebased and squashed. Prevalance still needs a fix: 40ants/cl-prevalence#25 Then there are a few more issues to iron out with this patch (like internal page URLs failing for some reason), but we are close! |
Internal page URLs may fail because they are being loaded before the context has all the schemes initialized. But that's a wild guess :) |
ef55b66
to
714fee4
Compare
I'm working on the problem that URLs / timestamps are serialized as strings and thus need some manual code to be deserialized properly. Of course the manual code is easy to write, the problem is that it needs to be set in many places which is cumbersome and error prone. The following seems to work to ensure that (defmethod (setf slot-value-using-class) :around (new-value
(class user-class)
(instance buffer)
slot)
(if (eq 'url (c2mop:slot-definition-name slot))
(call-next-method (ensure-url new-value) class instance slot)
(call-next-method new-value class instance slot))) Still, it needs to be done for all classes + it's verbose. Can we do better? I'm thinking of a few options:
(define-class ...
((foo "blah"
:type string
:type-coercion #'princ-to-string)
...)) Way less verbose, but still needs to be done for all slots.
(defmethod (setf slot-value-using-class) :around (new-value
(class user-class)
instance
slot)
(typecase (c2mop:slot-definition-type slot)
((quri:uri)
(call-next-method (ensure-url new-value) class instance slot))
(t
(call-next-method new-value class instance slot)))) The drawback is that this is global, so if we want a bit more flexibility for a specific slot, we would need to override the above method for the concerned given class. Or... just use a more flexible slot type. So maybe that's not much of a drawback after all. Thoughts? EDIT: Clarifications. |
But why not override cl-prevalence serialization for these? |
I guess you meant DEserialization. We cannot do it based on the type, because the type is So we would have to do it for every quri:uri / timestamp slot of every class. Which is what this pull request does. It's cumbersome and error prone since it's easy to forget some slots. Plus it's an extra burden for extension writers / user configuration. |
See ed72ca7 for the new This makes everything much simpler in my opinion. Plus now it succeeds while previously it would error on internal buffers. Only What do you people think? It seems to be working and I'm able to restart the browser and restore buffers with their modes. There are still some rough edges, in particular with auto-rules. Need to work on these. In the mean time, feedback welcome! |
ed72ca7
to
6f5c3c0
Compare
Remove deserialize-sexp-slot methods that handle URLs and timestamps since these are now covered by the more general coerce-slot.
f41de74
to
d3dbbde
Compare
Before this can be tested properly #2895 must be addressed. |
Please reopen when ready. |
Description
This persists buffer modes (and more buffer data) in history. This is useful so that on restart, modes are restored (which can be critical e.g. for privacy).
Fixes #2064 and #2583 (not yet).
Fixes #2036.
How to test
Discussion
Is the design sane?
In my opinion, yes, as it makes only minimal modifications to the Htree library, while adding a Nyxt core class that's easily extensible to add more buffer-related data to persist in the future.
Can we better serialize and deserialize URIs and timestamp? The problem is that until now we used to serialize them as strings, but then how can Nyxt know which string is a URI, a timestamp, or just a string?
An option would be to use reader macros, for instance
(local-time:enable-read-macros)
. But that would break history backward compatibility. Thoughts?uri-sepcifier
andtimestamp-specifier
which accept strings, then write accessors to automatically replace the string with the structured version. With a bit of MOP we could derive a general solution.coerce-slot
, which automatically coerce the value to the desired type.To do:
tags
slot and persist it.Checklist:
Everything in this checklist is required for each PR. Please do not approve a PR that does not have all of these items.
cd /path/to/nyxt/checkout git submodule add https://gitlab.common-lisp.net/nyxt/py-configparser _build/py-configparser
:documentation
s written in the aforementioned style. (It's OK to skip the docstring for really trivial parts.)changelog.lisp
with my changes if it's anything user-facing (new features, important bug fix, compatibility breakage).migration.lisp
entry for all compatibility-breaking changes.