2008-08-21 Monkey Encoding and SQL

Another snippet from my .emacs on the Windows machine. I think I’m going to focus on simple pieces of code, rambling style, and lazy Emacs geek culture (unlike SachaChua’s impressive collection of Emacs posts, hehe).

SachaChua

impressive collection of Emacs posts

Generally I don’t want to mess with my machine’s locale because everything else seems to work so well. But inside Emacs, I want UTF-8. Easy! The only problem is that filenames need to be compatible between Emacs and the rest of the system. Here’s how to solve that.

(prefer-coding-system 'utf-8)
(setq default-file-name-coding-system 'cp1252)

Remember last time (→ 2008-08-19 Emacs on Windows) I talked about liking C-z to toggle two tasks – usually editing and the shell (and Eshell in particular). Well, I want the same thing in SQL modes. I want to use C-z to toggle between the “SQL command line” and my SQL code buffer.

2008-08-19 Emacs on Windows

Eshell

(add-hook 'sql-mode-hook
	  (lambda ()
	    (local-set-key (kbd "C-z") 'sql-oracle)))
(add-hook 'sql-interactive-mode-hook
	  (lambda ()
	    (local-set-key (kbd "C-z") 'bury-buffer)
	    (set-process-coding-system (get-buffer-process sql-buffer) 'latin-1 'latin-1)))

Notice that last line mentioning some encoding issues? Back to the main point of this article: SQL*Plus expects me to send and read Latin-1. I guess I could fix this by setting the NLS_LANG environment variable (but only within Emacs since it works just fine outside of Emacs).

NLS_LANG

That reminds me of another SQL mode problem. When you create a new SQL buffer, it will adopt the current SQLi (the interactive buffer where your interpreter is running) as its own target buffer (to send commands to, for example). If you then kill the SQLi buffer, the original SQL buffer is using a killed buffer as its target. Bad. If you then create a new SQLi buffer, the buffer local sql-buffer variable isn’t fixed automatically. Here’s some code that does it for you:

(add-hook 'sql-interactive-mode-hook 'my-sql-set-buffer)

(defun my-sql-set-buffer ()
  (let ((new-buffer (current-buffer)))
    (dolist (buf (buffer-list))
      (with-current-buffer buf
	(unless (buffer-live-p sql-buffer)
	  (setq sql-buffer new-buffer)
	  (run-hooks 'sql-set-sqli-hook))))))

Let me go back to encoding problems... Where else do they pop up?

Strangely enough, the month names in calendar-month-name-array need to be in Latin-1. I don’t know why. That’s just what I found in my .emacs. Here goes the fix for German speakers trying to localize their calendar:

(setq calendar-week-start-day 1
      calendar-day-name-array ["Sonntag" "Montag" "Dienstag" "Mittwoch"
			       "Donnerstag" "Freitag" "Samstag"]
      calendar-month-name-array
      (apply 'vector
	     (mapcar (lambda (s)
		       (encode-coding-string s 'latin-1))
		     '("Januar" "Februar" "März" "April" "Mai"
		       "Juni" "Juli" "August" "September"
		       "Oktober" "November" "Dezember"))))

Notice that my .emacs file has this on the first line:

;;; .emacs for Alex Schroeder's machine at work -*- coding: utf-8 -*-

The coding cookie makes sure that the entire file (and the contents of all string literals) is decoded as UTF-8. Anyway, I think this might be a bug in CalendarMode. But I’m too lazy to follow up.

The SQL example is an example of an external process not using my favorite encoding. The same is true on IRC. I use rcirc as my IRC client, and the following allows Emacs to try and decode any incoming traffic using its own heuristics (MULE).

IRC

rcirc

(setq rcirc-decode-coding-system 'undecided)

As for encoding outgoing text, you can do that by setting rcirc-encode-coding-system. But doing that in a hurry sucks. So here’s a new command, `/encoding`. This code is also on rcircEncoding.

rcircEncoding

(eval-after-load 'rcirc
  '(defun-rcirc-command encoding (arg)
     "Change the encoding coding system
`rcirc-encode-coding-system' for the current buffer only."
     (interactive)
     (if (string= arg "")
	 (rcirc-print process (rcirc-nick process) "NOTICE" target
		      (symbol-name rcirc-encode-coding-system))
       (setq rcirc-encode-coding-system (intern-soft arg)))))

Notice how I use eval-after-load to delay the call to defun-rcirc-command until it will be available, avoiding the need to `(require 'rcirc)`.

Feel free to find the *Comments on 2008-08-21 Monkey Encoding and SQL* link below and ask questions or make suggestions. 😄

​#Emacs

Comments

(Please contact me if you want to remove your comment.)

I noticed the same issue with the SQLi buffer in SQL mode. I’ve always thought of brewing up patch at some point so that it DTRT.

You really use Emacs at work to crank out PL/SQL code all day? That’s wild.

– AaronHawley 2008-08-21 18:40 UTC

AaronHawley

---

Haha, not at all. The past few days I’ve been writing a Tutorial for our new development platform (Eclipse stuff), using a simple CRM example with companies, people, meetings, participants. The example uses five or six tables. My most important applications are therefore:

1. Eclipse, obviously

2. Word, which is where I write the stuff

3. [SqlMode sql-mode], in order to test simple SQL statements and insert sample rows

4. Pidgin, to keep in touch with co-workers

5. rcirc, to keep in touch with everybody else

Pidgin

rcirc

Haven’t written PL/SQL in a year, I think.

– Alex Schroeder 2008-08-21 20:28 UTC

Alex Schroeder

---

That’s good. You have your health to thank for that. PL/SQL is pretty mind numbing from my few experiences.

– AaronHawley 2008-08-28 20:25 UTC

AaronHawley

---

Hehe. I actually prefer PL/SQL to Java for stored procedures on the database because it will at least integrate seamlessly. Then again, in my free time I prefer not to use databases in the first place, haha.

– Alex Schroeder 2008-08-28 20:38 UTC

Alex Schroeder