Posts Tagged ‘Emacs’

(on Technorati , Del.icio.us)

Refactoring an Emacs theme

I’m gradually working on a custom theme for emacs, and I wanted to make it easier to update and read. (It’s not quite ready to share, but I look forward to doing just that when it is.) Surprising no-one, the theme format on emacs is not incredibly … “clean.” It’s basically a command that passes in a huge list of lists (of lists… this is lisp, after all). That command is custom-theme-set-faces.

(custom-theme-set-faces
 'my-cool-theme                         ;theme name
 '(
   (FACE SPEC)
   (FACE SPEC)
   ))

FACE is the symbol for a particular element, for example default for default text or error which is used for error messages. Easy. SPEC, however is a bit more complicated. SPEC is a list of DISPLAY ATTS pairs, each list of attributes pertaining to its paired display. If this were CSS, I think it would be similar to including the @media selector for each rule.

(DISPLAY can simply be default to apply to all displays, but I haven’t seen this used much and am trying to follow suit.)

So now we have this.

(custom-theme-set-faces
 'my-cool-theme                         ;theme name
 '(
   (FACE ((DISPLAY ATTS) (DISPLAY ATTS)))
   (FACE ((DISPLAY ATTS) (DISPLAY ATTS)))
   ))

ATTS is property list, where you can specify the width, height, etc. for the font face, on that display.

So plugging in some actual values, we have the following:

(custom-theme-set-faces
 'my-cool-theme                         ;theme name
 '(
   ;; error face, using default DISPLAY (simpler)
   (error ( (default (:foreground "red" :background "black")) ) )

   ;; default face using DISPLAY specified by a a list of conditions (less simpler)
   ;; In this case, a color terminal that supports at least 89 colors.
   (default ( ( ((class color) (min-colors 89)) (:foreground "white" :background "black")) ) )
   ))

I was working with a bunch of lines that basically looked like the second case. There was some substitution, but it was still painful to see all that repetition.

