   :type 'boolean
   :group 'ledger-post)
 
+(defcustom ledger-post-amount-alignment-column 52
+  "If non-nil, ."
+  :type 'integer
+  :group 'ledger-post)
+
+(defcustom ledger-post-use-iswitchb nil
+  "If non-nil, ."
+  :type 'boolean
+  :group 'ledger-post)
+
+(defcustom ledger-post-use-ido nil
+  "If non-nil, ."
+  :type 'boolean
+  :group 'ledger-post)
+
+(defun ledger-post-all-accounts ()
+  (let ((origin (point))
+	(ledger-post-list nil)
+	account elements)
+    (save-excursion
+      (goto-char (point-min))
+      (while (re-search-forward ledger-post-line-regexp nil t)
+	(unless (and (>= origin (match-beginning 0))
+		     (< origin (match-end 0)))
+	  (add-to-list 'ledger-post-list (ledger-regex-post-line-account))))
+      (nreverse ledger-post-list))))
+
 (declare-function iswitchb-read-buffer "iswitchb"
                   (prompt &optional default require-match start matches-set))
 (defvar iswitchb-temp-buflist)
-
-(defvar ledger-post-current-list nil)
-
-(defun ledger-post-find-all ()
-  (let ((origin (point))
-	(ledger-post-list nil)
-	account-path elements)
-    (save-excursion
-      (goto-char (point-min))
-      (while (re-search-forward
-	      "^[ \t]+\\([*!]\\s-+\\)?[[(]?\\(.+?\\)\\(\t\\|\n\\| [ \t]\\)" nil t)
-	(unless (and (>= origin (match-beginning 0))
-		     (< origin (match-end 0)))
-	  (setq account-path (match-string-no-properties 2))
-	  (unless (string-match "\\`\\s-*;" account-path)
-	    (add-to-list 'ledger-post-list account-path))))
-      (setq ledger-post-current-list
-	    (nreverse ledger-post-list)))))
 
 (defun ledger-post-completing-read (prompt choices)
   "Use iswitchb as a completing-read replacement to choose from choices.
 PROMPT is a string to prompt with.  CHOICES is a list of strings
 to choose from."
-  (let* ((iswitchb-use-virtual-buffers nil)
-	 (iswitchb-make-buflist-hook
-	  (lambda ()
-	    (setq iswitchb-temp-buflist choices))))
-    (iswitchb-read-buffer prompt)))
+  (cond
+   (ledger-post-use-iswitchb
+    (let* ((iswitchb-use-virtual-buffers nil)
+	   (iswitchb-make-buflist-hook
+	    (lambda ()
+	      (setq iswitchb-temp-buflist choices))))
+      (iswitchb-read-buffer prompt)))
+   (ledger-post-use-ido
+    (ido-completing-read prompt choices))
+   (t
+    (completing-read prompt choices))))
+
+(defvar ledger-post-current-list nil)
 
 (defun ledger-post-pick-account ()
   (interactive)
   (let* ((account
-	  (ledger-post-completing-read "Account: "
-					  (or ledger-post-current-list
-					      (ledger-post-find-all))))
+	  (ledger-post-completing-read
+	   "Account: " (or ledger-post-current-list
+			   (setq ledger-post-current-list
+				 (ledger-post-all-accounts)))))
 	 (account-len (length account))
 	 (pos (point)))
     (goto-char (line-beginning-position))
     (when (re-search-forward ledger-post-line-regexp (line-end-position) t)
-      (let ((existing-len (length (match-string 3))))
-	(goto-char (match-beginning 3))
-	(delete-region (match-beginning 3) (match-end 3))
+      (let ((existing-len (length (ledger-regex-post-line-account))))
+	(goto-char (match-beginning ledger-regex-post-line-group-account))
+	(delete-region (match-beginning ledger-regex-post-line-group-account)
+		       (match-end ledger-regex-post-line-group-account))
 	(insert account)
 	(cond
 	 ((> existing-len account-len)

	    (if (looking-at "[ \t]\\( [ \t]\\|\t\\)")
		(delete-char 1)))))))
    (goto-char pos)))

(defun ledger-post-align-amount ()
  (interactive)

  (when (re-search-backward ledger-xact-line-regexp nil t)
    (goto-char (match-beginning 0))
    (re-search-forward ledger-post-line-regexp)
    (goto-char (match-end ledger-regex-post-line-group-account))))

(defun ledger-post-next-xact ()
  (interactive)
  (when (re-search-forward ledger-xact-line-regexp nil t)
    (goto-char (match-beginning 0))
    (re-search-forward ledger-post-line-regexp)
    (goto-char (match-end ledger-regex-post-line-group-account))))

(defun ledger-post-setup ()
  (let ((map (current-local-map)))
