September 1st, 2009 | Categories: Desktop, Linux | Tags: , , , ,

2009-09-02: Uploaded the config files package clickable-dzen2.tar.bz2, and the complete XMonad config is available on github.

Xmobar and dzen2 are two poplar status panel for XMonad, because they can be hooked into the logHook and display the status of XMonad. But they are not interactively friendly. Although I can use keyboard to perform all the tasks, in very rare cases, I still want to be able to use only one hand and the mouse.

Fortunately, latest version 1 of dzen2 supports mouse action on region. But XMonad does not support client command to invoke windows management command. Two tools wmctrl and xdotool can help to resolve this problem. The former can interact with any EWMH/NetWM compatible X Window Manager, and the latter can simulate keyboard input. So my solution is adding mouse action in dzen2, use wmctrl to switch desktop and xdotool to change layout.

Read more...
August 30th, 2009 | Categories: Emacs | Tags: ,

Starting from Emacs 23, I start Emacs as a daemon (using emacs --daemon) when starting X session. And use emacsclient to bring up a frame (see my script emacs-dwim). When quitting X session, I send a HUP signal to Emacs.

Example: .xsession

pidof emacs && killall emacs && sleep 3
emacs --daemon &

ck-launch-session "$MY_WM" &
wait $!

killall -HUP emacs

Recently I find out features like ido, recentf no longer save histories into files so that they cannot restore after restart. These features all add hook in `kill-emacs-hook'. But in the daemon mode, it has no opportunity to run `kill-emacs-hook' because the process is killed by SIGHUP or SIGTERM, where the hooks are not ran in such case.

Call `kill-emacs'

A simple solution is use `kill-emacs' to quit Emacs before quitting X session. For example, the last line of the file .xsession listed above can be changed to:

emacsclient -e -n '
(progn
  (dolist (f (cdr-safe (reverse (frame-list))))
    (delete-frame f t))
  (kill-emacs))
'
declare -i c=1
while pgrep emacs && [ $c -le 3 ] && sleep $c; do
    c=c+1
done
killall -HUP emacs

The code above deletes all frames and kill Emacs using function `kill-emacs', then waits at most 6 seconds. If Emacs is still running, then send HUP signal.

The function (cdr-safe (reverse (frame-list))) returns all frames except the last one, which is the hidden frame in my Emacs.

Run `kill-emacs-hook' in `delete-frame-functions'

It is also a good idea to run hooks in `kill-emacs-hook' when a frame is deleted. But Emacs daemon server also registered a hook in `kill-emacs-hook' to stop the server. If it is invoked in `delete-frame-functions' then the background Emacs can no longer been connected.

The following code can be added in Emacs initialization file (.emacs) to call the listed functions when frame is deleted and Emacs is running as server:

