Previous Articles

There's also an index of all entries.
 

Want to share your recipes?

Yes, that's another el-get related entry. It seems to take a lot of my attention these days. After having setup the git repository so that you can update el-get from within itself (so that it's self-contained), the next logical step is providing recipes.

By that I mean that el-get-sources entries will certainly look a lot alike between a user and another. Let's take the el-get entry itself:

(:name el-get
       :type git
       :url "git://github.com/dimitri/el-get.git"
       :features "el-get")

I guess all el-get users will have just the same 4 lines in their el-get-sources. So let's call that a recipe, and have el-get look for yours into the el-get-recipe-path directories. A recipe is found looking in those directories in order, and must be named package.el. Now, el-get already contains a handful of them, as you can see:

ELISP> (directory-files "~/dev/emacs/el-get/recipes/" nil "[^.]$")
("auctex.el" "bbdb.el" "cssh.el" "el-get.el" "emms.el" "erc-track-score.el"
 "escreen.el" "google-maps.el" "haskell-mode.el" "hl-sexp.el" "magit.el"
 "muse-blog.el" "nxhtml.el" "psvn.el" "rainbow-mode.el" "rcirc-groups.el"
 "vkill.el" "xcscope.el" "xml-rpc-el.el" "yasnippet.el")

Please note that you can have your own local recipes by adding directories to el-get-recipe-path. So now your minimalistic el-get-sources list will look like '(el-get cssh screen), say. And if you want to override a recipe, for instance to use the default one but still have a personal :after function containing your own setup, then simply have your el-get-source entry a partial entry. Missing :type and el-get will merge your local overrides atop the default one.

Finally, the way to share your recipes is by sending me an email with the file, or to do the same over the github interface, I guess I'll still receive a mail then.

 

welcome el-get scratch installer

A very good remark from some users: installing and managing el-get should be simpler. They wanted both an easy install of the thing, and a way to be able to manage it afterwards (like, update the local copy against the authoritative source). So I decided it was high time for getting the code out of my ~/.emacs.d git repository and up to a public place: http://github.com/dimitri/el-get.

Then, I added some documentation (a README), and then, a *scratch* installer, following great ideas from ELPA. So have at it, it's a copy paste away!

Don't forget to setup your el-get-sources and include there the el-get source for updates, there's nothing magic about it so it's up to you. You may notice that it's not yet possible to init el-get from el-get-sources, though, that's the drawback of the lack of magic. So you will have to still add an explicit (require 'el-get) before to go and define you own el-get-sources then finally (el-get). I don't think that's a problem I need to solve, though.

 

el-get news

I've been receiving some requests for el-get, some of them even included a patch. So now there's support for bzr, CSV and http-tar, augmenting the existing support for git, git-svn, apt-get, fink and ELPA formats.

Also, as the install and even the build are completely asynchronous — there's a pending bugfix for the building, which is now using start-process-shell-command. The advantage of doing so is that you're free to use Emacs as usual while el-get is having your piece of elisp code compiled, which can take time.

The drawback is that it's uneasy to to do the associated setup at the right time without support from el-get, so you have the new option :after which takes a functionp object: please consider using that to give your own special setup for the external emacs bits and pieces you're using.

