<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Alex's Adventures on the Infobahn - elisp</title><link href="https://www.bennee.com/~alex/" rel="alternate"></link><link href="https://www.bennee.com/~alex/blog/tag/elisp/feed" rel="self"></link><id>https://www.bennee.com/~alex/</id><updated>2018-06-01T18:12:00+01:00</updated><subtitle>the wanderings of a supposed digital native</subtitle><entry><title>dired-rsync 0.4 released</title><link href="https://www.bennee.com/~alex/blog/2018/06/01/dired-rsync-0-4-released/" rel="alternate"></link><published>2018-06-01T18:12:00+01:00</published><updated>2018-06-01T18:12:00+01:00</updated><author><name>alex</name></author><id>tag:www.bennee.com,2018-06-01:/~alex/blog/2018/06/01/dired-rsync-0-4-released/</id><summary type="html">&lt;p&gt;I started hacking on this a while back but I've finally done the house-keeping tasks required to make it a proper grown up package.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/stsquad/dired-rsync"&gt;dired-rsync&lt;/a&gt; is a simple command which you can use to trigger an rsync copy from within dired. This is especially useful when you want to copy …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I started hacking on this a while back but I've finally done the house-keeping tasks required to make it a proper grown up package.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/stsquad/dired-rsync"&gt;dired-rsync&lt;/a&gt; is a simple command which you can use to trigger an rsync copy from within dired. This is especially useful when you want to copy across large files from a remote server without locking up Emacs/Tramp. The rsync just runs as an inferior process in the background.&lt;/p&gt;
&lt;p&gt;Today was mainly a process of cleaning up the CI and fixing any issues with it. I'd still like to add some proper tests but the whole thing is interactive and that seems to be tricky for Emacs to test. Anyway I've now tagged 0.4 so it will be available from MELPA Stable once it rebuilds. You can of course grab the building edge from MELPA any time ;-)&lt;/p&gt;
</content><category term="geek"></category><category term="dired"></category><category term="elisp"></category><category term="emacs"></category><category term="dired-rsync"></category></entry><entry><title>Many ways to skin a GNU</title><link href="https://www.bennee.com/~alex/blog/2012/07/24/many-ways-to-skin-a-gnu/" rel="alternate"></link><published>2012-07-24T15:09:00+01:00</published><updated>2012-07-24T15:09:00+01:00</updated><author><name>alex</name></author><id>tag:www.bennee.com,2012-07-24:/~alex/blog/2012/07/24/many-ways-to-skin-a-gnu/</id><summary type="html">&lt;p&gt;It's time for another examination of Emacs LISP and a selection of ways to solve the same problem. In this case it's the behaviour of the &lt;em&gt;etags-select&lt;/em&gt; package. This handy function will present a selection table when it finds multiple definitions of the same tag. This is handy if your …&lt;/p&gt;</summary><content type="html">&lt;p&gt;It's time for another examination of Emacs LISP and a selection of ways to solve the same problem. In this case it's the behaviour of the &lt;em&gt;etags-select&lt;/em&gt; package. This handy function will present a selection table when it finds multiple definitions of the same tag. This is handy if your global TAGs file contains reference to multiple binaries that might have a common code heritage. It even provides a handy function &lt;em&gt;etags-select-find-tag-at-point&lt;/em&gt; which will check &lt;em&gt;point&lt;/em&gt; to see if that is a tag. However if &lt;em&gt;point&lt;/em&gt; is on a blank line I'd prefer it to just prompt me for a tag name.&lt;/p&gt;
&lt;p&gt;First version:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(defun my-naive-find-tag ()
  &amp;quot;Find at point or fall back&amp;quot;
  (interactive)
  (unless (etags-select-find-tag-at-point)
    (etags-select-find-tag)))
&lt;/pre&gt;
&lt;p&gt;Unfortunately this fails rather badly. I naively assumed &lt;em&gt;etags-select-find-tag-at-point&lt;/em&gt; would return &lt;em&gt;'nil&lt;/em&gt; on failure. Instead it bombs out with an error because &lt;em&gt;etags-select-find&lt;/em&gt; expects a parameter and when &lt;em&gt;find-tag-default&lt;/em&gt; fails it errors out.&lt;/p&gt;
&lt;p&gt;Second version:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(defun my-working-find-tag()
  &amp;quot;Find tag and call etags-select-find-tag-at-point if it will work&amp;quot;
  (interactive)
  (if (find-tag-default)
      (etags-select-find-tag-at-point)
    (etags-select-find-tag)))
