Friday, July 17, 2009

Dired mode and too many buffers.

Emacs has a very nice file browser/directory editor builtin called Dired. It's convenient when you're searching for files or or just need a general directory browser. You open it with:
C-x d

Supply to the directory that you want, and the directory listing appears in a buffer which you can navigate like any Emacs buffer. You can open files and directories by moving the cursor sand selecting them, as well as delete, rename, move and apply other opperations to the files and directories. All in all, it's pretty slick.

Dired's one major inconvenience for me is that every time I open something, it opens in a separate buffer. This includes new directories. So, if I use it to browse directories I end up with a large backlog of buffers that I have to delete and it gets very annoying.

Fortunatly, this being Emacs, things are eay to fix. A Google search found me this code:

(defun dired-follow-file ()
"In dired, visit the file or directory on this line.
If a directory is on the current line, replace the current
dired buffer with one containing the contents of the directory.
Otherwise, invoke `dired-find-file' on the file."
(interactive)
(let ((filename (dired-get-filename)))
;; if the file is a directory, replace the buffer with the
;; directory's contents
(if (file-directory-p filename)
(find-alternate-file filename)
;; otherwise simply perform a normal `dired-find-file'
(dired-find-file))))

(add-hook
'dired-mode-hook
(lambda ()
(local-set-key "\C-m" 'dired-follow-file)
(local-set-key "e" 'dired-follow-file)
(local-set-key "f" 'dired-follow-file)))


Which causes Dired to do exactly what I want, with one caveat: for some reason it bombs on . and .. directories. A little bit probing showed that it was dired-get-filename that was was failing for some reasons on these entries. I couldn't find either the definition or a description of dired-get-filename, but did find usage examples through a simple web search and these examples showed the usage:
(dired-get-filename nil t)

Instead of:
(dired-get-filename)

Which seemed to be worth a shor and, in fact, solved the problem.

I also added:

(defun dired-follow-up ()
"In dired, visit the directory up in the
hierarchy from this one"
(interactive)
(find-alternate-file ".."))


So that ^ would also behave as I wanted. The final code in my .emacs is as follows:

;; dired stuff

(defun dired-follow-file ()
"In dired, visit the file or directory on this line.
If a directory is on the current line, replace the current
dired buffer with one containing the contents of the directory.
Otherwise, invoke `dired-find-file' on the file."
(interactive)
(let ((filename (dired-get-filename nil t)))
;; if the file is a directory, replace the buffer with the
;; directory's contents
(if (file-directory-p filename)
(find-alternate-file filename)
;; otherwise simply perform a normal `dired-find-file'
(dired-find-file))))

(defun dired-follow-up ()
"In dired, visit the directory up in the
hierarchy from this one"
(interactive)
(find-alternate-file ".."))

(add-hook
'dired-mode-hook
(lambda ()
(local-set-key "\C-m" 'dired-follow-file)
(local-set-key "e" 'dired-follow-file)
(local-set-key "f" 'dired-follow-file)
(local-set-key "^" 'dired-follow-up)))

Saturday, July 4, 2009

PhpPgAdmin for Gentoo

I just spent an afternoon getting PhpPgAdmin working on my Gentoo server. There were a couple of pitfalls that tripped me up so I thought I'd relate the process.

To get PhpPgAdmin working you need three things: Postgres (of course), Php, and a webserver. Postgres, I already had installed and working following this tutorial. Rather than emerging the default Postgres package which is version 8.2, I emerged the latest package 8.3. So:

emerge -av virtual/postgresql-base #emerge the database
passwd postgres #set a password for the db user
New UNIX password:
Retype new UNIX password:
passwd: password updated successfully
emerge --config =postgresql-8.3.5 #(now 8.3.7), finish the install
/etc/init.d/postgresql start #start the database
rc-update add postgresql default #and, of course, add to the default runlevel


You can then configure the users to your hearts content using the createuser and dropuser commands. In addition, make sure to edit pg_hba.conf to allow all the connections you need. Make sure local, unix socket, connections are available. Is should be available under /var/lib/postgresql/8.3/data/pg_hba.conf. Also, make sure any users that will need to locally access the database are in the Postgres group.

usermod -aG postgres username

Keep in mind that whatever user your webserver runs as will also need to be added.

Which, brings us to the next step: the webserver. For reasons unreleated to PhpPgAdmin I already had an install of Lighttpd, and I wanted to use it rather than the standard Apache2. After fiddling for a while I reallized that I would have to reemerge it with the fastcgi and php flags enables (they are not enabled by default.) So:

echo "www-servers/lighttpd fastcgi php" >> /etc/portage/package.use #enable flags
emerge -av lighttpd #emerge lighttpd
/etc/init.d/lighttpd start #start the server
rc-update add lighttpd default #make sure it starts on restart


Php is a straightforward install:

echo "dev-lang/php cgi" >> /etc/portage/package.use
emerge -av php


You may wany to set cgi.fix_pathinfo to 1 in php.info:

vim /etc/php/cgi-php/php.ini

Before you install PhpPgAdmin, change vhost_server to whatever webserver you installed. It defaults to Apache, so if you used Lighttpd, change it to that. This file is /etc/vhosts/webapp-config/. And we can install PhpPgAdmin:

emerge -av phppgadmin

That should be it. You can access it through http://your.domain.com/phppgadmin using whatever login you made for Postgres.

Friday, June 5, 2009

Elephant and UFFI

Reminder to self: don't attempt to install Elephant so that it uses CFFI. CFFI-UFFI-Compat does not work. Use the actual UFFI. That means not attempting to install Elephant through clbuild.

Another note, Elephant seems to go really slowly when accessing a Postgres database over the Internet. I hope that keeping it in the same cluster will allow performance to be sufficient.

Wednesday, June 3, 2009

Well Duh,

So I found an easy way to get clbuild to extend lisp library envionment rather than replace it: simply adding its registry to asdf:*central-registry*. One change to .sbclrc and it's done. Wow, that was easy. Can't beleive I didn't think of it earlier.

Tuesday, March 17, 2009

Lake

Within the Common Lisp atmosphere, ASDF is the tool of choice for build systems. It does for Lisp what Ant and Maven do for Java and what Make does for Unix, and it does so in a much cleaner and more powerful fashion. Instead of writing shell code or dealing with the most hideous XML ever conceived of, you can write a single lisp form in a single file:

(defsystem :system-name
:description "This is a great system"
:version "0.0.1"
:serial t
:components ((:file "lisp-source")
(:file "lisp-source2"))
:depends-on (:library1
:library2
:library3))

...and it does nearly everything for you. If you need to extend it or add support for other languages, file types or whatnot, you just extend the core system using methods. It's incredibly flexible, and the more I use it, the more i warm up to it.

However, there is just one thing I don't like about ASDF. It's all the symlinking. On Unix systems, to register a new asdf system, you have to symlink a .asd file into a systems directory. On my computer, installing a new system usually goes something like this:

wget http://somewhere.on.internet.com/system/system.tar.gz
tar -xvzf system.tar.gz
sudo ln -s /home/name/lisp/system/system.asd /usr/share/common-lisp/systems/

Really, it's not much more complicated than:

./configure
make
sudo make install

...But it is a little more complicated. For starters, I have to remember where the repository is and it's a lot of typing besides. Also, there is no easy way to manage different versions of the same library. And, furthermore, I generally don't know until after I've registered the system, loaded lisp, and tried to load the system, that I'm missing some dependency.

It gets to be nuisance.

There are solutions, such as ASDF-INSTALL, clbuild and the Common_Lisp_Controller, which handle dependencies, and automate installation of known libraries, but none quite do the one simple thing that I want, which is alleviate the need for me to type out the symlink. Even more troublesome, the can sometimes get in the way when a library needs manual configuration before installation.

ASDF-INSTALL, in particular, is annoying because it is so hard to install. This is ironic, because it is supposed to make installation easier, but it itself, is harder to install than your typical ASDF system. In addition, due to ASDF-INSTALL's tolerance for distributed libraries (That is, it allows people to add and modify dependencies for systems by editing a freely editable site on the Internet,) security concerns abound. The only was around this is to fetch the GPG key of nearly every Lisper who's library you want to download. This involves going right to their sites and to the sites of any dependencies. If you're going to do that, why not just down load the file's by hand?

Clbuild is better, but refuses to mix with any preexisting lisp configuration. Also, While ASDF-INSTALL will fetch only stables tars, Clbuild only fetches development versions from version control, which makes it impractical for production systems.

Really what I would like is for lisp system writers to start including simple Makefiles in their systems, which will configure the ASDF system to match my system, and ask me any questions that need asking, and then register itself automatically. It would be even better if the Makefile would then allow me to unregister the system as well. Because ASDF already does most of the dirty work, this wouldn't take much effort and most systems could just have a one size fits all Makefile. However, as long as I'm dreaming, I might ask that they just write me a full Common Lisp operating system while they're at it.

Oh well. The simplest solution to what I'm looking for is a simple alias:

alias asdf-register="ln -s ./*.asd /path/to/registry/"

Which is probably what most people do. But I want just a little more than that, so I wrote a script. It's called Lake and it's fairly simple: you can set it up just by typing

sudo make

and removal is

sudo make uninstall

To register a system:

lake register /path/to/system

The path can either point to a directory, a tarball, or an http path to a remote directory. Either way, it can handle the registration. Lake fits into my current environment and I can use it with clbuild, ADSF-INSTALL, or whatnot. It simply helps to simplify the process of manual ASDF system installation, rather than replace it completely. Which is how I like my tools.