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.

  • 2
    Do you use jabber? – Malabarba Oct 14 '14 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. – Amelio Vazquez-Reina Oct 14 '14 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 '14 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 '14 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 '14 at 15:15
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)
  • What does the # before 'dired-jump signify? I've also seen it being used when adding functions to hooks. – Kaushal Modi Oct 14 '14 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 '14 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))
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.

  • Thanks - I see C-x C-j RET (translated from C-x C-j <return>) is undefined. – Amelio Vazquez-Reina Oct 14 '14 at 13:47
  • Can you do M-x dired-jump? If not, then you don't have the dired-x package loaded. – Kaushal Modi Oct 14 '14 at 13:57
  • Thanks @kaushalmodi -- Yes I can do M-x dired-jump. Forgot to mention that in the OP – Amelio Vazquez-Reina Oct 14 '14 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? – Amelio Vazquez-Reina Oct 14 '14 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. – Kaushal Modi Oct 14 '14 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.

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

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.