Content tagged tips

Clean completions

Published on:

Today's post is very short. In my quest to make GNU Emacs look ever better I thought about something new (to me). Not all buffers need have a mode line. As such I will now turn off the mode line for completion-list-mode, since that only shows up for a short while and I've so far never had any trouble distinguishing it from other buffers.

(add-hook 'completion-list-mode-hook
          (lambda () (setq mode-line-format nil)))

Now, whenever a completion buffer pops up, it'll use all the space available, including the line where the mode line used to be. If it shows up just above the minibuffer (which for me it always has done) it looks more like a part of the same thing instead of two separate windows.


Filtering org tasks

Published on:

I want to be able to easily see a list of tasks that are relevant to the currently loaded desktop file. As I use desktop.el as a kind of project system, this means I only want the tasks for the project I'm currently working on.

First I wrote the tagify function, because org-mode tags can't contain . or - characters (among others I'm sure, but these are the only ones that have caused me any trouble so far). It's a simple string replacement:

(defun tagify (str)
  "Remove dots, replace - with _ in STR."
  (replace-regexp-in-string
   "-" "_" (replace-regexp-in-string "\\." "" (downcase str))))

Then I wrote a function to filter the task list by not showing anything that wasn't tagged with the name of the currently loaded desktop, unless it isn't tagged at all or no desktop has been loaded. And set this function to be the value of org-agenda-before-sorting-filter-function.

(defun filter-by-desktop (entry)
  "Return ENTRY if it has no tags or a tag corresponding to the desktop."
  (require 'desktop)
  (let ((label (when desktop-dirname
                 (tagify (file-name-base
                          (directory-file-name
                           (expand-file-name desktop-dirname))))))
        (tags (get-text-property 0 'tags entry)))
    (when (or (null desktop-dirname) (null tags) (member label tags))
      entry)))

(setq org-agenda-before-sorting-filter-function #'filter-by-desktop)

This works fine. I keep untagged tasks in the list as well because they might be important at all times and I don't want them falling through the cracks. I also want a complete list if no desktop has been loaded so I can browse through my tasks and decide what I'm going to do next.

The downside of this solution is that I have to close my current project in order to see the whole list.

Then I discovered the / key in the agenda buffer. I can't believe I didn't notice this key before. Anyway, that changed my solution.

Instead of setting org-agenda-before-sorting-filter-function I add a hook to the org-agenda-finalize-hook. The filter-by-desktop function looks a little different now:

(defun org-init-filter-by-desktop ()
  "Filter agenda by current label."
  (when desktop-dirname
    (let ((label (tagify (file-name-base
                          (directory-file-name
                           (expand-file-name desktop-dirname))))))
      (org-agenda-filter-apply (cons label nil) 'tag))))

(add-hook 'org-agenda-finalize-hook 'org-init-filter-by-desktop)

I don't need to compare any tags now, and if I want to see my entire list of tasks I can easily just press / /. Since it is easier to get back to the overview of my tasks it also doesn't bother me so much that this way any untagged tasks don't show up in the filtered buffer.

I haven't stopped using / since I discovered it. Filtering in this way is one of the things I like about ibuffer as well, now for org-mode it works excellently as well.


highlight VC diffs

Published on:

Sometimes you come across these gems of packages that seem to fulfill a wish that you didn't even realise you had.

Today I came across git-gutter for Emacs and its companion git-gutter-fringe, which are apparently based on an extension for Sumblime Text 2. These show the status of changes in a special "gutter" next to the fringe or in the fringe itself. This is very cool stuff.

To enable it I added the following code to my Emacs init file:

(eval-after-load "git-gutter" '(load "git-gutter-fringe"))

(defun maybe-use-git-gutter ()
  "Run `git-gutter' if the current file is being tracked by git."
  (when (eq (vc-backend (buffer-file-name)) 'Git)
    (git-gutter)))

(add-hook 'after-save-hook 'maybe-use-git-gutter)
(add-hook 'after-change-major-mode-hook 'maybe-use-git-gutter)
(add-hook 'window-configuration-change-hook 'maybe-use-git-gutter)

git-gutter was easily installed through MELPA, but I had to download git-gutter-fringe separately and use package-install-file to install that.

I had to load git-gutter-fringe manually because it didn't seem to have any autoloads defined, and I had to run it using these three hooks because the information seemed to disappear if I switched windows and came back, didn't automatically update after saving and didn't automatically show anything when first loading the file. This was all fine, since just calling the function updates the buffer it's easy to use this way.

Later, though, I stumbled upon diff-hl by accident. I was looking for anything involving the fringe, which I think, for the most part, is underused.

It does pretty much the same thing, except that it does so at least for git, bazaar and mercurial (according to the readme). It also defines some commands for working with the blocks of changes, like navigating between them and reverting them. It uses the fringe by default, and doesn't require a separate package to be installed. And it's much easier to set up.

It can also be installed through MELPA, and afterwards it's just a line in our init file away:

(global-diff-hl-mode)

Of course if you don't want it enabled globally you can call diff-hl-mode from some hooks, but this way works fine for me.

It's funny how I had no idea these existed, didn't even think about needing/wanting this feature and then finding two of them in the same day.


This blog covers archlinux, avandu, avandu-lua, cask, ci, clark, common-lisp, config, conkeror, diff, dispass, dispass.el, editors, elisp, emacs, eshell, evil, exherbo, experiments, file-synchronization, games, git, github, gnus, hla, html, javascript, lisp, lua, markam, meta, mpd, notion, org-mode, ox-coleslaw, projects, rc, sbcl, small-recent-posts, software, stumpwm, systemd, tasks, tekuti, testing, tips, todo, ttrss, utility, vagrant, vc, vim, visual, wdocker docker docker-compose, wm, wordpress, yoshi-theme

View content from 2016-02, 2015-09, 2015-08, 2014-12, 2014-10, 2014-08, 2014-07, 2014-06, 2014-04, 2014-01, 2013-11, 2013-10, 2013-08, 2013-05, 2013-04, 2013-02, 2013-01