onilog

posts tagged "emacs"

Stop shr from using background color

3 April 2014 10:13 PM (emacs | elisp | config)

Here's just one more example why Emacs is so awesome

Reading mail in Gnus is very nice, but shr has become a little too good at its job. Add to this the many occasions when a background is specified without specifying a foreground, plus a color theme that is the inverse of what is usually expected, and you can get hard-to-read HTML messages, gray foreground and gray background.

I've looked at the other possible renderers, but they don't look very nice compared to shr. So just remove its ability to add background colors.

(defun oni:shr-colorize-remove-last-arg (args)
  "If ARGS has more than 3 items, remove the last one."
  (if (> (length args) 3)
      (butlast args)
    args))

(with-eval-after-load 'shr
  (advice-add #'shr-colorize-region :filter-args
              #'oni:shr-colorize-remove-last-arg))

Hello, Cask

31 January 2014 11:17 PM (emacs | config | cask)

I've been very resistant to looking at Cask. I felt that, much like for example el-get, it was trying to re-solve a problem that has been solved by ELPA since Emacs v24 in a way incompatible with ELPA.

I have finally looked at it, and to my pleasant surprise it works with ELPA instead of beside it, as a wrapper adding some extra functionality. Using and supporting Cask doesn't mean you don't support ELPA. And theoretically using Cask does open up possibilities for development by creating separate development environments (package wise), though I haven't tried this out yet.

I've switched over my configuration to using Cask, which will also help me keep the configuration on my laptop synchronized more easily.

Aside from a fairly long Cask file, making it work is pretty simple, as the website suggests.

(eval-and-compile
  (require 'cask "~/projects/ext/cask/cask.el")
  (cask-initialize))

I add an eval-and-compile so the external process compiling my init.el doesn't complain about not being able to load ELPA-installed packages.

Now instead of starting up Emacs, running M-x list-packages, pressing U and then X (and y at least once) it's a matter of

cd ~/.emacs.d
cask update

Much easier.

C-d to close eshell

17 August 2013 2:25 AM (emacs | eshell | elisp | config)

One of the "tricks" that I have learned to use when working with terminals is using C-d to close them, or when working on a TTY logout. It somehow grew to the extent that if I can't use it, I get annoyed, like with eshell.

I have customized ansi-term to immediately close its buffer after the shell quits. This makes it very easy to start an ansi-term, which I've bound to C-c t, run a quick command (perhaps make, or similar), C-d, and I'm out. I want that for my eshell too.

There are a few conditions that I want met before the buffer is killed, though.

  1. Since eshell is an Emacs mode like any other, C-d is usually used
    to forward-kill characters, I don't want to lose this.

  2. I only want it to quit when the line of input is empty.

The following piece of code make sure these conditions are met.

  1. It interactively calls delete-char, which keeps keybindings like
    C-4 C-d to delete 4 characters working.

  2. It catches the error condition which is signaled wheneverdelete-char can't do it's job (like when there's nothing left to
    delete in the buffer).

  3. It checks to make sure that the signaled error is the end-of-buffer
    error. I don't want to kill the buffer if I try to delete more
    characters than are in the buffer because I feel that could cause
    irritating surprises.

  4. It checks of the cursor is at the eshell prompt. This, combined
    with only responding to the end-of-buffer error, makes sure we're
    on an empty line and not just at the end of the input. Sometimes
    keys are pressed at the wrong time and I don't want to have to
    re-type a command just because I was being an idiot.

  5. If the right conditions aren't met, signal the error again so I can
    see what's going on.

(defun eshell-C-d ()
  "Either call `delete-char' interactively or quit."
  (interactive)
  (condition-case err
      (call-interactively #'delete-char)
    (error (if (and (eq (car err) 'end-of-buffer)
                    (looking-back eshell-prompt-regexp))
               (kill-buffer)
             (signal (car err) (cdr err))))))

I then bind this to C-d in eshell.

(add-hook 'eshell-mode-hook
          (lambda () (local-set-key (kbd "C-d") #'eshell-C-d)))

Some quick git diff tips

11 August 2013 0:54 AM (git | org-mode | diff | tips | magit | emacs | lisp | hy | elisp)

A couple of quick tips. As you possibly know you can specify some options to be used for diffs (and other things) per file type. The one I'm interested in is the function name.

For org-mode

The primary way of identifying which part of an org-mode document a change occurs in seems to me to be the heading. So, in your $HOME/.gitconfig put:

[diff "org"]
      xfuncname = "^\\*+.*"

Which should show any lines starting with one or more * characters. And then in $XDG_CONFIG_HOME/git/attributes or $HOME/.config/git/attributes put:

*.org   diff=org

For lisp and lisp-like langauges

For anything that resembles lisp (so Common Lisp, Emacs Lisp, Hy, scheme, etc.) I would think that the easiest thing to do is just see the closes top-level form. So, in your $HOME/.gitconfig put:

[diff "lisp"]
      xfuncname = "^\\([^ ]+ [^ ]+"

Which should show the opening parenthesis and the first two words. For example:

(defun some-function-name
(defclass my-awesome-class
(define-route this-strange-route

And then put in your $XDG_CONFIG_HOME/git/attributes or $HOME/.config/git/attributes:

*.lisp  diff=lisp
*.el    diff=lisp
*.hy    diff=lisp
*.scm   diff=lisp

And possibly any other lisp-like language files you can think of.

highlight VC diffs

25 January 2013 2:20 AM (emacs | git | vc | diff)

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.

Org examples on github

20 January 2013 2:09 PM (github | org-mode | emacs)

github has an org-mode parser for their README files, but I always thought it didn't handle #+BEGIN_SRC and #+BEGIN_EXAMPLE style blocks. And I'm not wrong, but it does handle : blocks.

So this won't work:

#+BEGIN_EXAMPLE
  This is an example
#+END_EXAMPLE

But this will:

: This is an example

That was a nice surprise for me, because I prefer org-mode for almost all of my documents.

Different roles

10 January 2013 3:49 AM (org-mode | emacs | todo)

The other day I noticed that when I'm working I find it very annoying to have tasks for my personal projects appear in either my agenda or my todo list, so I was thinking if I couldn't make it somewhat more flexible.

First I've added some separation between my org files, I've split them into personal-org-agenda-files, work-org-agenda-files and common-org-agenda-files, since there are also some tasks that I would like to know about in either situation.

(defvar oni:personal-agenda-files
  (list (expand-file-name "~/documents/org/tasks"))
  "My personal agenda, should only show up at times I don't have
  to work.")

(defvar oni:work-agenda-files
  (list (expand-file-name "~/documents/org/work"))
  "My work agenda, should only show up at times I work.")

(defvar oni:common-agenda-files
  (list (expand-file-name "~/documents/org/misc"))
  "Agenda files that are work-agnostic, should always show up.")

At first I only seperated them with org-agenda-custom-commands:

(setq org-agenda-custom-commands
      '(("P" . "Personal only")
        ("Pa" "Personal agenda" agenda ""
         ((org-agenda-files (append oni:personal-agenda-files
                                    oni:common-agenda-files))))
        ("Pt" "Personal todo" agenda ""
         ((org-agenda-files (append oni:personal-agenda-files
                                    oni:common-agenda-files))))
        ("W" . "Work only")
        ("Wa" "Work agenda" agenda ""
         ((org-agenda-files (append oni:work-agenda-files
                                    oni:common-agenda-files))))
        ("Wt" "Work todo" todo ""
         ((org-agenda-files (append oni:work-agenda-files
                                    oni:common-agenda-files))))))

But it's clunky to have to use a separate command just to see a clean todo list. Then I thought, and tried, to have a function that checks the time to see which it should use, since I work from 09:00 to 17:00, if the current time is between those times I should only look at my work todo list, most of the time, outside of those hours I don't really care what I have to do for work.

(defun oni:set-org-agenda-files ()
  (interactive)
  (let ((current-time (current-time-string))
        (start-time (format-time-string "%a %b %e 09:00:00 %Y"))
        (end-time (format-time-string "%a %b %e 17:00:00 %Y")))
    (if (or (and (string< current-time start-time)
                 (string< current-time end-time))
            (and (string< start-time current-time)
                 (string< end-time current-time)))
        (setq org-agenda-files
              (append oni:personal-agenda-files
                      oni:common-agenda-files))
      (setq org-agenda-files
            (append oni:work-agenda-files
                    oni:common-agenda-files)))))

It's weird, but since Emacs doesn't have any real datetime functions for creation/comparison, for as far as I know, it seemed easiest to just create some strings representing the time and compare these.

Then it should be, if the current time is either before both start and end time or after both start and end time it should return my personal todo list, otherwise it should return my work todo list.

Now, it would be silly to have to call that manually every so-often, so I've set it up to do so automatically.

(oni:set-org-agenda-files)
(run-at-time "09:01" nil 'oni:set-org-agenda-files)
(run-at-time "17:01" nil 'oni:set-org-agenda-files)

First, I set my agenda files to whatevers they should be right now. Then I have this function run at 09:01 and 17:01, if either or both have already passed, they won't be executed today. This effectively tells Emacs to switch to my work "role" after 09:00 and back to my personal "role" after 17:00.

It's not perfect yet, but I felt like writing something. The things I would change might include:

  • Check the times for either < or = the start/end times, so I don't
    have to check for :01 every time, but Emacs doesn't have a string<=
    function so I'll have to mimic it.

  • Always set it to my personal "role" during weekends.

  • Have them repeat every 24 hours, just in case I don't turn off my
    PC for a few days.

I'll fix those soon, they're not hard to do, but this works for now. It has worked well for me today, but I might throw it out again tomorrow, as I sometimes tend to do.

diminish

19 December 2012 8:27 PM (emacs)

diminish.el is a collection of functions that help you manage your minor modes. I found out about it from Magnar Sveen's new blog and after trying it just a little bit it seems very nice, and like an almost perfect addition to my own mode-icons.el.

Installing it is easy if you have package.el (or GNU Emacs 24 or newer):

M-x package-install<RET> diminish

And otherwise it's merely a question of downloading it, putting it in your load-path and require-ing it.

org-agenda-prefix-format

4 December 2012 1:33 AM (emacs | org-mode | config)

I've been looking for a way to clearly identify my projects from within an org-mode agenda todo buffer, and a little while ago I finally came across a nice way to do this: org-agenda-prefix-format.

The problems with other options I could think of were that the category just doesn't feel like the right place to put it, that should be an indication of what kind of todo item it is, not what it's for. Tags get messy very quickly and separate files are shown when no category has been given and using a lot of files can slow list generation down.

Setting it to a value like, for example:

((agenda . " %i %-12:c%?-12t% s")
 (timeline . "  % s")
 (todo .
  " %i %-12:c %(concat \"[ \"(org-format-outline-path (org-get-outline-path)) \" ]\") ")
 (tags .
  " %i %-12:c %(concat \"[ \"(org-format-outline-path (org-get-outline-path)) \" ]\") ")
 (search . " %i %-12:c"))

Will give me lines like:

task:        [ Blog ] TODO Blog about something
task:        [ Blog ] TODO Blog about something else

Where task is the category, Blog is the project, which is defined by being its one and only parent, and TODO is, of course, its todo state. The rest being the headline for the task.

Of course, with these settings you need to have exactly 2 levels of tasks, otherwise, I think, you'll get [ Blog/heading ], which might also be useful, but will grow big quickly.

I also only use this setting with todo and tags, because I don't usually need it for the items that show up in agenda and I don't really use timeline or search too much, but have a look at the documentation for org-agenda-prefix-format, you might think of something to do with it.

w3m-fill-column

25 November 2012 1:35 PM (w3m | emacs | config)

I was just reading something in Emacs-w3m and I didn't like the way lines were being displayed, all the way to the end of the screen.

I like it that when I read something it is filled to something like the 80th column of the screen. So I looked and I found the w3m-fill-column variable.

By default it's set to -1, meaning the entire width of the screen -

  1. After changing this to 80, the pages being read are filled up to

that column and I don't need to think about the size of my window anymore.