&lt;/pre&gt;
&lt;p&gt;This works by checking &lt;em&gt;find-tag-default&lt;/em&gt; will work before calling &lt;em&gt;etags-select-find-tag-at-point&lt;/em&gt;. Of course there is some duplication here because &lt;em&gt;find-tag-default&lt;/em&gt; will get called again once I know it will work. Dissatisfied I asked the &lt;a class="reference external" href="%20http://stackoverflow.com/questions/11578723/whats-the-best-way-in-elisp-to-trap-an-error-case"&gt;stackoverflow&lt;/a&gt; community for suggestions. The first solution is to simply trap the error case.&lt;/p&gt;
&lt;p&gt;Third version:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(defun my-try-except-find-tag()
  &amp;quot;Find at point or fall to etags-select-find-tag on error&amp;quot;
  (interactive)
  (unless (ignore-errors (or (etags-select-find-tag-at-point) 't))
    (etags-select-find-tag)))
&lt;/pre&gt;
&lt;p&gt;This works by utilising deep lisp black magic to stop the error propagating and returning a 'nil if it does. The &lt;em&gt;(or (etags-select-find-tag-at-point) 't)&lt;/em&gt; line is to ensure a successful call returns something so we don't then fall through. Interestingly the comments around &lt;em&gt;subr.el&lt;/em&gt; mentions some of the keywords used may be redefined by common lisp.&lt;/p&gt;
&lt;p&gt;Forth version:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(defun my-efficent-find-tag()
  &amp;quot;Find tag at point, caching find-tag-default&amp;quot;
  (interactive)
  (let ((ftd (find-tag-default)))
    (flet ((find-tag-default () ftd))
      (if (find-tag-default)
          (etags-select-find-tag-at-point)
        (etags-select-find-tag)))))
&lt;/pre&gt;
&lt;p&gt;While I expected something like &lt;em&gt;ignore-errors&lt;/em&gt; to exist this demonstrates the flexibility of dynamic languages like Emacs Lisp. The key is the use of &lt;em&gt;flet&lt;/em&gt; to redefine &lt;em&gt;find-tag-default&lt;/em&gt; so when it gets executed again inside &lt;em&gt;etags-select-find-tag-at-point&lt;/em&gt; it simply returns the cached value.&lt;/p&gt;
&lt;p&gt;So as usual with these posts I try to invite feedback. Which of these forms do you prefer? Would you solve the problem another way? Have you just learnt something new about Emacs Lisp?&lt;/p&gt;
</content><category term="geek"></category><category term="code"></category><category term="elisp"></category><category term="emacs"></category></entry><entry><title>Perils of bleeding edge</title><link href="https://www.bennee.com/~alex/blog/2011/07/27/perils-of-bleeding-edge/" rel="alternate"></link><published>2011-07-27T16:55:00+01:00</published><updated>2011-07-27T16:55:00+01:00</updated><author><name>alex</name></author><id>tag:www.bennee.com,2011-07-27:/~alex/blog/2011/07/27/perils-of-bleeding-edge/</id><summary type="html">&lt;p&gt;I've taken to running the latest &lt;em&gt;emacs&lt;/em&gt; from a source tree install. It works well enough and additional modes I use have been liberally ${VC} fetched into my &lt;em&gt;.emacs.d&lt;/em&gt;. However there are still a number of packages I'd like to use from Debian's emacs version agnostic site-lisp directories. I …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I've taken to running the latest &lt;em&gt;emacs&lt;/em&gt; from a source tree install. It works well enough and additional modes I use have been liberally ${VC} fetched into my &lt;em&gt;.emacs.d&lt;/em&gt;. However there are still a number of packages I'd like to use from Debian's emacs version agnostic site-lisp directories. I came up with this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
 ;; Add site-lisp to search path
;
; This is a work-around function for when I'm running bleeding
; emacs from the source tree but still want Debian's developer
; tools. I'd caution about having too many extra packages about that
; have been merged into the source tree (cedet etc) lest it get
; confused.
(defun load-debian-site-lisp()
&amp;quot;Attempt to load Debian's site-lisp if it's there&amp;quot;
  (interactive)
  (when (and (not (member &amp;quot;/usr/share/emacs/site-lisp&amp;quot; load-path))
             (fboundp 'normal-top-level-add-subdirs-to-load-path))
          (let* ((default-directory &amp;quot;/usr/share/emacs/site-lisp&amp;quot;))
      (normal-top-level-add-subdirs-to-load-path))))

(load-debian-site-lisp)
&lt;/pre&gt;
&lt;p&gt;Which seems to work well enough to give me my &lt;em&gt;debian-changelog-mode&lt;/em&gt; back. However it's still not seamless as I have to manually &lt;em&gt;(require 'debian-changelog-mode)&lt;/em&gt; before loading a changelog which forces the issue with local variables. I suspect I'll have to replicate the boilerplate that &lt;em&gt;/usr/share/emacs/site-lisp/debian-startup.el&lt;/em&gt; does but I can't use because it doesn't degrade gracefully if no &lt;em&gt;debian-emacs-flavour&lt;/em&gt; is defined. Suggestions for making this behaviour neater would be useful....&lt;/p&gt;
</content><category term="geek"></category><category term="elisp"></category><category term="emacs"></category></entry><entry><title>completion-ignored-extensions</title><link href="https://www.bennee.com/~alex/blog/2011/04/13/completion-ignored-extensions/" rel="alternate"></link><published>2011-04-13T16:27:00+01:00</published><updated>2011-04-13T16:27:00+01:00</updated><author><name>alex</name></author><id>tag:www.bennee.com,2011-04-13:/~alex/blog/2011/04/13/completion-ignored-extensions/</id><summary type="html">&lt;p&gt;I've been using the rather spiffy &lt;a class="reference external" href="http://www.emacswiki.org/emacs/LustyExplorer"&gt;Lusty Explorer&lt;/a&gt; for some time for my buffer and file finding. However it (I thought) had a rather annoying bug where I could never tab directly into some of the repositories I was hacking on. Eventually I figured out that the problem was down …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I've been using the rather spiffy &lt;a class="reference external" href="http://www.emacswiki.org/emacs/LustyExplorer"&gt;Lusty Explorer&lt;/a&gt; for some time for my buffer and file finding. However it (I thought) had a rather annoying bug where I could never tab directly into some of the repositories I was hacking on. Eventually I figured out that the problem was down to the way I name them.&lt;/p&gt;
&lt;p&gt;My naming scheme for any repository is generally to add the version control extension to the directory. This is more for my benefit than emacs as it's quite capable of working this out for itself in any given repo. However it turns out that Lusty was being a good emacs citizen and using the variable &lt;em&gt;completion-ignored-extensions&lt;/em&gt; which included the pattern &amp;quot;.git/&amp;quot; and duly hiding my repo directories from completion. In fact there are a number of patterns in there which should probably be more specific. I wrote this to fix the problem:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(setq completion-ignored-extensions
      (mapcar '(lambda (ext)
                 (if (string-equal &amp;quot;/&amp;quot; (substring ext -1 nil))
                     (concat &amp;quot;^&amp;quot; ext)
                   ext)) completion-ignored-extensions))
