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.

  • 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 4: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 Aufflick Mar 28 '20 at 23:08

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.


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))
  • 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 at 22:16

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                                                                                                                                                                                                   
  :group 'pel-pkg-for-speedbar
  :type  'boolean
  :safe  #'booleanp)

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

(defun pel-sr-speedbar-toggle-select-behaviour ()
  "Toggle SR-Speedbar selection behaviour."
  (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

;; 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.