2

i wonder how i can configure the sr-speedbar mode to automatically move the cursor to a file, which i open by pressing enter in the sr-speedbar. Thanks for your input.

lawlist
  • 18,826
  • 5
  • 37
  • 118
Anton
  • 23
  • 2
  • I looked at `speedbar.el` and also `sr-speedbar.el` and see that the latter adds two functions to hooks that alter the selected-window; i.e., `sr-speedbar-before-visiting-file-hook` and `sr-speedbar-visiting-file-hook`. In a couple of tests with the stock version of `speedbar.el` and also the popular hack/modification known as `sr-speedbar.el` -- I pressed the enter key and was transported to a window that displays the file desired. So, without a recipe to reproduce what you are seeing, it is unknown how best to help you any further. – lawlist Apr 24 '19 at 18:32
  • So, you mean it should work right out of the box, right? Indeed, when i press the enter key, it does open the file, but the cursor remains in the sr-speedbar buffer. – Anton Apr 26 '19 at 04:39
  • No, in fact the opposite. The added `visiting-file-` and `visiting-tag-` hooks intentionally select the previous window to jump back to the speedbar. Why that is the behaviour I don't know, and it's not customisable, so I just hacked `sr-speedbar.el` to not do that. Making it customisable and submitting a patch would obviously be better :) – Mark Mar 28 '20 at 23:08

2 Answers2

2

I encountered the same problem when using sr-speedbar. I fix it with the following hacky stuff in my config file:

(with-eval-after-load 'sr-speedbar
  (add-hook 'speedbar-visiting-file-hook
             #'(lambda () (select-window (next-window))) t))

This is inspired by code I found near the end of the SrSpeedbar page of the Emacs Wiki, under the title « Make Sr-speedbar open files in the next window, instead of in the previous window ». I just found out more logical to use speedbar-visiting-file-hook than the before hook.

Edit:

Actually, the problem comes from custom hooks added by sr-speedbar author. Another very effective way of fixing this problem in just to remove these problematic hooks:

(with-eval-after-load 'sr-speedbar
  (advice-add 'sr-speedbar-open :after
              #'(lambda ()
                  ;; Remove weird sr-speedbar hooks
                  (remove-hook 'speedbar-before-visiting-file-hook #'sr-speedbar-before-visiting-file-hook)
                  (remove-hook 'speedbar-before-visiting-tag-hook #'sr-speedbar-before-visiting-tag-hook)
                  (remove-hook 'speedbar-visiting-file-hook #'sr-speedbar-visiting-file-hook)
                  (remove-hook 'speedbar-visiting-tag-hook #'sr-speedbar-visiting-tag-hook))
Étienne
  • 93
  • 5
  • thanks! i confirm that solves the problem. – Anton Apr 30 '20 at 11:22
  • One problem with the proposed code, however, occurs when more than 2 windows are opened in the current frame. It would be better to switch back to the window identified by the buffer named "*SPEEDBAR*" handling this case. I'm late to the discussion but I'll add cthe code I'm using as an alternative answer. – PRouleau Jan 18 '21 at 22:16
0

Alternative answer with more features:

  • If you want to handle the case where there are several windows opened in the current frame it's better to identify the SR-Speedbar window instead of the 'next-window.
  • You can also implement the ability to setect the default behaviour or the new by using a customizable user-option defined with defcustom form.
  • And for dynamic control, define a variable initialized to the user-option's value which can be changed by a command and then used in the hook to determine whether point should move back to the SR-Speedbar frame or not.

This is what I have written in my PEL package:


(defcustom pel-sr-speedbar-move-point-to-target-on-select t
  "When on, a SR-Speedback select moves point to the target buffer window.                                                                                                                                                                      
Otherwise it leaves point inside the SR-Speedbar buffer window.                                                                                                                                                                                 
This behaviour can be modified by the command                                                                                                                                                                                                   
`pel-sr-speedbar-toggle-select-behaviour'."
  :group 'pel-pkg-for-speedbar
  :type  'boolean
  :safe  #'booleanp)

(defvar pel--sr-speedbar-move-point-to-target-on-select
  pel-sr-speedbar-move-point-to-target-on-select
  "Global behaviour of `pel-sr-speedbar-move-point-to-target-on-select.")

;;-pel-autoload                                                                                                                                                                                                                                 
(defun pel-sr-speedbar-toggle-select-behaviour ()
  "Toggle SR-Speedbar selection behaviour."
  (interactive)
  (pel-toggle-and-show 'pel--sr-speedbar-move-point-to-target-on-select
               "Move to target on SR-Speedbar select"
               "Stay in SR-Speedbar buffer after select"))


(defun pel--select-sr-speedbar-buffer-window ()
  "Select SR-Speedbar buffer window."
  (let ((sp-win (get-buffer-window "*SPEEDBAR*")))
    (if sp-win
    (select-window sp-win)
      (error "Can't find buffer *SPEEDBAR*"))))

(defun pel-sr-speedbar-visiting-control ()
  "Hook callback: determine what buffer to select.                                                                                                                                                                                              
                                                                                                                                                                                                                                                
This function is used by SR-speedbar hooks `speedbar-visiting-file-hook'                                                                                                                                                                        
and `speedbar-visiting-tag-hook'. It returns point to the SR-Speedbar                                                                                                                                                                           
buffer window when pel--sr-speedbar-move-point-to-target-on-select is nil,                                                                                                                                                                      
otherwise it leaves it in the window of the file selected by the SR-Speedbar                                                                                                                                                                    
selection user action."
  (unless pel--sr-speedbar-move-point-to-target-on-select
    (pel--select-sr-speedbar-buffer-window)))

;; Inside the init file or something similar:

(defun pel--sr-speedbar-setup()
      "Setup the sr-speedbar hooks."
      ;; Remove sr-speedbar hooks that switch back to the speedbar buffer                                                                                                                                                                       
      (remove-hook 'speedbar-before-visiting-file-hook #'sr-speedbar-before-visiting-file-hook)
      (remove-hook 'speedbar-before-visiting-tag-hook  #'sr-speedbar-before-visiting-tag-hook)
      (remove-hook 'speedbar-visiting-file-hook        #'sr-speedbar-visiting-file-hook)
      (remove-hook 'speedbar-visiting-tag-hook         #'sr-speedbar-visiting-tag-hook)
      ;; Instead add hooks that a command can control the behaviour                                                                                                                                                                             
      (add-hook 'speedbar-visiting-file-hook         'pel-sr-speedbar-visiting-control t)
      (add-hook 'speedbar-visiting-tag-hook          'pel-sr-speedbar-visiting-control t))

    (with-eval-after-load 'sr-speedbar
      (advice-add 'sr-speedbar-open :after (function pel--sr-speedbar-setup)))


The default behaviour of doing a selection from the SR-Speedbar is to switch to the window of the target. That can be changed by customization and changed dynamically while editing by executing the command pen-sr-speedbar-toggle-select-behaviour.

The function pet-toggle-and-show takes a symbol and toggle its value between nil and non-nil, displaying the interpretation of the new value.

PRouleau
  • 744
  • 3
  • 10