&lt;/pre&gt;
&lt;p&gt;It still seems a little ugly to me so given the &lt;a class="reference external" href="http://www.bennee.com/~alex/blog/2010/08/10/looping-in-lisp/"&gt;last time I berated elisp's style&lt;/a&gt; gained so many useful suggestions I'd welcome improvements.&lt;/p&gt;
</content><category term="geek"></category><category term="code"></category><category term="elisp"></category><category term="emacs"></category><category term="examples"></category></entry><entry><title>Edit with Emacs v1.8</title><link href="https://www.bennee.com/~alex/blog/2010/08/19/edit-with-emacs-v1-8/" rel="alternate"></link><published>2010-08-19T11:10:00+01:00</published><updated>2010-08-19T11:10:00+01:00</updated><author><name>alex</name></author><id>tag:www.bennee.com,2010-08-19:/~alex/blog/2010/08/19/edit-with-emacs-v1-8/</id><summary type="html">&lt;p&gt;After a relatively quiet period a number of patches have flowed my way so I thought it was worth pushing out a new version. Perhaps the most &amp;quot;important&amp;quot; feature is the edit box flashing and fading from yellow after being updated (like &lt;a class="reference external" href="http://trac.gerf.org/itsalltext"&gt;It's All Text&lt;/a&gt;). It wasn't that hard to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;After a relatively quiet period a number of patches have flowed my way so I thought it was worth pushing out a new version. Perhaps the most &amp;quot;important&amp;quot; feature is the edit box flashing and fading from yellow after being updated (like &lt;a class="reference external" href="http://trac.gerf.org/itsalltext"&gt;It's All Text&lt;/a&gt;). It wasn't that hard to do given &lt;a class="reference external" href="http://jquery.com/"&gt;jQuery&lt;/a&gt; and the &lt;a class="reference external" href="http://plugins.jquery.com/project/color"&gt;colour animation plugin&lt;/a&gt; do all the heavy lifting.&lt;/p&gt;
&lt;p&gt;We've added a new hook to the edit-server for pre-edit customisation. If anyone has some nice examples of using the various hooks it would great if you could add examples at the &lt;a class="reference external" href="http://www.emacswiki.org/emacs/Edit_with_Emacs"&gt;emacs wiki&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As ever the extension can be found at the &lt;a class="reference external" href="https://chrome.google.com/extensions/detail/ljobjlafonikaiipfkggjbhkghgicgoh"&gt;Chrome Extensions site&lt;/a&gt;. Development versions are hosted at &lt;a class="reference external" href="http://github.com/stsquad/emacs_chrome"&gt;github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Full Change Log&lt;/p&gt;
&lt;p&gt;v1.8&lt;/p&gt;
&lt;p&gt;Extension&lt;/p&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;* Added option to enable/disable visual edit boxes&lt;/div&gt;
&lt;div class="line"&gt;* Improved feedback as editable elements come in and out of focus&lt;/div&gt;
&lt;div class="line"&gt;* Updated text box will now fade from yellow after an update&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;edit-server.el&lt;/p&gt;
&lt;p&gt;* Added edit-server-start-hook for additional customisation when edit starts&lt;/p&gt;
</content><category term="geek"></category><category term="chrome"></category><category term="chromium"></category><category term="development"></category><category term="elisp"></category><category term="emacs"></category><category term="extension"></category><category term="javascript"></category></entry><entry><title>Looping in LISP</title><link href="https://www.bennee.com/~alex/blog/2010/08/10/looping-in-lisp/" rel="alternate"></link><published>2010-08-10T09:04:00+01:00</published><updated>2010-08-10T09:04:00+01:00</updated><author><name>alex</name></author><id>tag:www.bennee.com,2010-08-10:/~alex/blog/2010/08/10/looping-in-lisp/</id><summary type="html">&lt;p&gt;Loops are a fairly important part of any programming language and fairly fundamental to a language that is purported to be all about manipulating lists. However it's not something I use that often in my .emacs code so I thought it might be useful to discuss the various options with …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Loops are a fairly important part of any programming language and fairly fundamental to a language that is purported to be all about manipulating lists. However it's not something I use that often in my .emacs code so I thought it might be useful to discuss the various options with some examples.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; I run emacs on a number of machines, each with a different set of sound sets. I want to set up set up a valid sound for erc but I don't want an overly verbose set of cases depending on what machine I'm on. Instead a given a list of sound files I want a function that will return the first one that actually exists.&lt;/p&gt;
&lt;p&gt;This problem can be easily generalised into return the first valid path from a list of paths.&lt;/p&gt;
&lt;div class="section" id="first-version-pure-emacs-lisp"&gt;
&lt;h2&gt;First version: pure emacs lisp&lt;/h2&gt;
&lt;pre class="literal-block"&gt;
; the 'elisp' way
(defun find-valid-file-elisp-way (list-of-files)
  &amp;quot;Go though a list of files and return the first one that is present&amp;quot;
  (let (r '())
    (mapc '(lambda (f)
             (if (file-exists-p f) (add-to-list 'r f)))
          list-of-files)
    (car r)))
&lt;/pre&gt;
&lt;p&gt;First impressions aren't good. The lisp parenthesis do seem to get in the way of making what is happening clear. However it's using one of common &lt;a class="reference external" href="http://www.gnu.org/s/emacs/manual/html_node/elisp/Mapping-Functions.html"&gt;mapping functions&lt;/a&gt; you see a lot of in lisp. A mapping function essentially takes a list, applies a function to each element of the list and eventually returns a result. The most common of the mapping functions is &lt;em&gt;mapcar&lt;/em&gt; which returns a modified list as a result. In this case that isn't what we want so we use &lt;em&gt;mapc&lt;/em&gt; where the only value that is built up is the result &lt;em&gt;r&lt;/em&gt; as we identify each valid file. The final return value is just the first entry in that list. This does mean we have processed the whole list of alternatives which is sub-optimal.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="second-version-common-lisp-version"&gt;
&lt;h2&gt;Second version: Common Lisp Version&lt;/h2&gt;
&lt;pre class="literal-block"&gt;
(defun find-valid-file-clisp-way (list-of-files)
  &amp;quot;Go though a list of files and return the first one that is present&amp;quot;
  (loop for path in list-of-files
        until (file-exists-p path)
        finally return path))
&lt;/pre&gt;
&lt;p&gt;This version probably is the easiest to read for people familiar with other programming languages. The intention of the code jumps out at you. However the actual implementation is done with a macro. If you look at the help for &lt;em&gt;loop&lt;/em&gt; you'll see it can take a number of different forms - follow that to the code and you'll see a fairly complex elisp implementation. However to my mind still easier to follow than the pure elisp version with mapc.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="third-version-using-the-dolist-macro"&gt;
&lt;h2&gt;Third Version: Using the dolist macro&lt;/h2&gt;
&lt;pre class="literal-block"&gt;
; using 'cl-macs
(defun find-valid-file-dolist-way (list-of-files)
  &amp;quot;Go though a list of files and return the first one that is present&amp;quot;
  (dolist (f list-of-files)
    (if (file-exists-p f)
        (return f))))
&lt;/pre&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;This is yet another version using an LISP macro but this one has considerably less potential forms to cause confusion. It's fairly comprehensible what is going on and even follows the traditional parenthesis happy form. It also takes advantage of the common LISP &lt;em&gt;return&lt;/em&gt; to early return from the loop when we detect a valid file. If it makes it to the end of the list it evaluates the 3rd optional form to calculate the result which in this case will be 'nil.&lt;/div&gt;
&lt;div class="line"&gt;&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;So what do you think? What version do you prefer? Where does the balance lie between writing code is LISPy ways and for code comprehension? Are there any other ways to solve this particular problem? I'll be looking forward to your comments.&lt;/p&gt;
&lt;/div&gt;
</content><category term="geek"></category><category term="code"></category><category term="elisp"></category><category term="emacs"></category><category term="examples"></category><category term="lisp"></category></entry><entry><title>First elisp patch for emacs chrome</title><link href="https://www.bennee.com/~alex/blog/2010/01/09/first-elisp-patch-for-emacs-chrome/" rel="alternate"></link><published>2010-01-09T12:40:00+00:00</published><updated>2010-01-09T12:40:00+00:00</updated><author><name>alex</name></author><id>tag:www.bennee.com,2010-01-09:/~alex/blog/2010/01/09/first-elisp-patch-for-emacs-chrome/</id><summary type="html">&lt;p&gt;One of the nice things about putting your coding experiments up early and under a permissive license is people can submit patches. I'd been trying to get the native elisp &lt;a class="reference external" href="http://github.com/stsquad/emacs_chrome/blob/master/servers/edit_server.el"&gt;edit server&lt;/a&gt; working but I'd fallen back to the working python script as I've been busy at work. However along …&lt;/p&gt;</summary><content type="html">&lt;p&gt;One of the nice things about putting your coding experiments up early and under a permissive license is people can submit patches. I'd been trying to get the native elisp &lt;a class="reference external" href="http://github.com/stsquad/emacs_chrome/blob/master/servers/edit_server.el"&gt;edit server&lt;/a&gt; working but I'd fallen back to the working python script as I've been busy at work. However along comes Riccardo Murri who cleaned up the code and got it working. I've pushed the changes to the &lt;a class="reference external" href="http://github.com/stsquad/emacs_chrome"&gt;repo&lt;/a&gt; and with a little extra glue spawn it when emacs is in &lt;em&gt;--daemon&lt;/em&gt; mode:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
;; Do we want an edit-server?
(if (and (daemonp) (maybe-load-library &amp;quot;edit_server&amp;quot;))
    (edit-server-start))
&lt;/pre&gt;
&lt;p&gt;And bingo you save the cost of 2 unnecessary fork/execve's to get emacs editing your Google Chrome(ium) hosted &amp;lt;textarea&amp;gt;. It seems to have an odd interaction with longlines-mode though which I need to investigate, perhaps longlines mode does magic stuff with the buffer text on save which gets skipped when the edit server does it's thing?&lt;/p&gt;
&lt;p&gt;I've submitted the extension to the Google extension gallery although it's currently held up in actual physical paperwork. As my content script needs fairly liberal permissions to work I have to at least demonstrate I'm not an evil hacker/spammer intent on creating browser malware. I may take advantage of the delay to some clean ups to the browser feedback as we will likely be housebound sheltering from the weather. That is of course unless anyone else beats me to it :-)&lt;/p&gt;
</content><category term="general"></category><category term="chrome"></category><category term="elisp"></category><category term="emacs"></category><category term="extensions"></category></entry></feed>