Let's see some examples of the new features:

  (:name xml-rpc-el
         :type bzr
         :url "lp:xml-rpc-el")

  (:name haskell-mode
         :type http-tar
         :options ("xzf")
         :url "http://projects.haskell.org/haskellmode-emacs/haskell-mode-2.8.0.tar.gz"
         :load "haskell-site-file.el"
         :after (lambda ()
                  (add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
                  (add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)))

  (:name auctex
         :type cvs
         :module "auctex"
         :url ":pserver:anonymous@cvs.sv.gnu.org:/sources/auctex"
         :build ("./autogen.sh" "./configure" "make")
         :load  ("auctex.el" "preview/preview-latex.el")
         :info "doc")

As you can see, there are also the new options :module (only used by CVS so far) and :options (only used by http-tar so far). With this later method, the :options key allows you to have support for virtually any kind of tar compression (.tar.bz2, etc).

The CVS support currently does not include authentication against the anonymous pserver, because the only repository I've been asked support for isn't using that, and the couple of servers that I know of are either wanting no password at the prompt, or a dummy one. That's for another day, if needed at all.

That pushes the little local hack to more than a thousand lines of elisp code, and the next steps include proposing it to ELPA so that getting to use it is easier than ever. You'd just have to choose whether to install ELPA from el-get or the other way around.

 

el-get and dim-switch-window status update

Thanks to you readers of Planet Emacsen taking the time to try those pieces of emacs lisp found in my blog, and also the time to comment on them, some bugs have been fixed, and new releases appeared.

el-get had some typo kind of bug in its support for apt-get and fink packages, and I managed to break the elpa and http support when going all asynchronous by forgetting to update the call convention I'm using. Fixing that, I also switched to using url-retrieve so that the http support also is asynchronous. That makes the version 0.5, available on emacswiki el-get page.

Meanwhile dim-switch-window.el got some testers too and got updated with a nice fix, or so I think. If you're using it with a small enough emacs frame, or some very little windows in there, you'd have noticed that the number get so big they don't fit anymore, and all you see while it's waiting for your window number choice is... blank windows. Not very helpful. Thanks to the following piece of code, that's no longer the case as of the current version, available on emacswiki switch-window page.

In short, where I used to blindly apply dim:switch-window-increase on the big numbers to display, the code now checks that there's enough room for it to get there, and adjust the increase level scaling it down if necessary. Very simple, and effective too:

    (with-current-buffer buf
      (text-scale-increase
       (if (> (/ (float (window-body-height win))
                 dim:switch-window-increase)
              1)
           dim:switch-window-increase
         (window-body-height win)))
      (insert "\n\n    " (number-to-string num)))

Centering the text in the window's width is another story entirely, as the text-scale-increase ain't linear on this axis. I'd take any good idea, here's what I'm currently at, but it's not there yet:

    (with-current-buffer buf
      (let* ((w (window-width win))
             (h (window-body-height win))
             (increased-lines (/ (float h) dim:switch-window-increase))
             (scale (if (> increased-lines 1) dim:switch-window-increase h))
             (lines-before (/ increased-lines 2))
             (margin-left (/ w h) ))
        ;; increase to maximum dim:switch-window-increase
        (text-scale-increase scale)
        ;; make it so that the hyuge number appears centered
        (dotimes (i lines-before) (insert "\n"))
        (dotimes (i margin-left)  (insert " "))
        (insert (number-to-string num))))

So, if you're using one or the other (both?) of those utilities, update your local version of them!

Note: I also fixed a but in rcirc-groups this week-end, but I'll talk about it in another entry, if I may.

 

el-get

I've been using emacs for a long time, and a long time it took me to consider learning Emacs Lisp. Before that, I didn't trust my level of understanding enough to be comfortable in managing my setup efficiently.

One of the main problems of setting up Emacs is that not only you tend to accumulate so many tricks from EmacsWiki and blog posts that your .emacs has to grow to a full ~/.emacs.d/ directory (starting at ~/.emacs.d/init.el), but also you finally depend on several librairies of code you're not authoring nor maintaining. Let's call them packages.

Some of them will typically be available on ELPA, which allows you to breathe and keep cool. But most of them, let's face it, are not there. Most of the packages I use I tend to get them either from debian (see apt-rdepends for having the complete list of packages that depends on emacs, unfortunately I'm not finding an online version of the tool to link too), or from ELPA, or from their own git repository somewhere. Some of them even I get directly from an obscure website not maintained anymore, but always there when you need them.

Of course, my emacs setup is managed in a private git repository. Some people on #emacs are using git submodules (or was it straight import) for managing external repositories in there, but all I can say is that I frown on this idea. I want an easy canonical list of packages I depend on to run emacs, and I want this documentation to be usable as-is. Enters el-get!

As we're all damn lazy, here's a visual introduction to el-get:

