onilog

posts tagged "config"

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.

Mounting music dir before MPD

24 November 2013 2:03 PM (systemd | mpd | config)

Systemd allows you to specify a program to run before running the main daemon (or program) with ExecStartPre. This can, for instance, be used to run a mount command before starting mpd. By adding under the [Service] heading:

ExecStartPre=/usr/bin/mount /mnt/music

Now I have already setup my fstab to know what to mount on /mnt/music, but of course that shouldn't be necessary. According to the systemd.service(5) man page it uses the same syntax as ExecStart, which tells us that one must use absolute file names since no shell is used to start them.

This also has the effect of stopping the ExecStart part from the .service from being executed if the ExecStartPre doesn't finish successfully. Which works out great in my case as I don't want to start mpd if my music directory didn't mount. If you want to ignore the exit status of (one of) the ExecStartPre commands you can prefix it with a -, for example:

ExecStartPre=-/usr/bin/mount /mnt/music

Which would continue running the ExecStart even if mounting failed.

Also know that there can be multiple ExecStartPre options and they will be executed serially, so for example:

ExecStartPre=/usr/bin/mount /mnt/music
ExecStartPre=-/usr/bin/mount /mnt/music2

This would fail if /mnt/music doesn't mount, but would continue just fine if /mnt/music did and /mnt/music2 didn't.

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)))

Notstumpwm

24 May 2013 0:10 AM (stumpwm | notion | config | lua | lisp | wm | archlinux | exherbo)

I have just returned from an excursion into the land of exherbo, which is an awesome source-based distro, and I found that while I was gone, something changed that made stumpwm cause a segmentation fault in X11 a few seconds after starting up.

I have tried everything I can think of to get it running again, but alas, to no avail. So I started looking at alternatives again. Feeling a little crazy I decided to give notion another try. And it fits strangely well.

It's configured/extended in lua, which I'm not particularly fond of, and it has a (in my opinion) crazy default configuration. But it also allows Emacs-like key combinations out-of-the-box, which is a very big plus in my book. So the quest to bring it closer to my stumpwm setup has begun.

Window layout

One of the nicest additions to my stumpwm configuration I made in the last few weeks was a loaded window configuration which put my Emacs frames in a big chunk of my left monitor, my terminals on my left monitor with just enough space for 80 columns and my web browser filling my right screen. I had also set-up some rules to always place them in the correct spots.

I have not yet tried to automatically place the windows in the right spots, but I do have the proportions right. I just had to delete the right frames and resize the one for terminals and, by default, notion remembers this set-up and automatically restores it when I log in.

I will look at creating a special layout for this so I don't have to worry about (accidentally) changing things.

run-or-raise

I found this interesting page about run-or-raise-like functionality for Ion3, which notion is a fork of. This is a little outdated, though, since notion has changed (apparently) the workings of some functions and lua 5.2 introduced the goto keyword, so I had to change it to this:

function oni_match_class(class)
   local result = {}
   ioncore.clientwin_i(
      function (win)
         if class == win:get_ident().class then
            table.insert(result, win)
            return false
         end
         return true
      end
   )
   return result
end

function xsteve_run_byclass(prog, class)
   local win = oni_match_class(class)[1]
   if win then
      win:goto_()
   else
      ioncore.exec(prog)
   end
end

There is no function to get a list of all the client windows, only a function to iterate over them. For the moment I am only interested in finding the first window with class CLASS, so I return false when a match is found, this stops the iteration process. I also had to use the WRegion.goto_ function, instead of WRegion.goto because of the mentioned change in lua 5.2, but they are the same.

I then only have to bind it:

defbindings("WScreen", {
    -- ...
    submap("Control+Z", {
        -- ...
        kpress("E", "xsteve_run_byclass('emacsclient -ca emacs', 'Emacs')"),
        kpress("W", "xsteve_run_byclass('conkeror', 'Conkeror')"),
        kpress("C", "xsteve_run_byclass('urxvt', 'URxvt')"),
    }),
})

Quoting C-z

One of the coolest things about using a prefix in stumpwm that I have been able to find in precious few other solutions is the ability to send the prefix key to the applications you use, so you don't entirely miss its functionality. In stumpwm this is easy, but in notion its a little more work:

defbindings("WClientWin", {
    -- ...
    submap("Control+Z", {
        -- ...
        kpress("Q", "WClientWin.quote_next(_)"),
    }),
})

This means that I have to type C-z q C-z to send the C-z key to, for instance, Emacs. That a few more keys than I was used to in stumpwm, but at least it's possible.

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.

gitolite lessons

7 November 2012 3:19 AM (git | gitolite | config | ssh)

A while back I found out how gitolite handles multiple users, by reading the manual, whilst trying to figure out how to enable SSH agent forwarding so I can semi-automatically mirror some repositories to, for instance, github. I came to the conclusion that I had to override the gitolite settings and add an extra line to my server's authorized_keys file. This seemed to work well.

