5

I'm looking for a command inside Emacs.

For example, you are currently in a directory. In the directory there are 2 files: foo.txt and bar.txt.

I have foo.txt opened in Emacs and is being displayed in a buffer. Then I would like to go to the next file of the current directory of the buffer, so open the bar.txt.

I know there is a Helm source for displaying the another files of the current directory, but I would like to make a keybinding for it, to scroll forth and back between the files in the directory. Dired gave me no suitable commands.

Anyone knows a suitable command?

  • 3
    (1) What is "the next file"? Please specify the order. (2) Why do you say that "Dired gave me no suitable commands"? What Dired commands did you try, and why were they not "suitable"? (Did you try n (dired-next-line), for instance?) As it stands now, your question is unclear and risks being closed. Please try to specify the problem more clearly, and include what you tried and why it was inadequate from your point of view. – Drew May 5 '15 at 14:39
  • 3
    Definitely Unclear as to how to resolve: (1) If there are more than 2 files, how to determine which is next (alphabetical, modification time...) (2) Were there any commands that were close to what you wanted (As a baseline to work from). – Jonathan Leech-Pepin May 5 '15 at 16:13
4

For simplicity, here is another take on a function that opens the next or previous file (by name) in the current directory.

(defun find-next-file (&optional backward)
  "Find the next file (by name) in the current directory.

With prefix arg, find the previous file."
  (interactive "P")
  (when buffer-file-name
    (let* ((file (expand-file-name buffer-file-name))
           (files (cl-remove-if (lambda (file) (cl-first (file-attributes file)))
                                (sort (directory-files (file-name-directory file) t nil t) 'string<)))
           (pos (mod (+ (cl-position file files :test 'equal) (if backward -1 1))
                     (length files))))
      (find-file (nth pos files)))))
  • Your asnwer seems suitable. But I have still one question left: what could I do add as argument, in order to switch back? For example (define-key evil-normal-state-map (kbd "C-M-k") 'find-next-file(?????)) – ReneFroger May 6 '15 at 11:29
  • You use a prefix argument. C-u C-M-k will go to the previous file. Or you can write a wrapper function like (defun find-previous-file () (interactive) (find-next-file t)) Also you cannot add arguments explicitly when binding a function. – Jordon Biondo May 6 '15 at 13:21
  • @JordonBiondo You CAN provide arguments to a function when binding but by using a lambda wrapper; (define-key evil-normal-state-map (kbd "C-M-k") (lambda () (interactive) (find-next-file :backward))) – Kaushal Modi May 6 '15 at 13:44
  • Kaushalmodi, thanks for your reply. It worked right for me! – ReneFroger May 6 '15 at 14:19
3

Here is one way to implement this but you will need to first install the neotree package from Melpa.

Then put the below in your emacs init.

(defun modi/find-file-next-in-dir (&optional prev)
  "Open the next file in the directory.
When PREV is non-nil, open the previous file in the directory."
  (interactive "P")
  (let ((neo-init-state (neo-global--window-exists-p)))
    (if (null neo-init-state)
        (neotree-show))
    (neo-global--select-window)
    (if (if prev
            (neotree-previous-line)
          (neotree-next-line))
        (progn
          (neo-buffer--execute nil
                               (quote neo-open-file)
                               (lambda (full-path &optional arg)
                                 (message "Reached dir: %s/" full-path)
                                 (if prev
                                     (neotree-next-line)
                                   (neotree-previous-line)))))
      (progn
        (if prev
            (message "You are already on the first file in the directory.")
          (message "You are already on the last file in the directory."))))
    (if (null neo-init-state)
        (neotree-hide))))

For the sake of this explanation, let's say you bound this function to C-c n. Then ..

  • C-c n - Go to the next file/dir in the current path
  • C-u C-c n - Go to the prev file/dir in the current path
  • 1
    I would like to choose your answer as the solution, but the answer of Jordon Biondo below works too without any dependencies. I would like to avoid to install some packages, when unnecessary. But I voted your solution up. Thanks, it's really appreciated. – ReneFroger May 6 '15 at 14:27
1

Since you mentioned that you use helm, here's one way to do it using helm.

Open the first file normally using helm-find-files and do whatever you need to with it. Then run helm-resume and press C-n RET. This will open the next file assuming that you are happy with the way helm orders the files (if not, it can be customized).

The downside of this approach is of course that you cannot use any helm commands in between files. If you do, helm-resume will resume that helm session instead.

  • I would like to choose your answer as the solution, but the answer of Jordon Biondo below works too without any dependencies and I don't need to open Helm first. So that's why I choose his answer as solution. But I voted your solution up. Thanks, it's really appreciated. – ReneFroger May 6 '15 at 14:27
  • No problem. If I needed such a function I would choose one of the others above as well. – Qudit May 6 '15 at 16:54
1

Here's a simple solution. First, you know that Dired gives you the commands n and p to go to the next and previous file, o to open it in the other window and s to sort (by modification time).

The package peep-dired automates a bit everything (like the ranger command line file browser).

Install it with M-x package-install (with melpa) Now when you use the arrow keys or C-n and C-p it will automatically display the file content in the other window.

More about Dired: http://wikemacs.org/wiki/Dired

More about (m)elpa: http://wikemacs.org/wiki/MELPA

  • I would like to choose your answer as the solution, but the answer of Jordon Biondo below works too without any dependencies and I don't need to open Peep Dired first. So that's why I choose his answer as solution. But I voted your solution up. Thanks, it's really appreciated. – ReneFroger May 6 '15 at 14:28

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.