You know how many windows managers have workspaces you can switch between? These are variously called “virtual desktops” (e.g. KDE) or “spaces” on OS X, but the idea is the same; you have one workspace with a collection of windows/apps (say for mail and browsing) and another with the windows/apps for a particular project, and you can quickly switch between them. The eyebrowse packages gives a nice simple interface to the same experience in Emacs.

The enables the shortcuts M-1 to M-4 to access 4 virtual desktops (N.B. you will have to disable the M- numeric prefixes first). Of course you can add more than 4 if you need to.

Now you will start by default in workspace 1. If you hit M-2 you will switch to a new empty workspace, numbered 2 in the modeline. It will initially just contain the scratch buffer, since we used (setq eyebrowse-new-workspace t). Open whichever buffers and window arrangements you like then hit M-1 to switch back to the first desktop where you will see the windows and buffers you had set up there.

A useful command is C-c C-w , (N.B. the comma is part of the command!) which runs eyebrowse-rename-window-config allowing you to name a workspace, and that name then appears in the modeline instead of the workspace number.

Some text forming a paragraph
# with some lines# commented out
but I still want this to be a single paragraph.

are exported in latex like this:

Some text forming a paragraph
but I still want this to be a single paragraph.

which leads to a paragraph break between the two lines. This is the intended behaviour of the exporter, but I want it to export like this:

Some text forming a paragraph
but I still want this to be a single paragraph.

This was raised on stackexchange, and the mighty John Kitchin provided a quick solution with the following simple function to strip comments from the org file, which we then add to the org export hook:

I like my dired directory listings to be sorted by name regardless of case. This was a bit fiddly to get working in OS X, but I found a solution using the built-in ls-lisp with a few extra options, rather than the system ls to generate the dired listing.

Despite living in the UK I am hard-wired from some years spent in the US to use a US keyboard layout. One problem for me is that these keyboards do not have a £ symbol on them. On a Mac, I can insert a £ using OPTION-3 but not in Emacs since I have OPTION set to META. This is easily addressed with a bit of code

I was at a conference this week and a colleague was making notes using Evernote on her laptop and taking photos of key slides on her phone which then appeared in her notes. Of course I was making my notes in org-mode but I was envious of this behaviour so decided to emulate it.

With the function below, I can take a photo on my phone and upload to google drive (I use Photo & Picture Resizer, but you could use anything you like to get the pictures onto your computer). Then with a single command in Emacs, I am prompted with a list of photos in the folder to which they are uploaded, with the most recent first. The selected image is then:

Moved the same directory as my org-mode notes file

Renamed based on the heading of the current section in my notes, with a numeric suffix if there is already a photo with that name

Linked in the notes and then the image is displayed

Here is a demonstration:

Here is the code:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; add image from conference phone upload ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; use case is taking a photo of a slide in a conference and uploading;; it to google drive or dropbox or whatever to get it on your;; computer. You then want to embed it in an org-mode document by;; moving it to the same folder and renaming according to the current;; section of the org file, avoiding name clashes;; required libraries(require 'dash)(require 'swiper)(require 's);; start directory(defvarbjm/conference-image-dir(expand-file-name "/path/to/image/upload/dir"))(defunbjm/insert-conference-image()"Insert image from conference directory, rename and add link in current file.The file is taken from a start directory set by `bjm/conference-image-dir' and moved to the current directory, renamed and embedded at the point as an org-mode link. The user is presented with a list of files in the start directory, from which to select the file to move, sorted by most recent first."(interactive)(let(file-list target-dir file-list-sorted start-file start-file-full file-ext end-file end-file-base end-file-full file-number);; clean directories from list but keep times(setq file-list
(-remove (lambda(x)(nth 1 x))(directory-files-and-attributes bjm/conference-image-dir)));; get target directory(setq target-dir (file-name-directory (buffer-file-name)));; sort list by most recent;; http://stackoverflow.com/questions/26514437/emacs-sort-list-of-directories-files-by-modification-date(setq file-list-sorted
(mapcar #'car
(sort file-list
#'(lambda (x y)(time-less-p (nth 6 y)(nth 6 x))))));; use ivy to select start-file(setq start-file (ivy-read
(concat "Move selected file to " target-dir ":")
file-list-sorted
:re-builder #'ivy--regex
:sort nil
:initial-input nil));; add full path to start file and end-file(setq start-file-full
(expand-file-name start-file bjm/conference-image-dir));; generate target file name from current org section;; (setq file-ext (file-name-extension start-file t));; my phone app doesn't add an extension to the image so I do it;; here. If you want to keep the existing extension then use the;; line above(setq file-ext ".jpg");; get section heading and clean it up(setq end-file-base (s-downcase (s-dashed-words (nth 4 (org-heading-components)))));; shorten to first 40 chars to avoid long file names(setq end-file-base (s-left 40 end-file-base));; number to append to ensure unique name(setq file-number 1)(setq end-file (concat
end-file-base
(format "-%s" file-number)
file-ext));; increment number at end of name if file exists(while(file-exists-p end-file);; increment(setq file-number (+ file-number 1))(setq end-file (concat
end-file-base
(format "-%s" file-number)
file-ext)));; final file name including path(setq end-file-full
(expand-file-name end-file target-dir));; rename file(rename-file start-file-full end-file-full)(message "moved %s to %s" start-file-full end-file);; insert link(insert (org-make-link-string (format "file:%s" end-file)));; display image(org-display-inline-images t t)))

