majuscule

Tuesday, September 02, 2008

Mac OS X Web Programmers Toolkit

Free (gratis)

  • Fugu - Secure FTP. SCP etc. Hasn't really been updated in a while but it works pretty well. Allows you to edit remote files with your favorite local text editor.
  • TextWrangler - Decent text editor from the makers of BBEdit. Major deficiency is that it doesn't support nested languages (e.g. Javascript within HTML, HTML within PHP, etc.).
  • RegExhibit - Interactively test regular expressions
  • Locomotive - Ruby on Rails in a box. A single standalone application that includes Ruby, MySQL, a web server, and an application to manage them all.
  • MySQL 5.0
  • PostgreSQL
  • CocoaMySQL
  • Aquamacs Emacs - Holy union of emacs and Aqua. Normal emacs key bindings work (e.g. C-e end of line). Normal Aqua keybindings work (e.g. Cmd-a select all). Includes various elisp functions to bring emacs closer to the 21st century. All in a nice OS X native application with lots of polish.

Not Free

  • TextMate - Best text editor ever. (Sorry emacs).
  • Transmit - Best FTP/SFTP/SCP client ever. Allows me to edit remote filew seemlessly with TextMate. These days I'm often connected to the internet intermittently or with high latency. Editing files in this idiom (which seems to be almost unique to the Mac) is the best way around that.

Tuesday, August 26, 2008

emacs deficiencies

I want to like emacs more than I do. But it's hard. It's missing all kinds of features that I've gotten used to from more modern text editors. There are many basic operations that, although common in other editing programs and easy enough to implement in emacs-lisp, have never found their way into standard emacs. For instance, why aren't there built-in functions for:

  • count-words-[buffer|region]
  • unfill-paragraph
  • kill-entire-line (this function is standard in xemacs)
  • kill-to-beginning-of-line (equivalent to M-0 C-k)

I mean honestly, it's the feakin' 21st century here. It's not like counting the number of words in your buffer is a fringe use-case.

Also, how hard would it be to support soft-wrapped text? And why can't I bind commands to the capital letter key combos (e.g. C-N in addition to C-n)? longlines-mode will get you a close-enough approximation of soft-wrapped text and it should be possible to bind commands with the shift modifier. I just can't get it working on my Mac but I think it's a Terminal.app configuration issue.

The biggest issue I have with emacs however is that it doesn't support multiple major modes at once. This is a big problem for anyone programming with embedded languages – particularly web programmers – as it means that when you're editing HTML with Javascript or CSS, emacs can only be in one (major) mode at a time. So even if it has support for all the different languages in a given buffer, emacs can't switch modes as you move around in the buffer from one language section to another.

There is a project called MMM (Multiple Major Modes) that's trying (or tried, it hasn't been updated since 2004) to remedy that problem but it's an add-on, has limited language support, and requires customization for every language combination that you want to use.

Okay, enough with the complaining. Let's try something a little more constructive. Here are some useful bits of emacs-lisp to rectify some of my complaints. I found all of them with Google so I can't take credit for anything below. Apologies for the line truncation that's happening in the <pre> tags. Something lame with blogspot templates going on there.

Kill Away

(defun unfill-paragraph ()
  (interactive)
  (let ((fill-column (point-max)))
  (fill-paragraph nil)))

;; No longer neccessary. See update below
(defun kill-entire-line ()
  "Kill this entire line (including newline), 
regardless of where point is within the line."
  (setq kill-whole-line t)
  (interactive)
  (beginning-of-line)
  (kill-line)
  (setq kill-whole-line nil))

