Changeset 19697 for lang/elisp

Show
Ignore:
Timestamp:
09/22/08 02:04:26 (2 months ago)
Author:
imakado
Message:

キーバインドを追加。anything起動中のキーバインドを追加。PERL5LIBに追加する際に末尾に:が入ってしまう場合があったのに対応。非同期でインストールされているモジュールを収得する際に前回の結果がクリアされていなかったのを修正。plcmp-get-module-file-pathがフルパスを返すように。他のperlバッファから補完候補を収得する部分にキャッシュを実装。

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • lang/elisp/perl-completion/branch/1.0/perl-completion.el

    r19503 r19697  
    3030 
    3131;; TODO: 
    32 ;; set-perl5lib 
    33 ;; open doc -> occur 
    34 ;; when remote(tramp) set-perl5lib 
    3532;; plcmp-cmd-show-environment 
    3633 
     
    4340 
    4441 
    45  
    46  
     42;;; customize-variables 
    4743(defgroup perl-completion nil 
    4844  "" 
    4945  :group 'perl-completion) 
     46 
     47(defcustom plcmp-lib-directory-re "lib/" 
     48  "regexp, used in `plcmp--get-lib-path' to get library path. 
     49eg, when directory of buffer is \"~/someproject/lib/hoge.pm\" and this value is \"lib/\" 
     50set \"~/someproject/lib\" to PERL5LIB automatically during perl-completion's command invocation." 
     51    :group 'perl-completion) 
     52 
     53;;; log util 
     54(defvar plcmp-debug nil) 
     55(defvar plcmp-log-buf-name "*plcmp debug*") 
     56(defun plcmp-log-buf () 
     57  (get-buffer-create plcmp-log-buf-name)) 
     58(defsubst plcmp-log (&rest messages) 
     59  (ignore-errors 
     60    (when plcmp-debug 
     61      (require 'pp) 
     62      (let* ((str (or (ignore-errors (apply 'format messages)) 
     63                      (pp-to-string (car messages)))) 
     64             (strn (concat str "\n"))) 
     65        (with-current-buffer (plcmp-log-buf) 
     66          (goto-char (point-max)) 
     67          (insert strn)) 
     68        str)))) 
     69(defun plcmp-message (&rest args) 
     70  (when plcmp-debug 
     71    (prog1 (apply 'message args) 
     72      (apply 'plcmp-log args)))) 
     73 
    5074 
    5175;;; variables 
     
    5983                                         (regexp ,plcmp-perl-ident-re))))) 
    6084 
    61 (defvar plcmp-perl-package-re "[a-zA-Z:]+") 
     85(defvar plcmp-perl-package-re "[a-zA-Z_][a-zA-Z0-9_:]*") 
    6286 
    6387(defvar plcmp-builtin-functions 
     
    119143(defvar plcmp--cached-variables nil "list of cached variable. each variable is cleared by `plcmp-cmd-clear-all-caches'") 
    120144 
     145(defvar plcmp-clear-all-caches-hook nil 
     146  "hook run when invoke `plcmp-cmd-clear-all-caches'") 
     147 
     148 
     149;;; keymap 
     150(defvar plcmp-mode-map 
     151  (let ((map (make-sparse-keymap))) 
     152    ;; completion 
     153    (define-key map (kbd "C-RET") 'plcmp-cmd-smart-complete) 
     154    (define-key map (kbd "C-<return>") 'plcmp-cmd-smart-complete) 
     155    (define-key map (kbd "C-M-i") 'plcmp-cmd-smart-complete) 
     156    (define-key map (kbd "C-c a") 'plcmp-cmd-complete-arrays) 
     157    (define-key map (kbd "C-c i") 'plcmp-cmd-complete-modules) 
     158    (define-key map (kbd "C-c v") 'plcmp-cmd-complete-variables) 
     159    (define-key map (kbd "C-c f") 'plcmp-cmd-complete-functions) 
     160    (define-key map (kbd "C-c h") 'plcmp-cmd-complete-hashes) 
     161    (define-key map (kbd "C-c m") 'plcmp-cmd-complete-methods) 
     162    (define-key map (kbd "C-c C-c a") 'plcmp-cmd-complete-all) 
     163 
     164    ;; doc 
     165    (define-key map (kbd "C-c d") 'plcmp-cmd-show-doc) 
     166    (define-key map (kbd "C-c s") 'plcmp-cmd-show-doc-at-point) 
     167    (define-key map (kbd "C-c M") 'plcmp-cmd-menu) 
     168 
     169    ;; other 
     170    (define-key map (kbd "C-c c") 'plcmp-cmd-clear-all-caches) 
     171    (define-key map (kbd "C-c C-c s") 'plcmp-cmd-show-environment) 
     172    (define-key map (kbd "C-c C-c u") 'plcmp-cmd-update-check) 
     173    (define-key map (kbd "C-c C-c d") 'plcmp-cmd-set-additional-lib-directory) 
     174     
     175    map)) 
     176 
     177(defvar plcmp-anything-map 
     178  (let ((map (make-sparse-keymap))) 
     179      (define-key map (kbd "O") 'plcmp-acmd-occur) 
     180      (define-key map (kbd "D") 'plcmp-acmd-show-doc) 
     181      (define-key map (kbd "F") 'plcmp-acmd-open-related-file) 
     182      (define-key map (kbd "G") 'plcmp-acmd-goto-looking-point) 
     183      (define-key map (kbd "J") 'scroll-other-window) 
     184      (define-key map (kbd "K") 'scroll-other-window-down) 
     185      (define-key map (kbd "L") 'plcmp-acmd-persistent-look)       
     186      (set-keymap-parent map anything-map) 
     187       
     188      map)) 
     189 
    121190 
    122191;;; macros 
     
    125194;; idea: http://svn.coderepos.org/share/lang/elisp/set-perl5lib/set-perl5lib.el 
    126195;;       http://d.hatena.ne.jp/sun-basix/20080117/1200528765 (Japanese) 
    127 ; (buffer-file-name default-directory 
    128 (defcustom plcmp-lib-directory-re "lib/" 
    129   "regexp, used in `plcmp--get-lib-path' to get library path. 
    130 eg, when directory of buffer is \"~/someproject/lib/hoge.pm\" and this value is \"lib/\" 
    131 set \"~/someproject/lib\" to PERL5LIB automatically during perl-completion's command invocation." 
    132     :group 'perl-completion) 
    133  
    134196(defvar plcmp-additional-lib-directories nil 
    135197  "list of string(directory),each directory set to PERL5LIB during perl-completion's command invocation. 
    136198this variable is buffer local") ;buffer local 
    137199(make-variable-buffer-local 'plcmp-additional-lib-directories) 
    138  
    139200 
    140201 
     
    163224       (when additional-lib-list 
    164225         (let* ((additional-lib-str (mapconcat 'identity additional-lib-list path-separator)) 
    165                 (current-perl5lib (concat additional-lib-str path-separator old-perl5lib))) 
     226                (current-perl5lib (concat additional-lib-str path-separator old-perl5lib)) 
     227                (current-perl5lib (replace-regexp-in-string ":$" "" current-perl5lib))) 
    166228           (when (and (stringp current-perl5lib) 
    167229                      (not (equal "" current-perl5lib))) 
     
    179241       (interactive) 
    180242       (unwind-protect 
    181            (plcmp-with-set-perl5-lib 
    182             (progn (plcmp-initialize-variables) 
    183                    ,@body)) 
     243           (let ((anything-map plcmp-anything-map)) 
     244             (plcmp-with-set-perl5-lib 
     245              (progn (plcmp-initialize-variables) 
     246                     ,@body))) 
    184247         (plcmp-cleanup))))) 
    185248(put 'define-plcmp-command 'lisp-indent-function 'defun) 
     
    242305             (match-sources) 
    243306             (unmatch-sources) 
    244              (sorted-sources (loop for source in sources 
    245               if (plcmp--re-match-sources1 regexps source) 
    246               collect source into match-sources 
    247               else 
    248               collect source into unmatch-sources 
    249               finally return (if reverse 
    250                                  (nconc unmatch-sources match-sources) 
    251                                (nconc match-sources unmatch-sources))))) 
    252         (prog1 sorted-sources 
    253           (plcmp-log "plcmp-re-sort-sources: %s" sorted-sources))) 
     307             (sorted-sources 
     308              (loop for source in sources 
     309                    if (plcmp--re-match-sources1 regexps source) 
     310                    collect source into match-sources 
     311                    else 
     312                    collect source into unmatch-sources 
     313                    finally return (if reverse 
     314                                       (nconc unmatch-sources match-sources) 
     315                                     (nconc match-sources unmatch-sources))))) 
     316        sorted-sources) 
    254317    (error (plcmp-log "Error: plcmp-re-sort-sources\nregexps: %s\nsources: %s" 
    255318                      regexps 
     
    272335 
    273336 
    274 ;;; log 
    275 (defvar plcmp-debug nil) 
    276 (defvar plcmp-log-buf-name "*plcmp debug*") 
    277 (defun plcmp-log-buf () 
    278   (get-buffer-create plcmp-log-buf-name)) 
    279 (defun plcmp-log (&rest messages) 
    280   (ignore-errors 
    281     (when plcmp-debug 
    282       (require 'pp) 
    283       (let* ((str (or (ignore-errors (apply 'format messages)) 
    284                       (pp-to-string (car messages)))) 
    285              (strn (concat str "\n"))) 
    286         (with-current-buffer (plcmp-log-buf) 
    287           (goto-char (point-max)) 
    288           (insert strn)) 
    289         str)))) 
    290 (defun plcmp-message (&rest args) 
    291   (when plcmp-debug 
    292     (prog1 (apply 'message args) 
    293       (apply 'plcmp-log args)))) 
    294  
    295  
     337 
     338;;; initial-input 
    296339(defvar plcmp-initial-input "") 
    297340(defvar plcmp-real-initial-input "real initial-input if required `anything-match-plugin' initial-input is not real initial-input") 
     
    304347        (when (string-equal str "::") 
    305348          (buffer-substring-no-properties start (point))))))) 
    306            
     349 
    307350 
    308351(defun plcmp-get-initial-real-input-list () 
     
    376419(defun plcmp--installed-modules-asynchronously () 
    377420  "start process, set sentinel, return process." 
    378   (message "fetching installed modules...") 
    379   (let* ((command "find") 
    380          (args (concat "`perl -e 'pop @INC; print join(q{ }, @INC);'`" 
    381                        " -name '*.pm' -type f " 
    382                        "| xargs grep -E -h -o 'package [a-zA-Z0-9:]+;' " 
    383                        "| perl -nle 's/package\s+(.+);/$1/; print' " 
    384                        "| sort " 
    385                        "| uniq ")) 
    386          (proc (start-process-shell-command "installed perl modules" 
    387                                             plcmp-installed-modules-buffer-name 
    388                                             command 
    389                                             args))) 
    390     (set-process-sentinel proc 'plcmp--installed-modules-set-cache) 
    391     ;; return process 
    392     proc)) 
     421  (unless (plcmp-tramp-p) 
     422    (message "fetching installed modules...") 
     423    (with-current-buffer (get-buffer-create plcmp-installed-modules-buffer-name) 
     424      (erase-buffer)) 
     425    (let* ((command "find") 
     426           (args (concat "`perl -e 'pop @INC; print join(q{ }, @INC);'`" 
     427                         " -name '*.pm' -type f " 
     428                         "| xargs grep -E -h -o 'package [a-zA-Z0-9:]+;' " 
     429                         "| perl -nle 's/package\s+(.+);/$1/; print' " 
     430                         "| sort " 
     431                         "| uniq ")) 
     432           (proc (start-process-shell-command "installed perl modules" 
     433                                              plcmp-installed-modules-buffer-name 
     434                                              command 
     435                                              args))) 
     436      (set-process-sentinel proc 'plcmp--installed-modules-set-cache) 
     437      ;; return process 
     438      proc))) 
    393439 
    394440 
     
    412458(defvar plcmp-using-modules nil) 
    413459(defun plcmp-get-using-modules () 
    414   (let ((re (rx-to-string `(and bol 
    415                                 (* space) 
    416                                 "use" 
    417                                 (+ space) 
    418                                 (group  ;1 package 
    419                                  (regexp ,plcmp-perl-package-re)) 
    420                                 (* not-newline) 
    421                                 ";")))) 
    422     (plcmp-collect-matches re 1 'match-string-no-properties))) 
     460  (let ((re (rx-to-string ` (and bol 
     461                                 (* space) 
     462                                 "use" 
     463                                 (+ space) 
     464                                    (group  ;1 package 
     465                                     (regexp ,plcmp-perl-package-re)) 
     466                                    (* not-newline) 
     467                                    ";"))) 
     468        (require-re (rx-to-string `(and "require" 
     469                                        (+ space) 
     470                                        (group 
     471                                         (regexp ,plcmp-perl-package-re)))))) 
     472    (nunion (plcmp-collect-matches re 1 'match-string-no-properties) 
     473            (delete-if-not (lambda (s) 
     474                             (member s plcmp-installed-modules)) 
     475                           (plcmp-collect-matches require-re 1 'match-string-no-properties)) 
     476            :test 'string-equal))) 
    423477 
    424478;;; methods 
     
    468522    (and (stringp path) 
    469523         (file-exists-p path) 
    470          path))) 
     524         (expand-file-name path)))) 
    471525 
    472526(defun plcmp--inspect-module-scrape (module-name) 
     
    486540    (message "getting methods %s ..." module-name))) 
    487541 
    488  
    489542(defvar plcmp-module-methods-alist nil 
    490543  "alist, (module-name . (list of methods))") 
     544(add-to-list 'plcmp--cached-variables 'plcmp-module-methods-alist) 
     545 
     546 
    491547(defun plcmp-get-module-methods-alist (using-modules) 
    492548  (dolist (module-name using-modules plcmp-module-methods-alist) 
     
    499555(defvar plcmp--mk-module-source-name " Methods") 
    500556 
    501 (defun plcmp--mk-module-source (module-name) 
     557(defsubst plcmp--mk-module-source (module-name) 
    502558  (anything-aif (assoc-default module-name plcmp-module-methods-alist) 
    503559      `((name . ,(concat module-name plcmp--mk-module-source-name)) 
     
    523579                        (plcmp-open-module-file module-name 'pop-to-buffer)))) 
    524580                   ("Open module file other frame" . 
    525                   (lambda (candidate) 
    526                     (let ((module-name (plcmp-get-current-module-name))) 
    527                       (plcmp-open-module-file module-name 
    528                                               'switch-to-buffer-other-frame)))) 
     581                    (lambda (candidate) 
     582                      (let ((module-name (plcmp-get-current-module-name))) 
     583                        (plcmp-open-module-file module-name 
     584                                                'switch-to-buffer-other-frame)))) 
     585                   ("Occur module file" . 
     586                    (lambda (candidate) 
     587                      (let ((module-name (plcmp-get-current-module-name))) 
     588                        (plcmp-open-module-file module-name 
     589                                                'switch-to-buffer) 
     590                        (funcall (plcmp-get-occur-fn) 
     591                                 candidate 
     592                                  nil)))) 
    529593                   ("Add to kill-ring" . kill-new) 
    530594                   ("Insert source name" . 
     
    537601                  (with-current-buffer (anything-candidate-buffer 'global) 
    538602                    (plcmp-insert-each-line ',it)))) 
    539         (candidates-in-buffer)))) 
     603        (candidates-in-buffer) 
     604        (persistent-action . (lambda (candidate) 
     605                               (let ((module-name (plcmp-get-current-module-name))) 
     606                                 (plcmp-open-doc module-name) 
     607                                 (plcmp-re-search-forward-fontify (regexp-quote candidate))))) 
     608        ))) 
    540609 
    541610 
    542611;; plcmp-using-modules -> sources 
    543 (defun plcmp-get-methods-completion-sources (using-modules) 
     612(defun plcmp-get-sources-methods (using-modules) 
    544613  (loop for module-name in using-modules 
    545614        collect (plcmp--mk-module-source module-name))) 
     
    564633(defsubst* plcmp-get-face-words (&optional (faces '(font-lock-variable-name-face 
    565634                                                    font-lock-function-name-face))) 
    566   (let ((hash (make-hash-table :test 'equal))) 
     635  (let ((hash (make-hash-table :test 'equal)) 
     636        (ret nil)) 
    567637    (save-excursion 
    568638      (loop initially (goto-char (point-min)) 
     
    574644                            (puthash it nil hash))) 
    575645                      (goto-char next-change))) 
    576       (let ((ret)) 
    577         (maphash (lambda (k v) (push k ret)) hash) ; remove-dups 
    578         ret)))) 
    579  
    580 (defvar plcmp-current-buffer-words-alist nil 
    581   "alist, ((variable . (list of variables)) 
    582  (array . (list of arrays)) 
    583  (hash . (list of hashes)) 
    584  (functions . (list of functions)))") 
    585 (add-hook 'plcmp--command-cleanup-hook 
    586           (lambda () 
    587             (setq plcmp-current-buffer-words-alist nil))) 
    588  
    589  
    590 (defun plcmp-get-current-buffer-words-alist () 
    591   (or plcmp-current-buffer-words-alist 
    592       (let ((variables (plcmp-get-face-words '(font-lock-variable-name-face))) 
    593             (arrays (plcmp-get-face-words '(cperl-array-face))) 
    594             (hashes (plcmp-get-face-words '(cperl-hash-face))) 
    595             (functions (plcmp-get-buffer-subs))) 
    596         (setq plcmp-current-buffer-words-alist 
    597               `((variable . ,variables) 
    598                 (array . ,arrays) 
    599                 (hash . ,hashes) 
    600                 (function . ,functions)))))) 
    601  
    602 (defun plcmp-get-current-buffer-variables () 
    603   (let ((alist (plcmp-get-current-buffer-words-alist))) 
    604     (prog1 (assoc-default 'variable alist 'eq) 
    605       (plcmp-log "getting current buffer variables")))) 
    606  
    607 (defvar plcmp-anything-source-completion-current-buffer-variables 
    608   `((name . "buffer variables") 
    609     (type . plcmp-completion) 
    610     (init . (lambda () 
    611               (let ((words (plcmp-get-current-buffer-variables))) 
    612                 (with-current-buffer (anything-candidate-buffer 'global) 
    613                   (plcmp-insert-each-line words))))) 
    614     (candidates-in-buffer))) 
    615  
    616 (defun plcmp-get-current-buffer-arrays () 
    617   (let ((alist (plcmp-get-current-buffer-words-alist))) 
    618     (prog1 (assoc-default 'array alist 'eq) 
    619       (plcmp-log "getting current buffer arrays")))) 
    620  
    621 (defvar plcmp-anything-source-completion-current-buffer-arrays 
    622   `((name . "buffer arrays") 
    623     (type . plcmp-completion) 
    624     (init . (lambda () 
    625               (let ((words (plcmp-get-current-buffer-arrays))) 
    626                 (with-current-buffer (anything-candidate-buffer 'global) 
    627                   (plcmp-insert-each-line words))))) 
    628     (candidates-in-buffer))) 
    629  
    630 (defun plcmp-get-current-buffer-hashes () 
    631   (let ((alist (plcmp-get-current-buffer-words-alist))) 
    632     (prog1 (assoc-default 'hash alist 'eq) 
    633       (plcmp-log "getting current buffer hashes")))) 
    634  
    635 (defvar plcmp-anything-source-completion-current-buffer-hashes 
    636   `((name . "buffer hashes") 
    637     (type . plcmp-completion) 
    638     (init . (lambda () 
    639               (let ((words (plcmp-get-current-buffer-hashes))) 
    640                 (with-current-buffer (anything-candidate-buffer 'global) 
    641                   (plcmp-insert-each-line words))))) 
    642     (candidates-in-buffer))) 
    643  
    644 (defun plcmp-get-current-buffer-functions () 
    645   (let ((alist (plcmp-get-current-buffer-words-alist))) 
    646     (prog1 (assoc-default 'function alist 'eq) 
    647       (plcmp-log "getting current buffer functions")))) 
    648  
    649 (defvar plcmp-anything-source-completion-current-buffer-functions 
    650   `((name . "buffer functions") 
    651     (type . plcmp-completion) 
    652     (init . (lambda () 
    653               (let ((words (plcmp-get-current-buffer-functions))) 
    654                 (with-current-buffer (anything-candidate-buffer 'global) 
    655                   (plcmp-insert-each-line words))))) 
    656     (candidates-in-buffer))) 
    657  
     646      (maphash (lambda (k v) (push k ret)) hash) ; remove-dups 
     647      (nreverse ret)))) 
    658648 
    659649;;; other buffer words 
     
    669659    cperl-hash-face)) 
    670660 
    671 (defun plcmp-get-other-perl-buffers-words () 
    672   (let* ((perl-buffers (remove-if-not (lambda (buf) 
    673                                        (string-match plcmp-perl-buffer-re (buffer-name buf))) 
    674                                      (buffer-list))) 
    675          (perl-buffers (subseq perl-buffers 0 plcmp-other-perl-buffer-limit-number))) 
    676     (prog1 (loop for buffer in perl-buffers 
    677                  when (bufferp buffer) 
    678                  nconc (with-current-buffer buffer 
    679                          (plcmp-get-face-words plcmp-other-perl-buffers-words-faces))) 
    680       (plcmp-log "length of other perl-buffers: %s" (length perl-buffers))))) 
    681  
     661;; cache 
     662(defvar plcmp-buffer-tick-hash (make-hash-table :test 'equal)) 
     663(defun* plcmp-buffer-is-modified (&optional (buffer (current-buffer))) 
     664  "Return non-nil when BUFFER is modified since `anything' was invoked." 
     665  (let* ((key (concat (buffer-name buffer) 
     666                      "/" 
     667                      (anything-attr 'name))) 
     668         (source-tick (or (gethash key plcmp-buffer-tick-hash) 0)) 
     669         (buffer-tick (buffer-chars-modified-tick buffer))) 
     670    (prog1 (/= source-tick buffer-tick) 
     671      (puthash key buffer-tick plcmp-buffer-tick-hash) 
     672      (plcmp-log "plcmp-buffer-is-modified") 
     673      (plcmp-log "current-buffer: %s" buffer) 
     674      (plcmp-log "source-tick: %s\nbuffer-tick: %s" source-tick buffer-tick)))) 
     675 
     676 
     677(defvar plcmp-other-perl-buffers-cache-hash (make-hash-table :test 'equal)) 
     678(add-hook 'plcmp-clear-all-caches-hook 
     679          (lambda () 
     680            (setq plcmp-other-perl-buffers-cache-hash 
     681                  (make-hash-table :test 'equal)))) 
     682 
     683(defun plcmp-add-to-other-perl-buffers-cache-hash (source-name faces buffer-name) 
     684  (let ((hash (or (gethash source-name plcmp-other-perl-buffers-cache-hash) 
     685                  (puthash source-name 
     686                           (make-hash-table :test 'equal) 
     687                           plcmp-other-perl-buffers-cache-hash))) 
     688        (words (plcmp-get-face-words faces))) 
     689    (assert (hash-table-p hash)) 
     690    (puthash buffer-name 
     691             words 
     692             hash) 
     693    (prog1 words 
     694      (plcmp-log "\nplcmp-add-to-other-perl-buffers-cache-hash: %s" 
     695                 words)))) 
     696 
     697(defun plcmp-get-other-perl-buffers-cache (source-name buffer-name) 
     698  "return los or nil if not cache ready" 
     699  (let ((hash (gethash source-name plcmp-other-perl-buffers-cache-hash))) 
     700    (and (hash-table-p hash) 
     701         (prog1 (gethash buffer-name hash) 
     702           (plcmp-log "plcmp-get-other-perl-buffers-cache: %s" 
     703                      (gethash buffer-name hash)))))) 
     704 
     705(defun plcmp-other-perl-buffers-get-buffer-name () 
     706  "return buffer or nil" 
     707  (let ((source-name (anything-attr 'name))) 
     708    (when (string-match (rx " *" (group (* not-newline)) "*" eol) 
     709                        source-name) 
     710      (let ((buffer-name (match-string 1 source-name))) 
     711        (when (stringp buffer-name) 
     712          (let ((buffer (get-buffer buffer-name))) 
     713            (and (bufferp buffer) 
     714                 buffer))))))) 
     715 
     716(defun plcmp-other-perl-buffers-action-open-related-buffer (candidate) 
     717  (let ((buffer (plcmp-other-perl-buffers-get-buffer-name))) 
     718    (switch-to-buffer buffer))) 
     719 
     720(defun plcmp-other-perl-buffers-action-occur (candidate) 
     721  (let ((buffer (plcmp-other-perl-buffers-get-buffer-name))) 
     722    (switch-to-buffer buffer) 
     723    (funcall (plcmp-get-occur-fn) 
     724             (regexp-quote candidate) 
     725             nil))) 
    682726 
    683727(defun plcmp--mk-other-perl-buffer-source (source-name faces buffer-name) 
    684728  `((name . ,(concat source-name " *" buffer-name "*")) 
    685     (action . (("Insert" . plcmp-insert))) 
     729    (action . (("Insert" . plcmp-insert) 
     730               ("Open related buffer" . plcmp-other-perl-buffers-action-open-related-buffer) 
     731               ("Occur" . plcmp-other-perl-buffers-action-occur))) 
    686732    (init . (lambda () 
    687733              (let ((words (with-current-buffer (get-buffer ,buffer-name) 
    688                              (plcmp-get-face-words ',faces)))) 
     734                             (anything-aif (and (not (plcmp-buffer-is-modified)) 
     735                                                (plcmp-get-other-perl-buffers-cache ,source-name ,buffer-name)) 
     736                                 (prog1 it 
     737                                   (plcmp-log "return cache buffer: %s source-name: %s " 
     738                                              ,buffer-name 
     739                                              ,source-name)) 
     740                               (prog1 (plcmp-add-to-other-perl-buffers-cache-hash 
     741                                       ,source-name 
     742                                       ',faces 
     743                                       ,buffer-name) 
     744                                 (plcmp-log "modified: %s" ,buffer-name)))))) 
    689745                (with-current-buffer (anything-candidate-buffer 'global) 
    690746                  (plcmp-insert-each-line words))))) 
    691     (candidates-in-buffer))) 
     747    (candidates-in-buffer) 
     748    (persistent-action . (lambda (candidate) 
     749                           (let ((buffer (plcmp-other-perl-buffers-get-buffer-name))) 
     750                             (when (bufferp buffer) 
     751                               (switch-to-buffer buffer) 
     752                               (plcmp-re-search-forward-fontify (regexp-quote candidate)))))) 
     753    )) 
    692754 
    693755(defun plcmp--sources-other-perl-buffers (source-name faces) 
     
    706768      (plcmp-log "plcmp--sources-other-perl-buffers:") 
    707769      (plcmp-log sources)))) 
    708      
     770 
     771(defun plcmp-get-sources-other-perl-buffers-words () 
     772  (plcmp--sources-other-perl-buffers "words" plcmp-other-perl-buffers-words-faces)) 
     773 
    709774(defun plcmp-get-sources-other-perl-buffers-variable () 
    710775  (plcmp--sources-other-perl-buffers "variables" '(font-lock-variable-name-face))) 
     
    738803;;;; Document 
    739804;;;; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    740 (defvar plcmp-doc-overlay nil "overlay") 
    741 (defvar plcmp-doc-current-point nil) 
     805(defvar plcmp-look-overlay nil "overlay") 
    742806(add-hook 'plcmp--command-cleanup-hook 
    743807          (lambda () 
    744             (setq plcmp-doc-current-point nil))) 
     808            (when (overlayp plcmp-look-overlay) 
     809              (delete-overlay plcmp-look-overlay)))) 
     810 
     811(defvar plcmp-look-current-positions nil 
     812  "list of (point buffer) 
     813point, after `plcmp-re-search-forward-fontify'") 
     814(add-hook 'plcmp--command-cleanup-hook 
     815          (lambda () 
     816            (setq plcmp-look-current-positions nil))) 
    745817 
    746818(defun plcmp-re-search-forward-fontify (regexp) 
    747   (when (re-search-forward regexp nil t) 
    748     (let ((beg (match-beginning 1)) 
    749           (end (match-end 1))) 
    750       ;; remember point 
    751       (setq plcmp-doc-current-point (point)) 
     819  (if (re-search-forward regexp nil t) 
     820      (let ((beg (match-beginning 0)) 
     821            (end (match-end 0))) 
     822        ;; remember positions 
     823        (setq plcmp-look-current-positions (list (point) (current-buffer))) 
     824        (plcmp-log "plcmp-look-current-positions: %s" (list (point) (current-buffer))) 
    752825       
    753       (when (and beg end) 
    754         (if (overlayp plcmp-doc-overlay) 
    755             (move-overlay plcmp-doc-overlay beg end (current-buffer)) 
    756           (setq plcmp-doc-overlay (make-overlay beg end))) 
    757         (overlay-put plcmp-doc-overlay 'face 'highlight))))) 
    758  
     826        (when (and beg end) 
     827          (if (overlayp plcmp-look-overlay) 
     828              (move-overlay plcmp-look-overlay beg end (current-buffer)) 
     829            (setq plcmp-look-overlay (make-overlay beg end))) 
     830          (overlay-put plcmp-look-overlay 'face 'highlight) 
     831          (recenter 5))) 
     832    (goto-char (point-min)))) 
    759833 
    760834 
     
    767841        plcmp-using-modules (plcmp-get-using-modules) 
    768842        plcmp-module-methods-alist (plcmp-get-module-methods-alist plcmp-using-modules) 
    769         plcmp-obj-instance-of-module-maybe-alist (plcmp-get-obj-instance-of-module-maybe-alist plcmp-using-modules) 
    770         ) 
     843        plcmp-obj-instance-of-module-maybe-alist (plcmp-get-obj-instance-of-module-maybe-alist plcmp-using-modules)) 
    771844  (multiple-value-setq 
    772845      (plcmp-initial-input plcmp-real-initial-input) (plcmp-get-initial-real-input-list))) 
    773846