I’ve writtenbefore about using yasnippet as a powerful text expansion and template tool in Emacs. In its basic form you type a keyword and press TAB to expand that into a template with active fields and then use TAB to move between the fields adding your content. I recently discovered that you can programme a snippet to contain multiple choices for fields.

For example, the following snippet uses the keyword test and inserts a template with the cursor initially in the first field and prompts the user to choose from the options “high”, “average” and “below average”. Selecting your choice and then hitting TAB takes you to the next field with options of “easy” and “hard”.

Org-mode is a fantastic way to organise information in simple text files. I often use internal links to other sections in a document for navigation, but I’ve found that there is not a great mechanism to quickly insert an internal link. I wanted an interface that would provide me a list of headlines in the document that I could use to select a link target, so I put together the functions below.

These simple functions leverage the fantastic ivy and worf packages, so install them first. Then put the code below into your emacs config file. Then, invoking M-x bjm/worf-insert-internal-link provides an ivy completion interface for the list of headlines in the document. Once you select the headline you want as the link target, the link is inserted for you.

;; use ivy to insert a link to a heading in the current document;; based on `worf-goto`(defunbjm/worf-insert-internal-link()"Use ivy to insert a link to a heading in the current `org-mode' document. Code is based on `worf-goto'."(interactive)(let((cands (worf--goto-candidates)))(ivy-read "Heading: " cands
:action 'bjm/worf-insert-internal-link-action)))(defunbjm/worf-insert-internal-link-action(x)"Insert link for `bjm/worf-insert-internal-link'";; go to heading(save-excursion(goto-char (cdr x));; store link(call-interactively 'org-store-link));; return to original point and insert link(org-insert-last-stored-link 1);; org-insert-last-stored-link adds a newline so delete this(delete-backward-char 1))

Recent Emacs versions include a decent text based web browser called eww. There is a good example configuration here. I found that I like using eww for some things, but at other times I want to use a full GUI web browser (I like Firefox).

I set eww to be my default browser in Emacs with

(setq browse-url-browser-function 'eww-browse-url)

but then I create some wrapper functions for times when I want to use my system default browser (i.e. Firefox).

In mu4e emails, hitting g will now open a URL in eww, but with the following lines I can use G to open in Firefox:

;; open link in firefox rather than eww(defunbjm/mu4e-view-go-to-url-gui()"Wrapper for mu4e-view-go-to-url to use gui browser instead of eww"(interactive)(let((browse-url-browser-function 'browse-url-default-browser))(mu4e-view-go-to-url)));; bind it(define-key mu4e-view-mode-map (kbd "G") 'bjm/mu4e-view-go-to-url-gui)

In elfeed, hitting b opens an article in eww if that is set to be the default Emacs browser. With the following lines I can hit B to open an article in Firefox. Note that I had to resort to calling the Mac open command to open the URL with the system default browser. On linux systems the xdg-open command should do the same thing.

Org mode is wonderful for managing todo lists. Usually to add a task, I would run org-capture using the default C-c c and then select my todo template by hitting t. I do this so often that I wanted a shorter shortcut, so I defined a function to call org-capture with the specific template I wanted and bound this to a simple shortcut (I used C-9 after removing numeric prefixes):