(let
    ((class '((class color) (min-colors 89))))
  ;; ...
  `(default ((,class (:foreground "white" :background "black"))))
  ;; ...
)

I wanted to remove the DISPLAY component completely and just add it later using code. This would mean a cleaner and easier to maintain theme. The excellent emacs-doom-themes has a very elegant solution, but I didn’t quite understand all the elisp and thought I could roll a simpler version myself as a good learning experience.

Lots of fumbling around elisp ensued, but I now have something I’m happy with.

;; the simple-faces are bound to a list `two-fifteen-simple-faces'
(default (:background ,bg1 :foreground ,fg1))
(error   (:foreground "red" :background "black"))
;; ...

;; Add the display to the simple-faces
(while two-fifteen-simple-faces
  (let*
      ((simple-face (car two-fifteen-simple-faces))
       (fname (car simple-face))
       (fattrs (cadr simple-face)))
    (setq two-fifteen-simple-faces (cdr two-fifteen-simple-faces))
    (setq built-faces (append
                       built-faces
                       `((,fname ((,class ,fattrs))))))))

;; apply custom-theme-set-faces to built-faces
(apply #'custom-theme-set-faces 'two-fifteen built-faces)

Next up is making a palette with re-usable colours, which I’ve started w/the bg1 and fg1.

Here are some functions and modes I’m finding extremely helpful when working on the theme:

  • describe-face : Describe the face at the point (cursor)
  • list-faces-display : List faces in use on display
  • rainbow-mode : Display colour values using the actual colour
  • list-colors-display : visually browse colours names and codes
  • align-regexp : Align attribute blocks of the theme to make it easier to read
  • sort-lines : Sort sections alphabetically
  • Iedit and narrow-to-region : Refactoring
  • Keyboard macros, OF COURSE. : start ( C-x ( ), stop ( C-x ) ), run ( C-x e )

There are moments where I do something and a big fat grin creeps onto my face, appreciating what I just did using Emacs. You know what I’m talking about! 🙂

Oh right, here’s a picture of what the theme currently looks like. It’s called two-fifteen. 2019-08-05_emacs_two_fifteen_theme.png

Org-mode: Indirect Buffer, Narrowing to tree

Here’s a really quick Emacs Org-mode tip that I find extremely useful.

In your config add the following two lines:

(setq org-indirect-buffer-display 'new-frame)
(setq org-src-window-setup 'other-frame)

(Or just run it in your scratch buffer to try it out for your current session.)

The first line sets the org-indirect-buffer-display variable to new-frame. Now when you call org-tree-to-indirect-buffer or org-agenda-tree-to-indirect-buffer (C-c C-x b) from an Org buffer or an Org agenda item, Emacs will create a new frame narrowed to that Org sub-tree. I find this much more useful than the default other-window as I usually operate with one frame vertically split with two windows, and like to maintain manual control over the contents of the windows.

Similarly, I like a frame-focused behaviour when editing literal source blocks, which is what the second line sets. While in an Org source block, calling org-edit-special (C-c ' ) will open a new frame narrowed to the current source block and in the appropriate major mode (python-mode, for example). The variable for this setting is org-src-window-setup.

To see the documentation for either variables, use the Emacs help system! (C-h v variable-name)

See also: Emacs Indirect-Buffers, Emacs Buffer Narrowing, org-narrow-to-subtree

Emacs and Org-mode

Well this is odd. I’ve returned to a text editor I was introduced to in university, but wasn’t really taken with until just recently. The editor is Emacs and the reason is org-mode. Apparently, my story is not all that uncommon and org-mode (with evil mode) has even converted many Vim users.

Emacs has been around since 1976. (Nineteen-seventy-six! And it’s still actively developed! That’s insane!) Org-mode is an Emacs extension (major-mode) that has been in development since 2003 and included in Emacs core since 2006. Org-mode is basically an everything-mode; it allows for really intuitive outlines and section management, source code blocks, inline evaluation of those blocks and literal programming, comprehensive exporting, intra- and inter-document hyperlinking, tables/spreadsheets, presentations, ….the list goes on, and on, and on. And on.

The Boston Emacs Meetup has quite a few good Emacs videos with live demonstrations, and I really enjoyed this one, by Harry Schwartz:

(YouTube: Getting Started With Org Mode)

As I continue to migrate all-the-things over to Emacs and Org-mode, it made me think about why I didn’t put more time into learning Emacs before.

When I was introduced to Emacs in university (somewhere around 2002 or 2003), org-mode was not included in Emacs and relatively young. At that time, Java was being promoted heavily in education, and for programming Java, it makes the most sense to use a Java IDE such as Eclipse or NetBeans which make the verbose language far more tolerable. So that’s generally what I did. But for my C or C++ programming, and general text file editing, I usually chose Emacs over Vi(m) due to it being more similar to what I was used to – but that’s it. I could move about in Emacs without leaving home-row, and I could make a few basic changes in VIM, save, and quit without panicking1. I could have been using Notepad++ and would have been just as happy. I was not taking advantage of either Emacs or Vim.

I never learned about org-mode until roughly 2 years ago (somewhere between June and August, 2016). Since then, I’ve gradually migrated as-much-as-I-fucking-can to these wonderful plain text files. I manage my work projects and todo lists. My agenda. My emacs config file. My blog(s); this post (via org2blog). I write documentation that can be exported into a variety of formats. And I keep learning new things; both for Emacs and for org-mode. Just recently, the org-mode time tracking finally clicked for me. I now schedule my days better and try to track where my time goes. This is extremely useful in evaluating what’s eating up my time, and estimating how long tasks will take so I can plan better.

2018-08-12_emacs.png

The draw of org-mode has also made me appreciate Emacs, of course. I connect to Jupyter notebooks via ein and work on them with conveniences not offered in the browser interface2. I’ve heavily customized my environment, picked up a bit of elisp, and I’ve started tweeking my own theme. I recently moved from primarily using Linux to primarily using Windows, which has presented a few challenges with Emacs’ setup, but it’s helped me develop a consistent environment between work and home.

Both Emacs and org-mode are powerful but take a significant time investment to configure and use effectively. Spacemacs, a distribution of Emacs that comes heavily pre-configured and tries to combine the best of Emacs and Vim, offers a simple way to see what an advanced setup could look like. It’s not how I started, and some consider it too bloated, but it’s very well put together and certainly worth looking at.

Anyway, I’ll probably be reviving this blog with the odd org-mode or Emacs post, as that is what I’m playing with, these days. But in addition to the video above, a good intro would be Carsten Dominik (org-mode’s creator) presentation at Google:

YouTube: Emacs Org-mode – a system for note-taking and project planning

Footnotes:

1

I have a great appreciation for Vim’s modal editing and language. Tempted to use Evil Mode, but I have enough things on my plate, at the moment. 🙂

2

I want to investigate moving my Jupyter notebook products to org-mode files under Git, only exporting them to notebooks, when needed… but that’s probably a separate post.