Archive for November, 2006

Using KDE’s kio-slaves with Emacs

Posted: November 29, 2006 in Emacs

With Emacs you can edit remote files with TRAMP. It’s really cool, but sometimes it fails because the remote host shell uses a hyper-fancy prompt. Once I had such troubles, so a replacement was needed.

I use KDE and I’m used to its kio-slaves, which enable the user to work with remote files as if they were on the local system. So I wrote an elisp function which utilize the KDE file dialog, the kio-slaves and emacsclient (only for remote files).

UPDATE: The function below was updated and includes all corrections and enhancements Noone mentioned in his comment.

(defun th-find-file-kio ()
  (interactive)
  (let ((file-name
         (replace-regexp-in-string
          "[\\n]+" ""
          (shell-command-to-string "kdialog --getopenurl ~ 2> /dev/null"))))
    (cond
     ((string-match "^file://" file-name)
      ;; Work arround a bug in kioexec, which causes it to delete local
      ;; files. (See bugs.kde.org, Bug 127894.) Because of this we open the
      ;; file with `find-file' instead of emacsclient.
      (let ((local-file-name (substring file-name 7)))
        (message "Opening local file '%s'" local-file-name)
        (find-file local-file-name)))
     ((string-match "^[:space:]*$" file-name)
      (message "Empty file name given, doing nothing..."))
     (t
      (message "Opening remote file '%s'" file-name)
      (save-window-excursion
        (shell-command (concat "kioexec emacsclient " file-name "&")))))))

(defalias 'ffk 'th-find-file-kio)

With M-x ffk or M-x th-find-file-kio the KDE file dialog will be opened and you can choose a file, may it be local or on a remote host. Then the file will be opened. If it’s local, it will be opened in Emacs with the find-file function and you can edit it as if you opened it in Emacs directly.

If it’s a remote file the temporary file created by the kio-slave will be opened with emacsclient. Edit the file and when you’re finished type C-c g (server-edit). A dialog box will pop up and ask if the changes should be uploaded to the remote host.

Giving weblogger.el a try

Posted: November 28, 2006 in Emacs

Because I’m a bit disappointed from KBlogger, I’m currently trying out weblogger.el. The configs were easily created by the weblogger-setup-weblog function.

The interface when writing a blog entry is nice and borrowed from Gnus’ message mode. But there are far too much items in the menu, and most of them are about newsgroups/mail and don’t fit here (But that’s on the TODO list).

One thing I’m missing is that I cannot set the category of my blog entry, so I’ll always have to do it manually in the web interface, but I see, categories are on the TODO list, too.

What’s a bit daunting is that the last CVS commit was nearly 9 month ago and even the project’s homepage http://elisp.info/package/weblogger/ is not available anymore. I hope this project isn’t dead!

What blogging software do you use? (Emacs preferred but at least it has to run with GNU/Linux)

UPDATE: Another nice feature is that you can fetch all entries from the server and update them. The problem with it: The entry does not change on the server.

One thing which bothered me with BASH are its limited completion capabilities, even though you have bash-completion installed.

This made me switch to ZSH some years ago, which felt more right. It has completions for the most common commands and seemed to be much better suited for interactve work. Nevertheless, I never got into shell programming, although ZSH has some nifty stuff that make it really powerful.

Then three weeks ago I fell over fish because of an LWN article. It’s (the article) quite outdated, but shows many of fish’s nice features. A more actual article can be found at Linux.com.

So what makes fish that cool? Why do we need another shell? Well, because it has many features no other shell has, and because it breaks compatibility. (Why in hell does anyone want compatibility with the 25 year old Korn shell, if the only "benefit" is broken usability? Ok, maybe you’re used to it, but try fish anyway!)

Now let’s talk about fish’s features:

  1. Fish has an advanced syntax highlighting. When you type an incomplete or unknown command, it’s colored in red to indicate an error. Once it’s complete, it’s colored in green. An existing path will be underlined to show its validity. Syntax errors are highlighted in red, too. There are other attributes for e.g. different file types or regular expressions, and of course you con adjust them to fit your needs.
  2. TAB completion is an essential feature when working in the shell, and it’s a part where fish really shines. Of course it completes all commands in PATH and directories/files, but it completes the options and switches of a command, too. For example it knows that the darcs command has the subcommands add, ..., whatsnew, and it knows the switches of those subcommands. Beside completing those subcommands and switches, it displays a short description, so the user can exploit the completion mechanism to explore what a command can do. The best thing is: All those completions are fish scripts utilizing the complete command. So if there’s no completion for the foobar command, you can easily write one yourself (and submit it to the fish ML to share it with the other users).
  3. Fish uses Emacs keybindings, so an emacs user will find it very comfortable. It even has a kill ring!
  4. The command history is awesome. If you press the up and down arrows, you walk accross the command history like in BASH. But if you enter a string at the prompt first, then fish shows only commands that match the entered string. If you use M-Up/M-Down the history commands are tokenized, so you can complete arguments this way.
  5. There’s an open command which open the given file with the application chosen in the desktop environment’s MIME database.

Beside those mentioned features, fish has a lot of other nice capabilities. So here’s my advice: TRY IT and join us at #fish at irc.oftc.net.

In emacs you can split each frame in several windows. Such a configuration is called window configuration. The window configurations of all frames make a frame configuration. Here are some functions which let you save and restore such a frame configuration with only one key.
First we define a register which will be used by default for saving the frame configuration:

(defparameter th-frame-config-register ?°
  "The register which is used for storing and restoring frame
configurations by `th-save-frame-configuration' and
`th-jump-to-register'.")

The next thing is the saving function. If you call it with a prefix arg you can choose a different register:

(defun th-save-frame-configuration (arg)
  "Stores the current frame configuration in register
`th-frame-config-register'. If a prefix argument is given, you
can choose which register to use."
  (interactive "P")
  (let ((register (if arg
                      (read-char "Which register? ")
                    th-frame-config-register)))
    (frame-configuration-to-register register)
    (message "Frame configuration saved in register '%c'."
             register)))

Now we need a function to restore a frame configuration. By default it uses th-frame-config-register, but with a prefix arg you can choose any register. (You can use this function not only for restoring frame configs, but for everything you can do with jump-to-register…)

(defun th-jump-to-register (arg)
  "Jumps to register `th-frame-config-register'. If a prefix
argument is given, you can choose which register to jump to."
  (interactive "P")
  (let ((register (if arg
                      (read-char "Which register? ")
                    th-frame-config-register)))
    (jump-to-register register)
    (message "Jumped to register '%c'."
             register)))

Ok, the last thing we gotta do is create some key bindings. I chose F5 and F6:

(global-set-key (kbd "<F5>")
                'th-save-frame-configuration)
(global-set-key (kbd "<F6>")
                'th-jump-to-register)

Now whenever you have a complex window/frame config press F5 to save it and press F6 to restore it.