7

I used to have a keyboard shortcut for the following action:

"Open the folder containing this file in Dired+, and place point (cursor) on the file"

I believe it was C-x C-j, and I don't recall setting it up manually. It seems to be gone. Did recent changes to Dired+ perhaps change this?

Either way, are there any Dired or Dired+ built-in interactive functions that I could use for this? If not, how can I go about building one?

I can run M-x dired-jump. The problem seems to be that the keybinding is gone. When I do C-h k C-x C-j RET, I see C-x C-j RET (translated from C-x C-j <return>) is undefined.

7
  • 2
    Do you use jabber?
    – Malabarba
    Oct 14, 2014 at 13:56
  • @Malabarba I do actually have Jabber installed (but am not directly loading it in Emacs directly). Could it still be the problem? I will check. Oct 14, 2014 at 14:06
  • 1
    jabber binds C-x C-j as a prefix. It might be getting loaded without you realising. Try uninstalling (just move it to a different directory, you can move it back later).
    – Malabarba
    Oct 14, 2014 at 14:09
  • 1
    FWIW: Library dired+.el does not change dired-jump or any key binding to it. dired-jump is not even mentioned in Dired+.
    – Drew
    Oct 14, 2014 at 14:18
  • 2
    In a case like this ("X stopped working"): (1) Try to repro from emacs -Q. (2) If you can't repro from emacs -Q then recursively bisect your init file, to see which part is causing the problem. To do that, comment-out 1/2, then 3/4, then 7/8... You can use comment-region to do that (C-u uncomments). After trying all of that, if you need more help (and you probably won't), ask here.
    – Drew
    Oct 14, 2014 at 15:15

5 Answers 5

8

The Problem

jabber.el and dired-x unfortunately conflict on this keybind. Jabber uses C-x C-j as the prefix for all its keys, while dired sets it to your beloved dired-jump (that’s probably why the latter is made optional through the dired-bind-jump variable).

Do complicate things further, if Jabber is installed with package.el it binds this key twice! First on Emacs startup, then upon loading jabber.el.

The Solution

Bind dired-jump both before and after Jabber has been loaded. Make sure this happens after (package-initialize) in your init file (if you use it).

(global-set-key (kbd "C-x C-j") #'dired-jump)
(eval-after-load 'jabber-keymap
  '(global-set-key (kbd "C-x C-j") #'dired-jump))

Or, if you’re using Emacs 24.4, the following is slightly preferred:

