| 120 | | (defvar plcmp-cache-installed-modules nil) |
| 121 | | (defvar plcmp-get-installed-modules-command "find `perl -e 'pop @INC; print join(q{ }, @INC);'` -name '*.pm' -type f | xargs egrep -h -o 'package [a-zA-Z0-9:]+;' | perl -nle 's/package\s+(.+);/$1/; print' | sort | uniq ") |
| 122 | | (defvar plcmp-get-installed-modules-async-command |
| 123 | | (concat plcmp-get-installed-modules-command " &")) |
| | 193 | ;;; anything's variables |
| | 194 | (defvar plcmp-anything-sources nil) |
| | 195 | (defvar plcmp-anything-enable-digit-shortcuts nil ) |
| | 196 | (defvar plcmp-anything-candidate-number-limit plcmp-anything-candidate-number-limit ) |
| | 197 | (defvar plcmp-anything-idle-delay 0.5 ) |
| | 198 | (defvar plcmp-anything-samewindow nil ) |
| | 199 | (defvar plcmp-anything-source-filter nil ) |
| | 200 | (defvar plcmp-anything-isearch-map |
| | 201 | (let ((map (copy-keymap (current-global-map)))) |
| | 202 | (define-key map (kbd "<return>") 'plcmp-anything-isearch-default-action) |
| | 203 | (define-key map (kbd "C-i") 'plcmp-anything-isearch-select-action) |
| | 204 | (define-key map (kbd "C-g") 'plcmp-anything-isearch-cancel) |
| | 205 | (define-key map (kbd "M-s") 'plcmp-anything-isearch-again) |
| | 206 | (define-key map (kbd "<backspace>") 'plcmp-anything-isearch-delete) |
| | 207 | (let ((i 32)) |
| | 208 | (while (< i 256) |
| | 209 | (define-key map (vector i) 'plcmp-anything-isearch-printing-char) |
| | 210 | (setq i (1+ i)))) |
| | 211 | map)) |
| | 212 | (defgroup plcmp-anything nil |
| | 213 | "Open plcmp-anything." :prefix "plcmp-anything-" :group 'convenience) |
| | 214 | (if (facep 'header-line) |
| | 215 | (copy-face 'header-line 'plcmp-anything-header) |
| | 216 | (defface plcmp-anything-header |
| | 217 | '((t (:bold t :underline t))) |
| | 218 | "Face for header lines in the plcmp-anything buffer." :group 'plcmp-anything)) |
| | 219 | (defvar plcmp-anything-header-face 'plcmp-anything-header ) |
| | 220 | (defface plcmp-anything-isearch-match '((t (:background "Yellow"))) |
| | 221 | "Face for isearch in the plcmp-anything buffer." :group 'plcmp-anything) |
| | 222 | (defvar plcmp-anything-isearch-match-face 'plcmp-anything-isearch-match ) |
| | 223 | (defvar plcmp-anything-iswitchb-idle-delay 1 ) |
| | 224 | (defvar plcmp-anything-iswitchb-dont-touch-iswithcb-keys nil ) |
| | 225 | (defconst plcmp-anything-buffer "*perl-completion anything*" ) |
| | 226 | (defvar plcmp-anything-selection-overlay nil ) |
| | 227 | (defvar plcmp-anything-isearch-overlay nil ) |
| | 228 | (defvar plcmp-anything-digit-overlays nil ) |
| | 229 | (defvar plcmp-anything-candidate-cache nil ) |
| | 230 | (defvar plcmp-anything-pattern "") |
| | 231 | (defvar plcmp-anything-input "") |
| | 232 | (defvar plcmp-anything-async-processes nil ) |
| | 233 | (defvar plcmp-anything-digit-shortcut-count 0 ) |
| | 234 | (defvar plcmp-anything-update-hook nil ) |
| | 235 | (defvar plcmp-anything-saved-sources nil ) |
| | 236 | (defvar plcmp-anything-saved-selection nil ) |
| | 237 | (defvar plcmp-anything-original-source-filter nil ) |
| | 238 | |
| | 239 | ;;; hack variables |
| | 240 | ;; idea: http://www.emacswiki.org/cgi-bin/wiki/RubikitchAnythingConfiguration |
| | 241 | (defvar plcmp-anything-saved-action nil |
| | 242 | "Saved value of the currently selected action by key.") |
| | 243 | |
| | 244 | (defvar plcmp-anything-matched-candidate-cache nil |
| | 245 | "(name . ((pattern . (list of string)) |
| | 246 | (pattern . (list of string)))) ") |
| | 247 | |
| | 251 | |
| | 252 | (defmacro plcmp-with-slots (struct conc-name slots &rest body) |
| | 253 | `(symbol-macrolet ,(loop for slot in slots |
| | 254 | collect `(,slot (,(intern (concat (symbol-name conc-name) (symbol-name slot))) ,struct))) |
| | 255 | ,@body)) |
| | 256 | (def-edebug-spec plcmp-with-slots (symbolp symbolp (&rest symbolp) body)) ;TODO |
| | 257 | |
| | 258 | (defmacro plcmp-with-completion-data-slots (struct slots &rest body) |
| | 259 | (declare (indent 2)) |
| | 260 | `(plcmp-with-slots ,struct plcmp-completion-data- ,slots ,@body)) |
| | 261 | (def-edebug-spec plcmp-with-completion-data-slots (symbolp (&rest symbolp) body)) |
| | 262 | |
| | 263 | (defmacro plcmp-with-gensyms (symbols &rest body) |
| | 264 | (declare (indent 1)) |
| | 265 | `(let ,(mapcar (lambda (sym) |
| | 266 | `(,sym (gensym))) |
| | 267 | symbols) |
| | 268 | ,@body)) |
| | 269 | |
| | 270 | (defmacro plcmp-my (var val &rest body) |
| | 271 | (declare (indent 2)) |
| | 272 | `(lexical-let ((,var ,val)) |
| | 273 | ,@body)) |
| | 274 | |
| | 275 | (put 'plcmp-acond 'lisp-indent-function 'defun) ;TODO |
| | 276 | (defmacro plcmp-acond (&rest clauses) |
| | 277 | (unless (null clauses) |
| | 278 | (plcmp-with-gensyms (sym) |
| | 279 | (plcmp-my clause (car clauses) |
| | 280 | `(plcmp-my ,sym ,(car clause) |
| | 281 | (if ,sym |
| | 282 | (plcmp-my it ,sym |
| | 283 | ,@(cdr clause)) ;expr |
| | 284 | (plcmp-acond ,@(cdr clauses)))))))) |
| | 285 | (def-edebug-spec plcmp-acond cond) |
| | 286 | |
| | 287 | (defsubst plcmp-trim (s) |
| | 288 | "strip space and newline" |
| | 289 | (replace-regexp-in-string |
| | 290 | "[ \t\n]*$" "" (replace-regexp-in-string "^[ \t\n]*" "" s))) |
| | 291 | |
| | 292 | (defun plcmp-get-preceding-string (&optional count) |
| | 293 | "現在の位置からcount文字前方位置までの文字列を返す |
| | 294 | 例外を出さない" |
| | 295 | (let ((count (or count 1))) |
| | 296 | (buffer-substring-no-properties |
| | 297 | (point) |
| | 298 | (condition-case nil |
| | 299 | (save-excursion (backward-char count) (point)) |
| | 300 | (error (point)))))) |
| | 301 | |
| | 302 | (defsubst plcmp-module-p (s) |
| | 303 | (string-match "^[a-zA-Z:_]+$" s)) |
| | 304 | |
| | 305 | (defsubst plcmp-perl-identifier-p (s) |
| | 306 | (string-match (concat "^" plcmp-perl-ident-re "$") s)) |
| | 307 | |
| | 308 | (defun plcmp-notfound-p (s) |
| | 309 | (string-match "^Can't locate [^ \t]+ in" s)) |
| | 310 | |
| | 311 | (defmacro plcmp-ignore-errors (&rest body) |
| | 312 | `(condition-case e (progn ,@body) |
| | 313 | (error (plcmp-log "Error plcmp-ignore-errors : %s" (error-message-string e))))) |
| | 314 | |
| | 315 | ;;; log |
| | 316 | (defvar plcmp-debug nil) |
| | 317 | (defvar plcmp-log-buf-name "*plcmp debug*") |
| | 318 | (defun plcmp-log-buf () |
| | 319 | (get-buffer-create plcmp-log-buf-name)) |
| | 320 | (defun plcmp-log (&rest messages) |
| | 321 | (ignore-errors |
| | 322 | (let* ((str (or (ignore-errors (apply 'format messages)) |
| | 323 | (prin1-to-string messages))) |
| | 324 | (strn (concat str "\n"))) |
| | 325 | (when plcmp-debug |
| | 326 | (with-current-buffer (plcmp-log-buf) |
| | 327 | (goto-char (point-max)) |
| | 328 | (insert strn))) |
| | 329 | str))) |
| | 330 | |
| | 331 | |
| | 332 | ;;;; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| | 333 | ;;;; Initialize |
| | 334 | ;;;; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| | 335 | |
| | 336 | ;; idea: http://subtech.g.hatena.ne.jp/antipop/20070917/1190009355 |
| | 337 | (defun plcmp-get-installed-modules-synchronously () |
| | 338 | (message "fetching installed modules...") |
| | 339 | (let ((modules (split-string (shell-command-to-string plcmp-get-installed-modules-command) "\n"))) |
| | 340 | (message "fetching installed modules done") |
| | 341 | (remove-if (lambda (module) |
| | 342 | (string-match "No such file or directory$" module)) |
| | 343 | modules))) |
| | 344 | |
| | 345 | (defun plcmp-get-installed-modules-from-buf (buf) |
| | 346 | (with-current-buffer buf |
| | 347 | (let ((modules (split-string (buffer-substring-no-properties (point-min) (point-max)) "\n"))) |
| | 348 | (remove-if (lambda (module) |
| | 349 | (string-match "No such file or directory$" module)) |
| | 350 | modules)))) |
| | 351 | |
| | 352 | (defun plcmp-send-command-get-installed-modules () |
| | 353 | (message "send command to get installed modules") |
| | 354 | (save-window-excursion |
| | 355 | (shell-command plcmp-get-installed-modules-async-command plcmp-installed-modules-buf-name)) |
| | 356 | (with-current-buffer plcmp-installed-modules-buf-name |
| | 357 | (setq buffer-read-only t))) |
| | 358 | |
| | 359 | (defun plcmp-fetch-installed-modules (struct) |
| | 360 | (plcmp-with-completion-data-slots struct |
| | 361 | (cache-installed-modules) |
| | 362 | (let ((buf (get-buffer plcmp-installed-modules-buf-name))) |
| | 363 | (cond |
| | 364 | ((null cache-installed-modules) |
| | 365 | (if (and (buffer-live-p buf) |
| | 366 | (not (processp (get-buffer-process buf)))) ;finished |
| | 367 | (setf cache-installed-modules (plcmp-get-installed-modules-from-buf buf)) |
| | 368 | (unless (buffer-live-p buf) |
| | 369 | (plcmp-send-command-get-installed-modules)) |
| | 370 | (plcmp-get-installed-modules-synchronously))) |
| | 371 | ;; return cache |
| | 372 | (t |
| | 373 | cache-installed-modules))))) |
| | 374 | |
| | 375 | (defun plcmp-get-current-package () |
| | 376 | "nil or string" |
| | 377 | (let ((re (concat "^[ \t]*package\\s *" "\\([a-zA-Z:]+\\)" ".*;$")) |
| | 378 | (limit 500)) |
| | 379 | (save-excursion |
| | 380 | (goto-char (point-min)) |
| | 381 | (when (re-search-forward re limit t) |
| | 382 | (match-string-no-properties 1))))) |
| | 383 | |
| 140 | | (defun plcmp-clear-cache-using-modules () |
| 141 | | (interactive) |
| 142 | | (setq plcmp-cache-using-modules nil)) |
| 143 | | |
| 144 | | |
| 145 | | (defun plcmp-modules-filter (mods) |
| 146 | | (let ((ret nil) ) |
| 147 | | (dolist (filter-mod plcmp-config-modules-filter-list ret) |
| 148 | | (setq ret (delete filter-mod mods))))) |
| 149 | | |
| 150 | | |
| 151 | | (defun plcmp-get-modules-methods-alist (using-modules) |
| 152 | | (let ((ret nil)) |
| 153 | | (cond |
| 154 | | ((and (equal using-modules plcmp-cache-using-modules) |
| 155 | | (not (null plcmp-modules-methods-alist))) |
| 156 | | (setq ret plcmp-modules-methods-alist)) |
| 157 | | ((null plcmp-modules-methods-alist) |
| 158 | | (dolist (mod using-modules) |
| 159 | | (message "getting methods of %s ..." mod) |
| 160 | | (push `(,mod . ,(plcmp-get-methods mod)) plcmp-modules-methods-alist) |
| 161 | | (message "getting methods of %s done" mod)) |
| 162 | | (setq ret plcmp-modules-methods-alist)) |
| 163 | | (t |
| 164 | | (let ((new-mods (delete-dups |
| 165 | | (set-difference using-modules plcmp-cache-using-modules :test 'string-equal))) |
| 166 | | (removed-mods (delete-dups |
| 167 | | (set-difference plcmp-cache-using-modules using-modules :test 'string-equal)))) |
| 168 | | (plcmp-log "new-mods: %S\nremoved-mods: %S" new-mods removed-mods) |
| 169 | | ;; add new |
| 170 | | (when new-mods |
| 171 | | (dolist (mod new-mods) |
| 172 | | (message "getting methods of %s ..." mod) |
| 173 | | (push `(,mod . ,(plcmp-get-methods mod)) plcmp-modules-methods-alist) |
| 174 | | (message "getting methods of %s done" mod))) |
| 175 | | ;; remove |
| 176 | | (when removed-mods |
| 177 | | (dolist (mod removed-mods) |
| 178 | | (setq plcmp-modules-methods-alist |
| 179 | | (remove (assoc mod plcmp-modules-methods-alist) plcmp-modules-methods-alist)))) |
| 180 | | (setq ret plcmp-modules-methods-alist)))) |
| 181 | | ;; set last |
| 182 | | (setq plcmp-cache-using-modules using-modules) |
| 183 | | ret |
| 184 | | )) |
| 185 | | |
| 186 | | (defun plcmp-clear-cache-modules-methods-alist () |
| 187 | | (setq plcmp-modules-methods-alist nil)) |
| 188 | | |
| 189 | | (defun plcmp-get-methods (module) |
| | 397 | ;;(plcmp-sort-methods '("_asdf" "asdf" "bsd" "_bsd" "ASDF")) |
| | 398 | ;; => ("ASDF" "asdf" "bsd" "_asdf" "_bsd") |
| | 399 | (defun plcmp-sort-methods (los) |
| | 400 | (loop for s in los |
| | 401 | if (string-match (rx bol "_") s) |
| | 402 | collect s into unders |
| | 403 | else |
| | 404 | collect s into methods |
| | 405 | finally return (nconc methods unders |
| | 406 | ;; (sort methods 'string<) |
| | 407 | ;; (sort unders 'string<) |
| | 408 | ))) |
| | 409 | |
| | 410 | (defsubst plcmp-inspect-methods (module) |
| 203 | | (split-string mods "\n")))))) |
| 204 | | |
| 205 | | (defsubst plcmp-get-modules-re () |
| 206 | | (regexp-opt plcmp-using-modules t)) |
| 207 | | |
| 208 | | ;; example |
| 209 | | ;; my $cpan = Parse::CPAN::Authors->new( $authors_file ); |
| 210 | | ;; => var = "$cpan", mod = Parse::CPAN::Authors |
| 211 | | (defun plcmp-get-obj-instance-of-module-maybe-alist () |
| 212 | | (let* ((re (plcmp-get-modules-re)) |
| 213 | | (re (concat "\\(\\$[A-Za-z_][A-Za-z_0-9]*\\)\\s *=\\s *" re)) ;perliden + usingmodule |
| 214 | | (ret nil)) |
| | 423 | (plcmp-sort-methods (split-string mods "\n"))))))) |
| | 424 | |
| | 425 | (defun plcmp-get-modules-methods (modules) |
| | 426 | "return alist" |
| | 427 | (let ((ret nil)) |
| | 428 | (dolist (mod modules ret) |
| | 429 | (message "getting methods of %s ..." mod) |
| | 430 | (push `(,mod . ,(plcmp-inspect-methods mod)) ret) |
| | 431 | (message "getting methods of %s done" mod)))) |
| | 432 | |
| | 433 | ;; TODO |
| | 434 | (defun plcmp-get-modules-methods-alist (struct) |
| | 435 | (plcmp-with-completion-data-slots struct |
| | 436 | (using-modules current-buffer) |
| | 437 | ;;`plcmp-modules-methods-alist' and `plcmp-last-using-modules' are buffer local variables |
| | 438 | (with-current-buffer current-buffer |
| | 439 | (let ((ret nil)) |
| | 440 | (cond |
| | 441 | ((and (equal using-modules plcmp-last-using-modules) |
| | 442 | (not (null plcmp-modules-methods-alist))) |
| | 443 | (setq ret plcmp-modules-methods-alist)) |
| | 444 | ;; cache not ready |
| | 445 | ((null plcmp-modules-methods-alist) |
| | 446 | (setf ret |
| | 447 | (setf plcmp-modules-methods-alist |
| | 448 | (plcmp-get-modules-methods using-modules)))) |
| | 449 | (t |
| | 450 | (let ((new-mods (delete-dups (set-difference using-modules plcmp-last-using-modules :test 'string-equal))) |
| | 451 | (removed-mods (delete-dups (set-difference plcmp-last-using-modules using-modules :test 'string-equal)))) |
| | 452 | (plcmp-log "new-mods: %S\nremoved-mods: %S" new-mods removed-mods) |
| | 453 | ;; add new |
| | 454 | (when new-mods |
| | 455 | (setq plcmp-modules-methods-alist |
| | 456 | (append plcmp-modules-methods-alist |
| | 457 | (plcmp-get-modules-methods new-mods)))) |
| | 458 | ;; remove |
| | 459 | (when removed-mods |
| | 460 | (setq plcmp-modules-methods-alist |
| | 461 | (remove-if (lambda (mod) (assoc mod plcmp-modules-methods-alist)) removed-mods))) |
| | 462 | (setq ret plcmp-modules-methods-alist)))) |
| | 463 | ;; set last |
| | 464 | (setq plcmp-last-using-modules using-modules) |
| | 465 | ret |
| | 466 | )))) |
| | 467 | |
| | 468 | (defun plcmp-get-obj-instance-of-module-maybe-alist (struct) |
| | 469 | (plcmp-with-completion-data-slots struct |
| | 470 | (using-modules) |
| | 471 | (let* ((re (regexp-opt using-modules t)) |
| | 472 | (re (concat "\\(\\$" plcmp-perl-ident-re "\\)\\s *=\\s *" re)) ;perliden + usingmodule |
| | 473 | (ret nil)) |
| | 474 | (save-excursion |
| | 475 | (goto-char (point-min)) |
| | 476 | (loop always (re-search-forward re nil t) |
| | 477 | do (let ((var (match-string-no-properties 1)) |
| | 478 | (mod (match-string-no-properties 2))) |
| | 479 | (add-to-list 'ret `(,var . ,mod))))) |
| | 480 | ret))) |
| | 481 | |
| | 482 | (defun plcmp-get-other-perl-buffers (struct) |
| | 483 | (plcmp-with-completion-data-slots struct |
| | 484 | (current-buffer) |
| | 485 | (remove current-buffer |
| | 486 | (remove-if-not (lambda (buf) |
| | 487 | (string-match "\\.p[lm]$" (buffer-name buf))) |
| | 488 | (buffer-list))))) |
| | 489 | |
| | 490 | (defun plcmp-initialize (struct) |
| | 491 | (plcmp-with-completion-data-slots struct |
| | 492 | (using-modules installed-modules current-package |
| | 493 | current-buffer obj-instance-of-module-maybe-alist |
| | 494 | current-object other-perl-buffers) |
| | 495 | ;; initialize slots |
| | 496 | (setf installed-modules (plcmp-fetch-installed-modules struct) |
| | 497 | current-buffer (current-buffer) |
| | 498 | current-package (plcmp-get-current-package) |
| | 499 | using-modules (plcmp-get-using-modules) |
| | 500 | plcmp-modules-methods-alist (plcmp-get-modules-methods-alist struct) ;buffer local variable |
| | 501 | obj-instance-of-module-maybe-alist (plcmp-get-obj-instance-of-module-maybe-alist struct) |
| | 502 | other-perl-buffers (plcmp-get-other-perl-buffers struct) |
| | 503 | current-object "") |
| | 504 | |
| | 505 | ;; initialize variable |
| | 506 | (setq plcmp-metadata-matcher |
| | 507 | (if plcmp-match-only-real-candidate |
| | 508 | plcmp-metadata-matcher-re |
| | 509 | "")) |
| | 510 | |
| | 511 | ;; get context |
| | 512 | (plcmp-get-context struct))) |
| | 513 | |
| | 514 | (defun plcmp-method-p () |
| | 515 | (let ((s (plcmp-get-preceding-string 2))) |
| | 516 | (string-equal s "->"))) |
| | 517 | |
| | 518 | (defun plcmp-get-context (struct) |
| | 519 | (plcmp-with-completion-data-slots struct |
| | 520 | (initial-input state current-object) |
| 216 | | (goto-char (point-min)) |
| 217 | | (loop always (re-search-forward re nil t) |
| 218 | | do (let ((var (match-string-no-properties 1)) |
| 219 | | (mod (match-string-no-properties 2))) |
| 220 | | (add-to-list 'ret `(,var . ,mod))))) |
| 221 | | ret)) |
| 222 | | |
| 223 | | |
| 224 | | ;; idea: http://subtech.g.hatena.ne.jp/antipop/20070917/1190009355 |
| 225 | | (defun plcmp-send-command-get-installed-modules () |
| 226 | | (save-window-excursion |
| 227 | | (shell-command plcmp-get-installed-modules-async-command plcmp-installed-modules-buf-name)) |
| 228 | | (with-current-buffer plcmp-installed-modules-buf-name |
| 229 | | (setq buffer-read-only t))) |
| 230 | | |
| 231 | | (defun plcmp-get-installed-modules () |
| 232 | | (let ((buf (get-buffer plcmp-installed-modules-buf-name))) |
| 233 | | (cond |
| 234 | | ((null plcmp-cache-installed-modules) |
| 235 | | (cond |
| 236 | | ;; コマンドの結果のバッファがある場合 |
| 237 | | ((buffer-live-p buf) |
| 238 | | (with-current-buffer buf |
| 239 | | (let* ((modules (split-string (buffer-substring-no-properties (point-min) (point-max)) "\n")) |
| 240 | | (modules (remove-if (lambda (module) |
| 241 | | (string-match "No such file or directory$" module)) |
| 242 | | modules))) |
| 243 | | ;; when process finished |
| 244 | | (unless (processp (get-buffer-process plcmp-installed-modules-buf-name)) |
| 245 | | (setq plcmp-cache-installed-modules modules)) |
| 246 | | modules))) |
| 247 | | ;; 事前にコマンドが走っていない場合はその場で同期的に習得する |
| 248 | | (t |
| 249 | | (let* ((modules (split-string (shell-command-to-string plcmp-get-installed-modules-command) "\n")) |
| 250 | | (modules (remove-if (lambda (module) |
| 251 | | (string-match "No such file or directory$" module)) |
| 252 | | modules))) |
| 253 | | (plcmp-send-command-get-installed-modules))))) |
| 254 | | ;; return cache |
| 255 | | (t |
| 256 | | plcmp-cache-installed-modules)))) |
| 257 | | |
| 258 | | (defun plcmp-clear-cache-installed-modules () |
| 259 | | (ignore-errors |
| 260 | | (setq plcmp-cache-installed-modules nil) |
| 261 | | (let ((process (get-buffer-process plcmp-installed-modules-buf-name))) |
| 262 | | (when (processp process) |
| 263 | | (kill-process (process-name process))) |
| 264 | | (plcmp-send-command-get-installed-modules)))) |
| 265 | | |
| 266 | | (defun plcmp-get-current-package () |
| 267 | | (let ((re (concat "^[ \t]*package" "\\([a-zA-Z:]+\\)" "\\s *[^;\n]*;")) |
| 268 | | (limit 500) |
| 269 | | (ret nil)) |
| 270 | | (save-excursion |
| 271 | | (goto-char (point-min)) |
| 272 | | (loop always (re-search-forward re limit t) |
| 273 | | do (add-to-list 'ret (match-string-no-properties 1)))) |
| 274 | | (plcmp-log "get-current-package: %S" ret) |
| 275 | | ret)) |
| 276 | | |
| 277 | | |
| 278 | | ;;; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 279 | | ;;; Smart dabbrev |
| 280 | | ;;; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 281 | | |
| 282 | | (defsubst plcmp-check-face (facename) |
| 283 | | "preceding-charの位置のフェイスを調べる(前の文字)" |
| 284 | | (let ((face (get-text-property (if (bobp) (point) (- (point) 1)) 'face))) |
| 285 | | ;;(plcmp-log "check-face-at-point: %s" face) |
| 286 | | (cond |
| 287 | | ((listp face) |
| 288 | | (memq facename face)) |
| 289 | | (t |
| 290 | | (eq facename face))))) |
| 291 | | |
| 292 | | (defsubst plcmp-check-face-at-point-p (facename) |
| 293 | | (let ((face (get-text-property (point) 'face))) |
| 294 | | ;;(plcmp-log "check-face-at-point: %s" face) |
| 295 | | (cond |
| 296 | | ((listp face) |
| 297 | | (memq facename face)) |
| 298 | | (t |
| 299 | | (eq facename face))))) |
| 300 | | |
| 301 | | (defsubst plcmp-bit-regep-p (s) |
| 302 | | (string-match "^[/$@%(),.?<>+!|^*';\"\\]+$" s)) |
| | 522 | (let* ((start (point)) |
| | 523 | (start-input (progn (skip-syntax-backward "w_") ;move point |
| | 524 | (buffer-substring-no-properties (point) start))) |
| | 525 | (obj-str (buffer-substring-no-properties |
| | 526 | (or (ignore-errors (save-excursion (forward-char -2) (point))) |
| | 527 | (point)) |
| | 528 | (save-excursion (or (ignore-errors (backward-sexp) |
| | 529 | (point)) |
| | 530 | (point)))))) |
| | 531 | (cond |
| | 532 | ;; $self->`!!' |
| | 533 | ((and (plcmp-method-p) ; TODO |
| | 534 | (string-match "^\\(\\$self\\|__PACKAGE__\\)$" obj-str)) |
| | 535 | (setf initial-input start-input |
| | 536 | state 'setf |
| | 537 | current-object obj-str)) |
| | 538 | ;; methods |
| | 539 | ;; Foo->`!!' |
| | 540 | ((plcmp-method-p) |
| | 541 | (setf initial-input start-input |
| | 542 | state 'methods |
| | 543 | current-object obj-str)) |
| | 544 | ;; $foo`!!' |
| | 545 | ((string-match "[$@%&]" (plcmp-get-preceding-string 1)) |
| | 546 | (save-excursion |
| | 547 | (forward-char -1) |
| | 548 | (setf initial-input (buffer-substring-no-properties start (point)) |
| | 549 | state 'globals))) |
| | 550 | ;; installed-modules |
| | 551 | ;; use Foo::Ba`!!' |
| | 552 | ((string-match "^\\s *use\\s *" (buffer-substring-no-properties (point-at-bol) (point))) |
| | 553 | (setf initial-input start-input |
| | 554 | state 'installed-modules)) |
| | 555 | ;; globals |
| | 556 | ((or (bolp) |
| | 557 | (string-match "[ \t]" (plcmp-get-preceding-string 1))) |
| | 558 | (setf initial-input start-input |
| | 559 | state 'globals)) |
| | 560 | ;; otherwise |
| | 561 | (t |
| | 562 | (setf initial-input start-input |
| | 563 | state 'globals)) |
| | 564 | ))))) |
| | 565 | |
| | 566 | ;;;; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| | 567 | ;;;; Candidates |
| | 568 | ;;;; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| | 569 | (defsubst plcmp-build-display-candidate (metadata str) |
| | 570 | (concat "[" metadata "]" " | " str)) |
| | 571 | |
| | 572 | (defsubst plcmp-get-real-candidate (display-candidate) |
| | 573 | "return string" |
| | 574 | (if (string-match (concat "^\\[[^\]\n]*\\] | " |
| | 575 | "\\(.*\\)") |
| | 576 | display-candidate) |
| | 577 | (match-string 1 display-candidate) |
| | 578 | display-candidate)) |
| | 579 | |
| | 580 | (defsubst plcmp-get-metadate-candidate (display-candidate) |
| | 581 | "return string" |
| | 582 | (if (string-match "^\\[\\([^\]\n]*\\)\\] | " display-candidate) |
| | 583 | (match-string 1 display-candidate) |
| | 584 | "")) |
| | 585 | |
| | 586 | (defun plcmp-get-modulename-candidate (struct display-candidate) |
| | 587 | (let ((metadata (plcmp-get-metadate-candidate display-candidate))) |
| | 588 | (plcmp-acond |
| | 589 | ((plcmp-get-module-and-method-by-candidate struct display-candidate) |
| | 590 | (multiple-value-bind (module method) it ;when bind, IT must be list of string '(module method) |
| | 591 | module)) |
| | 592 | (t |
| | 593 | (plcmp-get-real-candidate display-candidate))))) |
| | 594 | |
| | 595 | (defsubst plcmp-start-initial-input-p (initial-input candidate) |
| | 596 | (let ((re (concat "^" (regexp-quote initial-input)))) |
| | 597 | (string-match re candidate))) |
| | 598 | |
| | 599 | (defsubst plcmp-f |