Though apparently it didn't8239 I had noticed that I couldn't set any options through the gitolite.conf's config commands, but I thought this had something to do with not enabling the right settings to be added. I was wrong about that8239

I looked at my .gitolite.rc on my server and saw that I had already set GIT_CONFIG_KEYS to ~'.*'~, so everything was allowed. I also tested adding random config values to git locally, like test.something, which also worked; so it was neither git nor gitolite that was causing the trouble.

I also noticed today that when I pushed changes to gitolite, at least to the gitolite-admin repo, that it was complaining about not being able to fingerprint some file in /tmp/. At that time I didn't think the issues were connected, since I hadn't changed much lately and pushing/pulling to my repositories seemed to go fine, apart from the config values.

After some testing I noticed that I couldn't use any config values, not even the gitweb.owner setting which I was sure would work, since I'd used that for every repo, but trying to reset them now didn't work either. So I started looking on the server. It showed me the same error as when I'd push to the gitolite-admin repo plus a message about the first line of something being too long, showing the beginnings of a line in authorized_keys.

After a lot of looking around, testing, screwing up my entire setup and looking at the gitolite source on github, I think I figured out what it's doing. Now, I don't know any perl, but is seemed to me that it splits up the authorized_keys file, checking the validity of each line in it, except for the ones it put there. This is where it was failing, since it would assume each line was just a public key and could be verified by placing it in a temporary file and fingerprinting that with ssh-keygen -l -f, and I had the ~command="8239"~ part in there as well, to override gitolite's own settings to enable agent forwarding. So now I know why it was complaining and why it was always about line 1, even when I put my key on the last line in authorized_keys, but removing it would mean no ssh agent forwarding.

So I started looking at the gitolite source code again, trying to figure out where those settings of no-X11-forwarding, no-agent-forwarding, etc. were coming from and after a little while I found it. Here I also saw that it was actually looking for the AUTH_OPTIONS rc setting. I don't remember reading anything about this option, but then I'm still learning to navigate the gitolite manual. Setting that to whatever was in my authorized_keys file, but leaving out the no-agent-forwarding, fixed this latest problem.

So, now I've got my ssh agent forwarding and I can set any git config variable I want, which paves the way for writing a hook that will try to mirror a repository after receiving an update. This was certainly an interesting experience, and looking at some perl code was fun.

Oh, and I've also updated my gitolite installation, which now includes a update-description-file post-compile trigger, which takes the value from gitweb.description and puts it in the description file, so programs like cgit can use it too.

eval-and-compile

27 July 2012 9:19 PM (emacs | elisp | config | coding)

I'm reading up a little on byte-compilation in GNU Emacs and I read about just exactly a feature that I needed.

A while ago, I was working on my init file, adding some auto-complete code since I wanted to try it again. I noticed that, because auto-complete is installed through package, it couldn't load the appropriate files at compile time.

I know that package-initialize should be called before calling or using any package-installed functions and I have it in my init file, but this doesn't help at compile time. So, ugly as I thought it was, I added

(eval-when-compile (package-initialize))

just above the call to the auto-complete functions. I hated having to do that, I know it's just one line, but its not at all DRY.

Just now, though, I read about eval-and-compile, and according to the documentation in the elisp reference manual, it should do exactly what I want, eval both when running and when compiling.

(eval-and-compile (package-initialize))

I'm currently trying it out, I just tested it once and it seems to work like a charm.

Of course, this might never have been an issue if I didn't use emacs -Q to compile my init file, just to speed up loading during compilation a little bit.

New config project

28 June 2012 9:28 PM (org-mode | literate programming | config | project)

After reading that it was very easy to use Literate Programming for one's emacs init file and discovering that it's also a lot of fun to do, I was thinking that I could easily use this for all my configuration files.

Of course, not all programs have org-babel, so they can't all have something like this in their init file:

(require 'org)
(require 'ob-tangle)

(org-babel-load-file "~/.emacs.d/rinit.org")

Which, for emacs, tangles (extracts the code) and then loads the generated file. So something else has to be done.

On the other side of things, I, fairly recently, had a run-in with some Makefiles, which got me thinking that make is a very interesting tool and that it could be used to help with a lot of other tasks as well, much like I perceive Rake does. I just wasn't able to find where exactly it would fit (other than, of course, as compilation instructions for my projects).

Now, yesterday I got the idea of using org-mode to literate-program all my configuration files and then use make to tangle and install them. This would mean that I could easily keep documentation about decisions in configuration files and such in an easy to read format, easily export these files to somewhere on the web and practice my make skills to make everything easy.

Here is the result. I'm still working on it, as you can see my emacs init file still has a long way to go, my focus is on getting it in org-mode first and actually get it well-documented later. I've published it here, what I have at least, in case you would like to read about my mostly uninteresting configuration files.