wasamasa / eyebrowse

A simple-minded way of managing window configs in emacs
GNU General Public License v3.0
437 stars 24 forks source link

Uniquify + eyebrowse = deleted buffers #73

Closed mrcnski closed 6 years ago

mrcnski commented 6 years ago

Whenever I open a new buffer in one workspace that triggers a uniquify rename of a buffer in another workspace, the original buffer is deleted. If both buffers are in the same workspace or if I'm not using eyebrowse, this problem doesn't occur.

I've solved this for the time being with the following code to prevent most buffer renames:

(setq uniquify-min-dir-content 2)
wasamasa commented 6 years ago

Well, it's nice that you've found a workaround, but please provide a minimal repro. I use uniquify as well and don't see the described behavior.

mrcnski commented 6 years ago

Just tried with the following minimal init.el (after initializing use-package). Confirmed the error is not due to any other packages.

(use-package eyebrowse
  :bind (("s-," . eyebrowse-prev-window-config)
         ("s-." . eyebrowse-next-window-config)
         ;; ("C-\"" . eyebrowse-create-window-config)
         ("s-0" . eyebrowse-switch-to-window-config-0)
         ("s-1" . eyebrowse-switch-to-window-config-1)
         ("s-2" . eyebrowse-switch-to-window-config-2)
         ("s-3" . eyebrowse-switch-to-window-config-3)
         ("s-4" . eyebrowse-switch-to-window-config-4)
         ("s-5" . eyebrowse-switch-to-window-config-5)
         ("s-6" . eyebrowse-switch-to-window-config-6)
         ("s-7" . eyebrowse-switch-to-window-config-7)
         ("s-8" . eyebrowse-switch-to-window-config-8)
         ("s-9" . eyebrowse-switch-to-window-config-9)
         ("s-/" . eyebrowse-close-window-config)
         ("s-t" . eyebrowse-rename-window-config)
         )
  ;; :init
  ;; (setq eyebrowse-keymap-prefix nil) ; Broken!
  :config
  (eyebrowse-mode t)
  (setq eyebrowse-wrap-around t)
  (setq eyebrowse-switch-back-and-forth t)
  (setq eyebrowse-new-workspace nil)
  )

As far as triggering this, it's easy. Just open two identically named files, in different directories, in two separate workspaces.

I'm on Emacs 25.2.1.

wasamasa commented 6 years ago

Thanks, I can reproduce it now. The reason for the current behavior is that I've found restoring workspaces referring to no longer available buffers to fail silently, so I put in code there that checks whether a buffer can be found by the saved name and if no, replaces it by the scratch buffer and emits a message. That check fails after uniquify renamed the buffer as it doesn't know the buffer has been renamed.

I'm not sure how to fix this. Ideally, window-state-get would store a buffer instead of its name, that would avoid this problem (and make a new one because serialization would fail), other than that I can think of the following solutions:

What do you think, does the first option sound acceptable to you?

mrcnski commented 6 years ago

Make the fixing up behavior customizable. It would still fail for the buffer killing case, but at least uniquify wouldn't annoy you any longer.

Do you mind elaborating on this solution? I'm not sure what you mean by the bolded parts.

These are my pain points with the current behavior:

In Rust projects it is very common to have files called mod.rs, lib.rs, main.rs etc. (and often they are in a src folder, which is why my workaround sets the min-dir-content to 2), so I encounter this behavior many times a day. Any solution to minimize the annoyance would be great, but preferably not at the cost of breaking things or some complex logic.

wasamasa commented 6 years ago

There's two problematic scenarios with restoring a window configuration:

  1. The window configuration refers to a buffer that has been killed. Restoring such a window configuration as is will not create a window for that buffer. Therefore I've added code that checks for buffers in a window configuration with a name that doesn't refer to an existing buffer and replaces them with the scratch buffer so that a window will always be displayed.
  2. The window configuration refers to a buffer that has been renamed between saving it and switching back to it again. Suppose you have a mod.rs buffer living in foo/ on window config 1, switch to window config 2 and open a mod.rs buffer living in bar/. Uniquify renames the first buffer to foo/mod.rs and the second to bar/mod.rs. If you switch back to window config 1 it does the aforementioned check, finds a window referring to mod.rs, but no buffer with that name, so it displays the scratch buffer instead.

Opting out of this behavior would be an easy workaround. I'd ideally like both scenarios to work out of the box.

mrcnski commented 6 years ago

Thanks for the explanation.

Opting out of this behavior would be an easy workaround.

Sure, that would satisfy me personally. I don't think I've ever run into the first scenario, but the second one bugged me daily.

wasamasa commented 6 years ago

It turns out that no, opting out of it is in no way a workaround. I'll have to think up something smarter, like advising rename-buffer and going through all window configs, replacing all occurrences of the old name with the new one.

wasamasa commented 6 years ago

I figured out a way and it works for me. If it doesn't work for you, please comment and/or reopen the issue.

mrcnski commented 6 years ago

Thank you for taking the time to fix this. Looks good so far!