Sunrise Commander Tips

                                                                 see also Sunrise Commander For Noobs

The Sunrise Commander

A few tips for effectively using the Sunrise Commander file manager. If you can think of any other please share.

Any suggestions for someone wanting to learn to use sunrise?

(Thanks rustom)

  1. Find two good key shortcuts and assign them to the sunrise and sunrise-cd functions (e.g. mine are C-c x and C-c X).
  2. To get acquainted with the specific capabilities offered by Sunrise, I think the best first step is to get and install the Buttons Extension , it’ll provide you with a nice third pane (at the bottom) with buttons you can click to perform many basic operations. The trick with those buttons is that they’re labeled with their equivalent shortcuts, so in no time you memorize them and can use them directly from the keyboard. In general the highest productivity can be achieved when using exclusively the keyboard – use the mouse rather as kind of side-wheels to learn the basics (or to work while eating a sandwich), then just drop it.
  3. Once you know the buttons, go for the listing of bindings in the describe-mode message (just press h while in sunrise mode).
  4. You’ll be best served with Sunrise if you use some kind of Linux or MacOS X. On Windows there’s unfortunately a lot of things you have to set up first to make all the emacs capabilities integrated in Sunrise work. In particular try to have AVFS running in your box – it will allow you to transparently navigate into all kinds of archives (zip, rar, jar, iso, even mbox and patch) – great deal. Unfortunately AFAIK there’s no AVFS for Windows. BTW Archlinux offers Sunrise with AVFS and other goodies conveniently placed in one single package.
  5. Explore all the configurable settings Sunrise offers by typing: M-x customize-group RET sunrise RET
  6. Master Emacs Dired. After all, Sunrise is nothing more than a fancy front end for all the amazing capabilities Dired offers. One aspect of dired I’ve found particularly useful is dired marks (m marks one file, t toggles all marks in the current directory, u unmarks one file, U removes all marks). Most Sunrise and Dired commands can work on all marked files and directories at once.
  7. Learn Emacs. The WDired mode (C-x C-q) puts you in a regular emacs buffer that gives you all the possibilities you normally have while editing text to manipulate the names of your files and directories – query replace, regular expressions, serial numbering… your imagination is the only limit. Just one warning: be careful and play a LOT with it before using it for real, so there are no surprises later and you don’t shoot yourself in the foot.
  8. Learn how to use the “find” utility. Finding files by name (C-c C-n) or by contents (C-c C-g) is cool, but it’s in the raw find command (C-c C-f) where the real power is. Most file managers can only dream of providing such a rich search capability. If you need a place to get you started, here is a good tutorial. Also take the time to study the manual page (M-x man<RET>find<RET> ).
  9. Learn how to define and execute Keyboard Macros. Whenever you notice you’re pressing the same keys you did a while ago, and you suspect you’ll have to repeat the same actions over and over again, at least a few more times, do yourself a favor, stop for a while, and think how to make Emacs do the monkey work for you.
  10. Don’t forget a OFM is just a semi-graphical extension of the command line. Learn when it’s preferable to use the command line (CL) instead of the FM. Learn to use the FM to move fast through your directory hierarchy (e.g. use C-c t and C-c T to activate the CL from Sunrise, and the sunrise and sunrise-cd methods to switch to fullscreen CL and back to Sunrise from there. If you’re using an external shell for the CL (e.g. bash, or ksh, instead of eshell), learn when to use C-c C-j and C-c C-k to switch between line and character mode. Learn to use CLEX tags (%f, %F, %d, %D, %n, %N etc) to write fast your paths and file names in the CL.

How to show all files in the current directory and all its subdirectories?

(this is called XTree or "flat tree" VFS in the OFM standard)

Use find to list everything that’s not a directory: press C-c C-f and type:

    -not -type d

followed by Return. To get everything (including the subdirectories) use find by name instead: C-c C-n * [RET]

This trick is so useful that in version 5R346 I have added a keybinding for it: C-c b


Opening files in external applications.

OpenWith

The best emacs module I’ve seen for opening files in external applications is Markus Triska’s OpenWith. On Linux it works perfectly. On Windows you need to apply the following patch, so it knows how to use the w32-shell-execute function:

--- emacs/openwith.el	2009-01-19 10:26:09.000000000 +0100
+++ openwith.el	2009-03-18 15:44:30.000000000 +0100
@@ -75,16 +75,19 @@
         (setq oa (car assocs)
               assocs (cdr assocs))
         (when (save-match-data (string-match (car oa) file))
-          (let ((params (mapcar (lambda (x) (if (eq x 'file) file x))
-                                (nth 2 oa))))
-            (when (or (not openwith-confirm-invocation)
-                      (y-or-n-p (format "%s %s? " (cadr oa)
-                                        (mapconcat #'identity params " "))))
-              (apply #'start-process "openwith-process" nil (cadr oa) params)
-              (kill-buffer nil)
-              ;; inhibit further actions
-              (error "Opened %s in external program"
-                     (file-name-nondirectory file))))))))
+	  (let ((params (mapcar (lambda (x) (if (eq x 'file) file x))
+				(nth 2 oa))))
+	    (when (or (not openwith-confirm-invocation)
+		      (y-or-n-p (format "%s %s? " (cadr oa)
+					(mapconcat #'identity params " "))))
+	      (if (and (fboundp 'w32-shell-execute)
+		       (string= "open" (nth 1 oa)))
+		  (w32-shell-execute "open" file)
+		(apply #'start-process "openwith-process" nil (cadr oa) params))
+	      (kill-buffer nil)
+	      ;; inhibit further actions
+	      (error "Opened %s in external program"
+		     (file-name-nondirectory file))))))))
   ;; when no association was found, relay the operation to other handlers
   (let ((inhibit-file-name-handlers
          (cons 'openwith-file-handler

I have submitted this patch to Mr Triska, hope it gets included in the official distribution soon.

Once you’ve installed OpenWith, customize the openwith-associations variable as needed.

System Default Application

By default sr-browse-file (b) opens the item under the cursor in your web-browser. You can redefine this function to open the file with the system default application like this:

(defun sr-browse-file (&optional file)
  "Display the selected file with the default appication."
  (interactive)
  (setq file (or file (dired-get-filename)))
  (save-selected-window
    (sr-select-viewer-window)
    (let ((buff (current-buffer))
	  (fname (if (file-directory-p file)
		     file
		   (file-name-nondirectory file)))
	  (app (cond
		((eq system-type 'darwin)	"open %s")
		((eq system-type 'windows-nt)	"open %s")
		(t				"xdg-open %s"))))
      (start-process-shell-command "open" nil (format app file))
      (unless (eq buff (current-buffer))
        (sr-scrollable-viewer (current-buffer)))
      (message "Opening \"%s\" ..." fname))))

It should work on Windows, MacOS and GNU systems. I’ve tested it on Linux only.

– Vitalie Spinu


Experience with GNU Win32 and Windows 7

Recently I had occasion to try GNU Win32 as a way of running nix style tools under Emacs. I downloaded a bunch of GNU Win32 packages including find. My experience was that the find executable does not work at all with Windows 7, This link discusses the issue more specifically: http://gnuwin32.996325.n3.nabble.com/gnuwin32-Help-find-exe-td1265.html. Generally I use Cygwin to get the tools. This is referring to GNU Emacs 24.3 running Windows 7. I do not use Cygwin as my inferior shell interpreter (use cmd instead). Mike F


Adding files opened with external apps to the history of recent files.

When you start using Openwith to open different files with external applications it’s an annoyance not having them included in the list of recently visited files – fortunately an easy to fix one, just add the following snippet to your .emacs configuration:

        (defadvice openwith-file-handler
          (around advice-openwith-file-handler (operation &rest args))
          (condition-case description
              ad-do-it
            (error (progn
                     (recentf-add-file (car args))
                     (error (cadr description))))))
        (ad-activate 'openwith-file-handler)

Better mouse support?

There are several good extensions for enhancing the mouse support in Dired. Personally I like Seiichi Namba’s dired-dd (DiredDragAndDrop). Unfortunately, it won’t work out of the box with Sunrise, as it checks specifically for Dired as its only valid major mode. This can be easily fixed by applying the following patch to the latest version (0.9.1.28):

1569c1569
<   (if (not (eq major-mode 'dired-mode))
---
>   (if (not (derived-mode-p 'dired-mode))
1793c1793
<     (if (eq 'dired-mode major-mode)
---
>     (if (derived-mode-p 'dired-mode)
1836c1836
<       (if (setq target-diredp (eq 'dired-mode major-mode))
---
>       (if (setq target-diredp (derived-mode-p 'dired-mode))

I have been trying to contact Mr Seiichi to submit this patch, but unfortunately without success at the moment.

Drew Adams’ DiredPlus is another good alternative for better mouse support. It doesn’t have additional D&D functions, but gives you a lot of psychedelic colors instead ☺ Besides, Drag-n-drop is available even for vanilla Dired - no need for DiredPlus to add it. See the Emacs manual, node Drag and Drop (Thanks Drew).


How to use Sunrise where Emacs uses Dired by default?

If you provide find-file (C-x C-f) with the name of a directory, or when you use ffap or ido to visit a directory, Emacs will use standard Dired to display its contents. If you want to start Sunrise instead, do the following:

1. Upgrade your copy of SC to version 4R315 or newer.

2. Press M-S-: (or Alt-Shift-: if you prefer ;-)) and type this:

    (setq find-directory-functions (cons 'sr-dired find-directory-functions)) [RET]

3. Do M-x customize-variable [RET] find-directory-functions [RET]

4. Press the “Save for future sessions” button in the customization GUI.


How to use Sunrise with Ido?

If you use IDO and want to have Sunrise instead of plain Dired used, then append the following snippet to your .emacs file:

    (defun ido-sunrise ()
      "Call `sunrise' the ido way.
    The directory is selected interactively by typing a substring.
    For details on keybindings, see `ido-find-file'."
      (interactive)
      (let ((ido-report-no-match nil)
        (ido-auto-merge-work-directories-length -1))
        (ido-file-internal 'sr-dired 'sr-dired nil "Sunrise: " 'dir)))
    (define-key (cdr (assoc 'ido-mode minor-mode-map-alist)) [remap dired] 'ido-sunrise)

Highlighting files with inappropriate permissions.

The sr-rainbow macro allows to easily manipulate the font locking of file and directory names in Sunrise using regular expressions. For instance, in order to highlight files and directories that have read/write permissions set for users other than their owner you could add to your .emacs file a snippet like the following:

        (eval-after-load 'sunrise-commander
          '(progn
             (sr-rainbow sr-gorw-dir-face
                         (:background "misty rose"
                                      :foreground "blue1"
                                      :bold t)
                         "^..\\(d....\\(...\\)?w..*$\\)")
 
             (sr-rainbow sr-gorw-face
                         (:background "misty rose")
                         "^..\\(-....\\(...\\)?w..*$\\)")))

Setting up transparent navigation in compressed archives.

Sunrise integrates with AVFS to provide transparent navigation inside compressed archives with a minimal amount of configuration. How to install AVFS depends on your OS - in linux it’s usually a trivial operation (hopefully your distribution provides a package ready to install). In Debian all you have to do is type (as root):

        apt-get install avfs

in your command line and press Return. Installation instructions for Mac OS X (Lion) are available here.

Once you have AVFS installed in your system, you must launch the AVFS daemon, indicating a point (directory) where to “mount” your entire file system. For instance, If you use as mount point a directory called .avfs (it’s the one I use in my home directory), the command to use will look like the following:

       /usr/bin/avfsd -o allow_root -o intr -o sync_read .avfs 

(have a look at the AVFS documentation for the meaning of the options). If all goes well, you’ll be able to see a “mirror copy” of your file system inside the .avfs directory. Now, from the emacs side all you have to do is:

        M-x customize-variable <RET> sr-avfs-root <RET>

provide the full path to your AVFS mount point, and press the “Save for future sessions” button. That’s it – now try to open some *.zip file inside Sunrise, you should be able to navigate inside it as if it were a regular directory.


How to open the directory under the cursor in the passive pane?

In versions 3R228 and later that’s how the sr-quick-view command (“o” or “v”) works for directories. In previous versions you need to combine two commands: M-; M-Return (follow file in passive pane + visit selected file/directory in passive pane).


How to copy a directory structure without copying the files?

(You know, what "XCOPY /T/E" used to do in good ol' DOS. Sunrise calls this "cloning")

Upgrade your copy of SC to version 3R237 or newer, select the directories you want to clone, press K (sr-do-clone) and select “(D)irectories only”.

Cloning was devised as a more general operation than recursive copying of files and directories[1]: all directories are created with the same name and structure at the destination, while what happens to all the other files depends on the option you choose:

[1] in fact Copy is implemented as a cloning operation.


How to copy file names and paths to the clipboard?

This one is easy: press w to copy the name of the selected file to the clipboard and 0w (first the digit zero, then w) to copy the whole path. To copy more than one file name/path at once, mark (by pressing m) all the entries you’re interested in, then press w or 0w.


How do I compare two directories in Sunrise?

  1. CD to the directories to compare (in left and right panes)
  2. Press C-M-=
  3. Press one of d, s, a, n or c to compare by Date, Size, date And size or file Contents.
  4. Use = to run diff or C-= to run ediff on the files marked.

This facility is not limited to comparing two directories in the file system, it actually compares whatever left and right panes contain at the moment it is invoked: e.g. the results of find/locate operations, contents of compressed archives, etc.


How do I compare *recursively* two directories in Sunrise?

To perform recursive comparisons with Sunrise you need first to “flatten the branch”:

  1. press C-c b to invoke sr-flatten-branch,
  2. select one of “n” (non-directories) or “f” (files only).

This will display all the contents of the current directory and (recursively) all its sub-directories.

Once this is done you can perform a recursive comparison in exactly the same way as you’d do a regular one.

At any moment you can press C-c C-c to return to normal mode.


How do I hide (or modify) selected columns in the list of attributes?

The ‘sr-toggle-attributes’ function (C-Backspace) allows to hide all attributes that are normally displayed on the left of files and directories. Sometimes this is overkilling: one would like to remove most of them, but leave some always displayed, instead of having to choose between all or nothing.

Since version 5r414 it’s possible to control what specific attributes are hidden by ‘sr-toggle-attributes’. It’s just a matter of customizing appropriately one variable: ‘sr-attributes-display-mask’. The value of this variable may be either nil or a list of symbols, one for each attribute column. In this list, if a given element is nil, then the corresponding column will be hidden, and if it’s not nil the column will be displayed. An element may also be the name of a custom function that takes a string as its sole argument and evaluates to a different string – in this case that function will be used to transform the contents of the corresponding column and its result will be displayed instead.

For instance, if we set ‘sr-attributes-display-mask’ to the following value:

    '(t nil nil t nil nil nil)

then when ‘sr-toggle-attributes’ is invoked, all attributes will be hidden, except for the first (permissions) and the third one (e.g. file size). If the list contains more elements than columns on display, the excessive elements are silently ignored. If it contains less elements than columns, the missing elements are assumed to be t and their columns will be left alone.

If instead of t we provide at some position the name of a custom function:

    '(my/octal-permissions nil nil t nil nil nil)

then that function (my/octal-permissions in this case) will be used to transform the value of its corresponding column into something different that will replace its original value, instead of just hiding it.

The rule of thumb here is: if you can achieve the same result either by setting an appropriate value for the listing switches (‘sr-listing-switches’ and ‘sr-virtual-listing-switches’) or by setting ‘sr-attributes-display-mask’, then prefer always the first option – it will always have better performance.


How to display the permissions of files and directories in octal?

One of the most unfathomed mysteries in life is why ls did never provide an option to display file permissions in octal. After all that’s what überhackers use all the time isn’t it? Well, if you read carefully the previous tip then you know this can be achieved in Sunrise with little effort.

Here is a function (my/octal-permissions) than can be used in a display mask to automatically convert the permissions column from symbolic notation to octal in SC:

    (defvar my/octal-memo nil "Memoization cache for ls permissions.")
    (defun my/octal-permissions (input)
      "Convert ls permissions from symbolic representation to octal."
      (flet ((convert (part)
                      (or (assoc-default part my/octal-memo)
                          (let ((perms 0) (flags 0)
                                (perm-n '((?r . 4) (?w . 2) (?x . 1) (?s . 1) (?t . 1)))
                                (flag-n '((?s . 1) (?S . 1) (?t . 1) (?T . 1))))
                            (mapc (lambda (x)
                                    (setq perms (+ (or (assoc-default x perm-n) 0) perms))
                                    (setq flags (+ (or (assoc-default x flag-n) 0) flags)))
                                  (string-to-list part))
                            (cdar (add-to-list
                                   'my/octal-memo
                                   `(,part . ,(list (number-to-string perms) flags)))))))
             (combine (user group other)
                      (let ((flags (+ (* 4 (cadr user)) (* 2 (cadr group)) (cadr other))))
                        (concat (if (zerop flags) " " (number-to-string flags))
                                (car user) (car group) (car other)))))
        (combine (convert (substring-no-properties input 1 4))
                 (convert (substring-no-properties input 4 7))
                 (convert (substring-no-properties input 7)))))

Advanced navigation and location tracking.

Sunrise offers a few advanced mechanisms for moving around and keeping track of locations besides the traditional point-and-click. You can:

            1. M-x customize-group RET savehist RET
            2. Set savehist-mode to ON
            3. Add sr-history-registry to ``Savehist Additional Variables''
            4. Click on ``Save for future sessions''

Alternative usage patterns.

You can use the Sunrise functions to make your own Sunrise Commander. Is there anything you don’t like in Sunrise, or would you like it to have some additional functions it doesn’t have yet? Of course you can always write to the author and ask whether he likes the idea and has the time to implement it, but you can also read the code and do it yourself in the Ol' Good Open Source Tradition.

This section is intended for contributed ways of using / tweaking Sunrise, so it works better for concrete users. If you have your own original way of using the Sunrise Commander, consider adding it here – someone else will probably benefit from it, or maybe the author likes the idea and adds it to the official code ;-)

From Tom Short:

Both my laptop screen and my desktop monitor are quite wide, so I use a lot of horizontal split screen. In sr-mode, I don’t use the viewer much. I like to use windows split horizontally with the right window used as both the viewer/editor and the passive directory window. To do that, I use sr-setup-windows from the PopViewer Extension to get two windows in sr-mode, and I use sr-open-in-other defined below to open the directory or file in the passive window. I assign the space key to sr-open-in-other. I also redefine sr-select-viewer-window.

My usage is as follows:

  • hit space to open the file or directory in the other window
  • hit enter to open the file or directory in the existing window
  • hit v to temporarily open the file or directory in the other pane (works the same as space for directories)
  • hit \ to bring back both directory window

(old code removed, read the next entry for details) j.a.


Update: Feb 4th 2012

Version 2 of the PopViewer extension broke Tom’s code. Version 3 fixes this shortcoming by including out-of-the-box support for this popular usage pattern. Once the PopViewer extension is installed, the only thing needed to instruct SC to stop using frames and start using the passive pane as a transient viewer is:

    (setq sr-popviewer-select-viewer-action
         (lambda nil (let ((sr-running nil)) (other-window 1))))

Personally I prefer to use the M-x customize-variable interface for this kind of tasks, but that’s just a matter of preference.

j.a.


From Guido Van Hoecke:

I use SC on my iMac which has a very large screen, and one of the halves is used by my Emacs. That provides me with a frame of some 180+ cols and 90+ rows.

This is large enough to split it into four equal parts: the two sunrise commander panes on the top half, the emacs shell in the bottom left pane and some other stuff in the right pane.

José was kind enough to implement two new variables to help me enforcing this layout: sr-confirm-kill-viewer and sr-default-window-ratio. I do not want to be prompted when killing the viewer, so the former has value nil. And from the above it will be clear that my desired default ratio is set to 50 (which is a percentage of the available frame height).

I want this layout to be restored when I finish editing a file from the SC panes. José provided following elisp code to assist me with that:

    (defun guivho/sunrise ()
      "Invokes SC the Guido's way ;-)"
      (interactive)
      (unless sr-running
        (sunrise-cd)
        (sr-select-viewer-window)
        (split-window-horizontally)
        (sr-lock-panes)
        (sr-term)))
    (add-hook 'find-file-hook
              (lambda () (add-hook 'kill-buffer-hook 'guivho/sunrise t t)))

I call guivho/sunrise at the bottom of my .emacs, so this layout is present when I start a new Emacs session. The hook code calls this setup whenever I quit editing a file. I have following related key settings:

    (global-set-key (kbd "s-.") 'sunrise-cd)
    (global-set-key (kbd "s-/") 'guivho/sunrise)

The “s-” stands for the Apple/Cmd key on my iMac keyboard.

The window configuration does get lost from time to time, it isn’t perfect yet. But hey, most of the time it works and I can easily restore it by pressing “s-/” or “s-.”.

This setup puts the file management and eshell window in a configuration which surpasses my earlier usage pattern with Midnight Commander on the Mac and on Linux, Total Commander on the Microsoft environment. The idea is that the heart of the app is the file manager and the eshell, and whenever I finish with an action that obscured this setup, it should preferably be restored automagically.

As a related side note, my hot key to switch to the eshell buffer no longer calls eshell but sr-term. This selects the eshell buffer in the viewer window, thereby helping in preserving the layout on the one hand, and providing stability in my setup: eshell is always located in the viewer pane, and not in the SC panes.


Misc customizations

To start SC with no attributes (in case one doesn’t need them everyday), simply customize variable ‘sr-show-file-attributes’ and set it to nil:

    M-x customize-variable [RET] sr-show-file-attributes [RET]

then click on [toggle] and then [Save for future sessions].

Here’s a way to reset SC panes if one have messed them up:

    (defun sr-reset-panes ()
      "Hard-reset SC panes."
      (interactive)
      (when sr-running (sr-setup-windows)))

Here’s a way to have both panes in the same dir when doing sunrise-cd:

    (defadvice sunrise-cd
      (after boris-advice/sunrise-cd ())
      "Forces both SC panes into the current file's directory when using sunrise-cd"
      (when sr-running
        (sr-synchronize-panes)))
    (ad-activate 'sunrise-cd)

If You want SC to list dirs first, and files after that - customize the ‘sr-listing-switches’ variable:

    (setq sr-listing-switches " --group-directories-first -al")

You might also find useful the following:

    (setq sr-listing-switches " --time-style=locale --group-directories-first -alDhgG")

Checkpoint technology remembers both panes directory, if You want to bind some directory to a key, do:

    (define-key global-map [(f12)]
         (lambda ()
           (interactive)
           (sr-dired "/path/to/your/directory")))

if you want the directory to appear always in the same panel (e.g. the right one) you could do something like this:

    (define-key global-map [(f12)]
      (lambda ()
        (interactive)
        (unless sr-running (sunrise))
        (sr-select-window 'right)
        (sr-dired "/path/to/your/directory")))

CategoryDirectories CategoryEmulation