aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman2001-11-11 20:05:39 +0000
committerRichard M. Stallman2001-11-11 20:05:39 +0000
commit1c4fe319c900665cf0cee0817f627175fc723490 (patch)
tree21117326c616952c284b75fb4a9fdb67c1e5ca12
parent0542e206fe2aa03b5491271286ba430773af2b11 (diff)
downloademacs-1c4fe319c900665cf0cee0817f627175fc723490.tar.gz
emacs-1c4fe319c900665cf0cee0817f627175fc723490.zip
(query-replace-skip-read-only): New variable.
(perform-replace): If that variable is non-nil, ignore matches that have a read-only property.
-rw-r--r--lisp/replace.el311
1 files changed, 161 insertions, 150 deletions
diff --git a/lisp/replace.el b/lisp/replace.el
index aabe37f011d..1082caadc7b 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -56,6 +56,12 @@ strings or patterns."
56 :type 'symbol 56 :type 'symbol
57 :version "20.3") 57 :version "20.3")
58 58
59(defcustom query-replace-skip-read-only nil
60 "*Non-nil means `query-replace' and friends ignore read-only matches."
61 :type 'boolean
62 :group 'matching
63 :version "21.3")
64
59(defun query-replace-read-args (string regexp-flag) 65(defun query-replace-read-args (string regexp-flag)
60 (let (from to) 66 (let (from to)
61 (if query-replace-interactive 67 (if query-replace-interactive
@@ -967,158 +973,163 @@ see the documentation of `replace-match' to find out how to simulate
967 ;; For speed, use only integers and 973 ;; For speed, use only integers and
968 ;; reuse the list used last time. 974 ;; reuse the list used last time.
969 (match-data t real-match-data))))) 975 (match-data t real-match-data)))))
970 976 ;; Optionally ignore matches that have a read-only property.
971 ;; Record whether the match is nonempty, to avoid an infinite loop 977 (unless (and query-replace-skip-read-only
972 ;; repeatedly matching the same empty string. 978 (text-property-not-all
973 (setq nonempty-match 979 (match-beginning 0) (match-end 0)
974 (/= (nth 0 real-match-data) (nth 1 real-match-data))) 980 'read-only nil))
975 981
976 ;; If the match is empty, record that the next one can't be 982 ;; Record whether the match is nonempty, to avoid an infinite loop
977 ;; adjacent. 983 ;; repeatedly matching the same empty string.
978 984 (setq nonempty-match
979 ;; Otherwise, if matching a regular expression, do the next 985 (/= (nth 0 real-match-data) (nth 1 real-match-data)))
980 ;; match now, since the replacement for this match may 986
981 ;; affect whether the next match is adjacent to this one. 987 ;; If the match is empty, record that the next one can't be
982 ;; If that match is empty, don't use it. 988 ;; adjacent.
983 (setq match-again 989
984 (and nonempty-match 990 ;; Otherwise, if matching a regular expression, do the next
985 (or (not regexp-flag) 991 ;; match now, since the replacement for this match may
986 (and (looking-at search-string) 992 ;; affect whether the next match is adjacent to this one.
987 (let ((match (match-data))) 993 ;; If that match is empty, don't use it.
988 (and (/= (nth 0 match) (nth 1 match)) 994 (setq match-again
989 match)))))) 995 (and nonempty-match
990 996 (or (not regexp-flag)
991 ;; Calculate the replacement string, if necessary. 997 (and (looking-at search-string)
992 (when replacements 998 (let ((match (match-data)))
993 (set-match-data real-match-data) 999 (and (/= (nth 0 match) (nth 1 match))
994 (setq next-replacement 1000 match))))))
995 (funcall (car replacements) (cdr replacements) 1001
996 replace-count))) 1002 ;; Calculate the replacement string, if necessary.
997 (if (not query-flag) 1003 (when replacements
998 (progn 1004 (set-match-data real-match-data)
999 (set-match-data real-match-data) 1005 (setq next-replacement
1000 (replace-match next-replacement nocasify literal) 1006 (funcall (car replacements) (cdr replacements)
1001 (setq replace-count (1+ replace-count))) 1007 replace-count)))
1002 (undo-boundary) 1008 (if (not query-flag)
1003 (let (done replaced key def) 1009 (let ((inhibit-read-only query-replace-skip-read-only))
1004 ;; Loop reading commands until one of them sets done, 1010 (set-match-data real-match-data)
1005 ;; which means it has finished handling this occurrence. 1011 (replace-match next-replacement nocasify literal)
1006 (while (not done) 1012 (setq replace-count (1+ replace-count)))
1007 (set-match-data real-match-data) 1013 (undo-boundary)
1008 (replace-highlight (match-beginning 0) (match-end 0)) 1014 (let (done replaced key def)
1009 ;; Bind message-log-max so we don't fill up the message log 1015 ;; Loop reading commands until one of them sets done,
1010 ;; with a bunch of identical messages. 1016 ;; which means it has finished handling this occurrence.
1011 (let ((message-log-max nil)) 1017 (while (not done)
1012 (message message from-string next-replacement)) 1018 (set-match-data real-match-data)
1013 (setq key (read-event)) 1019 (replace-highlight (match-beginning 0) (match-end 0))
1014 ;; Necessary in case something happens during read-event 1020 ;; Bind message-log-max so we don't fill up the message log
1015 ;; that clobbers the match data. 1021 ;; with a bunch of identical messages.
1016 (set-match-data real-match-data) 1022 (let ((message-log-max nil))
1017 (setq key (vector key)) 1023 (message message from-string next-replacement))
1018 (setq def (lookup-key map key)) 1024 (setq key (read-event))
1019 ;; Restore the match data while we process the command. 1025 ;; Necessary in case something happens during read-event
1020 (cond ((eq def 'help) 1026 ;; that clobbers the match data.
1021 (with-output-to-temp-buffer "*Help*" 1027 (set-match-data real-match-data)
1022 (princ 1028 (setq key (vector key))
1023 (concat "Query replacing " 1029 (setq def (lookup-key map key))
1024 (if regexp-flag "regexp " "") 1030 ;; Restore the match data while we process the command.
1025 from-string " with " 1031 (cond ((eq def 'help)
1026 next-replacement ".\n\n" 1032 (with-output-to-temp-buffer "*Help*"
1027 (substitute-command-keys 1033 (princ
1028 query-replace-help))) 1034 (concat "Query replacing "
1029 (with-current-buffer standard-output 1035 (if regexp-flag "regexp " "")
1030 (help-mode)))) 1036 from-string " with "
1031 ((eq def 'exit) 1037 next-replacement ".\n\n"
1032 (setq keep-going nil) 1038 (substitute-command-keys
1033 (setq done t)) 1039 query-replace-help)))
1034 ((eq def 'backup) 1040 (with-current-buffer standard-output
1035 (if stack 1041 (help-mode))))
1036 (let ((elt (car stack))) 1042 ((eq def 'exit)
1037 (goto-char (car elt)) 1043 (setq keep-going nil)
1038 (setq replaced (eq t (cdr elt))) 1044 (setq done t))
1039 (or replaced 1045 ((eq def 'backup)
1040 (set-match-data (cdr elt))) 1046 (if stack
1041 (setq stack (cdr stack))) 1047 (let ((elt (car stack)))
1042 (message "No previous match") 1048 (goto-char (car elt))
1043 (ding 'no-terminate) 1049 (setq replaced (eq t (cdr elt)))
1044 (sit-for 1))) 1050 (or replaced
1045 ((eq def 'act) 1051 (set-match-data (cdr elt)))
1046 (or replaced 1052 (setq stack (cdr stack)))
1047 (progn 1053 (message "No previous match")
1048 (replace-match next-replacement nocasify literal) 1054 (ding 'no-terminate)
1049 (setq replace-count (1+ replace-count)))) 1055 (sit-for 1)))
1050 (setq done t replaced t)) 1056 ((eq def 'act)
1051 ((eq def 'act-and-exit) 1057 (or replaced
1052 (or replaced 1058 (progn
1053 (progn 1059 (replace-match next-replacement nocasify literal)
1054 (replace-match next-replacement nocasify literal) 1060 (setq replace-count (1+ replace-count))))
1055 (setq replace-count (1+ replace-count)))) 1061 (setq done t replaced t))
1056 (setq keep-going nil) 1062 ((eq def 'act-and-exit)
1057 (setq done t replaced t)) 1063 (or replaced
1058 ((eq def 'act-and-show) 1064 (progn
1059 (if (not replaced) 1065 (replace-match next-replacement nocasify literal)
1060 (progn 1066 (setq replace-count (1+ replace-count))))
1061 (replace-match next-replacement nocasify literal) 1067 (setq keep-going nil)
1062 (setq replace-count (1+ replace-count)) 1068 (setq done t replaced t))
1063 (setq replaced t)))) 1069 ((eq def 'act-and-show)
1064 ((eq def 'automatic) 1070 (if (not replaced)
1065 (or replaced 1071 (progn
1066 (progn 1072 (replace-match next-replacement nocasify literal)
1067 (replace-match next-replacement nocasify literal) 1073 (setq replace-count (1+ replace-count))
1068 (setq replace-count (1+ replace-count)))) 1074 (setq replaced t))))
1069 (setq done t query-flag nil replaced t)) 1075 ((eq def 'automatic)
1070 ((eq def 'skip) 1076 (or replaced
1071 (setq done t)) 1077 (progn
1072 ((eq def 'recenter) 1078 (replace-match next-replacement nocasify literal)
1073 (recenter nil)) 1079 (setq replace-count (1+ replace-count))))
1074 ((eq def 'edit) 1080 (setq done t query-flag nil replaced t))
1075 (let ((opos (point-marker))) 1081 ((eq def 'skip)
1076 (goto-char (match-beginning 0)) 1082 (setq done t))
1077 (save-excursion 1083 ((eq def 'recenter)
1078 (funcall search-function search-string limit t) 1084 (recenter nil))
1079 (setq real-match-data (match-data))) 1085 ((eq def 'edit)
1080 (save-excursion (recursive-edit)) 1086 (let ((opos (point-marker)))
1081 (goto-char opos)) 1087 (goto-char (match-beginning 0))
1082 (set-match-data real-match-data) 1088 (save-excursion
1083 ;; Before we make the replacement, 1089 (funcall search-function search-string limit t)
1084 ;; decide whether the search string 1090 (setq real-match-data (match-data)))
1085 ;; can match again just after this match. 1091 (save-excursion (recursive-edit))
1086 (if (and regexp-flag nonempty-match) 1092 (goto-char opos))
1087 (setq match-again (and (looking-at search-string) 1093 (set-match-data real-match-data)
1088 (match-data))))) 1094 ;; Before we make the replacement,
1095 ;; decide whether the search string
1096 ;; can match again just after this match.
1097 (if (and regexp-flag nonempty-match)
1098 (setq match-again (and (looking-at search-string)
1099 (match-data)))))
1089 1100
1090 ;; Edit replacement. 1101 ;; Edit replacement.
1091 ((eq def 'edit-replacement) 1102 ((eq def 'edit-replacement)
1092 (setq next-replacement 1103 (setq next-replacement
1093 (read-input "Edit replacement string: " 1104 (read-input "Edit replacement string: "
1094 next-replacement)) 1105 next-replacement))
1095 (or replaced 1106 (or replaced
1096 (replace-match next-replacement nocasify literal)) 1107 (replace-match next-replacement nocasify literal))
1097 (setq done t)) 1108 (setq done t))
1098 1109
1099 ((eq def 'delete-and-edit) 1110 ((eq def 'delete-and-edit)
1100 (delete-region (match-beginning 0) (match-end 0)) 1111 (delete-region (match-beginning 0) (match-end 0))
1101 (set-match-data 1112 (set-match-data
1102 (prog1 (match-data) 1113 (prog1 (match-data)
1103 (save-excursion (recursive-edit)))) 1114 (save-excursion (recursive-edit))))
1104 (setq replaced t)) 1115 (setq replaced t))
1105 ;; Note: we do not need to treat `exit-prefix' 1116 ;; Note: we do not need to treat `exit-prefix'
1106 ;; specially here, since we reread 1117 ;; specially here, since we reread
1107 ;; any unrecognized character. 1118 ;; any unrecognized character.
1108 (t 1119 (t
1109 (setq this-command 'mode-exited) 1120 (setq this-command 'mode-exited)
1110 (setq keep-going nil) 1121 (setq keep-going nil)
1111 (setq unread-command-events 1122 (setq unread-command-events
1112 (append (listify-key-sequence key) 1123 (append (listify-key-sequence key)
1113 unread-command-events)) 1124 unread-command-events))
1114 (setq done t)))) 1125 (setq done t))))
1115 ;; Record previous position for ^ when we move on. 1126 ;; Record previous position for ^ when we move on.
1116 ;; Change markers to numbers in the match data 1127 ;; Change markers to numbers in the match data
1117 ;; since lots of markers slow down editing. 1128 ;; since lots of markers slow down editing.
1118 (setq stack 1129 (setq stack
1119 (cons (cons (point) 1130 (cons (cons (point)
1120 (or replaced (match-data t))) 1131 (or replaced (match-data t)))
1121 stack))))) 1132 stack))))))
1122 1133
1123 ;; The code preventing adjacent regexp matches in the condition 1134 ;; The code preventing adjacent regexp matches in the condition
1124 ;; of the while-loop above will haven taken us one character 1135 ;; of the while-loop above will haven taken us one character