nex3 / perspective-el

Perspectives for Emacs.
MIT License
899 stars 71 forks source link

Feature Request: Perspective-specific next/prev buffer switch #63

Open Ailrun opened 7 years ago

Ailrun commented 7 years ago

At least I know, perspective doesn't have features that is like switch-to-next-buffer or switch-to-prev-buffer using specific perspective.

In detail, there is no simple way to change C-x <C-left> (switch-to-prev-buffer) to perspective-relative one. For example, suppose that I have 2 perspective perspA and perspB, and there are 5 buffers in perspA, and there are 7 buffers in perspB. In this case, I can't traverse my buffers only which are in perspA, and while traversing, all buffers of perspB will join to perspA and everything is messed up.

Could you add these features(next/prev) to this wonderful package?

inigoserna commented 7 years ago

I use these functions to achieve the same behaviour you are asking for:

(defun isr/persp-get-buffers-list ()
  "Get filtered list of buffers, sorted alphabetically."
  (sort
   (cl-remove-if '(lambda (b) (if (stringp b) (string-match "^\[* \]" b) t))
                 (mapcar 'buffer-name (persp-buffers persp-curr)))
   'string<))

(defun isr/persp-next-buffer ()
  "My own version of `next-buffer'. Don't show internal buffers."
  (interactive)
  (let ((buffername (buffer-name (current-buffer)))
        (bufferlist (isr/persp-get-buffers-list)))
    (switch-to-buffer (or (cadr (member buffername bufferlist)) (car bufferlist)))))

(defun isr/persp-previous-buffer ()
  "My own version of `next-buffer'. Don't show internal buffers"
  (interactive)
  (let ((buffername (buffer-name (current-buffer)))
        (bufferlist (reverse (isr/persp-get-buffers-list))))
    (switch-to-buffer (or (cadr (member buffername bufferlist)) (car bufferlist)))))
Ailrun commented 7 years ago

@inigoserna Thx for your info! I will try it! Why don't you send a PR?

inigoserna commented 7 years ago

IMO it's a personal customization, not something everyone could be interested in.

Ailrun commented 7 years ago

But it's useful to have, isn't it?

inigoserna commented 7 years ago

Well, I use it daily ;)

Ailrun commented 7 years ago

@inigoserna I mean, it's useful, so there's worth to send a PR with this feature, isn't it?

tonycpsu commented 5 years ago

Looking for something like this myself, and the functions above seem to not be compatible with current versions of perspective. I'm getting Symbol’s value as variable is void: persp-curr.

gcv commented 4 years ago

A few thoughts on this.

To address @tonycpsu's comment about @inigoserna's code not working with current Perspective. You can fix it by changing persp-curr to (persp-curr). If that's the functionality you want, that should be enough.

However, I don't think that code really does the right thing with regard to going to the "next" or "previous" buffer. Since it sorts buffers alphabetically, it actually goes to the next or previous buffer in alphabetical order, not in chronological last-viewed order as the Emacs built-in switch-to-next-buffer and switch-to-previous-buffer do.

Writing an implementation of persp-next-buffer and persp-previous-buffer which does the right thing with regard to chronological sorting is tricky. The equivalent Emacs built-ins are quite complex (and IMO have bad behavior with regard to uninteresting and temporary buffers anyway), and I don't see an easy way to make them respect Perspective.

I recently added Perspective-aware implementations of several buffer switchers, in addition to the Ido support which has been available for a long time. See the updated README for details. Would those work instead of a mechanism for iterating through all of a perspective's buffers in a given window?

gcv commented 4 years ago

Closing this unless someone convinces me that Perspective-aware buffer switchers are inadequate, and that there's a reasonably simple implementation path.

titibandit commented 4 weeks ago

I don't know if this is right, as this seems almost too easy, but I think I've achieved the desired behaviour using

  (defun +titi/persp-skip-buffers (window buff bury-or-kill)
    (not (persp-is-current-buffer buff)))
  (setq switch-to-prev-buffer-skip '+titi/persp-skip-buffers)

basically just forbidding the [previous|next]-buffer functions to switch to buffers that are not part of the current perspective. Doing this preserves the chronological order of last viewed buffers. This conversation maybe predates the switch-to-prev-buffer-skip variable.

Ailrun commented 4 weeks ago

@titibandit Yeah, if I know correctly, it is introduced 27.1 or so, which comes after this issue. But anyway, thank you for providing the snippet!

titibandit commented 3 weeks ago

@Ailrun You're welcome. And yes, it's been introduced in 27.1. I've made a pull request that mentions this customization in the readme file https://github.com/nex3/perspective-el/pull/211

gcv commented 3 weeks ago

Very nice! Thank you @titibandit.

I’m open to automatically setting switch-to-prev-buffer-skip when Perspective is activated on Emacs 27+, but it’s mildly annoying to do in a way that respects the user’s existing settings of switch-to-prev-buffer-skip. (I think the right way is to add a “customize” setting to opt out of setting switch-to-prev-buffer-skip, then save the user’s existing setting when persp-mode is turned on, and restore it when persp-mode is turned off.)

titibandit commented 3 weeks ago

Oh I thought since this is a user setting, it should be, from the perspective (pun not intended) of this package, left alone and only hinted at in the Readme. But it's true that this behavior makes just so much more sense. Having it set automatically by persp-mode is a real improvement to the package I think.