;; If you care to bind it
(global-set-key [(control ,)] 'kill-entire-line)

Counting words

;; This one is nice and simple but has a 
;; slightly awkward output. E.g.
;; Word count: 325 occurances.
(defun wc ()
  (interactive)
  (message "Word count: %s" 
           (how-many "\\w+" 
                     (point-min) (point-max))))

;; Nice version from Robert J. Chassell's 
;; /Programming in Emacs Lisp/
;; Available at http://www.gnu.org/software/emacs/emacs-lisp-intro/
(defun count-words-region (beginning end)
  "Print number of words in the region."
  (interactive "r")
  (message "Counting words in region ... ")

;;; 1. Set up appropriate conditions.
  (save-excursion
    (let ((count 0))
      (goto-char beginning)

;;; 2. Run the while loop.
      (while (and (< (point) end)
                  (re-search-forward "\\w+\\W*" end t))
        (setq count (1+ count)))

;;; 3. Send a message to the user.
      (cond ((zerop count)
             (message
              "The region does NOT have any words."))
            ((= 1 count)
             (message
              "The region has 1 word."))
            (t
             (message
              "The region has %d words." count))))))

;; Count the words in the entire document
(defun count-words-buffer ()
  "Count all the words in the buffer"
  (interactive)
  (count-words-region (point-min) (point-max) )
)

Longlines.el (aka soft-wrap)

Most excellent elisp code to simulate soft-wrapping in emacs. Basically, hard-returns are inserted when text is loaded or typed into a buffer but all such returns are removed when the buffer is saved to disk.

Shell Mode Improvements

I have my shell set to use a colorized prompt. With default setting, emacs shell mode renders a colorized prompt pretty poorly. Amit Patel's blogI has some useful settings

(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
(setq comint-prompt-read-only t)

Update: (2008-09-09)

Well eat me and get big: emacs22 addresses some of my complaints. First, kill-entire-line is a standard command. It's supposed to be bound to C-S-<backspace> but I can't get it to work on my Mac in Terminal.app. I suspect Terminal.app is doing something non-kosher to the shift-ctrl combo but I'm not sure. In any case, it should be possible to bind commands to capital letters.

Second, longlines support is standard. M-x longlines-mode and you're set.

Haven't checked it out yet but Flymake seems like it should be awfully cool. It's supposed to do on the fly compile/syntax checking.

You can cycle through open buffers with C-x left and C-x right.

Wednesday, July 23, 2008

Where art thou iTerm?

UPDATE(2009-05-16): I found a fix for the broken meta-key problem on the iTerm bug tracker. Check out: http://sourceforge.net/tracker/index.php?func=detail&aid=1294192&group_id=67789&atid=518973

UPDATE(2008-09-26): iTerm released an update on Sept 24th. It seems to fix the mouse selection problem mentioned below but I still can't get the alt key to act as a Meta key in either local or remote connections. Key combos using alt just print out non-ASCII characters.

Leopard has a pretty decent terminal emulator in Terminal.app and I use it all the time. But before Leopard, Terminal.app left much to be desired and so I used a third party freebie called iTerm. The biggest advantage over Terminal.app was that you could open a bunch of terms in tabs instead of needing a separate window for each. Now Terminal.app has tabs and that seems to have killed interest in iTerm. As of this writing, the "News" section on the iTerm webpage hasn't had any postings in a year and a half.

I find this a little sad. iTerm still has some things going for it that haven't found their way into Terminal.app (and may never). I miss Full screen mode. I miss iTerm's ability to override the color values for ANSI colors. The default blue color (used for directories) is essentially unreadable on a black background so with iTerm I lightened up the blue. I can't do this in Terminal.app so I'm back to squinting at directory names. I also think iTerms handling of bookmarks and tabs was more intelligent than Terminal but that's almost a quibbling issue.

So why don't I still use iTerm? Three reasons. First, iTerm has weird mouse selection behavior. When you select a line of text with the mouse moving from left to right, you have to be sure to position the cursor all the way to the left of the first character you want to select. I used to end up missing the first character all the time until I managed to override my habits. Right to left selection works fine. Second, I could never get the meta/alt/option key to work correctly in remote terms. I use Meta-d and Meta-backspace in bash quite often and I could never get it to work on remote connections to my Linux machines. It's easy to get working on Terminal.app. Lastly, iTerm has never supported .term files. These are a little known secret of Terminal.app that have been around since at least 10.3 (though they may go all the way back to 10.0). They allowed me to create files that would initiate ssh connections to particular machines. I used to keep a directory in my dock with a bunch of .term files in it so that I could right-click and jump to any machine that I needed to work on. Then I started using Quicksilver and dispensed with the Dock folder altogether. I could open a new Terminal.app window with an ssh connection to my workstation just as quickly as I could type Cmd-Space ws [enter].

So iTerms's source is freely available on sourceforge. Maybe when I get several months of free time I can hack in those features. Go open source. When you find yourself frustrated with a product, all it takes is a degree in Computer Science, years of professional experience, and several months to get up to speed on a codebase.

Wednesday, July 16, 2008

ANSI Color Codes in C++

I finally got around to figuring out how to get C++ to output text in different colors (assuming your output system (terminal) supports it). It's not at all difficult , it just requires knowing the string representations of the ANSI color codes. I haven't tried it with C/printf but I can't see why it wouldn't work the same way.