(setq el-get-sources
      '((:name bbdb
               :type git
               :url "git://github.com/barak/BBDB.git"
               :load-path ("./lisp" "./bits")
               :info "texinfo"
               :build ("./configure" "make"))

        (:name magit
               :type git
               :url "http://github.com/philjackson/magit.git"
               :info "."
               :build ("./autogen.sh" "./configure" "make"))

        (:name vkill
               :type http
               :url "http://www.splode.com/~friedman/software/emacs-lisp/src/vkill.el"
               :features vkill)

        (:name yasnippet
               :type git-svn
               :url "http://yasnippet.googlecode.com/svn/trunk/")

        (:name asciidoc         :type elpa)
        (:name dictionary-el    :type apt-get)
        (:name emacs-goodies-el :type apt-get)))

(el-get)

So now you have a pretty good documentation of the packages you want installed, where to get them, and how to install them. For the advanced methods (such as elpa or apt-get), you basically just need the package name. When relying on a bare git repository, you need to give some more information, such as the URL to clone and the build steps if any. Then also what features to require and maybe where to find the texinfo documentation of the package, for automatic inclusion into your local Info menu.

The good news is that not only you now have a solid readable description of all that in a central place, but this very description is all (el-get) needs to do its magic. This command will check that each and every package is installed on your system (in el-get-dir) and if that's not the case, it will actually install it. Then, it will init the packages: that means caring about the load-path, the Info-directory-list (and dir texinfo menu building), the loading of the emacs-lisp files, and finally it will require the features.

Here's a prettyfied ielm session that will serve as a demo:

ELISP> (el-get)
("aspell-en" "aspell-fr" "muse" "dictionary" "htmlize" "bbdb" "google-maps"
"magit" "emms" "nxhtml" "vkill" "xcscope" "yasnippet" "asciidoc"
"auto-dictionary" "css-mode" "gist" "lua-mode" "lisppaste")

All the packages being already installed, it's running fast enough that I won't bother measuring the run time, that seems to be somewhere around one second.

 

dim-switch-window.el: fixes

Thanks to amazing readers of planet emacsen, two annoyances of switch-window.el have already been fixed! The first is that handling of C-g isn't exactly an option after all, and the other is that you want to avoid the buffer creation in the simple cases (1 or 2 windows only), because it's the usual case.

I've received code to handle the second case, that I mostly merged. Thanks a lot guys, the new version is on emacswiki already!

 

dim-switch-window.el

So it's Sunday and I'm thinking I'll get into el-get sometime later. Now is the time to present dim-switch-window.el which implements a visual C-x o. I know of only one way to present a visual effect, and that's with a screenshot:

So as you can see, it's all about showing a big number in each window, tweaking each window's name, and waiting till the user press one of the expected key — or timeout and stay on the same window as before C-x o. When there's only 1 or 2 windows displayed, though, the right thing happen and you see no huge number (in the former case, nothing happens, in the latter, focus moves to the other window).

The code for that can be found on emacswiki under the name switch-window.el. Hope you'll find it useful!

 

