Month: October 2015

Double dired with sunrise commander

I’ve written several times about managing files in emacs with dired. However, if I am copying or moving files between two directories, I have found that I like a two-paned file browser showing the two directories side by side. The package sunrise commander provides this very nicely, giving a great interface for managing files and even copying files between remote and local directories.

It is a tiny bit fiddly to install as it is not in one of the standard package archives. I would suggest evaluating the following code snippet to add the required repository:

(add-to-list 'package-archives '("SC" . "http://joseito.republika.pl/sunrise-commander/") t)

You can then install sunrise-commander using M-x package-list-packages as normal. The repository will be forgotten next time you restart emacs, which is fine as sunrise-commander is stable and rarely updated, and the repository can be slow to respond sometimes, which can affect the package listing.

While you are at it, also install sunrise-x-buttons and sunrise-x-modeline from the same place.

Once you have done this, use M-x sunrise to start sunrise-commander. This will open a two-paned dired style file browser as illustrated in this screen shot:

wpid-sunrise-commander.png

The top left and right panes are two different directory listings, each of which behave very much like dired. You can switch between them with TAB, and if you try to copy or move files, it will default to copying them to the opposite pane, which is just what you want.

This works particularly well when using emacs to manage remote files, indeed in the screenshot above, the left pane is a directory on a remote machine, so it is easy to copy files back and forth between the local and remote machines.

The bottom panel is a set of buttons to perform common tasks (provided by the sunrise-x-buttons extension); I don’t use the buttons but I find them a useful reminder of the keys for those tasks.

The sunrise-x-modeline extension updates the modeline of each directory pane to show a clickable path to the current directory.

There are several other extensions available, as described on the wiki page, and there is a second useful wiki page of tips for sunrise commander.

I have a couple of tweaks that I make:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; sunrise commander                                                      ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'sunrise-commander)
;; disable mouse
(setq sr-cursor-follows-mouse nil)
(define-key sr-mode-map [mouse-1] nil)
(define-key sr-mode-map [mouse-movement] nil)

;;tweak faces for paths
(set-face-attribute 'sr-active-path-face nil
                    :background "black")
(set-face-attribute 'sr-passive-path-face nil
                    :background "black")

;;advise sunrise to save frame arrangement
;;requires frame-cmds package
(defun bjm-sc-save-frame ()
  "Save frame configuration and then maximise frame for sunrise commander."
  (save-frame-config)
  (maximize-frame)
  )
(advice-add 'sunrise :before #'bjm-sc-save-frame)

(defun bjm-sc-restore-frame ()
  "Restore frame configuration saved prior to launching sunrise commander."
  (interactive)
  (jump-to-frame-config-register)
  )
(advice-add 'sr-quit :after #'bjm-sc-restore-frame)

This code disables mouse interaction, and changes the background colour of the directory paths.

More interestingly, I want sunrise commander to run full screen, but then I want my original frame size back when I finish with it. To do this I wrote two simple functions above, that use the frame-cmds library mentioned recently. The first saves the current frame configuration and then maximises the current frame – sunrise commander is advised to call this function when it starts. The second restores the saved frame configuration, and sunrise commander is advised to call this when it quits.

Advertisement

Resize your emacs frame with keyboard shortcuts

I like my emacs windows to be the full height, and 86 columns wide and at the left of the screen if I am using a single monitor, or at the right hand side of the left screen if I am using two monitors.

I have set up a few functions to give me quick keyboard shortcuts to resize and move my frame in this way. These functions require the package frame-cmds (which you can install as usual) to provide the maximize-frame-vertically function.

With these I just use e.g. C-c b <left> or C-c b <S-right> to send my frame exactly where I want it to be.

;;set frame full height and 86 columns wide
;;and position at screen left
(defun bjm-frame-resize-l ()
  "set frame full height and 86 columns wide and position at screen left"
  (interactive)
  (set-frame-width (selected-frame) 86)
  (maximize-frame-vertically)
  (set-frame-position (selected-frame) 0 0)
  )

;;set frame full height and 86 columns wide
;;and position at screen right
(defun bjm-frame-resize-r ()
  "set frame full height and 86 columns wide and position at screen right"
  (interactive)
  (set-frame-width (selected-frame) 86)
  (maximize-frame-vertically)
  (set-frame-position (selected-frame) (- (display-pixel-width) (frame-pixel-width)) 0)
  )

