diff options
| author | Stefan Monnier | 2009-10-25 20:38:06 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2009-10-25 20:38:06 +0000 |
| commit | 2d0853070d1353348e6ef067b138d971cf52f341 (patch) | |
| tree | 9b9eebeab34943bb08b42832f2165025885408ee /lisp | |
| parent | 955ef4309a441a2d53605631d1346a238bba43ea (diff) | |
| download | emacs-2d0853070d1353348e6ef067b138d971cf52f341.tar.gz emacs-2d0853070d1353348e6ef067b138d971cf52f341.zip | |
(pcomplete-unquote-argument-function): New var.
(pcomplete-unquote-argument): New function.
(pcomplete--common-suffix): Always pay attention to case.
(pcomplete--table-subvert): Quote and unquote the text.
(pcomplete--common-quoted-suffix): New function.
(pcomplete-std-complete): Use it and pcomplete-begin.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 7 | ||||
| -rw-r--r-- | lisp/pcomplete.el | 330 |
2 files changed, 189 insertions, 148 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c6a8287942c..0ff59e4ef35 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,12 @@ | |||
| 1 | 2009-10-25 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2009-10-25 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | * pcomplete.el (pcomplete-unquote-argument-function): New var. | ||
| 4 | (pcomplete-unquote-argument): New function. | ||
| 5 | (pcomplete--common-suffix): Always pay attention to case. | ||
| 6 | (pcomplete--table-subvert): Quote and unquote the text. | ||
| 7 | (pcomplete--common-quoted-suffix): New function. | ||
| 8 | (pcomplete-std-complete): Use it and pcomplete-begin. | ||
| 9 | |||
| 3 | * bookmark.el (bookmark-bmenu-list): Don't use switch-to-buffer if | 10 | * bookmark.el (bookmark-bmenu-list): Don't use switch-to-buffer if |
| 4 | we're inside a dedicated or minibuffer window. | 11 | we're inside a dedicated or minibuffer window. |
| 5 | 12 | ||
diff --git a/lisp/pcomplete.el b/lisp/pcomplete.el index f23b219e1e1..371b61eea1b 100644 --- a/lisp/pcomplete.el +++ b/lisp/pcomplete.el | |||
| @@ -351,65 +351,69 @@ modified to be an empty string, or the desired separation string." | |||
| 351 | 351 | ||
| 352 | ;;; User Functions: | 352 | ;;; User Functions: |
| 353 | 353 | ||
| 354 | ;;;###autoload | 354 | ;;; Alternative front-end using the standard completion facilities. |
| 355 | (defun pcomplete (&optional interactively) | 355 | |
| 356 | "Support extensible programmable completion. | 356 | ;; The way pcomplete-parse-arguments, pcomplete-stub, and |
| 357 | To use this function, just bind the TAB key to it, or add it to your | 357 | ;; pcomplete-quote-argument work only works because of some deep |
| 358 | completion functions list (it should occur fairly early in the list)." | 358 | ;; hypothesis about the way the completion work. Basically, it makes |
| 359 | (interactive "p") | 359 | ;; it pretty much impossible to have completion other than |
| 360 | (if (and interactively | 360 | ;; prefix-completion. |
| 361 | pcomplete-cycle-completions | 361 | ;; |
| 362 | pcomplete-current-completions | 362 | ;; pcomplete--common-quoted-suffix and pcomplete--table-subvert try to |
| 363 | (memq last-command '(pcomplete | 363 | ;; work around this difficulty with heuristics, but it's |
| 364 | pcomplete-expand-and-complete | 364 | ;; really a hack. |
| 365 | pcomplete-reverse))) | 365 | |
| 366 | (progn | 366 | (defvar pcomplete-unquote-argument-function nil) |
| 367 | (delete-backward-char pcomplete-last-completion-length) | 367 | |
| 368 | (if (eq this-command 'pcomplete-reverse) | 368 | (defun pcomplete-unquote-argument (s) |
| 369 | (progn | 369 | (cond |
| 370 | (setq pcomplete-current-completions | 370 | (pcomplete-unquote-argument-function |
| 371 | (cons (car (last pcomplete-current-completions)) | 371 | (funcall pcomplete-unquote-argument-function s)) |
| 372 | pcomplete-current-completions)) | 372 | ((null pcomplete-arg-quote-list) s) |
| 373 | (setcdr (last pcomplete-current-completions 2) nil)) | 373 | (t |
| 374 | (nconc pcomplete-current-completions | 374 | (replace-regexp-in-string "\\\\\\(.\\)" "\\1" s t)))) |
| 375 | (list (car pcomplete-current-completions))) | ||
| 376 | (setq pcomplete-current-completions | ||
| 377 | (cdr pcomplete-current-completions))) | ||
| 378 | (pcomplete-insert-entry pcomplete-last-completion-stub | ||
| 379 | (car pcomplete-current-completions) | ||
| 380 | nil pcomplete-last-completion-raw)) | ||
| 381 | (setq pcomplete-current-completions nil | ||
| 382 | pcomplete-last-completion-raw nil) | ||
| 383 | (catch 'pcompleted | ||
| 384 | (let* ((pcomplete-stub) | ||
| 385 | pcomplete-seen pcomplete-norm-func | ||
| 386 | pcomplete-args pcomplete-last pcomplete-index | ||
| 387 | (pcomplete-autolist pcomplete-autolist) | ||
| 388 | (pcomplete-suffix-list pcomplete-suffix-list) | ||
| 389 | (completions (pcomplete-completions)) | ||
| 390 | (result (pcomplete-do-complete pcomplete-stub completions))) | ||
| 391 | (and result | ||
| 392 | (not (eq (car result) 'listed)) | ||
| 393 | (cdr result) | ||
| 394 | (pcomplete-insert-entry pcomplete-stub (cdr result) | ||
| 395 | (memq (car result) | ||
| 396 | '(sole shortest)) | ||
| 397 | pcomplete-last-completion-raw)))))) | ||
| 398 | 375 | ||
| 399 | (defun pcomplete-common-suffix (s1 s2) | 376 | (defun pcomplete--common-suffix (s1 s2) |
| 400 | (assert (not (or (string-match "\n" s1) (string-match "\n" s2)))) | 377 | (assert (not (or (string-match "\n" s1) (string-match "\n" s2)))) |
| 401 | (let ((case-fold-search pcomplete-ignore-case)) | 378 | ;; Since S2 is expected to be the "unquoted/expanded" version of S1, |
| 379 | ;; there shouldn't be any case difference, even if the completion is | ||
| 380 | ;; case-insensitive. | ||
| 381 | (let ((case-fold-search nil)) ;; pcomplete-ignore-case | ||
| 402 | (string-match ".*?\\(.*\\)\n.*\\1\\'" (concat s1 "\n" s2)) | 382 | (string-match ".*?\\(.*\\)\n.*\\1\\'" (concat s1 "\n" s2)) |
| 403 | (- (match-end 1) (match-beginning 1)))) | 383 | (- (match-end 1) (match-beginning 1)))) |
| 404 | 384 | ||
| 405 | (defun pcomplete-table-subvert (table s1 s2 string pred action) | 385 | (defun pcomplete--common-quoted-suffix (s1 s2) |
| 386 | "Find the common suffix between S1 and S2 where S1 is the expanded S2. | ||
| 387 | S1 is expected to be the unquoted and expanded version of S1. | ||
| 388 | Returns (PS1 . PS2), i.e. the shortest prefixes of S1 and S2, such that | ||
| 389 | S1 = (concat PS1 SS1) and S2 = (concat PS2 SS2) and | ||
| 390 | SS1 = (unquote SS2)." | ||
| 391 | (let* ((cs (pcomplete--common-suffix s1 s2)) | ||
| 392 | (ss1 (substring s1 (- (length s1) cs))) | ||
| 393 | (qss1 (pcomplete-quote-argument ss1)) | ||
| 394 | qc) | ||
| 395 | (if (and (not (equal ss1 qss1)) | ||
| 396 | (setq qc (pcomplete-quote-argument (substring ss1 0 1))) | ||
| 397 | (eq t (compare-strings s2 (- (length s2) cs (length qc) -1) | ||
| 398 | (- (length s2) cs -1) | ||
| 399 | qc nil nil))) | ||
| 400 | ;; The difference found is just that one char is quoted in S2 | ||
| 401 | ;; but not in S1, keep looking before this difference. | ||
| 402 | (pcomplete--common-quoted-suffix | ||
| 403 | (substring s1 0 (- (length s1) cs)) | ||
| 404 | (substring s2 0 (- (length s2) cs (length qc) -1))) | ||
| 405 | (cons (substring s1 0 (- (length s1) cs)) | ||
| 406 | (substring s2 0 (- (length s2) cs)))))) | ||
| 407 | |||
| 408 | (defun pcomplete--table-subvert (table s1 s2 string pred action) | ||
| 406 | "Completion table that replaces the prefix S1 with S2 in STRING. | 409 | "Completion table that replaces the prefix S1 with S2 in STRING. |
| 407 | When TABLE, S1 and S2 are provided by `apply-partially', the result | 410 | When TABLE, S1 and S2 are provided by `apply-partially', the result |
| 408 | is a completion table which completes strings of the form (concat S1 S) | 411 | is a completion table which completes strings of the form (concat S1 S) |
| 409 | in the same way as TABLE completes strings of the form (concat S2 S)." | 412 | in the same way as TABLE completes strings of the form (concat S2 S)." |
| 410 | (let* ((str (if (eq t (compare-strings string 0 (length s1) s1 nil nil | 413 | (let* ((str (if (eq t (compare-strings string 0 (length s1) s1 nil nil |
| 411 | completion-ignore-case)) | 414 | completion-ignore-case)) |
| 412 | (concat s2 (substring string (length s1))))) | 415 | (concat s2 (pcomplete-unquote-argument |
| 416 | (substring string (length s1)))))) | ||
| 413 | (res (if str (complete-with-action action table str pred)))) | 417 | (res (if str (complete-with-action action table str pred)))) |
| 414 | (when res | 418 | (when res |
| 415 | (cond | 419 | (cond |
| @@ -417,12 +421,14 @@ in the same way as TABLE completes strings of the form (concat S2 S)." | |||
| 417 | (let ((beg (or (and (eq (car-safe res) 'boundaries) (cadr res)) 0))) | 421 | (let ((beg (or (and (eq (car-safe res) 'boundaries) (cadr res)) 0))) |
| 418 | (list* 'boundaries | 422 | (list* 'boundaries |
| 419 | (max (length s1) | 423 | (max (length s1) |
| 424 | ;; FIXME: Adjust because of quoting/unquoting. | ||
| 420 | (+ beg (- (length s1) (length s2)))) | 425 | (+ beg (- (length s1) (length s2)))) |
| 421 | (and (eq (car-safe res) 'boundaries) (cddr res))))) | 426 | (and (eq (car-safe res) 'boundaries) (cddr res))))) |
| 422 | ((stringp res) | 427 | ((stringp res) |
| 423 | (if (eq t (compare-strings res 0 (length s2) s2 nil nil | 428 | (if (eq t (compare-strings res 0 (length s2) s2 nil nil |
| 424 | completion-ignore-case)) | 429 | completion-ignore-case)) |
| 425 | (concat s1 (substring res (length s2))))) | 430 | (concat s1 (pcomplete-quote-argument |
| 431 | (substring res (length s2)))))) | ||
| 426 | ((eq action t) | 432 | ((eq action t) |
| 427 | (let ((bounds (completion-boundaries str table pred ""))) | 433 | (let ((bounds (completion-boundaries str table pred ""))) |
| 428 | (if (>= (car bounds) (length s2)) | 434 | (if (>= (car bounds) (length s2)) |
| @@ -435,14 +441,14 @@ in the same way as TABLE completes strings of the form (concat S2 S)." | |||
| 435 | (substring c (match-end 0)))) | 441 | (substring c (match-end 0)))) |
| 436 | res)))))))))) | 442 | res)))))))))) |
| 437 | 443 | ||
| 438 | 444 | ;; I don't think such commands are usable before first setting up buffer-local | |
| 445 | ;; variables to parse args, so there's no point autoloading it. | ||
| 446 | ;; ;;;###autoload | ||
| 439 | (defun pcomplete-std-complete () | 447 | (defun pcomplete-std-complete () |
| 440 | "Provide standard completion using pcomplete's completion tables. | 448 | "Provide standard completion using pcomplete's completion tables. |
| 441 | Same as `pcomplete' but using the standard completion UI." | 449 | Same as `pcomplete' but using the standard completion UI." |
| 442 | (interactive) | 450 | (interactive) |
| 443 | ;; FIXME: it fails to unquote/requote the arguments. | ||
| 444 | ;; FIXME: it doesn't implement paring. | 451 | ;; FIXME: it doesn't implement paring. |
| 445 | ;; FIXME: when we bring up *Completions* we never bring it back down. | ||
| 446 | (catch 'pcompleted | 452 | (catch 'pcompleted |
| 447 | (let* ((pcomplete-stub) | 453 | (let* ((pcomplete-stub) |
| 448 | pcomplete-seen pcomplete-norm-func | 454 | pcomplete-seen pcomplete-norm-func |
| @@ -465,46 +471,98 @@ Same as `pcomplete' but using the standard completion UI." | |||
| 465 | ;; pcomplete-stub and works from the buffer's text instead, | 471 | ;; pcomplete-stub and works from the buffer's text instead, |
| 466 | ;; we need to trick minibuffer-complete, into using | 472 | ;; we need to trick minibuffer-complete, into using |
| 467 | ;; pcomplete-stub without its knowledge. To that end, we | 473 | ;; pcomplete-stub without its knowledge. To that end, we |
| 468 | ;; use pcomplete-table-subvert to construct a completion | 474 | ;; use pcomplete--table-subvert to construct a completion |
| 469 | ;; table which expects strings using a prefix from the | 475 | ;; table which expects strings using a prefix from the |
| 470 | ;; buffer's text but internally uses the corresponding | 476 | ;; buffer's text but internally uses the corresponding |
| 471 | ;; prefix from pcomplete-stub. | 477 | ;; prefix from pcomplete-stub. |
| 472 | (beg (max (- (point) (length pcomplete-stub)) | 478 | (beg (max (- (point) (length pcomplete-stub)) |
| 473 | ;; Rather than `point-min' we should use the | 479 | (pcomplete-begin))) |
| 474 | ;; beginning position of the current arg. | ||
| 475 | (point-min))) | ||
| 476 | (buftext (buffer-substring beg (point))) | 480 | (buftext (buffer-substring beg (point))) |
| 477 | ;; This isn't always strictly right (e.g. if | 481 | (table |
| 478 | ;; FOO="toto/$FOO", then completion of /$FOO/bar may | 482 | (if (not (equal pcomplete-stub buftext)) |
| 479 | ;; result in something incorrect), but given the lack of | 483 | ;; This isn't always strictly right (e.g. if |
| 480 | ;; any other info, it's about as good as it gets, and in | 484 | ;; FOO="toto/$FOO", then completion of /$FOO/bar may |
| 481 | ;; practice it should work just fine (fingers crossed). | 485 | ;; result in something incorrect), but given the lack of |
| 482 | (suflen (pcomplete-common-suffix pcomplete-stub buftext))) | 486 | ;; any other info, it's about as good as it gets, and in |
| 483 | (unless (= suflen (length pcomplete-stub)) | 487 | ;; practice it should work just fine (fingers crossed). |
| 484 | (setq completions | 488 | (let ((prefixes (pcomplete--common-quoted-suffix |
| 485 | (apply-partially | 489 | pcomplete-stub buftext))) |
| 486 | 'pcomplete-table-subvert | 490 | (apply-partially |
| 487 | completions | 491 | 'pcomplete--table-subvert |
| 488 | (substring buftext 0 (- (length buftext) suflen)) | 492 | completions |
| 489 | (substring pcomplete-stub | 493 | (cdr prefixes) (car prefixes))) |
| 490 | 0 (- (length pcomplete-stub) suflen))))) | 494 | (lexical-let ((completions completions)) |
| 495 | (lambda (string pred action) | ||
| 496 | (let ((res (complete-with-action | ||
| 497 | action completions string pred))) | ||
| 498 | (if (stringp res) | ||
| 499 | (pcomplete-quote-argument res) | ||
| 500 | res))))))) | ||
| 501 | |||
| 491 | (let ((ol (make-overlay beg (point) nil nil t)) | 502 | (let ((ol (make-overlay beg (point) nil nil t)) |
| 492 | (minibuffer-completion-table | 503 | (minibuffer-completion-table |
| 493 | ;; Add a space at the end of completion. Use a terminator-regexp | 504 | ;; Add a space at the end of completion. Use a terminator-regexp |
| 494 | ;; that never matches since the terminator cannot appear | 505 | ;; that never matches since the terminator cannot appear |
| 495 | ;; within the completion field anyway. | 506 | ;; within the completion field anyway. |
| 496 | (if (zerop (length pcomplete-termination-string)) | 507 | (if (zerop (length pcomplete-termination-string)) |
| 497 | completions | 508 | table |
| 498 | (apply-partially 'completion-table-with-terminator | 509 | (apply-partially 'completion-table-with-terminator |
| 499 | (cons pcomplete-termination-string | 510 | (cons pcomplete-termination-string |
| 500 | "\\`a\\`") | 511 | "\\`a\\`") |
| 501 | completions))) | 512 | table))) |
| 502 | (minibuffer-completion-predicate nil)) | 513 | (minibuffer-completion-predicate nil)) |
| 503 | (overlay-put ol 'field 'pcomplete) | 514 | (overlay-put ol 'field 'pcomplete) |
| 504 | (unwind-protect | 515 | (unwind-protect |
| 505 | (call-interactively 'minibuffer-complete) | 516 | (call-interactively 'minibuffer-complete) |
| 506 | (delete-overlay ol)))))) | 517 | (delete-overlay ol)))))) |
| 507 | 518 | ||
| 519 | ;;; Pcomplete's native UI. | ||
| 520 | |||
| 521 | ;;;###autoload | ||
| 522 | (defun pcomplete (&optional interactively) | ||
| 523 | "Support extensible programmable completion. | ||
| 524 | To use this function, just bind the TAB key to it, or add it to your | ||
| 525 | completion functions list (it should occur fairly early in the list)." | ||
| 526 | (interactive "p") | ||
| 527 | (if (and interactively | ||
| 528 | pcomplete-cycle-completions | ||
| 529 | pcomplete-current-completions | ||
| 530 | (memq last-command '(pcomplete | ||
| 531 | pcomplete-expand-and-complete | ||
| 532 | pcomplete-reverse))) | ||
| 533 | (progn | ||
| 534 | (delete-backward-char pcomplete-last-completion-length) | ||
| 535 | (if (eq this-command 'pcomplete-reverse) | ||
| 536 | (progn | ||
| 537 | (setq pcomplete-current-completions | ||
| 538 | (cons (car (last pcomplete-current-completions)) | ||
| 539 | pcomplete-current-completions)) | ||
| 540 | (setcdr (last pcomplete-current-completions 2) nil)) | ||
| 541 | (nconc pcomplete-current-completions | ||
| 542 | (list (car pcomplete-current-completions))) | ||
| 543 | (setq pcomplete-current-completions | ||
| 544 | (cdr pcomplete-current-completions))) | ||
| 545 | (pcomplete-insert-entry pcomplete-last-completion-stub | ||
| 546 | (car pcomplete-current-completions) | ||
| 547 | nil pcomplete-last-completion-raw)) | ||
| 548 | (setq pcomplete-current-completions nil | ||
| 549 | pcomplete-last-completion-raw nil) | ||
| 550 | (catch 'pcompleted | ||
| 551 | (let* ((pcomplete-stub) | ||
| 552 | pcomplete-seen pcomplete-norm-func | ||
| 553 | pcomplete-args pcomplete-last pcomplete-index | ||
| 554 | (pcomplete-autolist pcomplete-autolist) | ||
| 555 | (pcomplete-suffix-list pcomplete-suffix-list) | ||
| 556 | (completions (pcomplete-completions)) | ||
| 557 | (result (pcomplete-do-complete pcomplete-stub completions))) | ||
| 558 | (and result | ||
| 559 | (not (eq (car result) 'listed)) | ||
| 560 | (cdr result) | ||
| 561 | (pcomplete-insert-entry pcomplete-stub (cdr result) | ||
| 562 | (memq (car result) | ||
| 563 | '(sole shortest)) | ||
| 564 | pcomplete-last-completion-raw)))))) | ||
| 565 | |||
| 508 | ;;;###autoload | 566 | ;;;###autoload |
| 509 | (defun pcomplete-reverse () | 567 | (defun pcomplete-reverse () |
| 510 | "If cycling completion is in use, cycle backwards." | 568 | "If cycling completion is in use, cycle backwards." |
| @@ -713,6 +771,7 @@ this is `comint-dynamic-complete-functions'." | |||
| 713 | ;;;###autoload | 771 | ;;;###autoload |
| 714 | (defun pcomplete-shell-setup () | 772 | (defun pcomplete-shell-setup () |
| 715 | "Setup `shell-mode' to use pcomplete." | 773 | "Setup `shell-mode' to use pcomplete." |
| 774 | ;; FIXME: insufficient | ||
| 716 | (pcomplete-comint-setup 'comint-dynamic-complete-functions)) | 775 | (pcomplete-comint-setup 'comint-dynamic-complete-functions)) |
| 717 | 776 | ||
| 718 | (declare-function comint-bol "comint" (&optional arg)) | 777 | (declare-function comint-bol "comint" (&optional arg)) |
| @@ -789,23 +848,17 @@ this is `comint-dynamic-complete-functions'." | |||
| 789 | Magic characters are those in `pcomplete-arg-quote-list'." | 848 | Magic characters are those in `pcomplete-arg-quote-list'." |
| 790 | (if (null pcomplete-arg-quote-list) | 849 | (if (null pcomplete-arg-quote-list) |
| 791 | filename | 850 | filename |
| 792 | (let ((len (length filename)) | 851 | (let ((index 0)) |
| 793 | (index 0) | 852 | (mapconcat (lambda (c) |
| 794 | (result "") | 853 | (prog1 |
| 795 | replacement char) | 854 | (or (run-hook-with-args-until-success |
| 796 | (while (< index len) | 855 | 'pcomplete-quote-arg-hook filename index) |
| 797 | (setq replacement (run-hook-with-args-until-success | 856 | (when (memq c pcomplete-arg-quote-list) |
| 798 | 'pcomplete-quote-arg-hook filename index)) | 857 | (string "\\" c)) |
| 799 | (cond | 858 | (char-to-string c)) |
| 800 | (replacement | 859 | (setq index (1+ index)))) |
| 801 | (setq result (concat result replacement))) | 860 | filename |
| 802 | ((memq (setq char (aref filename index)) | 861 | "")))) |
| 803 | pcomplete-arg-quote-list) | ||
| 804 | (setq result (concat result (string "\\" char)))) | ||
| 805 | (t | ||
| 806 | (setq result (concat result (char-to-string char))))) | ||
| 807 | (setq index (1+ index))) | ||
| 808 | result))) | ||
| 809 | 862 | ||
| 810 | ;; file-system completion lists | 863 | ;; file-system completion lists |
| 811 | 864 | ||
| @@ -829,65 +882,46 @@ If PREDICATE is non-nil, it will also be used to refine the match | |||
| 829 | \(files for which the PREDICATE returns nil will be excluded). | 882 | \(files for which the PREDICATE returns nil will be excluded). |
| 830 | If no directory information can be extracted from the completed | 883 | If no directory information can be extracted from the completed |
| 831 | component, `default-directory' is used as the basis for completion." | 884 | component, `default-directory' is used as the basis for completion." |
| 832 | (let* ((name (substitute-env-vars pcomplete-stub)) | 885 | ;; FIXME: obey pcomplete-file-ignore and pcomplete-dir-ignore. |
| 833 | (completion-ignore-case pcomplete-ignore-case) | 886 | ;; FIXME: obey pcomplete-compare-entry-function (tho only if there |
| 834 | (default-directory (expand-file-name | 887 | ;; are less than pcomplete-cycle-cutoff-length completions). |
| 835 | (or (file-name-directory name) | 888 | ;; FIXME: expand envvars? shouldn't this be done globally instead? |
| 836 | default-directory))) | 889 | (let* ((reg-pred (when regexp |
| 837 | above-cutoff) | 890 | (lexical-let ((re regexp)) |
| 838 | (setq name (file-name-nondirectory name) | 891 | (lambda (f) |
| 839 | pcomplete-stub name) | 892 | ;; (let ((name (file-name-nondirectory f))) |
| 840 | (let ((completions | 893 | ;; (if (zerop (length name)) |
| 841 | (file-name-all-completions name default-directory))) | 894 | ;; (setq name (file-name-as-directory |
| 842 | (if regexp | 895 | ;; (file-name-nondirectory |
| 843 | (setq completions | 896 | ;; (directory-file-name f))))) |
| 844 | (pcomplete-pare-list | 897 | ;; (string-match re name)) |
| 845 | completions nil | 898 | (string-match re f))))) |
| 846 | (function | 899 | (pred (cond |
| 847 | (lambda (file) | 900 | ((null predicate) reg-pred) |
| 848 | (not (string-match regexp file))))))) | 901 | ((null reg-pred) predicate) |
| 849 | (if predicate | 902 | (t (lexical-let ((predicate predicate) |
| 850 | (setq completions | 903 | (reg-pred reg-pred)) |
| 851 | (pcomplete-pare-list | 904 | (lambda (f) |
| 852 | completions nil | 905 | (and (funcall predicate f) |
| 853 | (function | 906 | (funcall reg-pred f))))))) |
| 854 | (lambda (file) | 907 | (fun |
| 855 | (not (funcall predicate file))))))) | 908 | (lexical-let ((pred pred) |
| 856 | (if (or pcomplete-file-ignore pcomplete-dir-ignore) | 909 | (dir default-directory)) |
| 857 | (setq completions | 910 | (lambda (s p a) |
| 858 | (pcomplete-pare-list | 911 | ;; Remember the default-directory that was active when we built |
| 859 | completions nil | 912 | ;; the completion table. |
| 860 | (function | 913 | (let ((default-directory dir) |
| 861 | (lambda (file) | 914 | ;; The old code used only file-name-all-completions |
| 862 | (if (eq (aref file (1- (length file))) | 915 | ;; which ignores completion-ignored-extensions. |
| 863 | ?/) | 916 | (completion-ignored-extensions nil)) |
| 864 | (and pcomplete-dir-ignore | 917 | (completion-table-with-predicate |
| 865 | (string-match pcomplete-dir-ignore file)) | 918 | 'completion-file-name-table pred 'strict s p a))))) |
| 866 | (and pcomplete-file-ignore | 919 | ;; Indirect through a symbol rather than returning a lambda |
| 867 | (string-match pcomplete-file-ignore file)))))))) | 920 | ;; expression, so as to help catch bugs where the caller |
| 868 | (setq above-cutoff (and pcomplete-cycle-cutoff-length | 921 | ;; might treat the lambda expression as a list of completions. |
| 869 | (> (length completions) | 922 | (sym (make-symbol "pcomplete-read-file-name-internal"))) |
| 870 | pcomplete-cycle-cutoff-length))) | 923 | (fset sym fun) |
| 871 | (sort completions | 924 | sym)) |
| 872 | (function | ||
| 873 | (lambda (l r) | ||
| 874 | ;; for the purposes of comparison, remove the | ||
| 875 | ;; trailing slash from directory names. | ||
| 876 | ;; Otherwise, "foo.old/" will come before "foo/", | ||
| 877 | ;; since . is earlier in the ASCII alphabet than | ||
| 878 | ;; / | ||
| 879 | (let ((left (if (eq (aref l (1- (length l))) | ||
| 880 | ?/) | ||
| 881 | (substring l 0 (1- (length l))) | ||
| 882 | l)) | ||
| 883 | (right (if (eq (aref r (1- (length r))) | ||
| 884 | ?/) | ||
| 885 | (substring r 0 (1- (length r))) | ||
| 886 | r))) | ||
| 887 | (if above-cutoff | ||
| 888 | (string-lessp left right) | ||
| 889 | (funcall pcomplete-compare-entry-function | ||
| 890 | left right))))))))) | ||
| 891 | 925 | ||
| 892 | (defsubst pcomplete-all-entries (&optional regexp predicate) | 926 | (defsubst pcomplete-all-entries (&optional regexp predicate) |
| 893 | "Like `pcomplete-entries', but doesn't ignore any entries." | 927 | "Like `pcomplete-entries', but doesn't ignore any entries." |