-
-
Notifications
You must be signed in to change notification settings - Fork 405
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
Reopen tab #365
Reopen tab #365
Conversation
Hmm. I'm currently working on bringing this up to date with master. Probably best to ignore this for now. |
Thanks so much for working on this, and welcome to the still very small circle of Next contributors! :) I had a quick look and it's looking good! I'll go for a proper review after you've rebased. I just had an idea: you could add a command which prompts the user with the minibuffer which URL to restore. Awesome, nah? :) Also instead of storing just the URL, I recommend you store both the URL and the title so that it displays in the minibuffer just like for other buffers. |
Also as mentioned in #253, "buffer history" could be confused with the history of visited URLs for a given buffer. I suggest to use the term "recent buffers" instead, or something like that. |
Thanks for the notes! I'll change the variable shortly, and saving the title as well sounds like a good idea. I was also thinking of doing something like what you describe with the minibuffer. In that case, should the buffers be removed from the ring (as they normally are)? I don't think there's a neat way to remove things from the middle of the ring, but it's not as if there will be any performance issues as a result. |
Do you mean like how urls and titles are shown for the current buffer? I don't see where the minibuffer displays both title and url during selection. I'm looking into what I'll have to do to display/return something other than a url string. |
Are you using 1.3.1 or master? Then in `M-x switch-buffer` you should
see URL and titles.
To customize the display of candidates, you need to create a class, say
`dead-buffer`, and customize the object-string method.
For the ring deletion, I suggest the following:
- Create a ring-delete ((ring ring) index) procedure that removes
element at index INDEX.
If the INDEX is closer to HEAD-INDEX then the tail, shift all recent
elements to the "right". Watch for the wrap around. If the INDEX is
closer to the tail, shift all older elements to the "left". This
should be the fastest.
- The ring-pop procedure can then just call to ring-delete.
|
Ah yes, it seems like I was looking at an older version. I see it now. Do you mean shifting left/right by setting the value of the array at index for each element? Would it be faster to create a new ring with the starting array of the concatenation of all elements before the deleted value and all elements after the deleted value1? Or set Another thing: How does one close the minibuffer? Right now it's remaining open after reopening a buffer, and I can't see what I'm doing differently from And finally: should adding the recent-buffer to the ring be part of Thanks! 1 With an extra nil element in one of the arrays to preserve the total length, I guess? |
Okay it doesn't seem like concatenating is any better. I'll do as you described! |
Hmm, it seems kind of tedious to delete a buffer from the ring when there are duplicates, since I don't know how to determine the index. Is there a way for me to get the minibuffer to return the index of the selected item (the index in the original list passed to Also, is this worth it? :P |
libraries/ring/package.lisp
Outdated
#:make | ||
#:pop-most-recent | ||
#:item-count)) | ||
|
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.
Spurious new line?
next.asd
Outdated
@@ -50,6 +50,7 @@ | |||
(:file "window") | |||
(:file "minibuffer") | |||
(:file "keymap") | |||
(:file "recent-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.
What about "recent-buffers" with an "s"?
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.
Fixed.
source/minibuffer.lisp
Outdated
@@ -603,6 +603,7 @@ Return most recent entry in RING." | |||
(ring:insert ring clipboard-content))) | |||
(string (ring:ref ring 0))) | |||
|
|||
|
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.
Spurious new line?
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.
Should be fixed.
source/recent-buffer.lisp
Outdated
@@ -0,0 +1,37 @@ | |||
;;; recent-buffer.lisp --- lisp subroutines for creating and managing recent buffers |
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.
Shorter: "Manage list of recent buffers"
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.
Fixed.
source/remote.lisp
Outdated
(setf (recent-buffers interface) | ||
(ring:make :size (recent-buffers-length interface)))) | ||
;; (make-instance 'ring :items (make-array (recent-buffers-length interface) | ||
;; :initial-element nil)))) |
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.
What about removing this initialize-instance
, removing recent-buffers-length
and setting the initform of recent-buffers:
:initform (ring:make :size 50)
?
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.
In this case, people would set a custom length by putting something like the following in their init.lisp?
(setf (get-default 'remote-interface 'recent-buffersl) (ring:make :size n)
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.
Yes, this is how we used to do it, but I want to deprecate (setf (get-default ...))
.
Instead we can set it in after-init-hook
(or any appropriate hook).
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.
Also see #381
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.
Fixed.
source/remote.lisp
Outdated
@@ -243,6 +243,10 @@ by Next when the user session dbus instance is not available.") | |||
(minibuffer-generic-history :accessor minibuffer-generic-history :initform (ring:make)) | |||
(minibuffer-search-history :accessor minibuffer-search-history :initform (ring:make)) | |||
(minibuffer-set-url-history :accessor minibuffer-set-url-history :initform (ring:make)) | |||
(recent-buffers-length :accessor recent-buffers-length :initform 50 | |||
:documentation "The maximum length of the recent-buffers.") | |||
(recent-buffers :accessor recent-buffers |
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.
You should always set an :initform
(unless you know what you are doing) to prevent "unbound slot" errors.
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 think fixed.
source/remote.lisp
Outdated
;; (make-instance 'ring :items (make-array (recent-buffers-length interface) | ||
;; :initial-element nil)))) | ||
|
||
(defmethod add-buffer-to-recent-buffers-ring ((interface remote-interface) (buffer 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.
What about the shorter add-to-recent-buffers
?
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.
Fixed.
source/remote.lisp
Outdated
;; :initial-element nil)))) | ||
|
||
(defmethod add-buffer-to-recent-buffers-ring ((interface remote-interface) (buffer buffer)) | ||
"Add the url of a given buffer to the buffers ring." |
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.
url -> URL
"to the `recent-buffers' ring"
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.
Fixed.
source/recent-buffer.lisp
Outdated
((name :accessor name :initarg :name | ||
:initform nil) | ||
(title :accessor title :initarg :title | ||
:initform nil))) |
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.
We are trying to increase typing in Next, so could you specify the slot types here?
:type string
should do :)
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 think fixed.
An easy way to do it would be (delete-duplicates my-sequence
:test (lambda (rb1 rb2)
(and (string= (name rb1) (name rb2))
(string= (title rb1) (title rb2))))) Or maybe less costly, you would only delete the elements equal to the one you are adding in |
Regarding the minibuffer not closing: it's now fixed on master. |
Is `plusp` more readable than `(< 0 ...)`?
|
|
… to recent-buffers.
Okay, I think it's working and ~complete. One thing I wasn't sure how to handle was echo-ing to the minibuffer. The following doesn't seem to be working for me.
Also, should we add some keybindings? |
libraries/ring/ring.lisp
Outdated
@@ -17,6 +17,7 @@ | |||
|
|||
(defmethod index ((ring ring) index) | |||
"Return index converted to internal ring index, where items are ordered from newest to oldest." | |||
;; TODO: shouldn't that read "oldest to newest", since index 0 is the oldest? |
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 clarify, index 0 in the internal array is the oldest item, so this line is confusing to me.
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.
The index
method returns a "virtual" index. The internal index 0 is not the oldest item is there has been a wraparound.
For instance, in a ring of size 3,
- in [a b]:
a
at index 0 is indeed the oldest element. - in [a b c], you add
d
, then you get [d b c]: thered
at index 0 is the newest element.
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.
Ah got it.
@@ -29,7 +30,7 @@ Return NEW-ITEM." | |||
(mod (+ (head-index ring) (item-count ring)) | |||
(size ring))) | |||
new-item) | |||
(if (= (item-count ring) (length (items ring))) | |||
(if (= (item-count ring) (size ring)) |
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.
Good catch! ;)
(mod index (size ring))) | ||
(aref (items ring) | ||
(mod (1+ index) (size ring))))) | ||
(setf (aref (items ring) (mod end (size ring))) nil)) |
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.
Could use something like (replace (items ring) (items ring) :start2 1)
.
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 having sort of a hard time visualizing how this handles wrap arounds. Would you need to replace once from start to end, once from 0 to start, and then separately set element that wraps around?
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.
Good point, this might not be worth the complexity of having to deal with the internal index.
I'll think about it.
(mod index (size ring))) | ||
(aref (items ring) | ||
(mod (1- index) (size ring))))) | ||
(setf (aref (items ring) (mod end (size ring))) nil)) |
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.
Same as above, with :start1
.
libraries/ring/ring.lisp
Outdated
(setf (aref (items ring) (mod end (size ring))) nil)) | ||
|
||
(defmethod delete-index ((ring ring) index) | ||
"Delete the item at (internal oldest-first) index and move items to fill the space." |
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.
Hmmm, I think it's confusing that this is the only function where index
is the internal index. Why not using the ring virtual index instead?
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.
No big deal though, we might merge the ring library into cl-containers later.
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.
How about this current version?
(defmethod external-index ((ring ring) internal-index)
(1- (+ (- (head-index ring)
internal-index)
(item-count ring))))
(defmethod delete-index ((ring ring) index)
"Delete the item at external index and move items to fill the space."
(let* ((internal-index (index ring index))
(deleted-item (aref (items ring) (mod internal-index (size ring))))
(head (head-index ring))
(midpoint (mod (floor (+ head (item-count ring)) 2)
(size ring))))
(if (< midpoint internal-index)
(shift-left ring internal-index (+ head (item-count ring)))
(progn
(shift-right ring internal-index head)
(setf (head-index ring) (mod (1+ (head-index ring)) (size ring)))))
(decf (item-count ring))
deleted-item))
(defmethod delete-match ((ring ring) match-test)
(let ((match-index (position-if match-test (items ring))))
(when match-index (delete-index ring (external-index ring match-index)))))
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.
Hmm... I'm afraid external-index
might add extra confusion to the library. I think we should try to keep it to just one "index" method and keep the "internal index" within that method only.
No problem, I'll merge and tweak the code until I find a nice and simple way to put this together.
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.
Another idea: Maybe we should run `position-if' on the output of ring:recent-list, and then delete the index that returns?
Good job! It's mostly ready for merging, the only nit is if you could try using the Regarding the issue with |
Let me know when you grow tired of working on this issue, I can complete the finishing touches if need be, no problem! :) |
Please feel free to make any edits/finishing touches. This is my first time using common lisp so I've been enjoying learning how it all works, but I am also eager to look at other issues. |
That's an option :)
|
I've rebased and merged in befea72. A small tip to ease the burden or merging: when catching up with master, dont "merge", but "rebase against master" instead. This way all your commits will be packed together instead of being spread around merge branches. Also I noticed that you'd used different authors. I've picked one which does not seem to be recognized by GitHub, sorry :p Last but not least: Would you like to be included in the list of contributors in |
Awesome :). I'll rebase in the future and hopefully figure out what's going on with the authorship thing. I'd love to be included on the list of contributors. |
Done in commit
1df811d.
|
Please let me know if anything needs fixing. I wasn't totally sure about where to define things or what names to use.
For some reason, when I change the variables on my machine, something is failing to update somewhere and I am getting errors in slime because undefined variables are being invoked. I figure we can just change the name here when the code reaches an approvable state.
Fixes #253.