comparison lisp/completion.el @ 29079:3313f117f0ed

Doc fixes. Add to debug-ignored-errors. Don't quote keywords. (cmpl-string-case-type): Use character classes.
author Dave Love <fx@gnu.org>
date Mon, 22 May 2000 17:53:15 +0000
parents d1305a19933d
children cbc6a64048ee
comparison
equal deleted inserted replaced
29078:2e20146198ce 29079:3313f117f0ed
284 :group 'convenience) 284 :group 'convenience)
285 285
286 286
287 (defcustom enable-completion t 287 (defcustom enable-completion t
288 "*Non-nil means enable recording and saving of completions. 288 "*Non-nil means enable recording and saving of completions.
289 If nil, no new words added to the database or saved to the init file." 289 If nil, no new words are added to the database or saved to the init file."
290 :type 'boolean 290 :type 'boolean
291 :group 'completion) 291 :group 'completion)
292 292
293 (defcustom save-completions-flag t 293 (defcustom save-completions-flag t
294 "*Non-nil means save most-used completions when exiting Emacs. 294 "*Non-nil means save most-used completions when exiting Emacs.
411 ;;----------------------------------------------- 411 ;;-----------------------------------------------
412 ;; String case coercion 412 ;; String case coercion
413 ;;----------------------------------------------- 413 ;;-----------------------------------------------
414 414
415 (defun cmpl-string-case-type (string) 415 (defun cmpl-string-case-type (string)
416 "Returns :capitalized, :up, :down, :mixed, or :neither." 416 "Return :capitalized, :up, :down, :mixed, or :neither for case of STRING."
417 (let ((case-fold-search nil)) 417 (let ((case-fold-search nil))
418 (cond ((string-match "[a-z]" string) 418 (cond ((string-match "[[:lower:]]" string)
419 (cond ((string-match "[A-Z]" string) 419 (cond ((string-match "[[:upper:]]" string)
420 (cond ((and (> (length string) 1) 420 (cond ((and (> (length string) 1)
421 (null (string-match "[A-Z]" string 1))) 421 (null (string-match "[[:upper:]]" string 1)))
422 ':capitalized) 422 :capitalized)
423 (t 423 (t
424 ':mixed))) 424 :mixed)))
425 (t ':down))) 425 (t :down)))
426 (t 426 (t
427 (cond ((string-match "[A-Z]" string) 427 (cond ((string-match "[[:upper:]]" string)
428 ':up) 428 :up)
429 (t ':neither)))) 429 (t :neither))))))
430 ))
431 430
432 ;; Tests - 431 ;; Tests -
433 ;; (cmpl-string-case-type "123ABCDEF456") --> :up 432 ;; (cmpl-string-case-type "123ABCDEF456") --> :up
434 ;; (cmpl-string-case-type "123abcdef456") --> :down 433 ;; (cmpl-string-case-type "123abcdef456") --> :down
435 ;; (cmpl-string-case-type "123aBcDeF456") --> :mixed 434 ;; (cmpl-string-case-type "123aBcDeF456") --> :mixed
436 ;; (cmpl-string-case-type "123456") --> :neither 435 ;; (cmpl-string-case-type "123456") --> :neither
437 ;; (cmpl-string-case-type "Abcde123") --> :capitalized 436 ;; (cmpl-string-case-type "Abcde123") --> :capitalized
438 437
439 (defun cmpl-coerce-string-case (string case-type) 438 (defun cmpl-coerce-string-case (string case-type)
440 (cond ((eq case-type ':down) (downcase string)) 439 (cond ((eq case-type :down) (downcase string))
441 ((eq case-type ':up) (upcase string)) 440 ((eq case-type :up) (upcase string))
442 ((eq case-type ':capitalized) 441 ((eq case-type :capitalized)
443 (setq string (downcase string)) 442 (setq string (downcase string))
444 (aset string 0 (logand ?\337 (aref string 0))) 443 (aset string 0 (logand ?\337 (aref string 0)))
445 string) 444 string)
446 (t string) 445 (t string)))
447 ))
448 446
449 (defun cmpl-merge-string-cases (string-to-coerce given-string) 447 (defun cmpl-merge-string-cases (string-to-coerce given-string)
450 (let ((string-case-type (cmpl-string-case-type string-to-coerce)) 448 (let ((string-case-type (cmpl-string-case-type string-to-coerce)))
451 )
452 (cond ((memq string-case-type '(:down :up :capitalized)) 449 (cond ((memq string-case-type '(:down :up :capitalized))
453 ;; Found string is in a standard case. Coerce to a type based on 450 ;; Found string is in a standard case. Coerce to a type based on
454 ;; the given string 451 ;; the given string
455 (cmpl-coerce-string-case string-to-coerce 452 (cmpl-coerce-string-case string-to-coerce
456 (cmpl-string-case-type given-string)) 453 (cmpl-string-case-type given-string)))
457 )
458 (t 454 (t
459 ;; If the found string is in some unusual case, just insert it 455 ;; If the found string is in some unusual case, just insert it
460 ;; as is 456 ;; as is
461 string-to-coerce) 457 string-to-coerce))))
462 )))
463 458
464 ;; Tests - 459 ;; Tests -
465 ;; (cmpl-merge-string-cases "AbCdEf456" "abc") --> AbCdEf456 460 ;; (cmpl-merge-string-cases "AbCdEf456" "abc") --> AbCdEf456
466 ;; (cmpl-merge-string-cases "abcdef456" "ABC") --> ABCDEF456 461 ;; (cmpl-merge-string-cases "abcdef456" "ABC") --> ABCDEF456
467 ;; (cmpl-merge-string-cases "ABCDEF456" "Abc") --> Abcdef456 462 ;; (cmpl-merge-string-cases "ABCDEF456" "Abc") --> Abcdef456
544 (while (< i 10) 539 (while (< i 10)
545 (modify-syntax-entry (+ ?0 i) "_" table) 540 (modify-syntax-entry (+ ?0 i) "_" table)
546 (setq i (1+ i))) 541 (setq i (1+ i)))
547 ;; Other ones 542 ;; Other ones
548 (let ((symbol-chars '(?@ ?/ ?\\ ?* ?+ ?~ ?$ ?< ?> ?%)) 543 (let ((symbol-chars '(?@ ?/ ?\\ ?* ?+ ?~ ?$ ?< ?> ?%))
549 (symbol-chars-ignore '(?_ ?- ?: ?.)) 544 (symbol-chars-ignore '(?_ ?- ?: ?.)))
550 )
551 (dolist (char symbol-chars) 545 (dolist (char symbol-chars)
552 (modify-syntax-entry char "_" table)) 546 (modify-syntax-entry char "_" table))
553 (dolist (char symbol-chars-ignore) 547 (dolist (char symbol-chars-ignore)
554 (modify-syntax-entry char "w" table) 548 (modify-syntax-entry char "w" table)))
555 )
556 )
557 table)) 549 table))
558 550
559 (defconst cmpl-standard-syntax-table (cmpl-make-standard-completion-syntax-table)) 551 (defconst cmpl-standard-syntax-table (cmpl-make-standard-completion-syntax-table))
560 552
561 (defun cmpl-make-lisp-completion-syntax-table () 553 (defun cmpl-make-lisp-completion-syntax-table ()
562 (let ((table (copy-syntax-table cmpl-standard-syntax-table)) 554 (let ((table (copy-syntax-table cmpl-standard-syntax-table))
563 (symbol-chars '(?! ?& ?? ?= ?^)) 555 (symbol-chars '(?! ?& ?? ?= ?^)))
564 )
565 (dolist (char symbol-chars) 556 (dolist (char symbol-chars)
566 (modify-syntax-entry char "_" table)) 557 (modify-syntax-entry char "_" table))
567 table)) 558 table))
568 559
569 (defun cmpl-make-c-completion-syntax-table () 560 (defun cmpl-make-c-completion-syntax-table ()
570 (let ((table (copy-syntax-table cmpl-standard-syntax-table)) 561 (let ((table (copy-syntax-table cmpl-standard-syntax-table))
571 (separator-chars '(?+ ?* ?/ ?: ?%)) 562 (separator-chars '(?+ ?* ?/ ?: ?%)))
572 )
573 (dolist (char separator-chars) 563 (dolist (char separator-chars)
574 (modify-syntax-entry char " " table)) 564 (modify-syntax-entry char " " table))
575 table)) 565 table))
576 566
577 (defun cmpl-make-fortran-completion-syntax-table () 567 (defun cmpl-make-fortran-completion-syntax-table ()
578 (let ((table (copy-syntax-table cmpl-standard-syntax-table)) 568 (let ((table (copy-syntax-table cmpl-standard-syntax-table))
579 (separator-chars '(?+ ?- ?* ?/ ?:)) 569 (separator-chars '(?+ ?- ?* ?/ ?:)))
580 )
581 (dolist (char separator-chars) 570 (dolist (char separator-chars)
582 (modify-syntax-entry char " " table)) 571 (modify-syntax-entry char " " table))
583 table)) 572 table))
584 573
585 (defconst cmpl-lisp-syntax-table (cmpl-make-lisp-completion-syntax-table)) 574 (defconst cmpl-lisp-syntax-table (cmpl-make-lisp-completion-syntax-table))
618 ;; Remove chars to ignore at the start. 607 ;; Remove chars to ignore at the start.
619 (cond ((= (char-syntax (char-after cmpl-symbol-start)) ?w) 608 (cond ((= (char-syntax (char-after cmpl-symbol-start)) ?w)
620 (goto-char cmpl-symbol-start) 609 (goto-char cmpl-symbol-start)
621 (forward-word 1) 610 (forward-word 1)
622 (setq cmpl-symbol-start (point)) 611 (setq cmpl-symbol-start (point))
623 (goto-char cmpl-saved-point) 612 (goto-char cmpl-saved-point)))
624 ))
625 ;; Remove chars to ignore at the end. 613 ;; Remove chars to ignore at the end.
626 (cond ((= (char-syntax (char-after (1- cmpl-symbol-end))) ?w) 614 (cond ((= (char-syntax (char-after (1- cmpl-symbol-end))) ?w)
627 (goto-char cmpl-symbol-end) 615 (goto-char cmpl-symbol-end)
628 (forward-word -1) 616 (forward-word -1)
629 (setq cmpl-symbol-end (point)) 617 (setq cmpl-symbol-end (point))
630 (goto-char cmpl-saved-point) 618 (goto-char cmpl-saved-point)))
631 ))
632 ;; Return completion if the length is reasonable. 619 ;; Return completion if the length is reasonable.
633 (if (and (<= (cmpl-read-time-eval completion-min-length) 620 (if (and (<= (cmpl-read-time-eval completion-min-length)
634 (- cmpl-symbol-end cmpl-symbol-start)) 621 (- cmpl-symbol-end cmpl-symbol-start))
635 (<= (- cmpl-symbol-end cmpl-symbol-start) 622 (<= (- cmpl-symbol-end cmpl-symbol-start)
636 (cmpl-read-time-eval completion-max-length))) 623 (cmpl-read-time-eval completion-max-length)))
659 (set-syntax-table cmpl-syntax-table) 646 (set-syntax-table cmpl-syntax-table)
660 ;; Cursor is on following-char and after preceding-char 647 ;; Cursor is on following-char and after preceding-char
661 (cond ((= (setq cmpl-preceding-syntax (char-syntax (preceding-char))) ?_) 648 (cond ((= (setq cmpl-preceding-syntax (char-syntax (preceding-char))) ?_)
662 ;; Number of chars to ignore at end. 649 ;; Number of chars to ignore at end.
663 (setq cmpl-symbol-end (point) 650 (setq cmpl-symbol-end (point)
664 cmpl-symbol-start (scan-sexps cmpl-symbol-end -1) 651 cmpl-symbol-start (scan-sexps cmpl-symbol-end -1))
665 )
666 ;; Remove chars to ignore at the start. 652 ;; Remove chars to ignore at the start.
667 (cond ((= (char-syntax (char-after cmpl-symbol-start)) ?w) 653 (cond ((= (char-syntax (char-after cmpl-symbol-start)) ?w)
668 (goto-char cmpl-symbol-start) 654 (goto-char cmpl-symbol-start)
669 (forward-word 1) 655 (forward-word 1)
670 (setq cmpl-symbol-start (point)) 656 (setq cmpl-symbol-start (point))
671 (goto-char cmpl-symbol-end) 657 (goto-char cmpl-symbol-end)))
672 ))
673 ;; Return value if long enough. 658 ;; Return value if long enough.
674 (if (>= cmpl-symbol-end 659 (if (>= cmpl-symbol-end
675 (+ cmpl-symbol-start 660 (+ cmpl-symbol-start
676 (cmpl-read-time-eval completion-min-length))) 661 (cmpl-read-time-eval completion-min-length)))
677 (buffer-substring cmpl-symbol-start cmpl-symbol-end)) 662 (buffer-substring cmpl-symbol-start cmpl-symbol-end)))
678 )
679 ((= cmpl-preceding-syntax ?w) 663 ((= cmpl-preceding-syntax ?w)
680 ;; chars to ignore at end 664 ;; chars to ignore at end
681 (setq cmpl-saved-point (point) 665 (setq cmpl-saved-point (point)
682 cmpl-symbol-start (scan-sexps cmpl-saved-point -1)) 666 cmpl-symbol-start (scan-sexps cmpl-saved-point -1))
683 ;; take off chars. from end 667 ;; take off chars. from end
685 (setq cmpl-symbol-end (point)) 669 (setq cmpl-symbol-end (point))
686 ;; remove chars to ignore at the start 670 ;; remove chars to ignore at the start
687 (cond ((= (char-syntax (char-after cmpl-symbol-start)) ?w) 671 (cond ((= (char-syntax (char-after cmpl-symbol-start)) ?w)
688 (goto-char cmpl-symbol-start) 672 (goto-char cmpl-symbol-start)
689 (forward-word 1) 673 (forward-word 1)
690 (setq cmpl-symbol-start (point)) 674 (setq cmpl-symbol-start (point))))
691 ))
692 ;; Restore state. 675 ;; Restore state.
693 (goto-char cmpl-saved-point) 676 (goto-char cmpl-saved-point)
694 ;; Return completion if the length is reasonable 677 ;; Return completion if the length is reasonable
695 (if (and (<= (cmpl-read-time-eval completion-min-length) 678 (if (and (<= (cmpl-read-time-eval completion-min-length)
696 (- cmpl-symbol-end cmpl-symbol-start)) 679 (- cmpl-symbol-end cmpl-symbol-start))
741 (progn 724 (progn
742 (set-syntax-table cmpl-syntax-table) 725 (set-syntax-table cmpl-syntax-table)
743 (cond ((memq (setq cmpl-preceding-syntax (char-syntax (preceding-char))) 726 (cond ((memq (setq cmpl-preceding-syntax (char-syntax (preceding-char)))
744 '(?_ ?w)) 727 '(?_ ?w))
745 (setq cmpl-symbol-end (point) 728 (setq cmpl-symbol-end (point)
746 cmpl-symbol-start (scan-sexps cmpl-symbol-end -1) 729 cmpl-symbol-start (scan-sexps cmpl-symbol-end -1))
747 )
748 ;; Remove chars to ignore at the start. 730 ;; Remove chars to ignore at the start.
749 (cond ((= (char-syntax (char-after cmpl-symbol-start)) ?w) 731 (cond ((= (char-syntax (char-after cmpl-symbol-start)) ?w)
750 (goto-char cmpl-symbol-start) 732 (goto-char cmpl-symbol-start)
751 (forward-word 1) 733 (forward-word 1)
752 (setq cmpl-symbol-start (point)) 734 (setq cmpl-symbol-start (point))
753 (goto-char cmpl-symbol-end) 735 (goto-char cmpl-symbol-end)))
754 ))
755 ;; Return completion if the length is reasonable. 736 ;; Return completion if the length is reasonable.
756 (if (and (<= (cmpl-read-time-eval 737 (if (and (<= (cmpl-read-time-eval
757 completion-prefix-min-length) 738 completion-prefix-min-length)
758 (- cmpl-symbol-end cmpl-symbol-start)) 739 (- cmpl-symbol-end cmpl-symbol-start))
759 (<= (- cmpl-symbol-end cmpl-symbol-start) 740 (<= (- cmpl-symbol-end cmpl-symbol-start)
855 "Resets the cdabbrev search to search for abbrev-string. 836 "Resets the cdabbrev search to search for abbrev-string.
856 INITIAL-COMPLETIONS-TRIED is a list of downcased strings to ignore 837 INITIAL-COMPLETIONS-TRIED is a list of downcased strings to ignore
857 during the search." 838 during the search."
858 (setq cdabbrev-abbrev-string abbrev-string 839 (setq cdabbrev-abbrev-string abbrev-string
859 cdabbrev-completions-tried 840 cdabbrev-completions-tried
860 (cons (downcase abbrev-string) initial-completions-tried) 841 (cons (downcase abbrev-string) initial-completions-tried))
861 ) 842 (reset-cdabbrev-window t))
862 (reset-cdabbrev-window t)
863 )
864 843
865 (defun set-cdabbrev-buffer () 844 (defun set-cdabbrev-buffer ()
866 ;; cdabbrev-current-window must not be NIL 845 ;; cdabbrev-current-window must not be NIL
867 (set-buffer (if (eq cdabbrev-current-window t) 846 (set-buffer (if (eq cdabbrev-current-window t)
868 (other-buffer) 847 (other-buffer)
869 (window-buffer cdabbrev-current-window))) 848 (window-buffer cdabbrev-current-window))))
870 )
871 849
872 850
873 (defun reset-cdabbrev-window (&optional initializep) 851 (defun reset-cdabbrev-window (&optional initializep)
874 "Resets the cdabbrev search to search for abbrev-string." 852 "Resets the cdabbrev search to search for abbrev-string."
875 ;; Set the window 853 ;; Set the window
876 (cond (initializep 854 (cond (initializep
877 (setq cdabbrev-current-window (selected-window)) 855 (setq cdabbrev-current-window (selected-window)))
878 )
879 ((eq cdabbrev-current-window t) 856 ((eq cdabbrev-current-window t)
880 ;; Everything has failed 857 ;; Everything has failed
881 (setq cdabbrev-current-window nil)) 858 (setq cdabbrev-current-window nil))
882 (cdabbrev-current-window 859 (cdabbrev-current-window
883 (setq cdabbrev-current-window (next-window cdabbrev-current-window)) 860 (setq cdabbrev-current-window (next-window cdabbrev-current-window))
884 (if (eq cdabbrev-current-window (selected-window)) 861 (if (eq cdabbrev-current-window (selected-window))
885 ;; No more windows, try other buffer. 862 ;; No more windows, try other buffer.
886 (setq cdabbrev-current-window t))) 863 (setq cdabbrev-current-window t))))
887 )
888 (if cdabbrev-current-window 864 (if cdabbrev-current-window
889 (save-excursion 865 (save-excursion
890 (set-cdabbrev-buffer) 866 (set-cdabbrev-buffer)
891 (setq cdabbrev-current-point (point) 867 (setq cdabbrev-current-point (point)
892 cdabbrev-start-point cdabbrev-current-point 868 cdabbrev-start-point cdabbrev-current-point
893 cdabbrev-stop-point 869 cdabbrev-stop-point
894 (if completion-search-distance 870 (if completion-search-distance
895 (max (point-min) 871 (max (point-min)
896 (- cdabbrev-start-point completion-search-distance)) 872 (- cdabbrev-start-point completion-search-distance))
897 (point-min)) 873 (point-min))
898 cdabbrev-wrapped-p nil) 874 cdabbrev-wrapped-p nil))))
899 )))
900 875
901 (defun next-cdabbrev () 876 (defun next-cdabbrev ()
902 "Return the next possible cdabbrev expansion or nil if there isn't one. 877 "Return the next possible cdabbrev expansion or nil if there isn't one.
903 `reset-cdabbrev' must've been called already. 878 `reset-cdabbrev' must've been called already.
904 This is sensitive to `case-fold-search'." 879 This is sensitive to `case-fold-search'."
936 (progn 911 (progn
937 (setq saved-point-2 (point)) 912 (setq saved-point-2 (point))
938 (forward-word -1) 913 (forward-word -1)
939 (prog1 914 (prog1
940 (= (char-syntax (preceding-char)) ? ) 915 (= (char-syntax (preceding-char)) ? )
941 (goto-char saved-point-2) 916 (goto-char saved-point-2)))))
942 ))))
943 ;; is the symbol long enough ? 917 ;; is the symbol long enough ?
944 (setq expansion (symbol-under-point)) 918 (setq expansion (symbol-under-point))
945 ;; have we not tried this one before 919 ;; have we not tried this one before
946 (progn 920 (progn
947 ;; See if we've already used it 921 ;; See if we've already used it
949 downcase-expansion (downcase expansion)) 923 downcase-expansion (downcase expansion))
950 (while (and tried-list 924 (while (and tried-list
951 (not (string-equal downcase-expansion 925 (not (string-equal downcase-expansion
952 (car tried-list)))) 926 (car tried-list))))
953 ;; Already tried, don't choose this one 927 ;; Already tried, don't choose this one
954 (setq tried-list (cdr tried-list)) 928 (setq tried-list (cdr tried-list)))
955 )
956 ;; at this point tried-list will be nil if this 929 ;; at this point tried-list will be nil if this
957 ;; expansion has not yet been tried 930 ;; expansion has not yet been tried
958 (if tried-list 931 (if tried-list
959 (setq expansion nil) 932 (setq expansion nil)
960 t) 933 t)))))
961 ))))
962 ;; search failed 934 ;; search failed
963 (cdabbrev-wrapped-p 935 (cdabbrev-wrapped-p
964 ;; If already wrapped, then we've failed completely 936 ;; If already wrapped, then we've failed completely
965 nil) 937 nil)
966 (t 938 (t
968 (goto-char (setq cdabbrev-current-point 940 (goto-char (setq cdabbrev-current-point
969 (if completion-search-distance 941 (if completion-search-distance
970 (min (point-max) (+ cdabbrev-start-point completion-search-distance)) 942 (min (point-max) (+ cdabbrev-start-point completion-search-distance))
971 (point-max)))) 943 (point-max))))
972 944
973 (setq cdabbrev-wrapped-p t)) 945 (setq cdabbrev-wrapped-p t))))
974 ))
975 ;; end of while loop 946 ;; end of while loop
976 (cond (expansion 947 (cond (expansion
977 ;; successful 948 ;; successful
978 (setq cdabbrev-completions-tried 949 (setq cdabbrev-completions-tried
979 (cons downcase-expansion cdabbrev-completions-tried) 950 (cons downcase-expansion cdabbrev-completions-tried)
980 cdabbrev-current-point (point)))) 951 cdabbrev-current-point (point)))))
981 )
982 (set-syntax-table saved-syntax) 952 (set-syntax-table saved-syntax)
983 (goto-char saved-point) 953 (goto-char saved-point)))
984 ))
985 ;; If no expansion, go to next window 954 ;; If no expansion, go to next window
986 (cond (expansion) 955 (cond (expansion)
987 (t (reset-cdabbrev-window) 956 (t (reset-cdabbrev-window)
988 (next-cdabbrev)))))) 957 (next-cdabbrev))))))
989 958
1107 ;;----------------------------------------------- 1076 ;;-----------------------------------------------
1108 ;; Completion Database - Utilities 1077 ;; Completion Database - Utilities
1109 ;;----------------------------------------------- 1078 ;;-----------------------------------------------
1110 1079
1111 (defun clear-all-completions () 1080 (defun clear-all-completions ()
1112 "Initializes the completion storage. All existing completions are lost." 1081 "Initialize the completion storage. All existing completions are lost."
1113 (interactive) 1082 (interactive)
1114 (setq cmpl-prefix-obarray (make-vector cmpl-obarray-length 0)) 1083 (setq cmpl-prefix-obarray (make-vector cmpl-obarray-length 0))
1115 (setq cmpl-obarray (make-vector cmpl-obarray-length 0)) 1084 (setq cmpl-obarray (make-vector cmpl-obarray-length 0))
1116 (cmpl-statistics-block 1085 (cmpl-statistics-block
1117 (record-clear-all-completions)) 1086 (record-clear-all-completions)))
1118 )
1119 1087
1120 (defvar completions-list-return-value) 1088 (defvar completions-list-return-value)
1121 1089
1122 (defun list-all-completions () 1090 (defun list-all-completions ()
1123 "Returns a list of all the known completion entries." 1091 "Return a list of all the known completion entries."
1124 (let ((completions-list-return-value nil)) 1092 (let ((completions-list-return-value nil))
1125 (mapatoms 'list-all-completions-1 cmpl-prefix-obarray) 1093 (mapatoms 'list-all-completions-1 cmpl-prefix-obarray)
1126 completions-list-return-value)) 1094 completions-list-return-value))
1127 1095
1128 (defun list-all-completions-1 (prefix-symbol) 1096 (defun list-all-completions-1 (prefix-symbol)
1166 (defvar cmpl-db-debug-p nil 1134 (defvar cmpl-db-debug-p nil
1167 "Set to T if you want to debug the database.") 1135 "Set to T if you want to debug the database.")
1168 1136
1169 ;; READS 1137 ;; READS
1170 (defun find-exact-completion (string) 1138 (defun find-exact-completion (string)
1171 "Returns the completion entry for string or nil. 1139 "Return the completion entry for STRING or nil.
1172 Sets up `cmpl-db-downcase-string' and `cmpl-db-symbol'." 1140 Sets up `cmpl-db-downcase-string' and `cmpl-db-symbol'."
1173 (and (boundp (setq cmpl-db-symbol 1141 (and (boundp (setq cmpl-db-symbol
1174 (intern (setq cmpl-db-downcase-string (downcase string)) 1142 (intern (setq cmpl-db-downcase-string (downcase string))
1175 cmpl-obarray))) 1143 cmpl-obarray)))
1176 (symbol-value cmpl-db-symbol) 1144 (symbol-value cmpl-db-symbol)))
1177 ))
1178 1145
1179 (defun find-cmpl-prefix-entry (prefix-string) 1146 (defun find-cmpl-prefix-entry (prefix-string)
1180 "Returns the prefix entry for string. 1147 "Return the prefix entry for string.
1181 Sets `cmpl-db-prefix-symbol'. 1148 Sets `cmpl-db-prefix-symbol'.
1182 Prefix-string must be exactly `completion-prefix-min-length' long 1149 Prefix-string must be exactly `completion-prefix-min-length' long
1183 and downcased. Sets up `cmpl-db-prefix-symbol'." 1150 and downcased. Sets up `cmpl-db-prefix-symbol'."
1184 (and (boundp (setq cmpl-db-prefix-symbol 1151 (and (boundp (setq cmpl-db-prefix-symbol
1185 (intern prefix-string cmpl-prefix-obarray))) 1152 (intern prefix-string cmpl-prefix-obarray)))
1187 1154
1188 (defvar inside-locate-completion-entry nil) 1155 (defvar inside-locate-completion-entry nil)
1189 ;; used to trap lossage in silent error correction 1156 ;; used to trap lossage in silent error correction
1190 1157
1191 (defun locate-completion-entry (completion-entry prefix-entry) 1158 (defun locate-completion-entry (completion-entry prefix-entry)
1192 "Locates the completion entry. 1159 "Locate the completion entry.
1193 Returns a pointer to the element before the completion entry or nil if 1160 Returns a pointer to the element before the completion entry or nil if
1194 the completion entry is at the head. 1161 the completion entry is at the head.
1195 Must be called after `find-exact-completion'." 1162 Must be called after `find-exact-completion'."
1196 (let ((prefix-list (cmpl-prefix-entry-head prefix-entry)) 1163 (let ((prefix-list (cmpl-prefix-entry-head prefix-entry))
1197 next-prefix-list 1164 next-prefix-list)
1198 )
1199 (cond 1165 (cond
1200 ((not (eq (car prefix-list) completion-entry)) 1166 ((not (eq (car prefix-list) completion-entry))
1201 ;; not already at head 1167 ;; not already at head
1202 (while (and prefix-list 1168 (while (and prefix-list
1203 (not (eq completion-entry 1169 (not (eq completion-entry
1204 (car (setq next-prefix-list (cdr prefix-list))) 1170 (car (setq next-prefix-list (cdr prefix-list))))))
1205 )))
1206 (setq prefix-list next-prefix-list)) 1171 (setq prefix-list next-prefix-list))
1207 (cond (;; found 1172 (cond (;; found
1208 prefix-list) 1173 prefix-list)
1209 ;; Didn't find it. Database is messed up. 1174 ;; Didn't find it. Database is messed up.
1210 (cmpl-db-debug-p 1175 (cmpl-db-debug-p
1216 (locate-completion-db-error)) 1181 (locate-completion-db-error))
1217 (t 1182 (t
1218 ;; Patch out 1183 ;; Patch out
1219 (set cmpl-db-symbol nil) 1184 (set cmpl-db-symbol nil)
1220 ;; Retry 1185 ;; Retry
1221 (locate-completion-entry-retry completion-entry) 1186 (locate-completion-entry-retry completion-entry)))))))
1222 ))))))
1223 1187
1224 (defun locate-completion-entry-retry (old-entry) 1188 (defun locate-completion-entry-retry (old-entry)
1225 (let ((inside-locate-completion-entry t)) 1189 (let ((inside-locate-completion-entry t))
1226 (add-completion (completion-string old-entry) 1190 (add-completion (completion-string old-entry)
1227 (completion-num-uses old-entry) 1191 (completion-num-uses old-entry)
1229 (let* ((cmpl-entry (find-exact-completion (completion-string old-entry))) 1193 (let* ((cmpl-entry (find-exact-completion (completion-string old-entry)))
1230 (pref-entry 1194 (pref-entry
1231 (if cmpl-entry 1195 (if cmpl-entry
1232 (find-cmpl-prefix-entry 1196 (find-cmpl-prefix-entry
1233 (substring cmpl-db-downcase-string 1197 (substring cmpl-db-downcase-string
1234 0 completion-prefix-min-length)))) 1198 0 completion-prefix-min-length)))))
1235 )
1236 (if (and cmpl-entry pref-entry) 1199 (if (and cmpl-entry pref-entry)
1237 ;; try again 1200 ;; try again
1238 (locate-completion-entry cmpl-entry pref-entry) 1201 (locate-completion-entry cmpl-entry pref-entry)
1239 ;; still losing 1202 ;; still losing
1240 (locate-completion-db-error)) 1203 (locate-completion-db-error)))))
1241 )))
1242 1204
1243 (defun locate-completion-db-error () 1205 (defun locate-completion-db-error ()
1244 ;; recursive error: really scrod 1206 ;; recursive error: really scrod
1245 (error "Completion database corrupted. Try M-x clear-all-completions. Send bug report.") 1207 (error "Completion database corrupted. Try M-x clear-all-completions. Send bug report."))
1246 )
1247 1208
1248 ;; WRITES 1209 ;; WRITES
1249 (defun add-completion-to-tail-if-new (string) 1210 (defun add-completion-to-tail-if-new (string)
1250 "If STRING is not in the database add it to appropriate prefix list. 1211 "If STRING is not in the database add it to appropriate prefix list.
1251 STRING is added to the end of the appropriate prefix list with 1212 STRING is added to the end of the appropriate prefix list with
1259 (entry (make-completion string)) 1220 (entry (make-completion string))
1260 ;; setup the prefix 1221 ;; setup the prefix
1261 (prefix-entry (find-cmpl-prefix-entry 1222 (prefix-entry (find-cmpl-prefix-entry
1262 (substring cmpl-db-downcase-string 0 1223 (substring cmpl-db-downcase-string 0
1263 (cmpl-read-time-eval 1224 (cmpl-read-time-eval
1264 completion-prefix-min-length)))) 1225 completion-prefix-min-length)))))
1265 )
1266 ;; The next two forms should happen as a unit (atomically) but 1226 ;; The next two forms should happen as a unit (atomically) but
1267 ;; no fatal errors should result if that is not the case. 1227 ;; no fatal errors should result if that is not the case.
1268 (cond (prefix-entry 1228 (cond (prefix-entry
1269 ;; These two should be atomic, but nothing fatal will happen 1229 ;; These two should be atomic, but nothing fatal will happen
1270 ;; if they're not. 1230 ;; if they're not.
1271 (setcdr (cmpl-prefix-entry-tail prefix-entry) entry) 1231 (setcdr (cmpl-prefix-entry-tail prefix-entry) entry)
1272 (set-cmpl-prefix-entry-tail prefix-entry entry)) 1232 (set-cmpl-prefix-entry-tail prefix-entry entry))
1273 (t 1233 (t
1274 (set cmpl-db-prefix-symbol (make-cmpl-prefix-entry entry)) 1234 (set cmpl-db-prefix-symbol (make-cmpl-prefix-entry entry))))
1275 ))
1276 ;; statistics 1235 ;; statistics
1277 (cmpl-statistics-block 1236 (cmpl-statistics-block
1278 (note-added-completion)) 1237 (note-added-completion))
1279 ;; set symbol 1238 ;; set symbol
1280 (set cmpl-db-symbol (car entry)) 1239 (set cmpl-db-symbol (car entry)))))
1281 )))
1282 1240
1283 (defun add-completion-to-head (completion-string) 1241 (defun add-completion-to-head (completion-string)
1284 "If COMPLETION-STRING is not in the database, add it to prefix list. 1242 "If COMPLETION-STRING is not in the database, add it to prefix list.
1285 We add COMPLETION-STRING to the head of the appropriate prefix list, 1243 We add COMPLETION-STRING to the head of the appropriate prefix list,
1286 or it to the head of the list. 1244 or it to the head of the list.
1296 (let* ((prefix-entry (find-cmpl-prefix-entry 1254 (let* ((prefix-entry (find-cmpl-prefix-entry
1297 (substring cmpl-db-downcase-string 0 1255 (substring cmpl-db-downcase-string 0
1298 (cmpl-read-time-eval 1256 (cmpl-read-time-eval
1299 completion-prefix-min-length)))) 1257 completion-prefix-min-length))))
1300 (splice-ptr (locate-completion-entry cmpl-db-entry prefix-entry)) 1258 (splice-ptr (locate-completion-entry cmpl-db-entry prefix-entry))
1301 (cmpl-ptr (cdr splice-ptr)) 1259 (cmpl-ptr (cdr splice-ptr)))
1302 )
1303 ;; update entry 1260 ;; update entry
1304 (set-completion-string cmpl-db-entry completion-string) 1261 (set-completion-string cmpl-db-entry completion-string)
1305 ;; move to head (if necessary) 1262 ;; move to head (if necessary)
1306 (cond (splice-ptr 1263 (cond (splice-ptr
1307 ;; These should all execute atomically but it is not fatal if 1264 ;; These should all execute atomically but it is not fatal if
1310 (or (setcdr splice-ptr (cdr cmpl-ptr)) 1267 (or (setcdr splice-ptr (cdr cmpl-ptr))
1311 ;; fix up tail if necessary 1268 ;; fix up tail if necessary
1312 (set-cmpl-prefix-entry-tail prefix-entry splice-ptr)) 1269 (set-cmpl-prefix-entry-tail prefix-entry splice-ptr))
1313 ;; splice in at head 1270 ;; splice in at head
1314 (setcdr cmpl-ptr (cmpl-prefix-entry-head prefix-entry)) 1271 (setcdr cmpl-ptr (cmpl-prefix-entry-head prefix-entry))
1315 (set-cmpl-prefix-entry-head prefix-entry cmpl-ptr) 1272 (set-cmpl-prefix-entry-head prefix-entry cmpl-ptr)))
1316 ))
1317 cmpl-db-entry) 1273 cmpl-db-entry)
1318 ;; not there 1274 ;; not there
1319 (let (;; create an entry 1275 (let (;; create an entry
1320 (entry (make-completion completion-string)) 1276 (entry (make-completion completion-string))
1321 ;; setup the prefix 1277 ;; setup the prefix
1322 (prefix-entry (find-cmpl-prefix-entry 1278 (prefix-entry (find-cmpl-prefix-entry
1323 (substring cmpl-db-downcase-string 0 1279 (substring cmpl-db-downcase-string 0
1324 (cmpl-read-time-eval 1280 (cmpl-read-time-eval
1325 completion-prefix-min-length)))) 1281 completion-prefix-min-length)))))
1326 )
1327 (cond (prefix-entry 1282 (cond (prefix-entry
1328 ;; Splice in at head 1283 ;; Splice in at head
1329 (setcdr entry (cmpl-prefix-entry-head prefix-entry)) 1284 (setcdr entry (cmpl-prefix-entry-head prefix-entry))
1330 (set-cmpl-prefix-entry-head prefix-entry entry)) 1285 (set-cmpl-prefix-entry-head prefix-entry entry))
1331 (t 1286 (t
1332 ;; Start new prefix entry 1287 ;; Start new prefix entry
1333 (set cmpl-db-prefix-symbol (make-cmpl-prefix-entry entry)) 1288 (set cmpl-db-prefix-symbol (make-cmpl-prefix-entry entry))))
1334 ))
1335 ;; statistics 1289 ;; statistics
1336 (cmpl-statistics-block 1290 (cmpl-statistics-block
1337 (note-added-completion)) 1291 (note-added-completion))
1338 ;; Add it to the symbol 1292 ;; Add it to the symbol
1339 (set cmpl-db-symbol (car entry)) 1293 (set cmpl-db-symbol (car entry)))))
1340 )))
1341 1294
1342 (defun delete-completion (completion-string) 1295 (defun delete-completion (completion-string)
1343 "Deletes the completion from the database. 1296 "Delete the completion from the database.
1344 String must be longer than `completion-prefix-min-length'." 1297 String must be longer than `completion-prefix-min-length'."
1345 ;; Handle pending acceptance 1298 ;; Handle pending acceptance
1346 (if completion-to-accept (accept-completion)) 1299 (if completion-to-accept (accept-completion))
1347 (if (setq cmpl-db-entry (find-exact-completion completion-string)) 1300 (if (setq cmpl-db-entry (find-exact-completion completion-string))
1348 ;; found 1301 ;; found
1349 (let* ((prefix-entry (find-cmpl-prefix-entry 1302 (let* ((prefix-entry (find-cmpl-prefix-entry
1350 (substring cmpl-db-downcase-string 0 1303 (substring cmpl-db-downcase-string 0
1351 (cmpl-read-time-eval 1304 (cmpl-read-time-eval
1352 completion-prefix-min-length)))) 1305 completion-prefix-min-length))))
1353 (splice-ptr (locate-completion-entry cmpl-db-entry prefix-entry)) 1306 (splice-ptr (locate-completion-entry cmpl-db-entry prefix-entry)))
1354 )
1355 ;; delete symbol reference 1307 ;; delete symbol reference
1356 (set cmpl-db-symbol nil) 1308 (set cmpl-db-symbol nil)
1357 ;; remove from prefix list 1309 ;; remove from prefix list
1358 (cond (splice-ptr 1310 (cond (splice-ptr
1359 ;; not at head 1311 ;; not at head
1360 (or (setcdr splice-ptr (cdr (cdr splice-ptr))) 1312 (or (setcdr splice-ptr (cdr (cdr splice-ptr)))
1361 ;; fix up tail if necessary 1313 ;; fix up tail if necessary
1362 (set-cmpl-prefix-entry-tail prefix-entry splice-ptr)) 1314 (set-cmpl-prefix-entry-tail prefix-entry splice-ptr)))
1363 )
1364 (t 1315 (t
1365 ;; at head 1316 ;; at head
1366 (or (set-cmpl-prefix-entry-head 1317 (or (set-cmpl-prefix-entry-head
1367 prefix-entry (cdr (cmpl-prefix-entry-head prefix-entry))) 1318 prefix-entry (cdr (cmpl-prefix-entry-head prefix-entry)))
1368 ;; List is now empty 1319 ;; List is now empty
1369 (set cmpl-db-prefix-symbol nil)) 1320 (set cmpl-db-prefix-symbol nil))))
1370 ))
1371 (cmpl-statistics-block 1321 (cmpl-statistics-block
1372 (note-completion-deleted)) 1322 (note-completion-deleted)))
1373 ) 1323 (error "Unknown completion `%s'" completion-string)))
1374 (error "Unknown completion `%s'" completion-string)
1375 ))
1376 1324
1377 ;; Tests -- 1325 ;; Tests --
1378 ;; - Add and Find - 1326 ;; - Add and Find -
1379 ;; (add-completion-to-head "banana") --> ("banana" 0 nil 0) 1327 ;; (add-completion-to-head "banana") --> ("banana" 0 nil 0)
1380 ;; (find-exact-completion "banana") --> ("banana" 0 nil 0) 1328 ;; (find-exact-completion "banana") --> ("banana" 0 nil 0)
1425 (defun interactive-completion-string-reader (prompt) 1373 (defun interactive-completion-string-reader (prompt)
1426 (let* ((default (symbol-under-or-before-point)) 1374 (let* ((default (symbol-under-or-before-point))
1427 (new-prompt 1375 (new-prompt
1428 (if default 1376 (if default
1429 (format "%s: (default: %s) " prompt default) 1377 (format "%s: (default: %s) " prompt default)
1430 (format "%s: " prompt)) 1378 (format "%s: " prompt)))
1431 ) 1379 (read (completing-read new-prompt cmpl-obarray)))
1432 (read (completing-read new-prompt cmpl-obarray))
1433 )
1434 (if (zerop (length read)) (setq read (or default ""))) 1380 (if (zerop (length read)) (setq read (or default "")))
1435 (list read) 1381 (list read)))
1436 ))
1437 1382
1438 (defun check-completion-length (string) 1383 (defun check-completion-length (string)
1439 (if (< (length string) completion-min-length) 1384 (if (< (length string) completion-min-length)
1440 (error "The string `%s' is too short to be saved as a completion" 1385 (error "The string `%s' is too short to be saved as a completion"
1441 string) 1386 string)
1452 current-completion-source)) 1397 current-completion-source))
1453 (entry (add-completion-to-head string))) 1398 (entry (add-completion-to-head string)))
1454 1399
1455 (if num-uses (set-completion-num-uses entry num-uses)) 1400 (if num-uses (set-completion-num-uses entry num-uses))
1456 (if last-use-time 1401 (if last-use-time
1457 (set-completion-last-use-time entry last-use-time)) 1402 (set-completion-last-use-time entry last-use-time))))
1458 ))
1459 1403
1460 (defun add-permanent-completion (string) 1404 (defun add-permanent-completion (string)
1461 "Add STRING if it isn't already listed, and mark it permanent." 1405 "Add STRING if it isn't already listed, and mark it permanent."
1462 (interactive 1406 (interactive
1463 (interactive-completion-string-reader "Completion to add permanently")) 1407 (interactive-completion-string-reader "Completion to add permanently"))
1464 (let ((current-completion-source (if (interactive-p) 1408 (let ((current-completion-source (if (interactive-p)
1465 cmpl-source-interactive 1409 cmpl-source-interactive
1466 current-completion-source)) 1410 current-completion-source)))
1467 ) 1411 (add-completion string nil t)))
1468 (add-completion string nil t)
1469 ))
1470 1412
1471 (defun kill-completion (string) 1413 (defun kill-completion (string)
1472 (interactive (interactive-completion-string-reader "Completion to kill")) 1414 (interactive (interactive-completion-string-reader "Completion to kill"))
1473 (check-completion-length string) 1415 (check-completion-length string)
1474 (delete-completion string) 1416 (delete-completion string))
1475 )
1476 1417
1477 (defun accept-completion () 1418 (defun accept-completion ()
1478 "Accepts the pending completion in `completion-to-accept'. 1419 "Accepts the pending completion in `completion-to-accept'.
1479 This bumps num-uses. Called by `add-completion-to-head' and 1420 This bumps num-uses. Called by `add-completion-to-head' and
1480 `completion-search-reset'." 1421 `completion-search-reset'."
1481 (let ((string completion-to-accept) 1422 (let ((string completion-to-accept)
1482 ;; if this is added afresh here, then it must be a cdabbrev 1423 ;; if this is added afresh here, then it must be a cdabbrev
1483 (current-completion-source cmpl-source-cdabbrev) 1424 (current-completion-source cmpl-source-cdabbrev)
1484 entry 1425 entry)
1485 )
1486 (setq completion-to-accept nil) 1426 (setq completion-to-accept nil)
1487 (setq entry (add-completion-to-head string)) 1427 (setq entry (add-completion-to-head string))
1488 (set-completion-num-uses entry (1+ (completion-num-uses entry))) 1428 (set-completion-num-uses entry (1+ (completion-num-uses entry)))
1489 (setq cmpl-completions-accepted-p t) 1429 (setq cmpl-completions-accepted-p t)))
1490 ))
1491 1430
1492 (defun use-completion-under-point () 1431 (defun use-completion-under-point ()
1493 "Add the completion symbol underneath the point into the completion buffer." 1432 "Add the completion symbol underneath the point into the completion buffer."
1494 (let ((string (and enable-completion (symbol-under-point))) 1433 (let ((string (and enable-completion (symbol-under-point)))
1495 (current-completion-source cmpl-source-cursor-moves)) 1434 (current-completion-source cmpl-source-cursor-moves))
1513 `completion-on-separator-character' is non-nil." 1452 `completion-on-separator-character' is non-nil."
1514 (let ((string (and enable-completion (symbol-before-point))) 1453 (let ((string (and enable-completion (symbol-before-point)))
1515 (current-completion-source cmpl-source-separator) 1454 (current-completion-source cmpl-source-separator)
1516 entry) 1455 entry)
1517 (cmpl-statistics-block 1456 (cmpl-statistics-block
1518 (note-separator-character string) 1457 (note-separator-character string))
1519 )
1520 (cond (string 1458 (cond (string
1521 (setq entry (add-completion-to-head string)) 1459 (setq entry (add-completion-to-head string))
1522 (if (and completion-on-separator-character 1460 (if (and completion-on-separator-character
1523 (zerop (completion-num-uses entry))) 1461 (zerop (completion-num-uses entry)))
1524 (progn 1462 (progn
1525 (set-completion-num-uses entry 1) 1463 (set-completion-num-uses entry 1)
1526 (setq cmpl-completions-accepted-p t))))) 1464 (setq cmpl-completions-accepted-p t)))))))
1527 ))
1528 1465
1529 ;; Tests -- 1466 ;; Tests --
1530 ;; - Add and Find - 1467 ;; - Add and Find -
1531 ;; (add-completion "banana" 5 10) 1468 ;; (add-completion "banana" 5 10)
1532 ;; (find-exact-completion "banana") --> ("banana" 5 10 0) 1469 ;; (find-exact-completion "banana") --> ("banana" 5 10 0)
1587 (cmpl-prefix-entry-head 1524 (cmpl-prefix-entry-head
1588 (find-cmpl-prefix-entry 1525 (find-cmpl-prefix-entry
1589 (downcase (substring string 0 completion-prefix-min-length)))) 1526 (downcase (substring string 0 completion-prefix-min-length))))
1590 cmpl-test-string string 1527 cmpl-test-string string
1591 cmpl-test-regexp (concat (regexp-quote string) ".")) 1528 cmpl-test-regexp (concat (regexp-quote string) "."))
1592 (completion-search-reset-1) 1529 (completion-search-reset-1))
1593 )
1594 1530
1595 (defun completion-search-reset-1 () 1531 (defun completion-search-reset-1 ()
1596 (setq cmpl-next-possibilities cmpl-starting-possibilities 1532 (setq cmpl-next-possibilities cmpl-starting-possibilities
1597 cmpl-next-possibility nil 1533 cmpl-next-possibility nil
1598 cmpl-cdabbrev-reset-p nil 1534 cmpl-cdabbrev-reset-p nil
1599 cmpl-last-index -1 1535 cmpl-last-index -1
1600 cmpl-tried-list nil 1536 cmpl-tried-list nil))
1601 ))
1602 1537
1603 (defun completion-search-next (index) 1538 (defun completion-search-next (index)
1604 "Return the next completion entry. 1539 "Return the next completion entry.
1605 If INDEX is out of sequence, reset and start from the top. 1540 If INDEX is out of sequence, reset and start from the top.
1606 If there are no more entries, try cdabbrev and returns only a string." 1541 If there are no more entries, try cdabbrev and returns only a string."
1613 ;; reverse the possibilities list 1548 ;; reverse the possibilities list
1614 (setq cmpl-next-possibilities (reverse cmpl-starting-possibilities)) 1549 (setq cmpl-next-possibilities (reverse cmpl-starting-possibilities))
1615 ;; do a "normal" search 1550 ;; do a "normal" search
1616 (while (and (completion-search-peek nil) 1551 (while (and (completion-search-peek nil)
1617 (< (setq index (1+ index)) 0)) 1552 (< (setq index (1+ index)) 0))
1618 (setq cmpl-next-possibility nil) 1553 (setq cmpl-next-possibility nil))
1619 )
1620 (cond ((not cmpl-next-possibilities)) 1554 (cond ((not cmpl-next-possibilities))
1621 ;; If no more possibilities, leave it that way 1555 ;; If no more possibilities, leave it that way
1622 ((= -1 cmpl-last-index) 1556 ((= -1 cmpl-last-index)
1623 ;; next completion is at index 0. reset next-possibility list 1557 ;; next completion is at index 0. reset next-possibility list
1624 ;; to start at beginning 1558 ;; to start at beginning
1626 (t 1560 (t
1627 ;; otherwise point to one before current 1561 ;; otherwise point to one before current
1628 (setq cmpl-next-possibilities 1562 (setq cmpl-next-possibilities
1629 (nthcdr (- (length cmpl-starting-possibilities) 1563 (nthcdr (- (length cmpl-starting-possibilities)
1630 (length cmpl-next-possibilities)) 1564 (length cmpl-next-possibilities))
1631 cmpl-starting-possibilities)) 1565 cmpl-starting-possibilities)))))
1632 )))
1633 (t 1566 (t
1634 ;; non-negative index, reset and search 1567 ;; non-negative index, reset and search
1635 ;;(prin1 'reset) 1568 ;;(prin1 'reset)
1636 (completion-search-reset-1) 1569 (completion-search-reset-1)
1637 (setq cmpl-last-index index) 1570 (setq cmpl-last-index index)
1638 (while (and (completion-search-peek t) 1571 (while (and (completion-search-peek t)
1639 (not (< (setq index (1- index)) 0))) 1572 (not (< (setq index (1- index)) 0)))
1640 (setq cmpl-next-possibility nil) 1573 (setq cmpl-next-possibility nil))))
1641 ))
1642 )
1643 (prog1 1574 (prog1
1644 cmpl-next-possibility 1575 cmpl-next-possibility
1645 (setq cmpl-next-possibility nil) 1576 (setq cmpl-next-possibility nil)))
1646 ))
1647 1577
1648 1578
1649 (defun completion-search-peek (use-cdabbrev) 1579 (defun completion-search-peek (use-cdabbrev)
1650 "Returns the next completion entry without actually moving the pointers. 1580 "Returns the next completion entry without actually moving the pointers.
1651 Calling this again or calling `completion-search-next' results in the same 1581 Calling this again or calling `completion-search-next' results in the same
1658 ;; still a few possibilities left 1588 ;; still a few possibilities left
1659 (progn 1589 (progn
1660 (while 1590 (while
1661 (and (not (eq 0 (string-match cmpl-test-regexp 1591 (and (not (eq 0 (string-match cmpl-test-regexp
1662 (completion-string (car cmpl-next-possibilities))))) 1592 (completion-string (car cmpl-next-possibilities)))))
1663 (setq cmpl-next-possibilities (cdr cmpl-next-possibilities)) 1593 (setq cmpl-next-possibilities (cdr cmpl-next-possibilities))))
1664 )) 1594 cmpl-next-possibilities))
1665 cmpl-next-possibilities
1666 ))
1667 ;; successful match 1595 ;; successful match
1668 (setq cmpl-next-possibility (car cmpl-next-possibilities) 1596 (setq cmpl-next-possibility (car cmpl-next-possibilities)
1669 cmpl-tried-list (cons (downcase (completion-string cmpl-next-possibility)) 1597 cmpl-tried-list (cons (downcase (completion-string cmpl-next-possibility))
1670 cmpl-tried-list) 1598 cmpl-tried-list)
1671 cmpl-next-possibilities (cdr cmpl-next-possibilities) 1599 cmpl-next-possibilities (cdr cmpl-next-possibilities))
1672 )
1673 cmpl-next-possibility) 1600 cmpl-next-possibility)
1674 (use-cdabbrev 1601 (use-cdabbrev
1675 ;; unsuccessful, use cdabbrev 1602 ;; unsuccessful, use cdabbrev
1676 (cond ((not cmpl-cdabbrev-reset-p) 1603 (cond ((not cmpl-cdabbrev-reset-p)
1677 (reset-cdabbrev cmpl-test-string cmpl-tried-list) 1604 (reset-cdabbrev cmpl-test-string cmpl-tried-list)
1678 (setq cmpl-cdabbrev-reset-p t) 1605 (setq cmpl-cdabbrev-reset-p t)))
1679 )) 1606 (setq cmpl-next-possibility (next-cdabbrev)))
1680 (setq cmpl-next-possibility (next-cdabbrev))
1681 )
1682 ;; Completely unsuccessful, return nil 1607 ;; Completely unsuccessful, return nil
1683 )) 1608 ))
1684 1609
1685 ;; Tests -- 1610 ;; Tests --
1686 ;; - Add and Find - 1611 ;; - Add and Find -
1726 ;;----------------------------------------------- 1651 ;;-----------------------------------------------
1727 ;; COMPLETE 1652 ;; COMPLETE
1728 ;;----------------------------------------------- 1653 ;;-----------------------------------------------
1729 1654
1730 (defun completion-mode () 1655 (defun completion-mode ()
1731 "Toggles whether or not to add new words to the completion database." 1656 "Toggle whether or not to add new words to the completion database."
1732 (interactive) 1657 (interactive)
1733 (setq enable-completion (not enable-completion)) 1658 (setq enable-completion (not enable-completion))
1734 (message "Completion mode is now %s." (if enable-completion "ON" "OFF")) 1659 (message "Completion mode is now %s." (if enable-completion "ON" "OFF")))
1735 )
1736 1660
1737 (defvar cmpl-current-index 0) 1661 (defvar cmpl-current-index 0)
1738 (defvar cmpl-original-string nil) 1662 (defvar cmpl-original-string nil)
1739 (defvar cmpl-last-insert-location -1) 1663 (defvar cmpl-last-insert-location -1)
1740 (defvar cmpl-leave-point-at-start nil) 1664 (defvar cmpl-leave-point-at-start nil)
1752 ;;; Set up variables 1676 ;;; Set up variables
1753 (cond ((eq last-command this-command) 1677 (cond ((eq last-command this-command)
1754 ;; Undo last one 1678 ;; Undo last one
1755 (delete-region cmpl-last-insert-location (point)) 1679 (delete-region cmpl-last-insert-location (point))
1756 ;; get next completion 1680 ;; get next completion
1757 (setq cmpl-current-index (+ cmpl-current-index (or arg 1))) 1681 (setq cmpl-current-index (+ cmpl-current-index (or arg 1))))
1758 )
1759 (t 1682 (t
1760 (if (not cmpl-initialized-p) 1683 (if (not cmpl-initialized-p)
1761 (initialize-completions)) ;; make sure everything's loaded 1684 (initialize-completions)) ;; make sure everything's loaded
1762 (cond ((consp current-prefix-arg) ;; control-u 1685 (cond ((consp current-prefix-arg) ;; control-u
1763 (setq arg 0) 1686 (setq arg 0)
1764 (setq cmpl-leave-point-at-start t) 1687 (setq cmpl-leave-point-at-start t))
1765 )
1766 (t 1688 (t
1767 (setq cmpl-leave-point-at-start nil) 1689 (setq cmpl-leave-point-at-start nil)))
1768 ))
1769 ;; get string 1690 ;; get string
1770 (setq cmpl-original-string (symbol-before-point-for-complete)) 1691 (setq cmpl-original-string (symbol-before-point-for-complete))
1771 (cond ((not cmpl-original-string) 1692 (cond ((not cmpl-original-string)
1772 (setq this-command 'failed-complete) 1693 (setq this-command 'failed-complete)
1773 (error "To complete, point must be after a symbol at least %d character long" 1694 (error "To complete, point must be after a symbol at least %d character long"
1778 (cmpl-statistics-block 1699 (cmpl-statistics-block
1779 (note-complete-entered-afresh cmpl-original-string)) 1700 (note-complete-entered-afresh cmpl-original-string))
1780 ;; reset database 1701 ;; reset database
1781 (completion-search-reset cmpl-original-string) 1702 (completion-search-reset cmpl-original-string)
1782 ;; erase what we've got 1703 ;; erase what we've got
1783 (delete-region cmpl-symbol-start cmpl-symbol-end) 1704 (delete-region cmpl-symbol-start cmpl-symbol-end)))
1784 ))
1785 1705
1786 ;; point is at the point to insert the new symbol 1706 ;; point is at the point to insert the new symbol
1787 ;; Get the next completion 1707 ;; Get the next completion
1788 (let* ((print-status-p 1708 (let* ((print-status-p
1789 (and (>= baud-rate completion-prompt-speed-threshold) 1709 (and (>= baud-rate completion-prompt-speed-threshold)
1790 (not (minibuffer-window-selected-p)))) 1710 (not (minibuffer-window-selected-p))))
1791 (insert-point (point)) 1711 (insert-point (point))
1792 (entry (completion-search-next cmpl-current-index)) 1712 (entry (completion-search-next cmpl-current-index))
1793 string 1713 string)
1794 )
1795 ;; entry is either a completion entry or a string (if cdabbrev) 1714 ;; entry is either a completion entry or a string (if cdabbrev)
1796 1715
1797 ;; If found, insert 1716 ;; If found, insert
1798 (cond (entry 1717 (cond (entry
1799 ;; Setup for proper case 1718 ;; Setup for proper case
1808 ;; fixup and cache point 1727 ;; fixup and cache point
1809 (cond (cmpl-leave-point-at-start 1728 (cond (cmpl-leave-point-at-start
1810 (setq cmpl-last-insert-location (point)) 1729 (setq cmpl-last-insert-location (point))
1811 (goto-char insert-point)) 1730 (goto-char insert-point))
1812 (t;; point at end, 1731 (t;; point at end,
1813 (setq cmpl-last-insert-location insert-point)) 1732 (setq cmpl-last-insert-location insert-point)))
1814 )
1815 ;; statistics 1733 ;; statistics
1816 (cmpl-statistics-block 1734 (cmpl-statistics-block
1817 (note-complete-inserted entry cmpl-current-index)) 1735 (note-complete-inserted entry cmpl-current-index))
1818 ;; Done ! cmpl-stat-complete-successful 1736 ;; Done ! cmpl-stat-complete-successful
1819 ;;display the next completion 1737 ;;display the next completion
1827 completion-cdabbrev-prompt-flag))) 1745 completion-cdabbrev-prompt-flag)))
1828 (setq string (if (stringp entry) 1746 (setq string (if (stringp entry)
1829 entry (completion-string entry))) 1747 entry (completion-string entry)))
1830 (setq string (cmpl-merge-string-cases 1748 (setq string (cmpl-merge-string-cases
1831 string cmpl-original-string)) 1749 string cmpl-original-string))
1832 (message "Next completion: %s" string) 1750 (message "Next completion: %s" string))))
1833 ))
1834 )
1835 (t;; none found, insert old 1751 (t;; none found, insert old
1836 (insert cmpl-original-string) 1752 (insert cmpl-original-string)
1837 ;; Don't accept completions 1753 ;; Don't accept completions
1838 (setq completion-to-accept nil) 1754 (setq completion-to-accept nil)
1839 ;; print message 1755 ;; print message
1844 (if (eq this-command last-command) "more " ""))) 1760 (if (eq this-command last-command) "more " "")))
1845 ;; statistics 1761 ;; statistics
1846 (cmpl-statistics-block 1762 (cmpl-statistics-block
1847 (record-complete-failed cmpl-current-index)) 1763 (record-complete-failed cmpl-current-index))
1848 ;; Pretend that we were never here 1764 ;; Pretend that we were never here
1849 (setq this-command 'failed-complete) 1765 (setq this-command 'failed-complete)))))
1850 ))))
1851 1766
1852 ;;--------------------------------------------------------------------------- 1767 ;;---------------------------------------------------------------------------
1853 ;; Parsing definitions from files into the database 1768 ;; Parsing definitions from files into the database
1854 ;;--------------------------------------------------------------------------- 1769 ;;---------------------------------------------------------------------------
1855 1770
1857 ;; Top Level functions :: 1772 ;; Top Level functions ::
1858 ;;----------------------------------------------- 1773 ;;-----------------------------------------------
1859 1774
1860 ;; User interface 1775 ;; User interface
1861 (defun add-completions-from-file (file) 1776 (defun add-completions-from-file (file)
1862 "Parse possible completions from a file and add them to data base." 1777 "Parse possible completions from a FILE and add them to data base."
1863 (interactive "fFile: ") 1778 (interactive "fFile: ")
1864 (setq file (expand-file-name file)) 1779 (setq file (expand-file-name file))
1865 (let* ((buffer (get-file-buffer file)) 1780 (let* ((buffer (get-file-buffer file))
1866 (buffer-already-there-p buffer) 1781 (buffer-already-there-p buffer))
1867 )
1868 (if (not buffer-already-there-p) 1782 (if (not buffer-already-there-p)
1869 (let ((completions-merging-modes nil)) 1783 (let ((completions-merging-modes nil))
1870 (setq buffer (find-file-noselect file)))) 1784 (setq buffer (find-file-noselect file))))
1871 (unwind-protect 1785 (unwind-protect
1872 (save-excursion 1786 (save-excursion
1873 (set-buffer buffer) 1787 (set-buffer buffer)
1874 (add-completions-from-buffer) 1788 (add-completions-from-buffer))
1875 )
1876 (if (not buffer-already-there-p) 1789 (if (not buffer-already-there-p)
1877 (kill-buffer buffer))))) 1790 (kill-buffer buffer)))))
1878 1791
1879 (defun add-completions-from-buffer () 1792 (defun add-completions-from-buffer ()
1880 (interactive) 1793 (interactive)
1881 (let ((current-completion-source cmpl-source-file-parsing) 1794 (let ((current-completion-source cmpl-source-file-parsing)
1882 (start-num 1795 (start-num
1883 (cmpl-statistics-block 1796 (cmpl-statistics-block
1884 (aref completion-add-count-vector cmpl-source-file-parsing))) 1797 (aref completion-add-count-vector cmpl-source-file-parsing)))
1885 mode 1798 mode)
1886 )
1887 (cond ((memq major-mode '(emacs-lisp-mode lisp-mode)) 1799 (cond ((memq major-mode '(emacs-lisp-mode lisp-mode))
1888 (add-completions-from-lisp-buffer) 1800 (add-completions-from-lisp-buffer)
1889 (setq mode 'lisp) 1801 (setq mode 'lisp))
1890 )
1891 ((memq major-mode '(c-mode)) 1802 ((memq major-mode '(c-mode))
1892 (add-completions-from-c-buffer) 1803 (add-completions-from-c-buffer)
1893 (setq mode 'c) 1804 (setq mode 'c))
1894 )
1895 (t 1805 (t
1896 (error "Cannot parse completions in %s buffers" 1806 (error "Cannot parse completions in %s buffers"
1897 major-mode) 1807 major-mode)))
1898 ))
1899 (cmpl-statistics-block 1808 (cmpl-statistics-block
1900 (record-cmpl-parse-file 1809 (record-cmpl-parse-file
1901 mode (point-max) 1810 mode (point-max)
1902 (- (aref completion-add-count-vector cmpl-source-file-parsing) 1811 (- (aref completion-add-count-vector cmpl-source-file-parsing)
1903 start-num))) 1812 start-num)))))
1904 ))
1905 1813
1906 ;; Find file hook 1814 ;; Find file hook
1907 (defun cmpl-find-file-hook () 1815 (defun cmpl-find-file-hook ()
1908 (cond (enable-completion 1816 (cond (enable-completion
1909 (cond ((and (memq major-mode '(emacs-lisp-mode lisp-mode)) 1817 (cond ((and (memq major-mode '(emacs-lisp-mode lisp-mode))
1910 (memq 'lisp completions-merging-modes) 1818 (memq 'lisp completions-merging-modes))
1911 )
1912 (add-completions-from-buffer)) 1819 (add-completions-from-buffer))
1913 ((and (memq major-mode '(c-mode)) 1820 ((and (memq major-mode '(c-mode))
1914 (memq 'c completions-merging-modes) 1821 (memq 'c completions-merging-modes))
1915 ) 1822 (add-completions-from-buffer))))))
1916 (add-completions-from-buffer)
1917 )))
1918 ))
1919 1823
1920 ;;----------------------------------------------- 1824 ;;-----------------------------------------------
1921 ;; Tags Table Completions 1825 ;; Tags Table Completions
1922 ;;----------------------------------------------- 1826 ;;-----------------------------------------------
1923 1827
1933 (while t 1837 (while t
1934 (search-forward "\177") 1838 (search-forward "\177")
1935 (backward-char 3) 1839 (backward-char 3)
1936 (and (setq string (symbol-under-point)) 1840 (and (setq string (symbol-under-point))
1937 (add-completion-to-tail-if-new string)) 1841 (add-completion-to-tail-if-new string))
1938 (forward-char 3) 1842 (forward-char 3))
1939 ) 1843 (search-failed)))))
1940 (search-failed)
1941 ))))
1942 1844
1943 1845
1944 ;;----------------------------------------------- 1846 ;;-----------------------------------------------
1945 ;; Lisp File completion parsing 1847 ;; Lisp File completion parsing
1946 ;;----------------------------------------------- 1848 ;;-----------------------------------------------
1950 ;; We tried using forward-lines and explicit searches but the regexp technique 1852 ;; We tried using forward-lines and explicit searches but the regexp technique
1951 ;; was faster. (About 100K characters per second) 1853 ;; was faster. (About 100K characters per second)
1952 ;; 1854 ;;
1953 (defconst *lisp-def-regexp* 1855 (defconst *lisp-def-regexp*
1954 "\n(\\(\\w*:\\)?def\\(\\w\\|\\s_\\)*\\s +(*" 1856 "\n(\\(\\w*:\\)?def\\(\\w\\|\\s_\\)*\\s +(*"
1955 "A regexp that searches for lisp definition form." 1857 "A regexp that searches for Lisp definition form.")
1956 )
1957 1858
1958 ;; Tests - 1859 ;; Tests -
1959 ;; (and (string-match *lisp-def-regexp* "\n(defun foo") (match-end 0)) -> 8 1860 ;; (and (string-match *lisp-def-regexp* "\n(defun foo") (match-end 0)) -> 8
1960 ;; (and (string-match *lisp-def-regexp* "\n(si:def foo") (match-end 0)) -> 9 1861 ;; (and (string-match *lisp-def-regexp* "\n(si:def foo") (match-end 0)) -> 9
1961 ;; (and (string-match *lisp-def-regexp* "\n(def-bar foo")(match-end 0)) -> 10 1862 ;; (and (string-match *lisp-def-regexp* "\n(def-bar foo")(match-end 0)) -> 10
1971 (goto-char (point-min)) 1872 (goto-char (point-min))
1972 (condition-case e 1873 (condition-case e
1973 (while t 1874 (while t
1974 (re-search-forward *lisp-def-regexp*) 1875 (re-search-forward *lisp-def-regexp*)
1975 (and (setq string (symbol-under-point)) 1876 (and (setq string (symbol-under-point))
1976 (add-completion-to-tail-if-new string)) 1877 (add-completion-to-tail-if-new string)))
1977 ) 1878 (search-failed)))))
1978 (search-failed)
1979 ))))
1980 1879
1981 1880
1982 ;;----------------------------------------------- 1881 ;;-----------------------------------------------
1983 ;; C file completion parsing 1882 ;; C file completion parsing
1984 ;;----------------------------------------------- 1883 ;;-----------------------------------------------
1998 1897
1999 (defun cmpl-make-c-def-completion-syntax-table () 1898 (defun cmpl-make-c-def-completion-syntax-table ()
2000 (let ((table (make-syntax-table)) 1899 (let ((table (make-syntax-table))
2001 (whitespace-chars '(? ?\n ?\t ?\f ?\v ?\r)) 1900 (whitespace-chars '(? ?\n ?\t ?\f ?\v ?\r))
2002 ;; unfortunately the ?( causes the parens to appear unbalanced 1901 ;; unfortunately the ?( causes the parens to appear unbalanced
2003 (separator-chars '(?, ?* ?= ?\( ?\; 1902 (separator-chars '(?, ?* ?= ?\( ?\;))
2004 ))
2005 i) 1903 i)
2006 ;; default syntax is whitespace 1904 ;; default syntax is whitespace
2007 (setq i 0) 1905 (setq i 0)
2008 (while (< i 256) 1906 (while (< i 256)
2009 (modify-syntax-entry i "w" table) 1907 (modify-syntax-entry i "w" table)
2028 ;;"\n\\(#define\\s +.\\|\\(\\(\\w\\|\\s_\\)+\\b\\s *\\)+[(;,[*{=]\\)" 1926 ;;"\n\\(#define\\s +.\\|\\(\\(\\w\\|\\s_\\)+\\b\\s *\\)+[(;,[*{=]\\)"
2029 ;; This stops before the symbol to add. {Test cases in parens. below} 1927 ;; This stops before the symbol to add. {Test cases in parens. below}
2030 ;;"\n\\(\\(\\w\\|\\s_\\)+\\s *(\\|\\(\\(#define\\|auto\\|extern\\|register\\|static\\|int\\|long\\|short\\|unsigned\\|char\\|void\\|float\\|double\\|enum\\|struct\\|union\\|typedef\\)\\s +\\)+\\)" 1928 ;;"\n\\(\\(\\w\\|\\s_\\)+\\s *(\\|\\(\\(#define\\|auto\\|extern\\|register\\|static\\|int\\|long\\|short\\|unsigned\\|char\\|void\\|float\\|double\\|enum\\|struct\\|union\\|typedef\\)\\s +\\)+\\)"
2031 ;; this simple version picks up too much extraneous stuff 1929 ;; this simple version picks up too much extraneous stuff
2032 ;; "\n\\(\\w\\|\\s_\\|#\\)\\B" 1930 ;; "\n\\(\\w\\|\\s_\\|#\\)\\B"
2033 "A regexp that searches for a definition form." 1931 "A regexp that searches for a definition form.")
2034 )
2035 ; 1932 ;
2036 ;(defconst *c-cont-regexp* 1933 ;(defconst *c-cont-regexp*
2037 ; "\\(\\w\\|\\s_\\)+\\b\\s *\\({\\|\\(\\[[0-9\t ]*\\]\\s *\\)*,\\(*\\|\\s \\)*\\b\\)" 1934 ; "\\(\\w\\|\\s_\\)+\\b\\s *\\({\\|\\(\\[[0-9\t ]*\\]\\s *\\)*,\\(*\\|\\s \\)*\\b\\)"
2038 ; "This regexp should be used in a looking-at to parse for lists of variables.") 1935 ; "This regexp should be used in a looking-at to parse for lists of variables.")
2039 ; 1936 ;
2063 (defun add-completions-from-c-buffer () 1960 (defun add-completions-from-c-buffer ()
2064 ;; Benchmark -- 1961 ;; Benchmark --
2065 ;; Sun 3/280-- 1250 lines/sec. 1962 ;; Sun 3/280-- 1250 lines/sec.
2066 1963
2067 (let (string next-point char 1964 (let (string next-point char
2068 (saved-syntax (syntax-table)) 1965 (saved-syntax (syntax-table)))
2069 )
2070 (save-excursion 1966 (save-excursion
2071 (goto-char (point-min)) 1967 (goto-char (point-min))
2072 (catch 'finish-add-completions 1968 (catch 'finish-add-completions
2073 (unwind-protect 1969 (unwind-protect
2074 (while t 1970 (while t
2081 (cond 1977 (cond
2082 ((= (preceding-char) ?#) 1978 ((= (preceding-char) ?#)
2083 ;; preprocessor macro, see if it's one we handle 1979 ;; preprocessor macro, see if it's one we handle
2084 (setq string (buffer-substring (point) (+ (point) 6))) 1980 (setq string (buffer-substring (point) (+ (point) 6)))
2085 (cond ((or (string-equal string "define") 1981 (cond ((or (string-equal string "define")
2086 (string-equal string "ifdef ") 1982 (string-equal string "ifdef "))
2087 )
2088 ;; skip forward over definition symbol 1983 ;; skip forward over definition symbol
2089 ;; and add it to database 1984 ;; and add it to database
2090 (and (forward-word 2) 1985 (and (forward-word 2)
2091 (setq string (symbol-before-point)) 1986 (setq string (symbol-before-point))
2092 ;;(push string foo) 1987 ;;(push string foo)
2093 (add-completion-to-tail-if-new string) 1988 (add-completion-to-tail-if-new string)))))
2094 ))))
2095 (t 1989 (t
2096 ;; C definition 1990 ;; C definition
2097 (setq next-point (point)) 1991 (setq next-point (point))
2098 (while (and 1992 (while (and
2099 next-point 1993 next-point
2100 ;; scan to next separator char. 1994 ;; scan to next separator char.
2101 (setq next-point (scan-sexps next-point 1)) 1995 (setq next-point (scan-sexps next-point 1)))
2102 )
2103 ;; position the point on the word we want to add 1996 ;; position the point on the word we want to add
2104 (goto-char next-point) 1997 (goto-char next-point)
2105 (while (= (setq char (following-char)) ?*) 1998 (while (= (setq char (following-char)) ?*)
2106 ;; handle pointer ref 1999 ;; handle pointer ref
2107 ;; move to next separator char. 2000 ;; move to next separator char.
2108 (goto-char 2001 (goto-char
2109 (setq next-point (scan-sexps (point) 1))) 2002 (setq next-point (scan-sexps (point) 1))))
2110 )
2111 (forward-word -1) 2003 (forward-word -1)
2112 ;; add to database 2004 ;; add to database
2113 (if (setq string (symbol-under-point)) 2005 (if (setq string (symbol-under-point))
2114 ;; (push string foo) 2006 ;; (push string foo)
2115 (add-completion-to-tail-if-new string) 2007 (add-completion-to-tail-if-new string)
2116 ;; Local TMC hack (useful for parsing paris.h) 2008 ;; Local TMC hack (useful for parsing paris.h)
2117 (if (and (looking-at "_AP") ;; "ansi prototype" 2009 (if (and (looking-at "_AP") ;; "ansi prototype"
2118 (progn 2010 (progn
2119 (forward-word -1) 2011 (forward-word -1)
2120 (setq string 2012 (setq string
2121 (symbol-under-point)) 2013 (symbol-under-point))))
2122 )) 2014 (add-completion-to-tail-if-new string)))
2123 (add-completion-to-tail-if-new string)
2124 )
2125 )
2126 ;; go to next 2015 ;; go to next
2127 (goto-char next-point) 2016 (goto-char next-point)
2128 ;; (push (format "%c" (following-char)) foo) 2017 ;; (push (format "%c" (following-char)) foo)
2129 (if (= (char-syntax char) ?\() 2018 (if (= (char-syntax char) ?\()
2130 ;; if on an opening delimiter, go to end 2019 ;; if on an opening delimiter, go to end
2131 (while (= (char-syntax char) ?\() 2020 (while (= (char-syntax char) ?\()
2132 (setq next-point (scan-sexps next-point 1) 2021 (setq next-point (scan-sexps next-point 1)
2133 char (char-after next-point)) 2022 char (char-after next-point)))
2134 )
2135 (or (= char ?,) 2023 (or (= char ?,)
2136 ;; Current char is an end char. 2024 ;; Current char is an end char.
2137 (setq next-point nil) 2025 (setq next-point nil)))))))
2138 ))
2139 ))))
2140 (search-failed ;;done 2026 (search-failed ;;done
2141 (throw 'finish-add-completions t) 2027 (throw 'finish-add-completions t))
2142 )
2143 (error 2028 (error
2144 ;; Check for failure in scan-sexps 2029 ;; Check for failure in scan-sexps
2145 (if (or (string-equal (nth 1 e) 2030 (if (or (string-equal (nth 1 e)
2146 "Containing expression ends prematurely") 2031 "Containing expression ends prematurely")
2147 (string-equal (nth 1 e) "Unbalanced parentheses")) 2032 (string-equal (nth 1 e) "Unbalanced parentheses"))
2148 ;; unbalanced paren., keep going 2033 ;; unbalanced paren., keep going
2149 ;;(ding) 2034 ;;(ding)
2150 (forward-line 1) 2035 (forward-line 1)
2151 (message "Error parsing C buffer for completions--please send bug report") 2036 (message "Error parsing C buffer for completions--please send bug report")
2152 (throw 'finish-add-completions t) 2037 (throw 'finish-add-completions t)))))
2153 )) 2038 (set-syntax-table saved-syntax))))))
2154 ))
2155 (set-syntax-table saved-syntax)
2156 )))))
2157 2039
2158 2040
2159 ;;--------------------------------------------------------------------------- 2041 ;;---------------------------------------------------------------------------
2160 ;; Init files 2042 ;; Init files
2161 ;;--------------------------------------------------------------------------- 2043 ;;---------------------------------------------------------------------------
2204 last-use-time 2086 last-use-time
2205 (current-time (cmpl-hours-since-origin)) 2087 (current-time (cmpl-hours-since-origin))
2206 (total-in-db 0) 2088 (total-in-db 0)
2207 (total-perm 0) 2089 (total-perm 0)
2208 (total-saved 0) 2090 (total-saved 0)
2209 (backup-filename (completion-backup-filename filename)) 2091 (backup-filename (completion-backup-filename filename)))
2210 )
2211 2092
2212 (save-excursion 2093 (save-excursion
2213 (get-buffer-create " *completion-save-buffer*") 2094 (get-buffer-create " *completion-save-buffer*")
2214 (set-buffer " *completion-save-buffer*") 2095 (set-buffer " *completion-save-buffer*")
2215 (setq buffer-file-name filename) 2096 (setq buffer-file-name filename)
2242 (and last-use-time 2123 (and last-use-time
2243 ;; save-completions-retention-time is nil 2124 ;; save-completions-retention-time is nil
2244 (or (not save-completions-retention-time) 2125 (or (not save-completions-retention-time)
2245 ;; or time since last use is < ...retention-time* 2126 ;; or time since last use is < ...retention-time*
2246 (< (- current-time last-use-time) 2127 (< (- current-time last-use-time)
2247 save-completions-retention-time)) 2128 save-completions-retention-time)))))
2248 )))
2249 ;; write to file 2129 ;; write to file
2250 (setq total-saved (1+ total-saved)) 2130 (setq total-saved (1+ total-saved))
2251 (insert (prin1-to-string (cons (completion-string completion) 2131 (insert (prin1-to-string (cons (completion-string completion)
2252 last-use-time)) "\n") 2132 last-use-time)) "\n"))))
2253 )))
2254 2133
2255 ;; write the buffer 2134 ;; write the buffer
2256 (condition-case e 2135 (condition-case e
2257 (let ((file-exists-p (file-exists-p filename))) 2136 (let ((file-exists-p (file-exists-p filename)))
2258 (if file-exists-p 2137 (if file-exists-p
2273 (if file-exists-p 2152 (if file-exists-p
2274 ;; If successful, remove backup 2153 ;; If successful, remove backup
2275 (delete-file backup-filename))) 2154 (delete-file backup-filename)))
2276 (error 2155 (error
2277 (set-buffer-modified-p nil) 2156 (set-buffer-modified-p nil)
2278 (message "Couldn't save completion file `%s'" filename) 2157 (message "Couldn't save completion file `%s'" filename)))
2279 ))
2280 ;; Reset accepted-p flag 2158 ;; Reset accepted-p flag
2281 (setq cmpl-completions-accepted-p nil) 2159 (setq cmpl-completions-accepted-p nil) )
2282 )
2283 (cmpl-statistics-block 2160 (cmpl-statistics-block
2284 (record-save-completions total-in-db total-perm total-saved)) 2161 (record-save-completions total-in-db total-perm total-saved))))))
2285 ))))
2286 2162
2287 ;;(defun auto-save-completions () 2163 ;;(defun auto-save-completions ()
2288 ;; (if (and save-completions-flag enable-completion cmpl-initialized-p 2164 ;; (if (and save-completions-flag enable-completion cmpl-initialized-p
2289 ;; *completion-auto-save-period* 2165 ;; *completion-auto-save-period*
2290 ;; (> cmpl-emacs-idle-time *completion-auto-save-period*) 2166 ;; (> cmpl-emacs-idle-time *completion-auto-save-period*)
2292 ;; (save-completions-to-file))) 2168 ;; (save-completions-to-file)))
2293 2169
2294 ;;(add-hook 'cmpl-emacs-idle-time-hooks 'auto-save-completions) 2170 ;;(add-hook 'cmpl-emacs-idle-time-hooks 'auto-save-completions)
2295 2171
2296 (defun load-completions-from-file (&optional filename no-message-p) 2172 (defun load-completions-from-file (&optional filename no-message-p)
2297 "Loads a completion init file FILENAME. 2173 "Load a completion init file FILENAME.
2298 If file is not specified, then use `save-completions-file-name'." 2174 If file is not specified, then use `save-completions-file-name'."
2299 (interactive) 2175 (interactive)
2300 (setq filename (expand-file-name (or filename save-completions-file-name))) 2176 (setq filename (expand-file-name (or filename save-completions-file-name)))
2301 (let* ((backup-filename (completion-backup-filename filename)) 2177 (let* ((backup-filename (completion-backup-filename filename))
2302 (backup-readable-p (file-readable-p backup-filename)) 2178 (backup-readable-p (file-readable-p backup-filename)))
2303 )
2304 (if backup-readable-p (setq filename backup-filename)) 2179 (if backup-readable-p (setq filename backup-filename))
2305 (if (file-readable-p filename) 2180 (if (file-readable-p filename)
2306 (progn 2181 (progn
2307 (if (not no-message-p) 2182 (if (not no-message-p)
2308 (message "Loading completions from %sfile %s . . ." 2183 (message "Loading completions from %sfile %s . . ."
2322 cmpl-entry cmpl-last-use-time 2197 cmpl-entry cmpl-last-use-time
2323 (current-completion-source cmpl-source-init-file) 2198 (current-completion-source cmpl-source-init-file)
2324 (start-num 2199 (start-num
2325 (cmpl-statistics-block 2200 (cmpl-statistics-block
2326 (aref completion-add-count-vector cmpl-source-file-parsing))) 2201 (aref completion-add-count-vector cmpl-source-file-parsing)))
2327 (total-in-file 0) (total-perm 0) 2202 (total-in-file 0) (total-perm 0))
2328 )
2329 ;; insert the file into a buffer 2203 ;; insert the file into a buffer
2330 (condition-case e 2204 (condition-case e
2331 (progn (insert-file-contents filename t) 2205 (progn (insert-file-contents filename t)
2332 (setq insert-okay-p t)) 2206 (setq insert-okay-p t))
2333 2207
2351 ;; handle case sensitivity 2225 ;; handle case sensitivity
2352 (setq total-perm (1+ total-perm)) 2226 (setq total-perm (1+ total-perm))
2353 (setq last-use-time t)) 2227 (setq last-use-time t))
2354 ((eq last-use-time t) 2228 ((eq last-use-time t)
2355 (setq total-perm (1+ total-perm))) 2229 (setq total-perm (1+ total-perm)))
2356 ((integerp last-use-time)) 2230 ((integerp last-use-time))))
2357 ))
2358 ;; Valid entry 2231 ;; Valid entry
2359 ;; add it in 2232 ;; add it in
2360 (setq cmpl-last-use-time 2233 (setq cmpl-last-use-time
2361 (completion-last-use-time 2234 (completion-last-use-time
2362 (setq cmpl-entry 2235 (setq cmpl-entry
2363 (add-completion-to-tail-if-new string)) 2236 (add-completion-to-tail-if-new string))))
2364 ))
2365 (if (or (eq last-use-time t) 2237 (if (or (eq last-use-time t)
2366 (and (> last-use-time 1000);;backcompatibility 2238 (and (> last-use-time 1000);;backcompatibility
2367 (not (eq cmpl-last-use-time t)) 2239 (not (eq cmpl-last-use-time t))
2368 (or (not cmpl-last-use-time) 2240 (or (not cmpl-last-use-time)
2369 ;; more recent 2241 ;; more recent
2370 (> last-use-time cmpl-last-use-time)) 2242 (> last-use-time cmpl-last-use-time))))
2371 ))
2372 ;; update last-use-time 2243 ;; update last-use-time
2373 (set-completion-last-use-time cmpl-entry last-use-time) 2244 (set-completion-last-use-time cmpl-entry last-use-time)))
2374 ))
2375 (t 2245 (t
2376 ;; Bad format 2246 ;; Bad format
2377 (message "Error: invalid saved completion - %s" 2247 (message "Error: invalid saved completion - %s"
2378 (prin1-to-string entry)) 2248 (prin1-to-string entry))
2379 ;; try to get back in sync 2249 ;; try to get back in sync
2380 (search-forward "\n(") 2250 (search-forward "\n("))))
2381 )))
2382 (search-failed 2251 (search-failed
2383 (message "End of file while reading completions.") 2252 (message "End of file while reading completions."))
2384 )
2385 (end-of-file 2253 (end-of-file
2386 (if (= (point) (point-max)) 2254 (if (= (point) (point-max))
2387 (if (not no-message-p) 2255 (if (not no-message-p)
2388 (message "Loading completions from file %s . . . Done." 2256 (message "Loading completions from file %s . . . Done."
2389 filename)) 2257 filename))
2390 (message "End of file while reading completions.") 2258 (message "End of file while reading completions."))))))
2391 ))
2392 )))
2393 2259
2394 (cmpl-statistics-block 2260 (cmpl-statistics-block
2395 (record-load-completions 2261 (record-load-completions
2396 total-in-file total-perm 2262 total-in-file total-perm
2397 (- (aref completion-add-count-vector cmpl-source-init-file) 2263 (- (aref completion-add-count-vector cmpl-source-init-file)
2398 start-num))) 2264 start-num)))
2399 2265 ))))))
2400 ))))))
2401 2266
2402 (defun initialize-completions () 2267 (defun initialize-completions ()
2403 "Load the default completions file. 2268 "Load the default completions file.
2404 Also sets up so that exiting emacs will automatically save the file." 2269 Also sets up so that exiting emacs will automatically save the file."
2405 (interactive) 2270 (interactive)
2406 (cond ((not cmpl-initialized-p) 2271 (cond ((not cmpl-initialized-p)
2407 (load-completions-from-file) 2272 (load-completions-from-file)))
2408 )) 2273 (setq cmpl-initialized-p t))
2409 (setq cmpl-initialized-p t)
2410 )
2411 2274
2412 ;;----------------------------------------------- 2275 ;;-----------------------------------------------
2413 ;; Kill region patch 2276 ;; Kill region patch
2414 ;;----------------------------------------------- 2277 ;;-----------------------------------------------
2415 2278
2452 ;; symbol before point to the completion list (using ADD-COMPLETION). 2315 ;; symbol before point to the completion list (using ADD-COMPLETION).
2453 2316
2454 (defun completion-separator-self-insert-command (arg) 2317 (defun completion-separator-self-insert-command (arg)
2455 (interactive "p") 2318 (interactive "p")
2456 (use-completion-before-separator) 2319 (use-completion-before-separator)
2457 (self-insert-command arg) 2320 (self-insert-command arg))
2458 )
2459 2321
2460 (defun completion-separator-self-insert-autofilling (arg) 2322 (defun completion-separator-self-insert-autofilling (arg)
2461 (interactive "p") 2323 (interactive "p")
2462 (use-completion-before-separator) 2324 (use-completion-before-separator)
2463 (self-insert-command arg) 2325 (self-insert-command arg)
2464 (and auto-fill-function 2326 (and auto-fill-function
2465 (funcall auto-fill-function)) 2327 (funcall auto-fill-function)))
2466 )
2467 2328
2468 ;;----------------------------------------------- 2329 ;;-----------------------------------------------
2469 ;; Wrapping Macro 2330 ;; Wrapping Macro
2470 ;;----------------------------------------------- 2331 ;;-----------------------------------------------
2471 2332
2473 ;; the functions defined with this macro get byte compiled. 2334 ;; the functions defined with this macro get byte compiled.
2474 2335
2475 (defmacro def-completion-wrapper (function-name type &optional new-name) 2336 (defmacro def-completion-wrapper (function-name type &optional new-name)
2476 "Add a call to update the completion database before function execution. 2337 "Add a call to update the completion database before function execution.
2477 TYPE is the type of the wrapper to be added. Can be :before or :under." 2338 TYPE is the type of the wrapper to be added. Can be :before or :under."
2478 (cond ((eq type ':separator) 2339 (cond ((eq type :separator)
2479 (list 'put (list 'quote function-name) ''completion-function 2340 (list 'put (list 'quote function-name) ''completion-function
2480 ''use-completion-before-separator)) 2341 ''use-completion-before-separator))
2481 ((eq type ':before) 2342 ((eq type :before)
2482 (list 'put (list 'quote function-name) ''completion-function 2343 (list 'put (list 'quote function-name) ''completion-function
2483 ''use-completion-before-point)) 2344 ''use-completion-before-point))
2484 ((eq type ':backward-under) 2345 ((eq type :backward-under)
2485 (list 'put (list 'quote function-name) ''completion-function 2346 (list 'put (list 'quote function-name) ''completion-function
2486 ''use-completion-backward-under)) 2347 ''use-completion-backward-under))
2487 ((eq type ':backward) 2348 ((eq type :backward)
2488 (list 'put (list 'quote function-name) ''completion-function 2349 (list 'put (list 'quote function-name) ''completion-function
2489 ''use-completion-backward)) 2350 ''use-completion-backward))
2490 ((eq type ':under) 2351 ((eq type :under)
2491 (list 'put (list 'quote function-name) ''completion-function 2352 (list 'put (list 'quote function-name) ''completion-function
2492 ''use-completion-under-point)) 2353 ''use-completion-under-point))
2493 ((eq type ':under-or-before) 2354 ((eq type :under-or-before)
2494 (list 'put (list 'quote function-name) ''completion-function 2355 (list 'put (list 'quote function-name) ''completion-function
2495 ''use-completion-under-or-before-point)) 2356 ''use-completion-under-or-before-point))
2496 ((eq type ':minibuffer-separator) 2357 ((eq type :minibuffer-separator)
2497 (list 'put (list 'quote function-name) ''completion-function 2358 (list 'put (list 'quote function-name) ''completion-function
2498 ''use-completion-minibuffer-separator)))) 2359 ''use-completion-minibuffer-separator))))
2499 2360
2500 (defun use-completion-minibuffer-separator () 2361 (defun use-completion-minibuffer-separator ()
2501 (let ((cmpl-syntax-table cmpl-standard-syntax-table)) 2362 (let ((cmpl-syntax-table cmpl-standard-syntax-table))
2531 ;; FORTRAN mode diffs. (these are defined when fortran is called) 2392 ;; FORTRAN mode diffs. (these are defined when fortran is called)
2532 (defun completion-setup-fortran-mode () 2393 (defun completion-setup-fortran-mode ()
2533 (define-key fortran-mode-map "+" 'completion-separator-self-insert-command) 2394 (define-key fortran-mode-map "+" 'completion-separator-self-insert-command)
2534 (define-key fortran-mode-map "-" 'completion-separator-self-insert-command) 2395 (define-key fortran-mode-map "-" 'completion-separator-self-insert-command)
2535 (define-key fortran-mode-map "*" 'completion-separator-self-insert-command) 2396 (define-key fortran-mode-map "*" 'completion-separator-self-insert-command)
2536 (define-key fortran-mode-map "/" 'completion-separator-self-insert-command) 2397 (define-key fortran-mode-map "/" 'completion-separator-self-insert-command))
2537 )
2538 2398
2539 ;;; Enable completion mode. 2399 ;;; Enable completion mode.
2540 2400
2541 ;;;###autoload 2401 ;;;###autoload
2542 (defun dynamic-completion-mode () 2402 (defun dynamic-completion-mode ()
2669 (cmpl-statistics-block 2529 (cmpl-statistics-block
2670 (record-completion-file-loaded)) 2530 (record-completion-file-loaded))
2671 2531
2672 (initialize-completions)) 2532 (initialize-completions))
2673 2533
2534 (mapc (lambda (x)
2535 (add-to-list 'debug-ignored-errors x))
2536 '("^To complete, the point must be after a symbol at least [0-9]* character long\\.$"
2537 "^The string \".*\" is too short to be saved as a completion\\.$"))
2538
2674 (provide 'completion) 2539 (provide 'completion)
2675 2540
2676 ;;; completion.el ends here 2541 ;;; completion.el ends here