ClusterSSH gets `dsh' support

If you don't know about ClusterSSH, it's a project that builds on M-x term and ssh to offer a nice and simple way to open remote terminals. It's available in ELPA and developed at github cssh repository.

The default binding is C-= and asks for the name of the server to connect to, in the minibuffer, with completion. The host list used for the completion comes from tramp and is pretty complete, all the more if you've setup ~/.ssh/config with HashKnownHosts no.

So the usual way to use cssh.el would be to just open a single remote connection at a time. But of course you can open as many as you like, and you get them all in a mosaic of term in your emacs frame, with an input window at the bottom to control them all. There were two ways to get there, either opening all remote hosts whose name is matching a given regexp, that would be using C-M-= or getting to IBuffer and marking there the existing remote terms you want to control all at once then use C-=.

Well I've just added another mode of operation by supporting enhanced dsh group files. In such files, you're supposed to have a remote host name per line and that's it. We've added support for line containing @group kind of lines so that you can include another group easily. To use the facility, either open your ~/.dsh/group directory in dired and type C-= when on the right line, or simply use the global C-= you already know and love. Then, type @ and complete to any existing group found in your cssh-dsh-path (it defaults to the right places, so chances are you will never have to edit this one). And that's it, Emacs will open one term per remote host you have in the dsh group you just picked. With a *cssh* controler window, too.

Coming next, how I solved my init.el dependancies burden thanks to el-get!

 

Emacs Muse hacking

Now you know what piece of software is used to publish this blog. I really like it, the major mode makes it a great experience to be using this tool, and the fact that you produce the HTML and rsync it all from within Emacs (C-c C-p then C-c C-r with some easy elisp code) is a big advantage as far as I'm concerned. No need to resort to shell and Makefile.

What's new here is that I missed the one page per article trend that other blog software propose, and the blog entries index too. I didn't want to invest time into hacking Muse itself, that was my excuse for accepting the situation. But I finally took a deeper look at the Emacs Muse Manual, and found out about the :after and :final functions.

Those two function will get run while in the output buffer, the HTML formatted one. With the :after function, it's still possible to edit the buffer content, for example to add a mini index to previous articles, whereas with the :final function the buffer is read-only and already written to disk, so it's to late to edit it. Still it's possible to cut it in pieces and write a new file per article you find in there.

The code to realize my wishes is available but has not been edited with customisation in mind, so to use it you will have to edit some places rather than just setq some defcustom. Well, if I have demand, I'll generalize the code and share it on Emacs Wiki and ELPA. Meanwhile, happy hacking!

 

Emacs Muse based publishing

As you might have noticed, this little blog of mine is not compromising much and entirely maintained from Emacs. Until today, I had to resort to term to upload my publications, though, as I've been too lazy to hack up the tools integration for simply doing a single rsync command line. That was one time to many:

(defvar dim:muse-rsync-options "-avz"
  "rsync options")

(defvar dim:muse-rsync-source "~/dev/muse/out"
  "local path from where to rsync, with no ending /")

(defvar dim:muse-rsync-target
  "dim@tapoueh.org:/home/www/tapoueh.org/blog.tapoueh.org"
  "Remote URL to use as rsync target, with no ending /")

(defvar dim:muse-rsync-extra-subdirs
  '("../css" "../images" "../pdf")
  "static subdirs to rsync too, path from dim:muse-rsync-source, no ending /")

(defun dim:muse-project-rsync (&optional static)
  "publish tapoueh.org using rsync"
  (interactive "P")
  (let* ((rsync-command (format "rsync %s %s %s"
                                dim:muse-rsync-options
                                (concat dim:muse-rsync-source "/")
                                (concat dim:muse-rsync-target "/"))))
    (with-current-buffer (get-buffer-create "*muse-rsync*")
      (erase-buffer)
      (insert (concat rsync-command "\n"))
      (message "%s" rsync-command)
      (insert (shell-command-to-string rsync-command))
      (insert "\n")

      (when static
        (dolist (subdir dim:muse-rsync-extra-subdirs)
          (let ((cmd (format "rsync %s %s %s"
                             dim:muse-rsync-options
                             (concat dim:muse-rsync-source "/" subdir)
                             dim:muse-rsync-target)))
            (insert (concat cmd "\n"))
            (message "%s" cmd)
            (insert (shell-command-to-string cmd))
            (insert "\n")))))))

(define-key muse-mode-map (kbd "C-c R") 'dim:muse-project-rsync)

So now to publish this blog, it's just a C-c R away! :)

 

Emacs is Twinkling here

So you have a rolodex like database in your Emacs, or you have this phone number in a mail and you want to call it. It happens you have VoIP setup and you're using Twinkle to make your calls. Maybe you'll then find this function useful:

(defun twinkle-call-symbol-or-region ()
  "Call the phone number at point (symbol seems good enough), or in region"
  (interactive)
  (shell-command-to-string
   (format "twinkle --cmd 'call %s'"
           (replace-regexp-in-string
            "[^0-9+]" ""
            (if (use-region-p)
                (buffer-substring (region-beginning) (region-end))
              (thing-at-point 'symbol))))))

It happens that symbol is better than word here because some phone numbers begin with +. And some contains / or . as separators, or some other variations (spaces) so as the number is easy to read for human eyes. Twinkle will not like this.

 

Escreen integration

After having used elscreen for a long time, I'm now a very happy user of escreen, which feels much better integrated and allows to have one ring of recently visited buffers per screen. Which is what you need when using a screen like feature, really.

At first, it seemed so good as not to require any tweaking, but soon enough I had to adapt it to my workflow. After all that's exactly for being able to do this that I'm using emacs :)

It began quite simple with things like M-[ and M-] to navigate in screens, and mouse wheel support to, but then I found that the C-\ b list of screens could also support the C-\ a runs the command escreen-get-active-screen-numbers command by just adding some emphasis to the current escreen in use.

As soon as I had this, and seeing people eyes blinking when working with me in front of my computer, I wanted to have escreen switching display where I am in the minibuffer. You have to try the mouse wheel navigation to fully appreciate it I guess. Anyway, here it is:

(load "escreen")
(escreen-install)

;; add C-\ l to list screens with emphase for current one
(defun escreen-get-active-screen-numbers-with-emphasis ()
  "what the name says"
  (interactive)
  (let ((escreens (escreen-get-active-screen-numbers))
        (emphased ""))

    (dolist (s escreens)
      (setq emphased
            (concat emphased (if (= escreen-current-screen-number s)
                                 (propertize (number-to-string s)
                                             ;;'face 'custom-variable-tag) " ")
                                             'face 'info-title-3)
                                             ;;'face 'font-lock-warning-face)
                                             ;;'face 'secondary-selection)
                               (number-to-string s))
                    " ")))
    (message "escreen: active screens: %s" emphased)))

(global-set-key (kbd "C-\\ l") 'escreen-get-active-screen-numbers-with-emphasis)

(defun dim:escreen-goto-last-screen ()
  (interactive)
  (escreen-goto-last-screen)
  (escreen-get-active-screen-numbers-with-emphasis))

(defun dim:escreen-goto-prev-screen (&optional n)
  (interactive "p")
  (escreen-goto-prev-screen n)
  (escreen-get-active-screen-numbers-with-emphasis))

(defun dim:escreen-goto-next-screen (&optional n)
  (interactive "p")
  (escreen-goto-next-screen n)
  (escreen-get-active-screen-numbers-with-emphasis))

(define-key escreen-map escreen-prefix-char 'dim:escreen-goto-last-screen)

(global-set-key (kbd "M-[") 'dim:escreen-goto-prev-screen)
(global-set-key (kbd "M-]") 'dim:escreen-goto-next-screen)
(global-set-key (kbd "C-\\ DEL") 'dim:escreen-goto-prev-screen)
(global-set-key (kbd "C-\\ SPC") 'dim:escreen-goto-next-screen)

(global-set-key '[s-mouse-4] 'dim:escreen-goto-prev-screen)
(global-set-key '[s-mouse-5] 'dim:escreen-goto-next-screen)

Oh, and as I'm in the terms in emacs part of universe (rather than using emacs -nw in some terminal emulator, but loosing sync between X clipbloard and emacs selection), I had to add this too:

;; add support for C-\ from terms
(require 'term)
(define-key term-raw-map escreen-prefix-char escreen-map)
(define-key term-raw-map (kbd "M-[") 'dim:escreen-goto-prev-screen)
(define-key term-raw-map (kbd "M-]") 'dim:escreen-goto-next-screen)
 

Follow-up on dim:mailrc-add-entry

The function didn't allow for using more than one mailrc file, which isn't a good idea, so I've just added that. Oh and for gnus integration what I need is (add-hook 'message-mode-hook 'mail-abbrevs-setup) it seems... so that if I type the alias it'll get automatically expanded. And to be real lazy and avoid having to type in the entire alias, mail-abbrev-complete-alias to the rescue, assigned to some easy to reach keys.

(require 'message)
(define-key message-mode-map (kbd "C-'") 'mail-abbrev-complete-alias)

(defun dim:mailrc-add-entry (&optional prefix alias)
  "read email at point and add it to an ~/.mailrc file"
  (interactive "P\nMalias: ")
  (let* ((default-mailrc (file-name-nondirectory mail-personal-alias-file))
         (mailrc (if prefix (expand-file-name
                             (read-file-name
                              "Add alias into file: "
                              "~/"
                              default-mailrc
                              t
                              default-mailrc))
                   mail-personal-alias-file))
         (address (thing-at-point 'email-address))
         (buffer (find-file-noselect mailrc t)))
    (when address
      (with-current-buffer buffer
        ;; we don't support updating existing alias in the file
        (save-excursion
          (goto-char (point-min))
          (if (search-forward (concat "alias " alias) nil t)
              (error "Alias %s is already present in .mailrc" alias)))

        (save-current-buffer
          (save-excursion
            (goto-char (point-max))
            (insert (format "\nalias %s \"%s <%s>\"" alias (cdr address) (car address)))))))))
 

Improving ~/.mailrc usage

So I've been adviced to use ~/.mailrc for keeping a basic address book in Emacs, for use within gnus for example. I had to resort to the manual to find out how to use the file aliases when I need them, that is when composing a mail. For the record, here's what I had to do:

;; mails and aliases
(add-hook 'mail-mode-hook 'mail-abbrevs-setup)
(global-set-key (kbd "C-c @") 'mail-abbrev-insert-alias)

That means I prefer hitting C-c @, then typing the alias in the minibuffer (with completion) and there after see the full mail address in my message-mode buffer. This looks like it'll change over time, but rather than searching how to have a nice inline alias completion (M-tab maybe, but already used by the window manager), I've tackled the problem of maintaining the ~/.mailrc file.

Lazy as I am (or I wouldn't be using Emacs this much), having to manually select the email region in the buffer, open or switch to the mailrc buffer then paste my new entry, not forgetting to format it with alias foo prefix and checking for alias usage while doing so didn't strike me as appealing. Oh and don't forget to add quote where they belong, too.

Too much work that I wanted to automate. Here we go:

;; automate adding mail at point to ~/.mailrc
(defun dim:mailrc-add-entry (alias)
  "read email at point"
  (interactive "Malias: ")
  (let ((address (thing-at-point 'email-address))
        (buffer (find-file-noselect mail-personal-alias-file t)))
    (when address
      (with-current-buffer buffer
        ;; we don't support updating existing alias in the file
        (save-excursion
          (goto-char (point-min))
          (if (search-forward (concat "alias " alias) nil t)
              (error "Alias %s is already present in .mailrc" alias)))

        (save-current-buffer
          (save-excursion
            (goto-char (point-max))
            (insert (format "\nalias %s \"%s <%s>\"" alias (cdr address) (car address)))))))))

(global-set-key (kbd "C-c C-@") 'dim:mailrc-add-entry)

Quite there, you'll notice that I'm using thing-at-point 'email-address, and maybe you already know that emacs23 does not provide this. It provides thing-at-point 'email which will ignore real name and all. For example, given a point somewhere inside the right part of John Doe <johndoe@email.tld> the 'email variant of thing-at-point will return johndoe@email.tld. In words of one syllabe: not what I want.

So after searching around for a solution, I saw mail-header-parse-address from the API oriented mail-parse librairy, and finaly came up with this dead simple solution which works fine enough for me:

(require 'mail-parse)

(defun thing-at-point-bounds-of-email-address ()
  "return a cons of begin and end position of email address at point, including full name"
  (save-excursion
    (let* ((search-point (point))
           (start (re-search-backward "[:,]" (line-beginning-position) 'move))
           (dummy (goto-char search-point))
           (end   (re-search-forward  "[:,]" (line-end-position) t)))
      (setq start (if start (+ 1 start)
                    (line-beginning-position)))
      (unless end (setq end (line-end-position)))
      (cons start end))))

(defun thing-at-point-email-address ()
  "return full email address at point"
  (let* ((bounds (thing-at-point-bounds-of-email-address))
         (email-address-text
          (when bounds (buffer-substring-no-properties (car bounds) (cdr bounds)))))
    (mail-header-parse-address email-address-text)))

(put 'email-address 'bounds-of-thing-at-point 'thing-at-point-bounds-of-email-address)
(put 'email-address 'thing-at-point 'thing-at-point-email-address)

Now, when I receive a mail and want to store an alias for it, I simply place point somewhere in the mail then hit C-c C-@, and voilà my ~/.mailrc is uptodate.

Hope it'll be useful for someone else, but at least I'm keeping annotated history of the files :)

 

Some emacs nifties

First, here's a way to insert at current position the last message printed into the minibuffer... well not exactly, in *Messages* buffer in fact. I was tired of doing it myself after invoking, e.g., M-x emacs-version.

;; print last message
;; current-message is already lost by the time this gets called
(defun dim:previous-message (&optional nth)
  "get last line of *Message* buffer"
  (with-current-buffer (get-buffer "*Messages*")
    (save-excursion
      (goto-char (point-max))
      (setq nth (if nth nth 1))
      (while (> nth 0)
        (previous-line)
        (setq nth (- nth 1)))
      (buffer-substring (line-beginning-position) (line-end-position)))))

(defun dim:insert-previous-message (&optional nth)
  "insert last message of *Message* to current position"
  (interactive "p")
  (insert (format "%s" (dim:previous-message nth))))

(global-set-key (kbd "C-c m") 'dim:insert-previous-message)

Now I stumbled accross Planet Emacsen and saw this Emacs Utility Functions post, containing a version of duplicate-current-line that I didn't like... here's mine:

;; duplicate current line
(defun duplicate-current-line (&optional n)
  "duplicate current line, make more than 1 copy given a numeric argument"
  (interactive "p")
  (save-excursion
    (let ((nb (or n 1))
          (current-line (thing-at-point 'line)))
      ;; when on last line, insert a newline first
      (when (or (= 1 (forward-line 1)) (eq (point) (point-max)))
        (insert "\n"))

      ;; now insert as many time as requested
      (while (> n 0)
        (insert current-line)
        (decf n)))))

(global-set-key (kbd "C-S-d") 'duplicate-current-line)

And a last one inspired by some strange vim behavior for which I fail to see a need:

;; on request by cyrilb, who missed it from vim
;; no global-set-key yet, still have to think I'll use it someday...
(defun copy-char-from-prev-line ()
  "Copy char at same position on previous line, when such a line and position exists"
  (interactive)
  (let ((c)
        (p (- (point) (line-beginning-position))))
    (save-excursion
      (when (eq 0 (forward-line -1))
        (when (< (+ (point) p) (line-end-position))
          (forward-char p)
          (setq c (thing-at-point 'char)))))
    (when c
      (insert c))))

Next time I'll try to talk about rcirc-groups or cssh which have managed to take some of my free time recently.

 

Tue, 9 Dec 2008, 0:00 Useful emacs trick

(defun insert-date()
  "Insert a time-stamp according to locale's date and time format."
  (interactive)
  (insert (format-time-string "%a, %e %b %Y, %k:%M" (current-time))))

(global-set-key "\C-cd" 'insert-date)
 

Mon, 8 Dec 2008, 23:59 Predicting the next 5,000 days of the web

Watch Kevin Kelly's Talk here, it's about trying to predict what the Internet will look like 5 thousands days from now.

 

Mon, 8 Dec 2008, 16:10 emacs-snapshot

If you want to live on the bleeding edge, it's easy enough to get a non existing release of GNU Emacs under debian sid, thanks to http://emacs.orebokech.com/.

The problem is that Emacs Muse is broken on emacs-snapshot, partly because of Htmlize which is unable to find the face fonts (I got (error "Invalid face")), partly because of my configuration itself:

hunk ./dim-muse.el 22
-      '(("pgsql.tapoueh.org" $
-        (,@(muse-project-alist-dirs "~/dev/muse/site") $
+      '(("pgsql.tapoueh.org" ("~/dev/muse/site"
+        ;;(,@(muse-project-alist-dirs "~/dev/muse/site") $

The solution was to switch to using Emacs 22 on sid for pgsql.tapoueh.org editing, while using EmacsCVS for other activities.

And I'm using the patched Htmlize on both the versions, by the way.

 

December, 6th 2008

A new site, using new software. See Home Page to read a rant about it all.

Oh and check out the skytools page too. Emacs Muse is so great a project that instead of just working on how to publish a website with this tool, I found myself editing a rather large document about londite.py.

 

Emacs Muse powered blog

The problem with communication is that you think it happened.

So finaly a blogging software for geeks exists?