;;set frame full height and 86 columns wide
;;and position at screen right of left hand screen in 2 monitor display
;;assumes monitors are same resolution
(defun bjm-frame-resize-r2 ()
  "set frame full height and 86 columns wide and position at screen right of left hand screen in 2 monitor display assumes monitors are same resolution"
  (interactive)
  (set-frame-width (selected-frame) 86)
  (maximize-frame-vertically)
  (set-frame-position (selected-frame) (- (/ (display-pixel-width) 2) (frame-pixel-width)) 0)
  )

;;set keybindings
(global-set-key (kbd "C-c b <left>") 'bjm-frame-resize-l)
(global-set-key (kbd "C-c b <right>") 'bjm-frame-resize-r)
(global-set-key (kbd "C-c b <S-right>") 'bjm-frame-resize-r2)

Editing and managing files remotely

Emacs supports editing files remotely, as a nice alternative to opening a new emacs session on your remote machine and sending the window over X11. This feature is called tramp.

It works seamlessly – just open a file as usual with C-x C-f and then give the name of the remote file, including the host address – e.g.

C-x C-f /host.server.com:/home/bjm/myfile.org

Note the syntax, that the remote machine name is opened at the top level directory “/”.

You can then edit and save as normal.

It is useful to note that you can also do exactly the same thing to open remote directories in dired to browse, copy, rename and otherwise manage files on a remote machine.

Update

As commenter Nagora points out, if your username is different on the remote machine, you should specify it like

C-x C-f /user@host.server.com:/home/bjm/myfile.org

Toggle between most recent buffers

Here is a handy function to toggle between the two most recent buffers. It has the same effect as C-x b RET but can be bound to a simple key combination. I set it to C-` since it reminds me of the CMD-` used in OS X to switch between windows of the same app.

This code comes from the emacs wiki

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; toggle between most recent buffers                                     ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; http://www.emacswiki.org/emacs/SwitchingBuffers#toc5
(defun switch-to-previous-buffer ()
  "Switch to most recent buffer. Repeated calls toggle back and forth between the most recent two buffers."
  (interactive)
  (switch-to-buffer (other-buffer (current-buffer) 1)))

;; set key binding
(global-set-key (kbd "C-`") 'switch-to-previous-buffer)

Don’t search, swipe

We looked before at basic searches using isearch. However, for some time now I have been using a very nice alternative called swiper. The project page has some good information and a link to a video, so I’ll just summarise what I like about it here.

Swiper acts like isearch, in that you type a string and you get an updating list of matches, but the matching lines are shown in a list in an expanded minibuffer, which you can move through with arrows or C-n and C-p.

One of the best things is that swiper supports regular expressions in a simple way. The main thing you need to know is that spaces are interpreted as a wildcard .* so the query "don swi" would match the title of this post, for example.

The best way to understand it is to try it out yourself. Install swiper and then run it with M-x swiper. I like it so much I have bound it to C-s to replace isearch altogether:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; swiper                                                                 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(global-set-key (kbd "C-s") 'swiper)
(setq ivy-display-style 'fancy)

The second line in the above code sets the colours of the swiper results display to be a bit more, well, fancy! Apparently this option only works well for emacs versions 24.5 and higher, so get updated.

The other tweak I have made is to get swiper to recenter the display when it exits – I found it a little unpredictable where the point was going to be after I finished swiper. This is done with a little bit of advice:

;;advise swiper to recenter on exit
(defun bjm-swiper-recenter (&rest args)
  "recenter display after swiper"
  (recenter)
  )
(advice-add 'swiper :after #'bjm-swiper-recenter)

Wrap text in custom characters

I posted recently about wrapping text in an org-mode block, and decided I wanted a quick way to wrap text in other formatting strings. I quickly came across the excellent wrap-region package which does just this.

For example, with a quick bit of setup you can highlight some words like foo bar in an org-mode buffer and hit * which wraps the words with that character to give *foo bar*, rendering them in boldface. It supports various parentheses out of the box, so hitting ( will wrap the highlighted region in ().

This works really well with expand-region to quickly highlight a word or sentence before wrapping it.

You can install the wrap-region package through MELPA. I added the following lines to my emacs config file to configure it

;; wrap-region
(use-package wrap-region
  :ensure t
  :config
  (wrap-region-add-wrappers
   '(("*" "*" nil org-mode)
     ("~" "~" nil org-mode)
     ("/" "/" nil org-mode)
     ("=" "=" nil org-mode)
     ("_" "_" nil org-mode)
     ("$" "$" nil (org-mode latex-mode))))
  (add-hook 'org-mode-hook 'wrap-region-mode)
  (add-hook 'latex-mode-hook 'wrap-region-mode))

This sets up the common org-mode delimiters and adds $ delimiters for org-mode and latex-mode. I then use the hooks so that wrap-region is only active in org-mode and latex-mode buffers.

Note that in this configuration I have made use of use-package which is a nice way of organising your installed packages and their configuration. I’ll write more about that in due course, but for now, if you want to use the code above in your emacs config file then you need to install use-package and add

(require 'use-package)

to the top of your config file.

Update

I realised that configuration above doesn’t work perfectly with expand-region, since hitting = to wrap a region in = instead expands the region by another level. Happily, wrap-region provides a nice way to work around this. In the code below I set + as the key to wrap a region in = characters, which is convenient as it is on the same key. Usually wrapping a string in + symbols in org-mode gives a strikethrough, but I rarely use this so I’m happy to do that manually when needed.

;; wrap-region
(use-package wrap-region
  :ensure t
  :config
  (wrap-region-add-wrappers
   '(("*" "*" nil org-mode)
     ("~" "~" nil org-mode)
     ("/" "/" nil org-mode)
     ("=" "=" "+" org-mode)
     ("_" "_" nil org-mode)
     ("$" "$" nil (org-mode latex-mode))))
  (add-hook 'org-mode-hook 'wrap-region-mode)
  (add-hook 'latex-mode-hook 'wrap-region-mode))

Org-mode basics V: Exporting your notes

In this final post of my short series on using org-mode to write rich, structured notes, we will look at exporting the notes as a web page or pdf document. The previous posts covered structuring your notes and adding tables and links and images, and formatting text and source code.

If you have been following along, you should have an org file containing all of the notes on org-mode from the previous posts. We’ll now look at exporting that file.

One strength of org-mode is the ability to export to multiple formats. Probably the most useful to begin with are web pages and pdf (via latex) but more are available; to quote the org manual

ASCII export produces a readable and simple version of an Org file for printing and sharing notes. HTML export allows you to easily publish notes on the web, or to build full-fledged websites. LaTeX export lets you use Org mode and its structured editing functions to create arbitrarily complex LaTeX files for any kind of document. OpenDocument Text (ODT) export allows seamless collaboration across organizational boundaries. Markdown export lets you seamlessly collaborate with other developers. Finally, iCal export can extract entries with deadlines or appointments to produce a file in the iCalendar format.

To export your org file to a web page, type C-c C-e to start the exporter and then press h to select html and o to select open. A new web page should now open in your browser.

Similarly, typing l and o in the exporter will convert the org file to latex and then compile it to produce a pdf and display that. Try both of these.

It is possible to add many customisations to the export process. For example, go to the top of the buffer (using M-<) and use C-c C-e and then # to insert an export template. You can then choose to add html or latex (or other) templates (press TAB to see the list).

As an example, add the following to the top of your org file to tweak the appearance of the exported documents.

#+LaTeX_CLASS: bjmarticle
#+TITLE:     Org-mode Basics
#+AUTHOR: Ben Maughan
#+OPTIONS: html-link-use-abs-url:nil html-postamble:auto
#+OPTIONS: html-preamble:t html-scripts:t html-style:t
#+OPTIONS: html5-fancy:nil tex:t
#+HTML_DOCTYPE: xhtml-strict
#+HTML_CONTAINER: div
#+DESCRIPTION:
#+KEYWORDS:
#+HTML_LINK_HOME:
#+HTML_LINK_UP:
#+HTML_MATHJAX:
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.star.bris.ac.uk/bjm/css/bjm.css" />
#+HTML_HEAD_EXTRA:
#+SUBTITLE:
#+INFOJS_OPT:
#+CREATOR: <a href="http://www.gnu.org/software/emacs/">Emacs</a> 24.4.1 (<a href="http://orgmode.org">Org</a> mode 8.3.2)
#+LATEX_HEADER:

This is the default html export template with a couple of tweaks.

  • I have added a link to a style sheet to style the html
  • I have added a latex class bjmarticle to control the appearance of the generated pdf

The latex class is defined in my emacs config file with the following

(add-to-list 'org-latex-classes
             '("bjmarticle"
               "\\documentclass{article}
\\usepackage[utf8]{inputenc}
\\usepackage[T1]{fontenc}
\\usepackage{graphicx}
\\usepackage{longtable}
\\usepackage{hyperref}
\\usepackage{natbib}
\\usepackage{amssymb}
\\usepackage{amsmath}
\\usepackage{geometry}
\\geometry{a4paper,left=2.5cm,top=2cm,right=2.5cm,bottom=2cm,marginparsep=7pt, marginparwidth=.6in}"
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
               ("\\paragraph{%s}" . "\\paragraph*{%s}")
               ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))

You’ll need some experience of LaTeX to make significant changes here, but the sky is the limit.

I have compiled the series of posts on org-mode basics into a single org file, and exported it with this set of export options.

  • The org file is here
  • The exported web page is here
  • The exported pdf is here

The wrapping of the example and code blocks in the pdf needs to be fixed, but overall we get some pretty nice looking documents with minimal effort.

Transpose characters

You can use C-t to run transpose-chars to switch the character at the cursor position with the previous character. Repeated uses have the effect of dragging the character behind the point to the right.

I have found that I prefer the behaviour to be that the previous two characters before the point are switched, as I usually want to do this if I spot I have just made a typo. This is what transpose-chars does if you are at the end of a line, but not if you are somewhere in the middle of the line. To modify the behaviour in this way, I use

;; adjust transpose-chars to switch previous two characters
(global-set-key (kbd "C-t")
                (lambda () (interactive)
                  (backward-char)
                  (transpose-chars 1)))

As an example, with the modified behaviour, using C-t with the point at the end of the string teh changes it to the, while the original behaviour gives you te h (unless you are at the end of a line, in which case you get the). Repeated use of the modified version simply toggles back and forth.

Wrap text in an org-mode block

In my most recent post on org-mode, I talked about using blocks to mark text as being latex, or source code and so on. I mentioned using the shortcuts like <e then TAB on a new line to create an empty block. Sometimes it is handy to wrap existing text in a block, and the following function does that for the text you have selected.

This has been in my config file for ages and I can’t remember where it came from – I know I didn’t write it! A bit of googleing suggests this could be the origin, but if anyone knows different, let me know.

I bind the function to C-< because it reminds me of the < shortcuts to create the blocks, and I don’t use the org-cycle-agenda-files that is usually bound to that key combo.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; function to wrap blocks of text in org templates                       ;;
;; e.g. latex or src etc                                                  ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun org-begin-template ()
  "Make a template at point."
  (interactive)
  (if (org-at-table-p)
      (call-interactively 'org-table-rotate-recalc-marks)
    (let* ((choices '(("s" . "SRC")
                      ("e" . "EXAMPLE")
                      ("q" . "QUOTE")
                      ("v" . "VERSE")
                      ("c" . "CENTER")
                      ("l" . "LaTeX")
                      ("h" . "HTML")
                      ("a" . "ASCII")))
           (key
            (key-description
             (vector
              (read-key
               (concat (propertize "Template type: " 'face 'minibuffer-prompt)
                       (mapconcat (lambda (choice)
                                    (concat (propertize (car choice) 'face 'font-lock-type-face)
                                            ": "
                                            (cdr choice)))
                                  choices
                                  ", ")))))))
      (let ((result (assoc key choices)))
        (when result
          (let ((choice (cdr result)))
            (cond
             ((region-active-p)
              (let ((start (region-beginning))
                    (end (region-end)))
                (goto-char end)
                (insert "#+END_" choice "\n")
                (goto-char start)
                (insert "#+BEGIN_" choice "\n")))
             (t
              (insert "#+BEGIN_" choice "\n")
              (save-excursion (insert "#+END_" choice))))))))))

;;bind to key
(define-key org-mode-map (kbd "C-<") 'org-begin-template)