see also Sunrise Commander For Noobs
A few tips for effectively using the Sunrise Commander file manager. If you can think of any other please share.
(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
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.
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
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)
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).
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.
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)
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..*$\\)")))
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.
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).
(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: 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:
 in fact Copy is implemented as a cloning operation.
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.
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.
To perform recursive comparisons with Sunrise you need first to “flatten the branch”:
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.
‘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)
‘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-virtual-listing-switches’) or by setting
‘sr-attributes-display-mask’, then prefer always the first option – it will always have better performance.
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)))))
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''
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:
(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.
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
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.
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
(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")))