comparison lisp/add-log.el @ 75372:a1962c941648

(add-log-current-defun): Use CC Mode functions to find the beginning and end of a defun.
author Richard M. Stallman <rms@gnu.org>
date Mon, 22 Jan 2007 00:09:22 +0000
parents e3694f1cb928
children affed975ee67 95d0cdf160ea
comparison
equal deleted inserted replaced
75371:7267980a2f42 75372:a1962c941648
811 (skip-chars-forward " \t") 811 (skip-chars-forward " \t")
812 (buffer-substring-no-properties (point) 812 (buffer-substring-no-properties (point)
813 (progn (forward-sexp 1) 813 (progn (forward-sexp 1)
814 (point)))) 814 (point))))
815 ((memq major-mode add-log-c-like-modes) 815 ((memq major-mode add-log-c-like-modes)
816 (beginning-of-line) 816 ;; See whether the point is inside a defun.
817 ;; See if we are in the beginning part of a function, 817 (let (having-previous-defun
818 ;; before the open brace. If so, advance forward. 818 having-next-defun
819 (while (not (looking-at "{\\|\\(\\s *$\\)")) 819 previous-defun-end
820 (forward-line 1)) 820 next-defun-beginning)
821 (or (eobp) 821
822 (forward-char 1)) 822 (save-excursion
823 (let (maybe-beg) 823 (setq having-previous-defun
824 ;; Try to find the containing defun. 824 (c-beginning-of-defun))
825 (beginning-of-defun) 825 (c-end-of-defun)
826 (end-of-defun) 826 ;; `c-end-of-defun' moves point to the line after
827 ;; If the defun we found ends before the desired position, 827 ;; the function close, but the position we prefer
828 ;; see if there's a DEFUN construct 828 ;; here is the position after the final }.
829 ;; between that end and the desired position. 829 (backward-sexp 1)
830 (when (save-excursion 830 (forward-sexp 1)
831 (and (> location (point)) 831 (setq previous-defun-end (point)))
832 (re-search-forward "^DEFUN" 832
833 (save-excursion 833 (save-excursion
834 (goto-char location) 834 (setq having-next-defun
835 (line-end-position)) 835 (c-end-of-defun))
836 t) 836 (c-beginning-of-defun)
837 (re-search-forward "^{" nil t) 837 (setq next-defun-beginning (point)))
838 (setq maybe-beg (point)))) 838
839 ;; If so, go to the end of that instead. 839 (if (and having-next-defun
840 (goto-char maybe-beg) 840 (< location next-defun-beginning))
841 (end-of-defun))) 841 (skip-syntax-forward " "))
842 ;; If the desired position is within the defun we found, 842 (if (and having-previous-defun
843 ;; find the function name. 843 (> location previous-defun-end))
844 (when (< location (point)) 844 (skip-syntax-backward " "))
845 ;; Move back over function body. 845 (unless (or
846 (backward-sexp 1) 846 ;; When there is no previous defun, the
847 (let (beg) 847 ;; point is not in a defun if it is not at
848 ;; Skip back over typedefs and arglist. 848 ;; the beginning of the next defun.
849 ;; Stop at the function definition itself 849 (and (not having-previous-defun)
850 ;; or at the line that follows end of function doc string. 850 (not (= (point)
851 (forward-line -1) 851 next-defun-beginning)))
852 (while (and (not (bobp)) 852 ;; When there is no next defun, the point
853 (looking-at "[ \t\n]") 853 ;; is not in a defun if it is not at the
854 (not (looking-back "[*]/)\n" (- (point) 4)))) 854 ;; end of the previous defun.
855 (forward-line -1)) 855 (and (not having-next-defun)
856 ;; If we found a doc string, this must be the DEFUN macro 856 (not (= (point)
857 ;; used in Emacs. Move back to the DEFUN line. 857 previous-defun-end)))
858 (when (looking-back "[*]/)\n" (- (point) 4)) 858 ;; If the point is between two defuns, it
859 (backward-sexp 1) 859 ;; is not in a defun.
860 (beginning-of-line)) 860 (and (> (point) previous-defun-end)
861 (< (point) next-defun-beginning)))
862 ;; If the point is already at the beginning of a
863 ;; defun, there is no need to move point again.
864 (if (not (= (point) next-defun-beginning))
865 (c-beginning-of-defun))
861 ;; Is this a DEFUN construct? And is LOCATION in it? 866 ;; Is this a DEFUN construct? And is LOCATION in it?
862 (if (and (looking-at "DEFUN\\b") 867 (if (and (looking-at "DEFUN\\b")
863 (>= location (point))) 868 (>= location (point)))
864 ;; DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory, ...) ==> Ffile_name_directory 869 ;; DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory, ...) ==> Ffile_name_directory
865 ;; DEFUN(POSIX::STREAM-LOCK, stream lockp &key BLOCK SHARED START LENGTH) ==> POSIX::STREAM-LOCK 870 ;; DEFUN(POSIX::STREAM-LOCK, stream lockp &key BLOCK SHARED START LENGTH) ==> POSIX::STREAM-LOCK
877 (point)))) 882 (point))))
878 (if (looking-at "^[+-]") 883 (if (looking-at "^[+-]")
879 ;; Objective-C 884 ;; Objective-C
880 (change-log-get-method-definition) 885 (change-log-get-method-definition)
881 ;; Ordinary C function syntax. 886 ;; Ordinary C function syntax.
882 (setq beg (point)) 887 (let ((beg (point)))
883 (if (and 888 (if (and
884 ;; Protect against "Unbalanced parens" error. 889 ;; Protect against "Unbalanced parens" error.
885 (condition-case nil 890 (condition-case nil
886 (progn 891 (progn
887 (down-list 1) ; into arglist 892 (down-list 1) ; into arglist
888 (backward-up-list 1) 893 (backward-up-list 1)
889 (skip-chars-backward " \t") 894 (skip-chars-backward " \t")
890 t) 895 t)
891 (error nil)) 896 (error nil))
892 ;; Verify initial pos was after 897 ;; Verify initial pos was after
893 ;; real start of function. 898 ;; real start of function.
894 (save-excursion 899 (save-excursion
895 (goto-char beg) 900 (goto-char beg)
896 ;; For this purpose, include the line 901 ;; For this purpose, include the line
897 ;; that has the decl keywords. This 902 ;; that has the decl keywords. This
898 ;; may also include some of the 903 ;; may also include some of the
899 ;; comments before the function. 904 ;; comments before the function.
900 (while (and (not (bobp)) 905 (while (and (not (bobp))
901 (save-excursion 906 (save-excursion
902 (forward-line -1) 907 (forward-line -1)
903 (looking-at "[^\n\f]"))) 908 (looking-at "[^\n\f]")))
904 (forward-line -1)) 909 (forward-line -1))
905 (>= location (point))) 910 (>= location (point)))
906 ;; Consistency check: going down and up 911 ;; Consistency check: going down and up
907 ;; shouldn't take us back before BEG. 912 ;; shouldn't take us back before BEG.
908 (> (point) beg)) 913 (> (point) beg))
909 (let (end middle) 914 (let (end middle)
910 ;; Don't include any final whitespace 915 ;; Don't include any final whitespace
911 ;; in the name we use. 916 ;; in the name we use.
912 (skip-chars-backward " \t\n") 917 (skip-chars-backward " \t\n")
913 (setq end (point))
914 (backward-sexp 1)
915 ;; Now find the right beginning of the name.
916 ;; Include certain keywords if they
917 ;; precede the name.
918 (setq middle (point))
919 ;; Single (forward-sexp -1) invocation is
920 ;; not enough for C++ member function defined
921 ;; as part of nested class and/or namespace
922 ;; like:
923 ;;
924 ;; void
925 ;; foo::bar::baz::bazz ()
926 ;; { ...
927 ;;
928 ;; Here we have to move the point to
929 ;; the beginning of foo, not bazz.
930 (while (not (looking-back "\\(^\\|[ \t]\\)"))
931 (forward-sexp -1))
932 ;; Is this C++ method?
933 (when (and (< 2 middle)
934 (string= (buffer-substring (- middle 2)
935 middle)
936 "::"))
937 ;; Include "classname::".
938 (setq middle (point)))
939 ;; Ignore these subparts of a class decl
940 ;; and move back to the class name itself.
941 (while (looking-at "public \\|private ")
942 (skip-chars-backward " \t:")
943 (setq end (point)) 918 (setq end (point))
944 (backward-sexp 1) 919 (backward-sexp 1)
920 ;; Now find the right beginning of the name.
921 ;; Include certain keywords if they
922 ;; precede the name.
945 (setq middle (point)) 923 (setq middle (point))
946 (forward-word -1)) 924 ;; Single (forward-sexp -1) invocation is
947 (and (bolp) 925 ;; not enough for C++ member function defined
948 (looking-at 926 ;; as part of nested class and/or namespace
949 "enum \\|struct \\|union \\|class ") 927 ;; like:
950 (setq middle (point))) 928 ;;
951 (goto-char end) 929 ;; void
952 (when (eq (preceding-char) ?=) 930 ;; foo::bar::baz::bazz ()
953 (forward-char -1) 931 ;; { ...
954 (skip-chars-backward " \t") 932 ;;
955 (setq end (point))) 933 ;; Here we have to move the point to
956 (buffer-substring-no-properties 934 ;; the beginning of foo, not bazz.
957 middle end)))))))) 935 (while (not (looking-back "\\(^\\|[ \t]\\)"))
936 (forward-sexp -1))
937 ;; Is this C++ method?
938 (when (and (< 2 middle)
939 (string= (buffer-substring (- middle 2)
940 middle)
941 "::"))
942 ;; Include "classname::".
943 (setq middle (point)))
944 ;; Ignore these subparts of a class decl
945 ;; and move back to the class name itself.
946 (while (looking-at "public \\|private ")
947 (skip-chars-backward " \t:")
948 (setq end (point))
949 (backward-sexp 1)
950 (setq middle (point))
951 (forward-word -1))
952 (and (bolp)
953 (looking-at
954 "enum \\|struct \\|union \\|class ")
955 (setq middle (point)))
956 (goto-char end)
957 (when (eq (preceding-char) ?=)
958 (forward-char -1)
959 (skip-chars-backward " \t")
960 (setq end (point)))
961 (buffer-substring-no-properties
962 middle end)))))))))
958 ((memq major-mode add-log-tex-like-modes) 963 ((memq major-mode add-log-tex-like-modes)
959 (if (re-search-backward 964 (if (re-search-backward
960 "\\\\\\(sub\\)*\\(section\\|paragraph\\|chapter\\)" 965 "\\\\\\(sub\\)*\\(section\\|paragraph\\|chapter\\)"
961 nil t) 966 nil t)
962 (progn 967 (progn