(global-set-key (kbd "C-x C-j") #'dired-jump)
(with-eval-after-load 'jabber-keymap
  (global-set-key (kbd "C-x C-j") #'dired-jump))

To continue using the jabber keymap, you can bind it to a different key sequence, as in

(global-set-key (kbd "C-c C-j") jabber-global-keymap)
2
  • What does the # before 'dired-jump signify? I've also seen it being used when adding functions to hooks. Oct 14, 2014 at 14:36
  • 5
    @kaushalmodi It's a function quote. It’s almost the same as a regular quote, but it tells the byte-compiler this symbol is a function (which it can use to give useful warnings). It’s irrelevant in your init-file, but it’s relevant in packages so I try to motivate good practice.
    – Malabarba
    Oct 14, 2014 at 15:01
4

As others have already noted, you're thinking of the function dired-jump, which is provided by Dired-x (not Dired+), and is bound to C-x C-j when the Dired-x library is loaded. (You can turn off this binding by setting dired-bind-jump to nil before Dired-x is loaded.)

Given that C-x C-j does something, rather than complaining that C-x C-j is undefined, what's happening is that something else has defined a binding for it. Whoever defined the binding last wins.

So you need to track down what other package that you're loading is overriding C-x C-j. That package is loaded after Dired-x, so if you're loading dired-x in your init file, it's either something that you're loading further on or something that gets autoloaded at some point.

Since C-x C-j doesn't do anything on its own, but waits for another key to be pressed, it's a prefix key. Press C-x C-j C-h to see a list of bindings that start with this prefix. This should give you a good idea of the culprit package. Malabarba's hypothesis that it's Jabber mode is a plausible one. Once you've identified a key sequence that starts with the prefix C-x C-j, press C-h k followed by that key sequence. This will show the help text for that command and the package that provides the command. It's likely that the package that provides the command is the same package that defines the binding.

It's unlikely that you'll need to go that far, but just in case, if there's some key binding you can't track down, see How can I find out in which keymap a key is bound?

If you want to load that package that overrides C-x C-j, but you don't want it to take over that binding, see if it has an option to skip that binding. If it doesn't, you can snatch the binding back: arrange to run (global-set-key "\C-x\C-j" 'dired-jump) after the offending package is loaded. It may be enough to put that at the end of your init file. If not, you can use

(eval-after-load "NAME-OF-THE-OFFENDING-PACKAGE" '(global-set-key "\C-x\C-j" 'dired-jump))
0
2

What do you see when you do C-hkC-xC-jRET?

You should see that it is bound to dired-jump. If it's not then you either haven't done require of dired-x or you/some other package overrode that binding with something else.

If you can do M-x dired-jump and just need that binding, then you can do

(global-set-key (kbd "C-x C-j") 'dired-jump)

But if dired-bind-jump is t and if you have (require 'dired-x), then that package will set that binding for you.

6
  • Thanks - I see C-x C-j RET (translated from C-x C-j <return>) is undefined. Oct 14, 2014 at 13:47
  • Can you do M-x dired-jump? If not, then you don't have the dired-x package loaded. Oct 14, 2014 at 13:57
  • Thanks @kaushalmodi -- Yes I can do M-x dired-jump. Forgot to mention that in the OP Oct 14, 2014 at 13:58
  • Given that the command is there and the problem is that my bindings are messed up, perhaps I am better off asking this in a different question "How can I debug a missing keyboard binding?" or similar? Oct 14, 2014 at 14:00
  • 1
    That binding should work as expected if you launch emacs -Q and do just (require 'dired-x). If that works, then gradually populate your init.el till that binding goes away once again; that way you'll find the culprit. Another way is doing recursive grep/ag/ack for C\-x\s+C\-j in your .emacs.d folder. Oct 14, 2014 at 14:04
1

I use this regularly. Just tested it with emacs -Q, this is all you need:

(require 'dired-x)

The functionality is provided by dired-x, which is different from dired+. The former is shipped with core Emacs, the latter is a 3rd party extension library.

2
  • Also ensure that dired-bind-jump is set to its default value t.
    – legoscia
    Oct 14, 2014 at 13:38
  • Thanks @legoscia I just checked and dired-bind-jump is t. I am also loading (require 'dired-x). Strange Oct 14, 2014 at 13:52
0

I didn't have any offending packages i.e. no packages took over the binding C-x C-j but still this shortcut, which was working on a different Emacs session, stopped working i.e. a new Emacs session didn't have this bound.

I realized that in the session where this binding was working, I'd earlier launched dired manually (using M-x) and then on this key combination was bound; I used it subsequently mistaking it as a binding that's always there. While on the newer Emacs session, I hadn't launched dired or dired-x till that point, so the key combination wasn't bound; it wasn't working. The solution is to manually bind it so that it works irrespective of whether dired was launched or not.

Dired Extra has a section in its manual on this which cleared it up for me.

In order to have dired-jump and dired-jump-other-window work before dired and dired-x have been properly loaded you should set-up an autoload for these functions. In your .emacs file put

     (autoload 'dired-jump "dired-x"
       "Jump to Dired buffer corresponding to current buffer." t)
     
     (autoload 'dired-jump-other-window "dired-x"
       "Like \\[dired-jump] (dired-jump) but in other window." t)
     
     (define-key global-map "\C-x\C-j" 'dired-jump)
     (define-key global-map "\C-x4\C-j" 'dired-jump-other-window)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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