(add-hook 'server-switch-hook 
          (lambda ()
            (when (current-local-map)
              (use-local-map (copy-keymap (current-local-map))))
            (local-set-key (kbd "C-x k") 'server-edit)))

(setq iy/delete-frame-functions
      '(anything-c-adaptive-save-history
        w3m-cookie-shutdown
        w3m-arrived-shutdown
        recentf-save-list
        ido-kill-emacs-hook))

(defun iy/run-delete-frame-hooks (frame)
  (when (and (server-running-p)
             (= 2 (length (frame-list))))
    (dolist (f iy/delete-frame-functions)
      (when (fboundp f)
        (funcall f)))))

(add-hook 'delete-frame-functions 'iy/run-delete-frame-hooks)
August 30th, 2009 | Categories: Linux | Tags: , ,

Install GCC 4.1

Install using makepkg

I have switched from Ubuntu to Arch Linux because of its lightweight and seamless upgrade.

In the project I'm working in, I must use GCC 4.1. However, the latest Arch Linux uses GCC 4.4. I searched in AUR and only found gcc-43 and gcc-34. After google, I got the old revision of the GCC used in Arch Linux from the svn repository. The PKGBUILD should be updated like the one in gcc-snapshot, so that it can be installed with a version suffix. The major changes are adding options --program-suffix and --enable-version-specific-runtime-libs while running the configure script.

I had packaged it as gcc41.tar.gz. The binaries are installed as /usr/bin/gcc-4.1 and /usr/bin/g++-4.1.

Makepkg configuration

I met another problem while building the GCC 4.1. I installed the 64bit os, and GCC cannot recognize the CPU type because of the option --with-tune=generic. The solution is in Arch wiki page Makepkg.conf. On my "Core 2 Duo" machine, I should set the flags as:

CHOST="x86_64-pc-linux-gnu"
CFLAGS="-march=nocona -O2 -pipe"
CXXFLAGS="${CFLAGS}"

Use GCC 4.1

The compiler name gcc-4.1 and g++4.1 can be specified in the build tool to use GCC 4.1. For example, in the project using autotool, the compiler can be specified using environment variable while running configure:

$ CC=gcc-4.1 CXX=g++-4.1 ./configure --prefix=/opt/gcc41

To use them globally, just create symbol link in /bin. Because /bin is before /usr/bin in the PATH by default in Arch Linux:

$ ln -s /usr/bin/gcc-4.1 /bin/gcc
$ ln -s /usr/bin/g++-4.1 /bin/g++

But it is not recommended, because the kernel is built using GCC 4.4.

Another issues is that GCC 4.1 cannot link many dynamic libraries (.so) in the system, such as boost library in the repository, because these libraries are built using GCC 4.4. I can only link the static version (.a) or build another copy of these libraries using GCC 4.1.

I adopted the latter solution. I built required libraries in a uniform prefix such as /opt/gcc41. The prefix will be used to tell build tool to find the gcc41 version, such as:

$ CC=gcc-4.1 CXX=gcc-4.1 ./configure --with-xxx=/opt/gcc41

I also have implemented a wrapper to start a program compiled by GCC 4.1.

File: gcc41-exec
#!/bin/bash
[ -z "$LD_LIBRARY_PATH" ] \
&& export LD_LIBRARY_PATH=/opt/gcc41/lib \
|| export LD_LIBRARY_PATH="/opt/gcc41/lib:$LD_LIBRARY_PATH"

exec "$@"

Then normal programs still load libraries from default system location. And programs started using gcc41-exec will search libraries in /opt/gcc41/lib first.

July 14th, 2009 | Categories: Emacs | Tags: , ,

Default diff-mode is really ugly, I prefer using color to indicate changes, green for added and red for removed. Fortunately, we can customized faces in diff-mode ourselves.

Following is my customization:

(custom-set-faces
  ;; custom-set-faces was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 '(diff-added ((t (:foreground "#559944"))))
 '(diff-context ((t nil)))
 '(diff-file-header ((((class color) (min-colors 88) (background dark)) (:foreground "RoyalBlue1"))))
 '(diff-function ((t (:foreground "#00bbdd"))))
 '(diff-header ((((class color) (min-colors 88) (background dark)) (:foreground "RoyalBlue1"))))
 '(diff-hunk-header ((t (:foreground "#fbde2d"))))
 '(diff-nonexistent ((t (:inherit diff-file-header :strike-through nil))))
 '(diff-refine-change ((((class color) (min-colors 88) (background dark)) (:background "#182042"))))
 '(diff-removed ((t (:foreground "#de1923")))))

And the sample display:

diff --git a/lisp/org-exp.el b/lisp/org-exp.el
index ed1778c..905a065 100644
--- a/lisp/org-exp.el
+++ b/lisp/org-exp.el
@@ -2109,9 +2109,11 @@ is a string, prepend it to the first line instead of PREFIX."
    (insert (or prefix1 prefix))
    (setq prefix1 nil)
    (beginning-of-line 2)))
-    (buffer-string)
     (goto-char (point-min))
-    (while (re-search-forward "^\\(\\*\\|[ \t]*#\\)" nil t)
+    (while (re-search-forward "^[ \t]*#+\\(TITLE\\|AUTHOR\\|EMAIL\\|DATE\\|DESCRIPTION\\|KEYWORDS\\|LANGUAGE\\|OPTIONS\\|INFOJS_OPT\\|EXPORT_SELECT_TAGS\\|EXPORT_EXCLUDE_TAGS\\|LINK_UP\\|LINK_HOME\\).*$" nil t)
+      (replace-match "" nil nil))
+    (goto-char (point-min))
+    (while (re-search-forward "^\\*" nil t)
       (goto-char (match-beginning 0))
       (insert ",")
       (end-of-line 1))

You can merge these into your face customizations. They are generated by customize-face in the default custom file (~/.emacs).

I use the dark theme Blackboard, in which the background color is "#0C1021" and foreground color is "#F8F8F8" (Sample Text). So the theme may be only readable in dark theme. You can customize-group "diff-mode" to generate your own diff-mode theme.

June 27th, 2009 | Categories: Linux | Tags: , ,

In Ubuntu, command update-alternatives maintains symbolic links determining default commands. This article introduces how to switch gcc-4.1 and gcc-4.3 as default compiler in Ubuntu.

Install Packages

It seems that both gcc-4.1 and gcc-4.3 are installed after I install build-essential. However, we can explicitly install the following packages:

$ sudo apt-get install gcc-4.1 gcc-4.3 g++-4.1 g++-4.3

Install Alternatives

Symbolic links cc and c++ are installed by default. We will install symbol links for gcc and g++, then link cc and c++ to gcc and g++ respectively.

$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.1 10
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.3 20

$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.1 10
$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.3 20

$ sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30
$ sudo update-alternatives --set cc /usr/bin/gcc

$ sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30
$ sudo update-alternatives --set c++ /usr/bin/g++

Configure Alternatives

The last step is configuring the default commands for gcc, g++. It's easy to switch between 4.1 and 4.3 interactively:

$ sudo update-alternatives --config gcc
$ sudo update-alternatives --config g++

Or switch using script:

#!/bin/sh

if [ -z "$1" ]; then
    echo "usage: $0 version" 1>&2
    exit 1
fi

if [ ! -f "/usr/bin/gcc-$1" ] || [ ! -f "/usr/bin/g++-$1" ]; then
    echo "no such version gcc/g++ installed" 1>&2
    exit 1
fi

update-alternatives --set gcc "/usr/bin/gcc-$1"
update-alternatives --set g++ "/usr/bin/g++-$1"
This website uses a Hackadelic PlugIn, Hackadelic SEO Table Of Contents 1.7.3.