shellarchive

 

Webkit in emacs

An emacs hacker called Joakim Verona has built preliminary support for the embedding of GTK widgets into a buffer (of a GTK linked emacsen) which opens up the possibility of embedding webkit into emacs. This sounds very cool, especially what with Webkit gaining popularity so quickly. Web-browsing is just about the only (important) thing left that emacs can't really do.

 

Merge directory contents (with links)

I wrote this as part of my dotfiles installation procedure. If you have directories 1, 2 and 3 all with files you want to link into ${HOME} then running:

link-files 1 "${HOME}" \
    && link-files 2 "${HOME}" \
    && link-files 3 "${HOME}"

Will do the trick, assuming this is defined:

function link-files {
    from="${1}"; to="${2}"

    # first we need the same directory structure
    ( cd "${from}" && find . \( \( -name "..?" -or -name \*.elc \) \
        -prune -or -true \) -type d -exec mkdir -p "${to}/"\{\} \; )

    # now link the files to "to"
    ( cd "${from}" && find . -type f -exec ln -fs \
        "${from}/"\{\} "${to}/"\{\} \; )
}
 

Find file in project for project-root.el

Today a chap I know begged me to add project specific find-file support to project-root.el, so, once I realised what he was talking about (he's from foreign and so talks all funny like) I added project-root-find-file. All you need to do to use it is set project-root-default-find-command to the find command you want to use and then when you M-x project-root-find-file you will get a list of all files matched by the find, all wrapped up in ido goodness. The files in the list appear relative to the current project's root directory.

To be honest, I thought it would be too slow but tested it on a few medium sized projects and it actually performs OK.

 

Add filenames to log-edit

I bind this to C-c C-f in log-edit-mode. It will insert the list of edited files with a colon after the filename. One of those small, simple macros that I use all of the time, and thought I might share.

(defun insert-edited-files ()
  (interactive)
  (let ((pos (point)))
    (insert (mapconcat
             (lambda (x)
               (concat (file-name-nondirectory x) ": "))
             (log-edit-files) "\n"))
    (align-regexp pos (point) ": " 0 2)))
 

Project Root

I realise there is already many an effort to implement 'projects' in emacs but I've decided to have a stab at it myself. What I've ended up with is a really simple module that is configurable purely via elisp (meaning no files needed in the root of your project). So, buried in my startup, I have this:

(with-library 'project-root
  (setq project-roots
        '(("Generic Perl Project"
           :root-contains-files ("t" "lib")
           :on-hit (lambda (p)
                     (project-root-setup-ack p)))))
  (add-hook 'cperl-mode-hook 'project-root-fetch)
  (add-hook 'dired-mode-hook 'project-root-fetch)
  (define-key dired-mode-map (kbd "r") 'project-root-goto-root))

with-library looks like this by the way:

(defmacro with-library (symbol &rest body)
  `(when (require ,symbol nil t)
     ,@body))

At the moment I only use this for anything resembling Perl projects, this being determined by the :root-contains-files property. You can also use :path-matches to pull out a path where the first match group is the root:

"\\(/home/someone/work/projects/blah\\)"

The function given to :on-hit will execute when a match for the root is found, so in my case I setup ack to cd to the root of the project first.

I'd love to get some feedback on how use(ful|less) this is to people, even in its early state.

 

Keeping your configuration in check

I used to pile stuff into my .emacs which whilst convenient for moving between sites was a nightmare to maintain. What I use now is an init style system which is kicked of with this in my .emacs:

(defun load-dir (dir)
  (mapc 'load
        (mapcar (lambda (file)
                  (if (file-exists-p (concat file "c")) (concat file "c") file))
                (directory-files dir t "\\.el$"))))

Which will load all of the files in dir favouring compiled lisp. Each of the files is named to reflect its function. Here is my lisp.d:

001-definitions.el      030-org-mode.el
002-init-load-path.el   030-sql.el
010-initial-buffers.el  040-lang-lisp.el
030-dvc.el              040-lang-perl.el
030-erc.el              060-third-party-lisp.el
030-eshell.el           070-defaults.el
030-ibuffer.el          080-environment.el
030-muse.el
 

Gnus at work

For the first time conditions have been met that allow me to use Gnus at work. It's great not to have to use Outlook, or even worse Notes. I wonder if the whole gnus/bbdb/org system will make me more organised in that area?

 

How that tab bar works

Two (the grand total of my readership?) people have asked how I make the tabs above this content stay active depending on the content (considering I use Muse Mode). I would love to say it was a masterpiece of code and ingenuity but I'm afraid it's just a simple hack.

Within the header.muse file which all pages use as their header is this snippet (in <lisp> brackets of course):

(mapconcat
 (lambda (x)
   (concat "<li"
           (when (string= (muse-publishing-directive "menu-name") (car x))
             " id=\"current\"")
           "><a href=\"" (cdr x) "\"><span>"
           (car x) "</span></a></li>"))
 muse/web-menu-alist "\n")

This depends on setting a directive in each page called menu-name. As the code loops through the items in muse/web-menu-alist it will print out the link, if the (car) of the alist matches menu-name it will be given the "current" css property. This is what makes the current tab appear highlighted.

This is what muse/web-menu-alist looks like:

(setq muse/web-menu-alist
      '(("home" . "/index.html")
        ("shell" . "/content/shell.html")
        ("emacs" . "/content/emacs.html")
        ("contact" . "mailto:web@shellarchive.co.uk")))

It's really that simple I'm afraid.