| 3 |
;; Copyright (C) 2004 Masatake YAMATO and Hideyuki SHIRAI |
;; Copyright (C) 2004 Masatake YAMATO and Hideyuki SHIRAI |
| 4 |
|
|
| 5 |
;; Author: Masatake YAMATO <jet@gyve.org> and |
;; Author: Masatake YAMATO <jet@gyve.org> and |
| 6 |
;; Hideyuki SHIRAI <shirai@meadowy.org> |
;; Hideyuki SHIRAI <shirai@meadowy.org> |
| 7 |
|
|
| 8 |
;; This file is free software; you can redistribute it and/or modify |
;; This file is free software; you can redistribute it and/or modify |
| 9 |
;; it under the terms of the GNU General Public License as published by |
;; it under the terms of the GNU General Public License as published by |
| 39 |
;; kogiku.elはmigemo.el及びGNU Emacs 21に依存しています。migemo.elの |
;; kogiku.elはmigemo.el及びGNU Emacs 21に依存しています。migemo.elの |
| 40 |
;; 動作をまず確認して下さい。kogiku.elをロードパスが通って通っている |
;; 動作をまず確認して下さい。kogiku.elをロードパスが通って通っている |
| 41 |
;; ディレクトリに置き.emacsに (require 'kogiku)と書き加えてemacsを再 |
;; ディレクトリに置き.emacsに (require 'kogiku)と書き加えてemacsを再 |
| 42 |
;; 起動します。migemoは http://migemo.namazu.rog から入手できます。 |
;; 起動します。migemoは http://migemo.namazu.org から入手できます。 |
| 43 |
|
|
| 44 |
;;; Acknowledgments: |
;;; Acknowledgments: |
| 45 |
|
|
| 74 |
"reading file and directory name with migemo service" |
"reading file and directory name with migemo service" |
| 75 |
:group 'convenience) |
:group 'convenience) |
| 76 |
|
|
| 77 |
(defcustom kogiku-enable-once nil |
(defcustom kogiku-enable-once t |
| 78 |
"*If non-nil, kogiku effects a one time when call with a prefix argument. |
"*If non-nil, kogiku effects a one time when call with a prefix argument. |
| 79 |
If nil, kogiku toggle with a prefix argument." |
If nil, kogiku toggle with a prefix argument." |
| 80 |
:group 'kogiku |
:group 'kogiku |
| 98 |
:group 'kogiku |
:group 'kogiku |
| 99 |
:type 'string) |
:type 'string) |
| 100 |
|
|
| 101 |
(defcustom kogiku-minibuffer-indicator-strings '("ON" "off" "ONESHOT") |
(defcustom kogiku-minibuffer-indicator-strings '("ON" "Fire") |
| 102 |
"*Indicators in minibuffer prpmpt." |
"*Indicators in minibuffer prpmpt." |
| 103 |
:group 'kogiku |
:group 'kogiku |
| 104 |
:type '(list (string :tag "Toggle-mode ON") |
:type '(list (string :tag "Kogiku-mode") |
|
(string :tag "Toggle-mode off") |
|
| 105 |
(string :tag "Oneshot-mode"))) |
(string :tag "Oneshot-mode"))) |
| 106 |
|
|
| 107 |
|
(defcustom kogiku-use-advocate t |
| 108 |
|
"*Use kogiku `advocate' mode." |
| 109 |
|
:group 'kogiku |
| 110 |
|
:type 'boolean) |
| 111 |
|
|
| 112 |
(defface kogiku-indicator-face |
(defface kogiku-indicator-face |
| 113 |
'((((class color) (type tty)) (:foreground "blue" :bold t)) |
'((((class color) (type tty)) (:foreground "blue" :bold t)) |
| 114 |
(((class color) (background light)) (:foreground "dark blue" :bold t)) |
(((class color) (background light)) (:foreground "dark blue" :bold t)) |
| 117 |
"*Face of kogiku indicator." |
"*Face of kogiku indicator." |
| 118 |
:group 'kogiku) |
:group 'kogiku) |
| 119 |
|
|
| 120 |
|
(defface kogiku-indicator-advocate-face |
| 121 |
|
'((((class color) (type tty)) (:foreground "red" :bold t)) |
| 122 |
|
(((class color) (background light)) |
| 123 |
|
(:foreground "firebrick" :background "pink" :bold t)) |
| 124 |
|
(((class color) (background dark)) |
| 125 |
|
(:foreground "pink" :background "firebrick" :bold t)) |
| 126 |
|
(t (:inverse-video t :bold t))) |
| 127 |
|
"*Face of kogiku indicator." |
| 128 |
|
:group 'kogiku) |
| 129 |
|
|
| 130 |
(defvar kogiku-original-functions nil) |
(defvar kogiku-original-functions nil) |
| 131 |
(defvar kogiku-original-completion-tables nil) |
(defvar kogiku-original-completion-tables nil) |
| 132 |
|
|
| 135 |
(defvar kogiku-mode-change-original-functions nil) |
(defvar kogiku-mode-change-original-functions nil) |
| 136 |
|
|
| 137 |
(defvar kogiku-emacs21-p (fboundp 'field-beginning)) |
(defvar kogiku-emacs21-p (fboundp 'field-beginning)) |
| 138 |
|
(defvar kogiku-minibuffer-prompt-advocate-files nil) |
| 139 |
(defun kogiku-complete (&optional arg) |
(defvar kogiku-migemo-pattern-alist nil) |
| 140 |
(interactive "P") |
(defvar kogiku-migemo-pattern-alist-length 128) |
|
(if kogiku-enable-once |
|
|
(kogiku-oneshot-complete arg) |
|
|
(kogiku-complete-with-toggle arg))) |
|
|
|
|
|
(defun kogiku-oneshot-complete (fire) |
|
|
(let ((minibuffer-completion-table minibuffer-completion-table)) |
|
|
(when fire |
|
|
(setq minibuffer-completion-table 'kogiku-read-file-name-internal)) |
|
|
(prog1 |
|
|
(funcall (car kogiku-original-functions)) |
|
|
(kogiku-minibuffer-prompt)))) |
|
|
|
|
|
(defun kogiku-complete-with-toggle (switch) |
|
|
(cond |
|
|
((and switch |
|
|
(eq minibuffer-completion-table 'kogiku-read-file-name-internal)) |
|
|
(setq minibuffer-completion-table (car kogiku-original-completion-tables)) |
|
|
(kogiku-minibuffer-prompt)) |
|
|
(switch |
|
|
(setq minibuffer-completion-table 'kogiku-read-file-name-internal) |
|
|
(kogiku-minibuffer-prompt))) |
|
|
(prog1 |
|
|
(funcall (car kogiku-original-functions)) |
|
|
(kogiku-minibuffer-prompt))) |
|
| 141 |
|
|
| 142 |
(defvar kogiku-minibuffer-prompt-map nil |
(defvar kogiku-minibuffer-prompt-map nil |
| 143 |
"kogiku prompt map for mode change.") |
"kogiku prompt map for mode change.") |
| 146 |
(define-key map [mouse-2] 'kogiku-mode-change-at-mouse) |
(define-key map [mouse-2] 'kogiku-mode-change-at-mouse) |
| 147 |
(setq kogiku-minibuffer-prompt-map map)) |
(setq kogiku-minibuffer-prompt-map map)) |
| 148 |
|
|
| 149 |
(defun kogiku-minibuffer-prompt () |
(if kogiku-emacs21-p |
| 150 |
(let* ((mode (cond |
(defalias 'kogiku-field-beginning 'field-beginning) |
| 151 |
(kogiku-enable-once |
(defalias 'kogiku-field-beginning 'point-min)) |
| 152 |
(nth 2 kogiku-minibuffer-indicator-strings)) |
|
| 153 |
((eq minibuffer-completion-table 'kogiku-read-file-name-internal) |
(defun kogiku-complete (&optional arg) |
| 154 |
(nth 0 kogiku-minibuffer-indicator-strings)) |
(interactive "P") |
| 155 |
(t |
(let ((minibuffer-completion-table minibuffer-completion-table)) |
| 156 |
(nth 1 kogiku-minibuffer-indicator-strings)))) |
(when (or (and kogiku-enable-once arg) |
| 157 |
(indicator |
(not (or kogiku-enable-once arg))) |
| 158 |
(if kogiku-emacs21-p |
(setq minibuffer-completion-table 'kogiku-read-file-name-internal)) |
| 159 |
(format "[%s:%s] " kogiku-minibuffer-prompt-string mode) |
(funcall (car kogiku-original-functions)))) |
|
(format "%s(%s): " kogiku-minibuffer-prompt-string mode))) |
|
|
(max (if kogiku-emacs21-p (1+ (point-min)) (point-max)))) |
|
|
(when kogiku-emacs21-p |
|
|
(add-text-properties 0 (1- (length indicator)) |
|
|
'(face kogiku-indicator-face) |
|
|
indicator) |
|
|
(add-text-properties 0 (length indicator) |
|
|
`(local-map |
|
|
,kogiku-minibuffer-prompt-map |
|
|
mouse-face |
|
|
highlight) |
|
|
indicator)) |
|
|
(if kogiku-minibuffer-prompt-overlay |
|
|
(move-overlay kogiku-minibuffer-prompt-overlay |
|
|
(point-min) max) |
|
|
(setq kogiku-minibuffer-prompt-overlay |
|
|
(make-overlay (point-min) max))) |
|
|
(overlay-put kogiku-minibuffer-prompt-overlay |
|
|
'before-string indicator) |
|
|
(overlay-put kogiku-minibuffer-prompt-overlay 'evaporate t) |
|
|
indicator)) |
|
| 160 |
|
|
| 161 |
(if (fboundp 'compare-strings) |
(if (fboundp 'compare-strings) |
| 162 |
(defalias 'kogiku-compare-strings 'compare-strings) |
(defalias 'kogiku-compare-strings 'compare-strings) |
| 197 |
|
|
| 198 |
(defun kogiku-migemo-get-pattern (string) |
(defun kogiku-migemo-get-pattern (string) |
| 199 |
(let ((migemo-pattern-alist migemo-pattern-alist) |
(let ((migemo-pattern-alist migemo-pattern-alist) |
| 200 |
(migemo-white-space-regexp " *")) |
(migemo-white-space-regexp " *") |
| 201 |
|
pattern) |
| 202 |
(let ((case-fold-search nil)) |
(let ((case-fold-search nil)) |
| 203 |
(while (string-match "[^a-zA-Z]\\([a-z]+\\)" string) |
(while (string-match "[^a-zA-Z]\\([a-z]+\\)" string) |
| 204 |
(setq string |
(setq string |
| 205 |
(replace-match (capitalize (match-string 1 string)) nil nil string 1)))) |
(replace-match (capitalize (match-string 1 string)) nil nil string 1)))) |
| 206 |
(migemo-get-pattern string))) |
(if (setq pattern (assoc string kogiku-migemo-pattern-alist)) |
| 207 |
|
(prog1 |
| 208 |
|
(cdr pattern) |
| 209 |
|
(setq kogiku-migemo-pattern-alist |
| 210 |
|
(cons pattern |
| 211 |
|
(delete pattern kogiku-migemo-pattern-alist)))) |
| 212 |
|
(prog1 |
| 213 |
|
(setq pattern (migemo-get-pattern string)) |
| 214 |
|
(setq kogiku-migemo-pattern-alist |
| 215 |
|
(cons (cons string pattern) kogiku-migemo-pattern-alist)) |
| 216 |
|
(when (> (length kogiku-migemo-pattern-alist) |
| 217 |
|
kogiku-migemo-pattern-alist-length) |
| 218 |
|
(setcdr |
| 219 |
|
(nthcdr (1- kogiku-migemo-pattern-alist-length) kogiku-migemo-pattern-alist) |
| 220 |
|
nil)))))) |
| 221 |
|
|
| 222 |
(defun kogiku-file-name-completion (string dir &optional all) |
(defun kogiku-file-name-completion (string dir &optional all) |
| 223 |
(let* ((expanded-string (expand-file-name string dir)) |
(let* ((expanded-string (expand-file-name string dir)) |
| 331 |
|
|
| 332 |
(defun kogiku-mode-change () |
(defun kogiku-mode-change () |
| 333 |
(interactive) |
(interactive) |
| 334 |
;; Cyclic: on-off, off->oneshot, oneshot->on |
(setq kogiku-enable-once (not kogiku-enable-once))) |
| 335 |
(let ((nextmode (cond |
|
| 336 |
(kogiku-enable-once 'on) |
(defun kogiku-minibuffer-prompt () |
| 337 |
((eq minibuffer-completion-table |
(when (and (window-minibuffer-p (selected-window)) |
| 338 |
'kogiku-read-file-name-internal) 'off) |
(not (input-pending-p))) |
| 339 |
(t 'oneshot)))) |
(let* ((advocate (and kogiku-use-advocate |
| 340 |
(cond |
(kogiku-minibuffer-prompt-advocate))) |
| 341 |
((eq nextmode 'on) |
(mode (if kogiku-enable-once |
| 342 |
(setq kogiku-enable-once nil) |
(nth 1 kogiku-minibuffer-indicator-strings) |
| 343 |
(setq minibuffer-completion-table 'kogiku-read-file-name-internal)) |
(nth 0 kogiku-minibuffer-indicator-strings))) |
| 344 |
((eq nextmode 'off) |
(indicator |
| 345 |
(setq kogiku-enable-once nil) |
(cond |
| 346 |
(setq minibuffer-completion-table (car kogiku-original-completion-tables))) |
((and kogiku-emacs21-p advocate) |
| 347 |
(t ;; oneshot |
(format "<%s:%s> " kogiku-minibuffer-prompt-string mode)) |
| 348 |
(setq kogiku-enable-once t) |
(kogiku-emacs21-p |
| 349 |
(setq minibuffer-completion-table (car kogiku-original-completion-tables)))) |
(format "[%s:%s] " kogiku-minibuffer-prompt-string mode)) |
| 350 |
(kogiku-minibuffer-prompt))) |
(advocate |
| 351 |
|
(format "%s<%s>: " kogiku-minibuffer-prompt-string mode)) |
| 352 |
|
(t |
| 353 |
|
(format "%s(%s): " kogiku-minibuffer-prompt-string mode)))) |
| 354 |
|
(max (if kogiku-emacs21-p (1+ (point-min)) (point-max))) |
| 355 |
|
(force (and (not kogiku-emacs21-p) (eq (point-min) max)))) |
| 356 |
|
(when force |
| 357 |
|
(insert " ") |
| 358 |
|
(goto-char (point-min)) |
| 359 |
|
(setq max (point-max))) |
| 360 |
|
(when kogiku-emacs21-p |
| 361 |
|
(add-text-properties 0 (1- (length indicator)) |
| 362 |
|
`(face ,(if advocate |
| 363 |
|
'kogiku-indicator-advocate-face |
| 364 |
|
'kogiku-indicator-face)) |
| 365 |
|
indicator) |
| 366 |
|
(add-text-properties 0 (length indicator) |
| 367 |
|
`(local-map |
| 368 |
|
,kogiku-minibuffer-prompt-map |
| 369 |
|
mouse-face |
| 370 |
|
highlight) |
| 371 |
|
indicator)) |
| 372 |
|
(if kogiku-minibuffer-prompt-overlay |
| 373 |
|
(move-overlay kogiku-minibuffer-prompt-overlay |
| 374 |
|
(point-min) max) |
| 375 |
|
(setq kogiku-minibuffer-prompt-overlay |
| 376 |
|
(make-overlay (point-min) max))) |
| 377 |
|
(overlay-put kogiku-minibuffer-prompt-overlay |
| 378 |
|
'before-string indicator) |
| 379 |
|
(overlay-put kogiku-minibuffer-prompt-overlay 'evaporate t) |
| 380 |
|
(when force |
| 381 |
|
(let ((inhibit-quit t)) |
| 382 |
|
(sit-for 60) |
| 383 |
|
(delete-region (point-min) (point-max)))) |
| 384 |
|
indicator))) |
| 385 |
|
|
| 386 |
|
(defun kogiku-minibuffer-prompt-advocate () |
| 387 |
|
(when (and (window-minibuffer-p (selected-window)) |
| 388 |
|
(not (input-pending-p))) |
| 389 |
|
(let* ((full (buffer-substring-no-properties |
| 390 |
|
(kogiku-field-beginning) (point-max))) |
| 391 |
|
(dir (or (file-name-directory full) default-directory)) |
| 392 |
|
(file (file-name-nondirectory full)) |
| 393 |
|
(files (cdr (assoc dir kogiku-minibuffer-prompt-advocate-files))) |
| 394 |
|
(count 0) |
| 395 |
|
(kcount 0) |
| 396 |
|
(case-fold-search completion-ignore-case) |
| 397 |
|
fileregex tmpfiles host) |
| 398 |
|
(catch 'advocate |
| 399 |
|
(unless (and (not files) |
| 400 |
|
(or (not (eq (point) (point-max))) |
| 401 |
|
(and (string-match "^\\(/[^/]+:\\)\\|\\(//[^/]+/[^/]+\\)" dir) |
| 402 |
|
(setq host (concat "^" (regexp-quote (match-string 0 dir)))) |
| 403 |
|
(not (string-match host default-directory))))) |
| 404 |
|
(unless (or (input-pending-p) |
| 405 |
|
(not (and (file-exists-p dir) (file-directory-p dir)))) |
| 406 |
|
(unless files |
| 407 |
|
(setq files (directory-files dir nil nil 'nosort)) |
| 408 |
|
(setq kogiku-minibuffer-prompt-advocate-files |
| 409 |
|
(cons (cons dir files) kogiku-minibuffer-prompt-advocate-files))) |
| 410 |
|
(if (or (and (string= file "") (setq fileregex "^\\cj")) |
| 411 |
|
(and (string-match "\\cj$" file) |
| 412 |
|
(setq fileregex (concat "^" (regexp-quote file) "\\cj")))) |
| 413 |
|
(while (and files (not (input-pending-p))) |
| 414 |
|
(when (string-match fileregex (car files)) |
| 415 |
|
(throw 'advocate t)) |
| 416 |
|
(setq files (cdr files))) |
| 417 |
|
(unless (input-pending-p) |
| 418 |
|
(setq tmpfiles files) |
| 419 |
|
(setq fileregex (concat "^" (regexp-quote file) "\\Cj" |
| 420 |
|
"\\|^" (regexp-quote file) "$")) |
| 421 |
|
(while (and tmpfiles (not (input-pending-p))) |
| 422 |
|
(when (string-match fileregex (car tmpfiles)) |
| 423 |
|
(setq count (1+ count))) |
| 424 |
|
(setq tmpfiles (cdr tmpfiles))) |
| 425 |
|
(unless (input-pending-p) |
| 426 |
|
(setq fileregex |
| 427 |
|
(concat "^\\(" |
| 428 |
|
(if (string-match "^\\(\\(\\Cj*\\)?\\cj+\\)\\(\\Cj+\\)$" file) |
| 429 |
|
(concat (match-string 1 file) |
| 430 |
|
"\\(" |
| 431 |
|
(kogiku-migemo-get-pattern (match-string 3 file)) |
| 432 |
|
"\\)") |
| 433 |
|
(kogiku-migemo-get-pattern file)) |
| 434 |
|
"\\)")) |
| 435 |
|
(while (and (<= kcount count) |
| 436 |
|
files (not (input-pending-p))) |
| 437 |
|
(when (string-match fileregex (car files)) |
| 438 |
|
(setq kcount (1+ kcount))) |
| 439 |
|
(setq files (cdr files))) |
| 440 |
|
(> kcount count)))))))))) |
| 441 |
|
|
| 442 |
(defun kogiku-install-key () |
(defun kogiku-install-key () |
| 443 |
(when (memq minibuffer-completion-table kogiku-take-over-targets) |
(when (memq minibuffer-completion-table kogiku-take-over-targets) |
| 456 |
(push cfunc kogiku-mode-change-original-functions)) |
(push cfunc kogiku-mode-change-original-functions)) |
| 457 |
(define-key (current-local-map) kogiku-completion-key 'kogiku-complete) |
(define-key (current-local-map) kogiku-completion-key 'kogiku-complete) |
| 458 |
(define-key (current-local-map) kogiku-mode-change-key 'kogiku-mode-change) |
(define-key (current-local-map) kogiku-mode-change-key 'kogiku-mode-change) |
| 459 |
|
(setq kogiku-minibuffer-prompt-advocate-files nil) |
| 460 |
|
(add-hook 'post-command-hook 'kogiku-minibuffer-prompt) |
| 461 |
(kogiku-minibuffer-prompt)))) |
(kogiku-minibuffer-prompt)))) |
| 462 |
|
|
| 463 |
(add-hook 'minibuffer-setup-hook 'kogiku-install-key) |
(add-hook 'minibuffer-setup-hook 'kogiku-install-key) |
| 472 |
(when (eq (lookup-key (current-local-map) kogiku-mode-change-key) |
(when (eq (lookup-key (current-local-map) kogiku-mode-change-key) |
| 473 |
'kogiku-mode-change) |
'kogiku-mode-change) |
| 474 |
(define-key (current-local-map) kogiku-mode-change-key |
(define-key (current-local-map) kogiku-mode-change-key |
| 475 |
(pop kogiku-mode-change-original-functions))))) |
(pop kogiku-mode-change-original-functions)))) |
| 476 |
|
(setq kogiku-minibuffer-prompt-advocate-files nil) |
| 477 |
|
(remove-hook 'post-command-hook 'kogiku-minibuffer-prompt)) |
| 478 |
|
|
| 479 |
(add-hook 'minibuffer-exit-hook 'kogiku-uninstall-key) |
(add-hook 'minibuffer-exit-hook 'kogiku-uninstall-key) |
| 480 |
|
|