auto-complete.elの欠点?を解消してみるパッチ

テキスト入力中に補完候補を自動的に表示してくれる auto-complete.el をリリースしました — ありえるえりあ
Emacs補完候補の選択を便利に - あどけない話

今話題のauto-complete.elを使ってみましたが、以下の点が使いづらく、使うのを止めてしま
いました。

・ 候補が最大10個しか出ない
  □ 10個以上の候補がある場合、次に打つべき文字が分らない
・ バッファの最下部でメニューが表示されると、勝手にスクロールされる


候補数はac-candidate-maxで設定できる。
勝手にスクロールされる問題は…うーんどうしようか。最初のバージョンではバッファの下部でメニューが表示されたとき、残りの行数分の候補しかでなかったので今のはスクロールしてまで全候補を出すようになった。 window-start/set-window-start で表示開始位置を復元するのはどうなんかなぁ。vimautocomplpop.vimではどうなっているのか。

とりあえず、表示開始位置を復元してみた。

--- auto-complete.el	2008/11/17 11:18:54	1.2
+++ auto-complete.el	2008/11/17 11:48:03
@@ -141,6 +141,9 @@
 (defvar ac-selection nil
   "Current candidate index.")
 
+(defvar ac-window-start nil
+  "Current position at which display currently starts.")
+
 (defvar ac-find-target-function 'ac-default-find-target
   "When `auto-complete-mode' finds it can start completion
 or update candidates, it will call this function to find a
@@ -181,6 +184,7 @@
 
 (defun ac-setup (point)
   "Setup popup menu."
+  (setq ac-window-start (window-start))  
   (save-excursion
     (goto-char point)
     (let ((column (current-column))
@@ -256,7 +260,7 @@
   (setq ac-candidates candidates)
   (setq ac-completing (if candidates t))
   (let ((i 0)
-        (height (ac-menu-height ac-menu)))
+        (height (ac-menu-height ac-menu))) 
     ;; show line and set string to the line
     (mapcar
      (lambda (candidate)
@@ -466,7 +470,7 @@
                          (overlay-put overlay
                                       'after-string
                                       (concat (overlay-get overlay 'prefix)
-                                              (propertize (ac-menu-create-line-string menu string) 'face (or face 'ac-menu-face))
+                                              (propertize (ac-menu-create-line-string ac-menu string) 'face (or face 'ac-menu-face))
                                               (overlay-get overlay 'postfix)))))
           (aset overlays i overlay))
         (forward-line))
@@ -479,7 +483,10 @@
 
 (defun ac-menu-delete (menu)
   "Delete `MENU'."
-  (mapcar 'delete-overlay (ac-menu-overlays menu)))
+  (let ((overlays (ac-menu-overlays menu)))
+    (when overlays
+      (mapcar 'delete-overlay overlays)
+      (set-window-start (selected-window) ac-window-start))))
 
 (provide 'auto-complete)
 ;;; auto-complete.el ends here

追記

id:ka-nachtさんよりvimのポップアップメニューは下部の領域が足りないと、上部に表示するとの情報をいただきました。ありがとうございます。
例: http://gyazo.com/68b22b87c285f16020a3d45ff627f97c.png

auto-complete.elもそれに倣って必要に応じて上に表示させてみた。今のところ、候補を絞っていくうちに現在行とメニュー表示位置がずれてしまうが、とりあえず。上のパッチとどっちがいいのかな。やっぱこっちかな。

--- auto-complete.el	2008/11/17 18:01:47	1.4
+++ auto-complete.el	2008/11/17 18:16:04
@@ -264,13 +264,6 @@
        (ac-menu-set-line-string ac-menu i candidate (if (= i ac-selection) 'ac-selection-face))
        (setq i (1+ i)))
      candidates)
-    ;; assure lines visible
-    (if (> i (-
-              (max 1 (- (window-height)
-                        (if mode-line-format 1 0)
-                        (if header-line-format 1 0)))
-              (1+ (count-lines (window-start) (point)))))
-        (recenter (- (1+ i))))
     ;; hide remaining lines
     (while (< i height)
       (ac-menu-hide-line ac-menu i)
@@ -431,7 +424,13 @@
   "Create popup menu."
   (save-excursion
     (let ((overlays (make-vector height nil)))
-      (goto-line line)
+      (if (> height (-
+                (max 1 (- (window-height)
+                          (if mode-line-format 1 0)
+                          (if header-line-format 1 0)))
+                (1+ (count-lines (window-start) (point)))))
+          (goto-line (- line (1+ height)))
+        (goto-line line))
       (dotimes (i height)
         (move-to-column column)
         (let (overlay begin w current-column prefix postfix)