replace.el 80 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136
  1. ;;; replace.el --- replace commands for Emacs
  2. ;; Copyright (C) 1985-1987, 1992, 1994, 1996-1997, 2000-2012
  3. ;; Free Software Foundation, Inc.
  4. ;; Maintainer: FSF
  5. ;; Package: emacs
  6. ;; This file is part of GNU Emacs.
  7. ;; GNU Emacs is free software: you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation, either version 3 of the License, or
  10. ;; (at your option) any later version.
  11. ;; GNU Emacs is distributed in the hope that it will be useful,
  12. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;; GNU General Public License for more details.
  15. ;; You should have received a copy of the GNU General Public License
  16. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  17. ;;; Commentary:
  18. ;; This package supplies the string and regular-expression replace functions
  19. ;; documented in the Emacs user's manual.
  20. ;;; Code:
  21. (defcustom case-replace t
  22. "Non-nil means `query-replace' should preserve case in replacements."
  23. :type 'boolean
  24. :group 'matching)
  25. (defvar query-replace-history nil
  26. "Default history list for query-replace commands.
  27. See `query-replace-from-history-variable' and
  28. `query-replace-to-history-variable'.")
  29. (defvar query-replace-defaults nil
  30. "Default values of FROM-STRING and TO-STRING for `query-replace'.
  31. This is a cons cell (FROM-STRING . TO-STRING), or nil if there is
  32. no default value.")
  33. (defvar query-replace-interactive nil
  34. "Non-nil means `query-replace' uses the last search string.
  35. That becomes the \"string to replace\".")
  36. (defcustom query-replace-from-history-variable 'query-replace-history
  37. "History list to use for the FROM argument of `query-replace' commands.
  38. The value of this variable should be a symbol; that symbol
  39. is used as a variable to hold a history list for the strings
  40. or patterns to be replaced."
  41. :group 'matching
  42. :type 'symbol
  43. :version "20.3")
  44. (defcustom query-replace-to-history-variable 'query-replace-history
  45. "History list to use for the TO argument of `query-replace' commands.
  46. The value of this variable should be a symbol; that symbol
  47. is used as a variable to hold a history list for replacement
  48. strings or patterns."
  49. :group 'matching
  50. :type 'symbol
  51. :version "20.3")
  52. (defcustom query-replace-skip-read-only nil
  53. "Non-nil means `query-replace' and friends ignore read-only matches."
  54. :type 'boolean
  55. :group 'matching
  56. :version "22.1")
  57. (defcustom query-replace-show-replacement t
  58. "Non-nil means to show what actual replacement text will be."
  59. :type 'boolean
  60. :group 'matching
  61. :version "23.1")
  62. (defcustom query-replace-highlight t
  63. "Non-nil means to highlight matches during query replacement."
  64. :type 'boolean
  65. :group 'matching)
  66. (defcustom query-replace-lazy-highlight t
  67. "Controls the lazy-highlighting during query replacements.
  68. When non-nil, all text in the buffer matching the current match
  69. is highlighted lazily using isearch lazy highlighting (see
  70. `lazy-highlight-initial-delay' and `lazy-highlight-interval')."
  71. :type 'boolean
  72. :group 'lazy-highlight
  73. :group 'matching
  74. :version "22.1")
  75. (defface query-replace
  76. '((t (:inherit isearch)))
  77. "Face for highlighting query replacement matches."
  78. :group 'matching
  79. :version "22.1")
  80. (defvar replace-count 0
  81. "Number of replacements done so far.
  82. See `replace-regexp' and `query-replace-regexp-eval'.")
  83. (defun query-replace-descr (string)
  84. (mapconcat 'isearch-text-char-description string ""))
  85. (defun query-replace-read-from (prompt regexp-flag)
  86. "Query and return the `from' argument of a query-replace operation.
  87. The return value can also be a pair (FROM . TO) indicating that the user
  88. wants to replace FROM with TO."
  89. (if query-replace-interactive
  90. (car (if regexp-flag regexp-search-ring search-ring))
  91. (let* ((history-add-new-input nil)
  92. (from
  93. ;; The save-excursion here is in case the user marks and copies
  94. ;; a region in order to specify the minibuffer input.
  95. ;; That should not clobber the region for the query-replace itself.
  96. (save-excursion
  97. (read-from-minibuffer
  98. (if query-replace-defaults
  99. (format "%s (default %s -> %s): " prompt
  100. (query-replace-descr (car query-replace-defaults))
  101. (query-replace-descr (cdr query-replace-defaults)))
  102. (format "%s: " prompt))
  103. nil nil nil
  104. query-replace-from-history-variable
  105. nil t))))
  106. (if (and (zerop (length from)) query-replace-defaults)
  107. (cons (car query-replace-defaults)
  108. (query-replace-compile-replacement
  109. (cdr query-replace-defaults) regexp-flag))
  110. (add-to-history query-replace-from-history-variable from nil t)
  111. ;; Warn if user types \n or \t, but don't reject the input.
  112. (and regexp-flag
  113. (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\(\\\\[nt]\\)" from)
  114. (let ((match (match-string 3 from)))
  115. (cond
  116. ((string= match "\\n")
  117. (message "Note: `\\n' here doesn't match a newline; to do that, type C-q C-j instead"))
  118. ((string= match "\\t")
  119. (message "Note: `\\t' here doesn't match a tab; to do that, just type TAB")))
  120. (sit-for 2)))
  121. from))))
  122. (defun query-replace-compile-replacement (to regexp-flag)
  123. "Maybe convert a regexp replacement TO to Lisp.
  124. Returns a list suitable for `perform-replace' if necessary,
  125. the original string if not."
  126. (if (and regexp-flag
  127. (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" to))
  128. (let (pos list char)
  129. (while
  130. (progn
  131. (setq pos (match-end 0))
  132. (push (substring to 0 (- pos 2)) list)
  133. (setq char (aref to (1- pos))
  134. to (substring to pos))
  135. (cond ((eq char ?\#)
  136. (push '(number-to-string replace-count) list))
  137. ((eq char ?\,)
  138. (setq pos (read-from-string to))
  139. (push `(replace-quote ,(car pos)) list)
  140. (let ((end
  141. ;; Swallow a space after a symbol
  142. ;; if there is a space.
  143. (if (and (or (symbolp (car pos))
  144. ;; Swallow a space after 'foo
  145. ;; but not after (quote foo).
  146. (and (eq (car-safe (car pos)) 'quote)
  147. (not (= ?\( (aref to 0)))))
  148. (eq (string-match " " to (cdr pos))
  149. (cdr pos)))
  150. (1+ (cdr pos))
  151. (cdr pos))))
  152. (setq to (substring to end)))))
  153. (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" to)))
  154. (setq to (nreverse (delete "" (cons to list))))
  155. (replace-match-string-symbols to)
  156. (cons 'replace-eval-replacement
  157. (if (cdr to)
  158. (cons 'concat to)
  159. (car to))))
  160. to))
  161. (defun query-replace-read-to (from prompt regexp-flag)
  162. "Query and return the `to' argument of a query-replace operation."
  163. (query-replace-compile-replacement
  164. (save-excursion
  165. (let* ((history-add-new-input nil)
  166. (to (read-from-minibuffer
  167. (format "%s %s with: " prompt (query-replace-descr from))
  168. nil nil nil
  169. query-replace-to-history-variable from t)))
  170. (add-to-history query-replace-to-history-variable to nil t)
  171. (setq query-replace-defaults (cons from to))
  172. to))
  173. regexp-flag))
  174. (defun query-replace-read-args (prompt regexp-flag &optional noerror)
  175. (unless noerror
  176. (barf-if-buffer-read-only))
  177. (let* ((from (query-replace-read-from prompt regexp-flag))
  178. (to (if (consp from) (prog1 (cdr from) (setq from (car from)))
  179. (query-replace-read-to from prompt regexp-flag))))
  180. (list from to current-prefix-arg)))
  181. (defun query-replace (from-string to-string &optional delimited start end)
  182. "Replace some occurrences of FROM-STRING with TO-STRING.
  183. As each match is found, the user must type a character saying
  184. what to do with it. For directions, type \\[help-command] at that time.
  185. In Transient Mark mode, if the mark is active, operate on the contents
  186. of the region. Otherwise, operate from point to the end of the buffer.
  187. If `query-replace-interactive' is non-nil, the last incremental search
  188. string is used as FROM-STRING--you don't have to specify it with the
  189. minibuffer.
  190. Matching is independent of case if `case-fold-search' is non-nil and
  191. FROM-STRING has no uppercase letters. Replacement transfers the case
  192. pattern of the old text to the new text, if `case-replace' and
  193. `case-fold-search' are non-nil and FROM-STRING has no uppercase
  194. letters. \(Transferring the case pattern means that if the old text
  195. matched is all caps, or capitalized, then its replacement is upcased
  196. or capitalized.)
  197. Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
  198. only matches surrounded by word boundaries.
  199. Fourth and fifth arg START and END specify the region to operate on.
  200. To customize possible responses, change the \"bindings\" in `query-replace-map'."
  201. (interactive
  202. (let ((common
  203. (query-replace-read-args
  204. (concat "Query replace"
  205. (if current-prefix-arg " word" "")
  206. (if (and transient-mark-mode mark-active) " in region" ""))
  207. nil)))
  208. (list (nth 0 common) (nth 1 common) (nth 2 common)
  209. ;; These are done separately here
  210. ;; so that command-history will record these expressions
  211. ;; rather than the values they had this time.
  212. (if (and transient-mark-mode mark-active)
  213. (region-beginning))
  214. (if (and transient-mark-mode mark-active)
  215. (region-end)))))
  216. (perform-replace from-string to-string t nil delimited nil nil start end))
  217. (define-key esc-map "%" 'query-replace)
  218. (defun query-replace-regexp (regexp to-string &optional delimited start end)
  219. "Replace some things after point matching REGEXP with TO-STRING.
  220. As each match is found, the user must type a character saying
  221. what to do with it. For directions, type \\[help-command] at that time.
  222. In Transient Mark mode, if the mark is active, operate on the contents
  223. of the region. Otherwise, operate from point to the end of the buffer.
  224. If `query-replace-interactive' is non-nil, the last incremental search
  225. regexp is used as REGEXP--you don't have to specify it with the
  226. minibuffer.
  227. Matching is independent of case if `case-fold-search' is non-nil and
  228. REGEXP has no uppercase letters. Replacement transfers the case
  229. pattern of the old text to the new text, if `case-replace' and
  230. `case-fold-search' are non-nil and REGEXP has no uppercase letters.
  231. \(Transferring the case pattern means that if the old text matched is
  232. all caps, or capitalized, then its replacement is upcased or
  233. capitalized.)
  234. Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
  235. only matches surrounded by word boundaries.
  236. Fourth and fifth arg START and END specify the region to operate on.
  237. In TO-STRING, `\\&' stands for whatever matched the whole of REGEXP,
  238. and `\\=\\N' (where N is a digit) stands for
  239. whatever what matched the Nth `\\(...\\)' in REGEXP.
  240. `\\?' lets you edit the replacement text in the minibuffer
  241. at the given position for each replacement.
  242. In interactive calls, the replacement text can contain `\\,'
  243. followed by a Lisp expression. Each
  244. replacement evaluates that expression to compute the replacement
  245. string. Inside of that expression, `\\&' is a string denoting the
  246. whole match as a string, `\\N' for a partial match, `\\#&' and `\\#N'
  247. for the whole or a partial match converted to a number with
  248. `string-to-number', and `\\#' itself for the number of replacements
  249. done so far (starting with zero).
  250. If the replacement expression is a symbol, write a space after it
  251. to terminate it. One space there, if any, will be discarded.
  252. When using those Lisp features interactively in the replacement
  253. text, TO-STRING is actually made a list instead of a string.
  254. Use \\[repeat-complex-command] after this command for details."
  255. (interactive
  256. (let ((common
  257. (query-replace-read-args
  258. (concat "Query replace"
  259. (if current-prefix-arg " word" "")
  260. " regexp"
  261. (if (and transient-mark-mode mark-active) " in region" ""))
  262. t)))
  263. (list (nth 0 common) (nth 1 common) (nth 2 common)
  264. ;; These are done separately here
  265. ;; so that command-history will record these expressions
  266. ;; rather than the values they had this time.
  267. (if (and transient-mark-mode mark-active)
  268. (region-beginning))
  269. (if (and transient-mark-mode mark-active)
  270. (region-end)))))
  271. (perform-replace regexp to-string t t delimited nil nil start end))
  272. (define-key esc-map [?\C-%] 'query-replace-regexp)
  273. (defun query-replace-regexp-eval (regexp to-expr &optional delimited start end)
  274. "Replace some things after point matching REGEXP with the result of TO-EXPR.
  275. Interactive use of this function is deprecated in favor of the
  276. `\\,' feature of `query-replace-regexp'. For non-interactive use, a loop
  277. using `search-forward-regexp' and `replace-match' is preferred.
  278. As each match is found, the user must type a character saying
  279. what to do with it. For directions, type \\[help-command] at that time.
  280. TO-EXPR is a Lisp expression evaluated to compute each replacement. It may
  281. reference `replace-count' to get the number of replacements already made.
  282. If the result of TO-EXPR is not a string, it is converted to one using
  283. `prin1-to-string' with the NOESCAPE argument (which see).
  284. For convenience, when entering TO-EXPR interactively, you can use `\\&' or
  285. `\\0' to stand for whatever matched the whole of REGEXP, and `\\N' (where
  286. N is a digit) to stand for whatever matched the Nth `\\(...\\)' in REGEXP.
  287. Use `\\#&' or `\\#N' if you want a number instead of a string.
  288. In interactive use, `\\#' in itself stands for `replace-count'.
  289. In Transient Mark mode, if the mark is active, operate on the contents
  290. of the region. Otherwise, operate from point to the end of the buffer.
  291. If `query-replace-interactive' is non-nil, the last incremental search
  292. regexp is used as REGEXP--you don't have to specify it with the
  293. minibuffer.
  294. Preserves case in each replacement if `case-replace' and `case-fold-search'
  295. are non-nil and REGEXP has no uppercase letters.
  296. Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
  297. only matches that are surrounded by word boundaries.
  298. Fourth and fifth arg START and END specify the region to operate on."
  299. (interactive
  300. (progn
  301. (barf-if-buffer-read-only)
  302. (let* ((from
  303. ;; Let-bind the history var to disable the "foo -> bar" default.
  304. ;; Maybe we shouldn't disable this default, but for now I'll
  305. ;; leave it off. --Stef
  306. (let ((query-replace-to-history-variable nil))
  307. (query-replace-read-from "Query replace regexp" t)))
  308. (to (list (read-from-minibuffer
  309. (format "Query replace regexp %s with eval: "
  310. (query-replace-descr from))
  311. nil nil t query-replace-to-history-variable from t))))
  312. ;; We make TO a list because replace-match-string-symbols requires one,
  313. ;; and the user might enter a single token.
  314. (replace-match-string-symbols to)
  315. (list from (car to) current-prefix-arg
  316. (if (and transient-mark-mode mark-active)
  317. (region-beginning))
  318. (if (and transient-mark-mode mark-active)
  319. (region-end))))))
  320. (perform-replace regexp (cons 'replace-eval-replacement to-expr)
  321. t 'literal delimited nil nil start end))
  322. (make-obsolete 'query-replace-regexp-eval
  323. "for interactive use, use the special `\\,' feature of
  324. `query-replace-regexp' instead. Non-interactively, a loop
  325. using `search-forward-regexp' and `replace-match' is preferred." "22.1")
  326. (defun map-query-replace-regexp (regexp to-strings &optional n start end)
  327. "Replace some matches for REGEXP with various strings, in rotation.
  328. The second argument TO-STRINGS contains the replacement strings, separated
  329. by spaces. This command works like `query-replace-regexp' except that
  330. each successive replacement uses the next successive replacement string,
  331. wrapping around from the last such string to the first.
  332. In Transient Mark mode, if the mark is active, operate on the contents
  333. of the region. Otherwise, operate from point to the end of the buffer.
  334. Non-interactively, TO-STRINGS may be a list of replacement strings.
  335. If `query-replace-interactive' is non-nil, the last incremental search
  336. regexp is used as REGEXP--you don't have to specify it with the minibuffer.
  337. A prefix argument N says to use each replacement string N times
  338. before rotating to the next.
  339. Fourth and fifth arg START and END specify the region to operate on."
  340. (interactive
  341. (let* ((from (if query-replace-interactive
  342. (car regexp-search-ring)
  343. (read-from-minibuffer "Map query replace (regexp): "
  344. nil nil nil
  345. query-replace-from-history-variable
  346. nil t)))
  347. (to (read-from-minibuffer
  348. (format "Query replace %s with (space-separated strings): "
  349. (query-replace-descr from))
  350. nil nil nil
  351. query-replace-to-history-variable from t)))
  352. (list from to
  353. (and current-prefix-arg
  354. (prefix-numeric-value current-prefix-arg))
  355. (if (and transient-mark-mode mark-active)
  356. (region-beginning))
  357. (if (and transient-mark-mode mark-active)
  358. (region-end)))))
  359. (let (replacements)
  360. (if (listp to-strings)
  361. (setq replacements to-strings)
  362. (while (/= (length to-strings) 0)
  363. (if (string-match " " to-strings)
  364. (setq replacements
  365. (append replacements
  366. (list (substring to-strings 0
  367. (string-match " " to-strings))))
  368. to-strings (substring to-strings
  369. (1+ (string-match " " to-strings))))
  370. (setq replacements (append replacements (list to-strings))
  371. to-strings ""))))
  372. (perform-replace regexp replacements t t nil n nil start end)))
  373. (defun replace-string (from-string to-string &optional delimited start end)
  374. "Replace occurrences of FROM-STRING with TO-STRING.
  375. Preserve case in each match if `case-replace' and `case-fold-search'
  376. are non-nil and FROM-STRING has no uppercase letters.
  377. \(Preserving case means that if the string matched is all caps, or capitalized,
  378. then its replacement is upcased or capitalized.)
  379. In Transient Mark mode, if the mark is active, operate on the contents
  380. of the region. Otherwise, operate from point to the end of the buffer.
  381. Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
  382. only matches surrounded by word boundaries.
  383. Fourth and fifth arg START and END specify the region to operate on.
  384. If `query-replace-interactive' is non-nil, the last incremental search
  385. string is used as FROM-STRING--you don't have to specify it with the
  386. minibuffer.
  387. This function is usually the wrong thing to use in a Lisp program.
  388. What you probably want is a loop like this:
  389. (while (search-forward FROM-STRING nil t)
  390. (replace-match TO-STRING nil t))
  391. which will run faster and will not set the mark or print anything.
  392. \(You may need a more complex loop if FROM-STRING can match the null string
  393. and TO-STRING is also null.)"
  394. (interactive
  395. (let ((common
  396. (query-replace-read-args
  397. (concat "Replace"
  398. (if current-prefix-arg " word" "")
  399. " string"
  400. (if (and transient-mark-mode mark-active) " in region" ""))
  401. nil)))
  402. (list (nth 0 common) (nth 1 common) (nth 2 common)
  403. (if (and transient-mark-mode mark-active)
  404. (region-beginning))
  405. (if (and transient-mark-mode mark-active)
  406. (region-end)))))
  407. (perform-replace from-string to-string nil nil delimited nil nil start end))
  408. (defun replace-regexp (regexp to-string &optional delimited start end)
  409. "Replace things after point matching REGEXP with TO-STRING.
  410. Preserve case in each match if `case-replace' and `case-fold-search'
  411. are non-nil and REGEXP has no uppercase letters.
  412. In Transient Mark mode, if the mark is active, operate on the contents
  413. of the region. Otherwise, operate from point to the end of the buffer.
  414. Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
  415. only matches surrounded by word boundaries.
  416. Fourth and fifth arg START and END specify the region to operate on.
  417. In TO-STRING, `\\&' stands for whatever matched the whole of REGEXP,
  418. and `\\=\\N' (where N is a digit) stands for
  419. whatever what matched the Nth `\\(...\\)' in REGEXP.
  420. `\\?' lets you edit the replacement text in the minibuffer
  421. at the given position for each replacement.
  422. In interactive calls, the replacement text may contain `\\,'
  423. followed by a Lisp expression used as part of the replacement
  424. text. Inside of that expression, `\\&' is a string denoting the
  425. whole match, `\\N' a partial match, `\\#&' and `\\#N' the respective
  426. numeric values from `string-to-number', and `\\#' itself for
  427. `replace-count', the number of replacements occurred so far.
  428. If your Lisp expression is an identifier and the next letter in
  429. the replacement string would be interpreted as part of it, you
  430. can wrap it with an expression like `\\,(or \\#)'. Incidentally,
  431. for this particular case you may also enter `\\#' in the
  432. replacement text directly.
  433. When using those Lisp features interactively in the replacement
  434. text, TO-STRING is actually made a list instead of a string.
  435. Use \\[repeat-complex-command] after this command for details.
  436. If `query-replace-interactive' is non-nil, the last incremental search
  437. regexp is used as REGEXP--you don't have to specify it with the minibuffer.
  438. This function is usually the wrong thing to use in a Lisp program.
  439. What you probably want is a loop like this:
  440. (while (re-search-forward REGEXP nil t)
  441. (replace-match TO-STRING nil nil))
  442. which will run faster and will not set the mark or print anything."
  443. (interactive
  444. (let ((common
  445. (query-replace-read-args
  446. (concat "Replace"
  447. (if current-prefix-arg " word" "")
  448. " regexp"
  449. (if (and transient-mark-mode mark-active) " in region" ""))
  450. t)))
  451. (list (nth 0 common) (nth 1 common) (nth 2 common)
  452. (if (and transient-mark-mode mark-active)
  453. (region-beginning))
  454. (if (and transient-mark-mode mark-active)
  455. (region-end)))))
  456. (perform-replace regexp to-string nil t delimited nil nil start end))
  457. (defvar regexp-history nil
  458. "History list for some commands that read regular expressions.
  459. Maximum length of the history list is determined by the value
  460. of `history-length', which see.")
  461. (defvar occur-collect-regexp-history '("\\1")
  462. "History of regexp for occur's collect operation")
  463. (defun read-regexp (prompt &optional default-value)
  464. "Read regexp as a string using the regexp history and some useful defaults.
  465. Prompt for a regular expression with PROMPT (without a colon and
  466. space) in the minibuffer. The optional argument DEFAULT-VALUE
  467. provides the value to display in the minibuffer prompt that is
  468. returned if the user just types RET.
  469. Values available via M-n are the string at point, the last isearch
  470. regexp, the last isearch string, and the last replacement regexp."
  471. (let* ((defaults
  472. (list (regexp-quote
  473. (or (funcall (or find-tag-default-function
  474. (get major-mode 'find-tag-default-function)
  475. 'find-tag-default))
  476. ""))
  477. (car regexp-search-ring)
  478. (regexp-quote (or (car search-ring) ""))
  479. (car (symbol-value
  480. query-replace-from-history-variable))))
  481. (defaults (delete-dups (delq nil (delete "" defaults))))
  482. ;; Don't add automatically the car of defaults for empty input
  483. (history-add-new-input nil)
  484. (input
  485. (read-from-minibuffer
  486. (if default-value
  487. (format "%s (default %s): " prompt
  488. (query-replace-descr default-value))
  489. (format "%s: " prompt))
  490. nil nil nil 'regexp-history defaults t)))
  491. (if (equal input "")
  492. (or default-value input)
  493. (prog1 input
  494. (add-to-history 'regexp-history input)))))
  495. (defalias 'delete-non-matching-lines 'keep-lines)
  496. (defalias 'delete-matching-lines 'flush-lines)
  497. (defalias 'count-matches 'how-many)
  498. (defun keep-lines-read-args (prompt)
  499. "Read arguments for `keep-lines' and friends.
  500. Prompt for a regexp with PROMPT.
  501. Value is a list, (REGEXP)."
  502. (list (read-regexp prompt) nil nil t))
  503. (defun keep-lines (regexp &optional rstart rend interactive)
  504. "Delete all lines except those containing matches for REGEXP.
  505. A match split across lines preserves all the lines it lies in.
  506. When called from Lisp (and usually interactively as well, see below)
  507. applies to all lines starting after point.
  508. If REGEXP contains upper case characters (excluding those preceded by `\\')
  509. and `search-upper-case' is non-nil, the matching is case-sensitive.
  510. Second and third arg RSTART and REND specify the region to operate on.
  511. This command operates on (the accessible part of) all lines whose
  512. accessible part is entirely contained in the region determined by RSTART
  513. and REND. (A newline ending a line counts as part of that line.)
  514. Interactively, in Transient Mark mode when the mark is active, operate
  515. on all lines whose accessible part is entirely contained in the region.
  516. Otherwise, the command applies to all lines starting after point.
  517. When calling this function from Lisp, you can pretend that it was
  518. called interactively by passing a non-nil INTERACTIVE argument.
  519. This function starts looking for the next match from the end of
  520. the previous match. Hence, it ignores matches that overlap
  521. a previously found match."
  522. (interactive
  523. (progn
  524. (barf-if-buffer-read-only)
  525. (keep-lines-read-args "Keep lines containing match for regexp")))
  526. (if rstart
  527. (progn
  528. (goto-char (min rstart rend))
  529. (setq rend
  530. (progn
  531. (save-excursion
  532. (goto-char (max rstart rend))
  533. (unless (or (bolp) (eobp))
  534. (forward-line 0))
  535. (point-marker)))))
  536. (if (and interactive transient-mark-mode mark-active)
  537. (setq rstart (region-beginning)
  538. rend (progn
  539. (goto-char (region-end))
  540. (unless (or (bolp) (eobp))
  541. (forward-line 0))
  542. (point-marker)))
  543. (setq rstart (point)
  544. rend (point-max-marker)))
  545. (goto-char rstart))
  546. (save-excursion
  547. (or (bolp) (forward-line 1))
  548. (let ((start (point))
  549. (case-fold-search
  550. (if (and case-fold-search search-upper-case)
  551. (isearch-no-upper-case-p regexp t)
  552. case-fold-search)))
  553. (while (< (point) rend)
  554. ;; Start is first char not preserved by previous match.
  555. (if (not (re-search-forward regexp rend 'move))
  556. (delete-region start rend)
  557. (let ((end (save-excursion (goto-char (match-beginning 0))
  558. (forward-line 0)
  559. (point))))
  560. ;; Now end is first char preserved by the new match.
  561. (if (< start end)
  562. (delete-region start end))))
  563. (setq start (save-excursion (forward-line 1) (point)))
  564. ;; If the match was empty, avoid matching again at same place.
  565. (and (< (point) rend)
  566. (= (match-beginning 0) (match-end 0))
  567. (forward-char 1)))))
  568. (set-marker rend nil)
  569. nil)
  570. (defun flush-lines (regexp &optional rstart rend interactive)
  571. "Delete lines containing matches for REGEXP.
  572. When called from Lisp (and usually when called interactively as
  573. well, see below), applies to the part of the buffer after point.
  574. The line point is in is deleted if and only if it contains a
  575. match for regexp starting after point.
  576. If REGEXP contains upper case characters (excluding those preceded by `\\')
  577. and `search-upper-case' is non-nil, the matching is case-sensitive.
  578. Second and third arg RSTART and REND specify the region to operate on.
  579. Lines partially contained in this region are deleted if and only if
  580. they contain a match entirely contained in it.
  581. Interactively, in Transient Mark mode when the mark is active, operate
  582. on the contents of the region. Otherwise, operate from point to the
  583. end of (the accessible portion of) the buffer. When calling this function
  584. from Lisp, you can pretend that it was called interactively by passing
  585. a non-nil INTERACTIVE argument.
  586. If a match is split across lines, all the lines it lies in are deleted.
  587. They are deleted _before_ looking for the next match. Hence, a match
  588. starting on the same line at which another match ended is ignored."
  589. (interactive
  590. (progn
  591. (barf-if-buffer-read-only)
  592. (keep-lines-read-args "Flush lines containing match for regexp")))
  593. (if rstart
  594. (progn
  595. (goto-char (min rstart rend))
  596. (setq rend (copy-marker (max rstart rend))))
  597. (if (and interactive transient-mark-mode mark-active)
  598. (setq rstart (region-beginning)
  599. rend (copy-marker (region-end)))
  600. (setq rstart (point)
  601. rend (point-max-marker)))
  602. (goto-char rstart))
  603. (let ((case-fold-search
  604. (if (and case-fold-search search-upper-case)
  605. (isearch-no-upper-case-p regexp t)
  606. case-fold-search)))
  607. (save-excursion
  608. (while (and (< (point) rend)
  609. (re-search-forward regexp rend t))
  610. (delete-region (save-excursion (goto-char (match-beginning 0))
  611. (forward-line 0)
  612. (point))
  613. (progn (forward-line 1) (point))))))
  614. (set-marker rend nil)
  615. nil)
  616. (defun how-many (regexp &optional rstart rend interactive)
  617. "Print and return number of matches for REGEXP following point.
  618. When called from Lisp and INTERACTIVE is omitted or nil, just return
  619. the number, do not print it; if INTERACTIVE is t, the function behaves
  620. in all respects as if it had been called interactively.
  621. If REGEXP contains upper case characters (excluding those preceded by `\\')
  622. and `search-upper-case' is non-nil, the matching is case-sensitive.
  623. Second and third arg RSTART and REND specify the region to operate on.
  624. Interactively, in Transient Mark mode when the mark is active, operate
  625. on the contents of the region. Otherwise, operate from point to the
  626. end of (the accessible portion of) the buffer.
  627. This function starts looking for the next match from the end of
  628. the previous match. Hence, it ignores matches that overlap
  629. a previously found match."
  630. (interactive
  631. (keep-lines-read-args "How many matches for regexp"))
  632. (save-excursion
  633. (if rstart
  634. (progn
  635. (goto-char (min rstart rend))
  636. (setq rend (max rstart rend)))
  637. (if (and interactive transient-mark-mode mark-active)
  638. (setq rstart (region-beginning)
  639. rend (region-end))
  640. (setq rstart (point)
  641. rend (point-max)))
  642. (goto-char rstart))
  643. (let ((count 0)
  644. opoint
  645. (case-fold-search
  646. (if (and case-fold-search search-upper-case)
  647. (isearch-no-upper-case-p regexp t)
  648. case-fold-search)))
  649. (while (and (< (point) rend)
  650. (progn (setq opoint (point))
  651. (re-search-forward regexp rend t)))
  652. (if (= opoint (point))
  653. (forward-char 1)
  654. (setq count (1+ count))))
  655. (when interactive (message "%d occurrence%s"
  656. count
  657. (if (= count 1) "" "s")))
  658. count)))
  659. (defvar occur-menu-map
  660. (let ((map (make-sparse-keymap)))
  661. (define-key map [next-error-follow-minor-mode]
  662. `(menu-item ,(purecopy "Auto Occurrence Display")
  663. next-error-follow-minor-mode
  664. :help ,(purecopy
  665. "Display another occurrence when moving the cursor")
  666. :button (:toggle . (and (boundp 'next-error-follow-minor-mode)
  667. next-error-follow-minor-mode))))
  668. (define-key map [separator-1] menu-bar-separator)
  669. (define-key map [kill-this-buffer]
  670. `(menu-item ,(purecopy "Kill Occur Buffer") kill-this-buffer
  671. :help ,(purecopy "Kill the current *Occur* buffer")))
  672. (define-key map [quit-window]
  673. `(menu-item ,(purecopy "Quit Occur Window") quit-window
  674. :help ,(purecopy "Quit the current *Occur* buffer. Bury it, and maybe delete the selected frame")))
  675. (define-key map [revert-buffer]
  676. `(menu-item ,(purecopy "Revert Occur Buffer") revert-buffer
  677. :help ,(purecopy "Replace the text in the *Occur* buffer with the results of rerunning occur")))
  678. (define-key map [clone-buffer]
  679. `(menu-item ,(purecopy "Clone Occur Buffer") clone-buffer
  680. :help ,(purecopy "Create and return a twin copy of the current *Occur* buffer")))
  681. (define-key map [occur-rename-buffer]
  682. `(menu-item ,(purecopy "Rename Occur Buffer") occur-rename-buffer
  683. :help ,(purecopy "Rename the current *Occur* buffer to *Occur: original-buffer-name*.")))
  684. (define-key map [occur-edit-buffer]
  685. `(menu-item ,(purecopy "Edit Occur Buffer") occur-edit-mode
  686. :help ,(purecopy "Edit the *Occur* buffer and apply changes to the original buffers.")))
  687. (define-key map [separator-2] menu-bar-separator)
  688. (define-key map [occur-mode-goto-occurrence-other-window]
  689. `(menu-item ,(purecopy "Go To Occurrence Other Window") occur-mode-goto-occurrence-other-window
  690. :help ,(purecopy "Go to the occurrence the current line describes, in another window")))
  691. (define-key map [occur-mode-goto-occurrence]
  692. `(menu-item ,(purecopy "Go To Occurrence") occur-mode-goto-occurrence
  693. :help ,(purecopy "Go to the occurrence the current line describes")))
  694. (define-key map [occur-mode-display-occurrence]
  695. `(menu-item ,(purecopy "Display Occurrence") occur-mode-display-occurrence
  696. :help ,(purecopy "Display in another window the occurrence the current line describes")))
  697. (define-key map [occur-next]
  698. `(menu-item ,(purecopy "Move to Next Match") occur-next
  699. :help ,(purecopy "Move to the Nth (default 1) next match in an Occur mode buffer")))
  700. (define-key map [occur-prev]
  701. `(menu-item ,(purecopy "Move to Previous Match") occur-prev
  702. :help ,(purecopy "Move to the Nth (default 1) previous match in an Occur mode buffer")))
  703. map)
  704. "Menu keymap for `occur-mode'.")
  705. (defvar occur-mode-map
  706. (let ((map (make-sparse-keymap)))
  707. ;; We use this alternative name, so we can use \\[occur-mode-mouse-goto].
  708. (define-key map [mouse-2] 'occur-mode-mouse-goto)
  709. (define-key map "\C-c\C-c" 'occur-mode-goto-occurrence)
  710. (define-key map "e" 'occur-edit-mode)
  711. (define-key map "\C-m" 'occur-mode-goto-occurrence)
  712. (define-key map "o" 'occur-mode-goto-occurrence-other-window)
  713. (define-key map "\C-o" 'occur-mode-display-occurrence)
  714. (define-key map "\M-n" 'occur-next)
  715. (define-key map "\M-p" 'occur-prev)
  716. (define-key map "r" 'occur-rename-buffer)
  717. (define-key map "c" 'clone-buffer)
  718. (define-key map "\C-c\C-f" 'next-error-follow-minor-mode)
  719. (define-key map [menu-bar occur] (cons (purecopy "Occur") occur-menu-map))
  720. map)
  721. "Keymap for `occur-mode'.")
  722. (defvar occur-revert-arguments nil
  723. "Arguments to pass to `occur-1' to revert an Occur mode buffer.
  724. See `occur-revert-function'.")
  725. (make-variable-buffer-local 'occur-revert-arguments)
  726. (put 'occur-revert-arguments 'permanent-local t)
  727. (defcustom occur-mode-hook '(turn-on-font-lock)
  728. "Hook run when entering Occur mode."
  729. :type 'hook
  730. :group 'matching)
  731. (defcustom occur-hook nil
  732. "Hook run by Occur when there are any matches."
  733. :type 'hook
  734. :group 'matching)
  735. (defcustom occur-mode-find-occurrence-hook nil
  736. "Hook run by Occur after locating an occurrence.
  737. This will be called with the cursor position at the occurrence. An application
  738. for this is to reveal context in an outline-mode when the occurrence is hidden."
  739. :type 'hook
  740. :group 'matching)
  741. (put 'occur-mode 'mode-class 'special)
  742. (define-derived-mode occur-mode special-mode "Occur"
  743. "Major mode for output from \\[occur].
  744. \\<occur-mode-map>Move point to one of the items in this buffer, then use
  745. \\[occur-mode-goto-occurrence] to go to the occurrence that the item refers to.
  746. Alternatively, click \\[occur-mode-mouse-goto] on an item to go to it.
  747. \\{occur-mode-map}"
  748. (set (make-local-variable 'revert-buffer-function) 'occur-revert-function)
  749. (setq next-error-function 'occur-next-error))
  750. ;;; Occur Edit mode
  751. (defvar occur-edit-mode-map
  752. (let ((map (make-sparse-keymap)))
  753. (set-keymap-parent map text-mode-map)
  754. (define-key map [mouse-2] 'occur-mode-mouse-goto)
  755. (define-key map "\C-c\C-c" 'occur-cease-edit)
  756. (define-key map "\C-o" 'occur-mode-display-occurrence)
  757. (define-key map "\C-c\C-f" 'next-error-follow-minor-mode)
  758. (define-key map [menu-bar occur] (cons (purecopy "Occur") occur-menu-map))
  759. map)
  760. "Keymap for `occur-edit-mode'.")
  761. (define-derived-mode occur-edit-mode occur-mode "Occur-Edit"
  762. "Major mode for editing *Occur* buffers.
  763. In this mode, changes to the *Occur* buffer are also applied to
  764. the originating buffer.
  765. To return to ordinary Occur mode, use \\[occur-cease-edit]."
  766. (setq buffer-read-only nil)
  767. (add-hook 'after-change-functions 'occur-after-change-function nil t)
  768. (message (substitute-command-keys
  769. "Editing: Type \\[occur-cease-edit] to return to Occur mode.")))
  770. (defun occur-cease-edit ()
  771. "Switch from Occur Edit mode to Occur mode."
  772. (interactive)
  773. (when (derived-mode-p 'occur-edit-mode)
  774. (occur-mode)
  775. (message "Switching to Occur mode.")))
  776. (defun occur-after-change-function (beg end length)
  777. (save-excursion
  778. (goto-char beg)
  779. (let* ((line-beg (line-beginning-position))
  780. (m (get-text-property line-beg 'occur-target))
  781. (buf (marker-buffer m))
  782. col)
  783. (when (and (get-text-property line-beg 'occur-prefix)
  784. (not (get-text-property end 'occur-prefix)))
  785. (when (= length 0)
  786. ;; Apply occur-target property to inserted (e.g. yanked) text.
  787. (put-text-property beg end 'occur-target m)
  788. ;; Did we insert a newline? Occur Edit mode can't create new
  789. ;; Occur entries; just discard everything after the newline.
  790. (save-excursion
  791. (and (search-forward "\n" end t)
  792. (delete-region (1- (point)) end))))
  793. (let* ((line (- (line-number-at-pos)
  794. (line-number-at-pos (window-start))))
  795. (readonly (with-current-buffer buf buffer-read-only))
  796. (win (or (get-buffer-window buf)
  797. (display-buffer buf t)))
  798. (line-end (line-end-position))
  799. (text (save-excursion
  800. (goto-char (next-single-property-change
  801. line-beg 'occur-prefix nil
  802. line-end))
  803. (setq col (- (point) line-beg))
  804. (buffer-substring-no-properties (point) line-end))))
  805. (with-selected-window win
  806. (goto-char m)
  807. (recenter line)
  808. (if readonly
  809. (message "Buffer `%s' is read only." buf)
  810. (delete-region (line-beginning-position) (line-end-position))
  811. (insert text))
  812. (move-to-column col)))))))
  813. (defun occur-revert-function (_ignore1 _ignore2)
  814. "Handle `revert-buffer' for Occur mode buffers."
  815. (apply 'occur-1 (append occur-revert-arguments (list (buffer-name)))))
  816. (defun occur-mode-find-occurrence ()
  817. (let ((pos (get-text-property (point) 'occur-target)))
  818. (unless pos
  819. (error "No occurrence on this line"))
  820. (unless (buffer-live-p (marker-buffer pos))
  821. (error "Buffer for this occurrence was killed"))
  822. pos))
  823. (defalias 'occur-mode-mouse-goto 'occur-mode-goto-occurrence)
  824. (defun occur-mode-goto-occurrence (&optional event)
  825. "Go to the occurrence on the current line."
  826. (interactive (list last-nonmenu-event))
  827. (let ((pos
  828. (if (null event)
  829. ;; Actually `event-end' works correctly with a nil argument as
  830. ;; well, so we could dispense with this test, but let's not
  831. ;; rely on this undocumented behavior.
  832. (occur-mode-find-occurrence)
  833. (with-current-buffer (window-buffer (posn-window (event-end event)))
  834. (save-excursion
  835. (goto-char (posn-point (event-end event)))
  836. (occur-mode-find-occurrence))))))
  837. (pop-to-buffer (marker-buffer pos))
  838. (goto-char pos)
  839. (run-hooks 'occur-mode-find-occurrence-hook)))
  840. (defun occur-mode-goto-occurrence-other-window ()
  841. "Go to the occurrence the current line describes, in another window."
  842. (interactive)
  843. (let ((pos (occur-mode-find-occurrence)))
  844. (switch-to-buffer-other-window (marker-buffer pos))
  845. (goto-char pos)
  846. (run-hooks 'occur-mode-find-occurrence-hook)))
  847. (defun occur-mode-display-occurrence ()
  848. "Display in another window the occurrence the current line describes."
  849. (interactive)
  850. (let ((pos (occur-mode-find-occurrence))
  851. window)
  852. (setq window (display-buffer (marker-buffer pos) t))
  853. ;; This is the way to set point in the proper window.
  854. (save-selected-window
  855. (select-window window)
  856. (goto-char pos)
  857. (run-hooks 'occur-mode-find-occurrence-hook))))
  858. (defun occur-find-match (n search message)
  859. (if (not n) (setq n 1))
  860. (let ((r))
  861. (while (> n 0)
  862. (setq r (funcall search (point) 'occur-match))
  863. (and r
  864. (get-text-property r 'occur-match)
  865. (setq r (funcall search r 'occur-match)))
  866. (if r
  867. (goto-char r)
  868. (error message))
  869. (setq n (1- n)))))
  870. (defun occur-next (&optional n)
  871. "Move to the Nth (default 1) next match in an Occur mode buffer."
  872. (interactive "p")
  873. (occur-find-match n #'next-single-property-change "No more matches"))
  874. (defun occur-prev (&optional n)
  875. "Move to the Nth (default 1) previous match in an Occur mode buffer."
  876. (interactive "p")
  877. (occur-find-match n #'previous-single-property-change "No earlier matches"))
  878. (defun occur-next-error (&optional argp reset)
  879. "Move to the Nth (default 1) next match in an Occur mode buffer.
  880. Compatibility function for \\[next-error] invocations."
  881. (interactive "p")
  882. ;; we need to run occur-find-match from within the Occur buffer
  883. (with-current-buffer
  884. ;; Choose the buffer and make it current.
  885. (if (next-error-buffer-p (current-buffer))
  886. (current-buffer)
  887. (next-error-find-buffer nil nil
  888. (lambda ()
  889. (eq major-mode 'occur-mode))))
  890. (goto-char (cond (reset (point-min))
  891. ((< argp 0) (line-beginning-position))
  892. ((> argp 0) (line-end-position))
  893. ((point))))
  894. (occur-find-match
  895. (abs argp)
  896. (if (> 0 argp)
  897. #'previous-single-property-change
  898. #'next-single-property-change)
  899. "No more matches")
  900. ;; In case the *Occur* buffer is visible in a nonselected window.
  901. (let ((win (get-buffer-window (current-buffer) t)))
  902. (if win (set-window-point win (point))))
  903. (occur-mode-goto-occurrence)))
  904. (defface match
  905. '((((class color) (min-colors 88) (background light))
  906. :background "yellow1")
  907. (((class color) (min-colors 88) (background dark))
  908. :background "RoyalBlue3")
  909. (((class color) (min-colors 8) (background light))
  910. :background "yellow" :foreground "black")
  911. (((class color) (min-colors 8) (background dark))
  912. :background "blue" :foreground "white")
  913. (((type tty) (class mono))
  914. :inverse-video t)
  915. (t :background "gray"))
  916. "Face used to highlight matches permanently."
  917. :group 'matching
  918. :version "22.1")
  919. (defcustom list-matching-lines-default-context-lines 0
  920. "Default number of context lines included around `list-matching-lines' matches.
  921. A negative number means to include that many lines before the match.
  922. A positive number means to include that many lines both before and after."
  923. :type 'integer
  924. :group 'matching)
  925. (defalias 'list-matching-lines 'occur)
  926. (defcustom list-matching-lines-face 'match
  927. "Face used by \\[list-matching-lines] to show the text that matches.
  928. If the value is nil, don't highlight the matching portions specially."
  929. :type 'face
  930. :group 'matching)
  931. (defcustom list-matching-lines-buffer-name-face 'underline
  932. "Face used by \\[list-matching-lines] to show the names of buffers.
  933. If the value is nil, don't highlight the buffer names specially."
  934. :type 'face
  935. :group 'matching)
  936. (defcustom occur-excluded-properties
  937. '(read-only invisible intangible field mouse-face help-echo local-map keymap
  938. yank-handler follow-link)
  939. "Text properties to discard when copying lines to the *Occur* buffer.
  940. The value should be a list of text properties to discard or t,
  941. which means to discard all text properties."
  942. :type '(choice (const :tag "All" t) (repeat symbol))
  943. :group 'matching
  944. :version "22.1")
  945. (defun occur-read-primary-args ()
  946. (let* ((perform-collect (consp current-prefix-arg))
  947. (regexp (read-regexp (if perform-collect
  948. "Collect strings matching regexp"
  949. "List lines matching regexp")
  950. (car regexp-history))))
  951. (list regexp
  952. (if perform-collect
  953. ;; Perform collect operation
  954. (if (zerop (regexp-opt-depth regexp))
  955. ;; No subexpression so collect the entire match.
  956. "\\&"
  957. ;; Get the regexp for collection pattern.
  958. (let ((default (car occur-collect-regexp-history)))
  959. (read-string
  960. (format "Regexp to collect (default %s): " default)
  961. nil 'occur-collect-regexp-history default)))
  962. ;; Otherwise normal occur takes numerical prefix argument.
  963. (when current-prefix-arg
  964. (prefix-numeric-value current-prefix-arg))))))
  965. (defun occur-rename-buffer (&optional unique-p interactive-p)
  966. "Rename the current *Occur* buffer to *Occur: original-buffer-name*.
  967. Here `original-buffer-name' is the buffer name where Occur was originally run.
  968. When given the prefix argument, or called non-interactively, the renaming
  969. will not clobber the existing buffer(s) of that name, but use
  970. `generate-new-buffer-name' instead. You can add this to `occur-hook'
  971. if you always want a separate *Occur* buffer for each buffer where you
  972. invoke `occur'."
  973. (interactive "P\np")
  974. (with-current-buffer
  975. (if (eq major-mode 'occur-mode) (current-buffer) (get-buffer "*Occur*"))
  976. (rename-buffer (concat "*Occur: "
  977. (mapconcat #'buffer-name
  978. (car (cddr occur-revert-arguments)) "/")
  979. "*")
  980. (or unique-p (not interactive-p)))))
  981. (defun occur (regexp &optional nlines)
  982. "Show all lines in the current buffer containing a match for REGEXP.
  983. If a match spreads across multiple lines, all those lines are shown.
  984. Each line is displayed with NLINES lines before and after, or -NLINES
  985. before if NLINES is negative.
  986. NLINES defaults to `list-matching-lines-default-context-lines'.
  987. Interactively it is the prefix arg.
  988. The lines are shown in a buffer named `*Occur*'.
  989. It serves as a menu to find any of the occurrences in this buffer.
  990. \\<occur-mode-map>\\[describe-mode] in that buffer will explain how.
  991. If REGEXP contains upper case characters (excluding those preceded by `\\')
  992. and `search-upper-case' is non-nil, the matching is case-sensitive.
  993. When NLINES is a string or when the function is called
  994. interactively with prefix argument without a number (`C-u' alone
  995. as prefix) the matching strings are collected into the `*Occur*'
  996. buffer by using NLINES as a replacement regexp. NLINES may
  997. contain \\& and \\N which convention follows `replace-match'.
  998. For example, providing \"defun\\s +\\(\\S +\\)\" for REGEXP and
  999. \"\\1\" for NLINES collects all the function names in a lisp
  1000. program. When there is no parenthesized subexpressions in REGEXP
  1001. the entire match is collected. In any case the searched buffers
  1002. are not modified."
  1003. (interactive (occur-read-primary-args))
  1004. (occur-1 regexp nlines (list (current-buffer))))
  1005. (defvar ido-ignore-item-temp-list)
  1006. (defun multi-occur (bufs regexp &optional nlines)
  1007. "Show all lines in buffers BUFS containing a match for REGEXP.
  1008. This function acts on multiple buffers; otherwise, it is exactly like
  1009. `occur'. When you invoke this command interactively, you must specify
  1010. the buffer names that you want, one by one.
  1011. See also `multi-occur-in-matching-buffers'."
  1012. (interactive
  1013. (cons
  1014. (let* ((bufs (list (read-buffer "First buffer to search: "
  1015. (current-buffer) t)))
  1016. (buf nil)
  1017. (ido-ignore-item-temp-list bufs))
  1018. (while (not (string-equal
  1019. (setq buf (read-buffer
  1020. (if (eq read-buffer-function 'ido-read-buffer)
  1021. "Next buffer to search (C-j to end): "
  1022. "Next buffer to search (RET to end): ")
  1023. nil t))
  1024. ""))
  1025. (add-to-list 'bufs buf)
  1026. (setq ido-ignore-item-temp-list bufs))
  1027. (nreverse (mapcar #'get-buffer bufs)))
  1028. (occur-read-primary-args)))
  1029. (occur-1 regexp nlines bufs))
  1030. (defun multi-occur-in-matching-buffers (bufregexp regexp &optional allbufs)
  1031. "Show all lines matching REGEXP in buffers specified by BUFREGEXP.
  1032. Normally BUFREGEXP matches against each buffer's visited file name,
  1033. but if you specify a prefix argument, it matches against the buffer name.
  1034. See also `multi-occur'."
  1035. (interactive
  1036. (cons
  1037. (let* ((default (car regexp-history))
  1038. (input
  1039. (read-from-minibuffer
  1040. (if current-prefix-arg
  1041. "List lines in buffers whose names match regexp: "
  1042. "List lines in buffers whose filenames match regexp: ")
  1043. nil
  1044. nil
  1045. nil
  1046. 'regexp-history)))
  1047. (if (equal input "")
  1048. default
  1049. input))
  1050. (occur-read-primary-args)))
  1051. (when bufregexp
  1052. (occur-1 regexp nil
  1053. (delq nil
  1054. (mapcar (lambda (buf)
  1055. (when (if allbufs
  1056. (string-match bufregexp
  1057. (buffer-name buf))
  1058. (and (buffer-file-name buf)
  1059. (string-match bufregexp
  1060. (buffer-file-name buf))))
  1061. buf))
  1062. (buffer-list))))))
  1063. (defun occur-1 (regexp nlines bufs &optional buf-name)
  1064. (unless (and regexp (not (equal regexp "")))
  1065. (error "Occur doesn't work with the empty regexp"))
  1066. (unless buf-name
  1067. (setq buf-name "*Occur*"))
  1068. (let (occur-buf
  1069. (active-bufs (delq nil (mapcar #'(lambda (buf)
  1070. (when (buffer-live-p buf) buf))
  1071. bufs))))
  1072. ;; Handle the case where one of the buffers we're searching is the
  1073. ;; output buffer. Just rename it.
  1074. (when (member buf-name (mapcar 'buffer-name active-bufs))
  1075. (with-current-buffer (get-buffer buf-name)
  1076. (rename-uniquely)))
  1077. ;; Now find or create the output buffer.
  1078. ;; If we just renamed that buffer, we will make a new one here.
  1079. (setq occur-buf (get-buffer-create buf-name))
  1080. (with-current-buffer occur-buf
  1081. (if (stringp nlines)
  1082. (fundamental-mode) ;; This is for collect operation.
  1083. (occur-mode))
  1084. (let ((inhibit-read-only t)
  1085. ;; Don't generate undo entries for creation of the initial contents.
  1086. (buffer-undo-list t))
  1087. (erase-buffer)
  1088. (let ((count
  1089. (if (stringp nlines)
  1090. ;; Treat nlines as a regexp to collect.
  1091. (let ((bufs active-bufs)
  1092. (count 0))
  1093. (while bufs
  1094. (with-current-buffer (car bufs)
  1095. (save-excursion
  1096. (goto-char (point-min))
  1097. (while (re-search-forward regexp nil t)
  1098. ;; Insert the replacement regexp.
  1099. (let ((str (match-substitute-replacement nlines)))
  1100. (if str
  1101. (with-current-buffer occur-buf
  1102. (insert str)
  1103. (setq count (1+ count))
  1104. (or (zerop (current-column))
  1105. (insert "\n"))))))))
  1106. (setq bufs (cdr bufs)))
  1107. count)
  1108. ;; Perform normal occur.
  1109. (occur-engine
  1110. regexp active-bufs occur-buf
  1111. (or nlines list-matching-lines-default-context-lines)
  1112. (if (and case-fold-search search-upper-case)
  1113. (isearch-no-upper-case-p regexp t)
  1114. case-fold-search)
  1115. list-matching-lines-buffer-name-face
  1116. nil list-matching-lines-face
  1117. (not (eq occur-excluded-properties t))))))
  1118. (let* ((bufcount (length active-bufs))
  1119. (diff (- (length bufs) bufcount)))
  1120. (message "Searched %d buffer%s%s; %s match%s%s"
  1121. bufcount (if (= bufcount 1) "" "s")
  1122. (if (zerop diff) "" (format " (%d killed)" diff))
  1123. (if (zerop count) "no" (format "%d" count))
  1124. (if (= count 1) "" "es")
  1125. ;; Don't display regexp if with remaining text
  1126. ;; it is longer than window-width.
  1127. (if (> (+ (length regexp) 42) (window-width))
  1128. "" (format " for `%s'" (query-replace-descr regexp)))))
  1129. (setq occur-revert-arguments (list regexp nlines bufs))
  1130. (if (= count 0)
  1131. (kill-buffer occur-buf)
  1132. (display-buffer occur-buf)
  1133. (setq next-error-last-buffer occur-buf)
  1134. (setq buffer-read-only t)
  1135. (set-buffer-modified-p nil)
  1136. (run-hooks 'occur-hook)))))))
  1137. (defun occur-engine (regexp buffers out-buf nlines case-fold
  1138. title-face prefix-face match-face keep-props)
  1139. (with-current-buffer out-buf
  1140. (let ((globalcount 0)
  1141. (coding nil)
  1142. (case-fold-search case-fold))
  1143. ;; Map over all the buffers
  1144. (dolist (buf buffers)
  1145. (when (buffer-live-p buf)
  1146. (let ((matches 0) ;; count of matched lines
  1147. (lines 1) ;; line count
  1148. (prev-after-lines nil) ;; context lines of prev match
  1149. (prev-lines nil) ;; line number of prev match endpt
  1150. (matchbeg 0)
  1151. (origpt nil)
  1152. (begpt nil)
  1153. (endpt nil)
  1154. (marker nil)
  1155. (curstring "")
  1156. (ret nil)
  1157. (inhibit-field-text-motion t)
  1158. (headerpt (with-current-buffer out-buf (point))))
  1159. (with-current-buffer buf
  1160. (or coding
  1161. ;; Set CODING only if the current buffer locally
  1162. ;; binds buffer-file-coding-system.
  1163. (not (local-variable-p 'buffer-file-coding-system))
  1164. (setq coding buffer-file-coding-system))
  1165. (save-excursion
  1166. (goto-char (point-min)) ;; begin searching in the buffer
  1167. (while (not (eobp))
  1168. (setq origpt (point))
  1169. (when (setq endpt (re-search-forward regexp nil t))
  1170. (setq matches (1+ matches)) ;; increment match count
  1171. (setq matchbeg (match-beginning 0))
  1172. ;; Get beginning of first match line and end of the last.
  1173. (save-excursion
  1174. (goto-char matchbeg)
  1175. (setq begpt (line-beginning-position))
  1176. (goto-char endpt)
  1177. (setq endpt (line-end-position)))
  1178. ;; Sum line numbers up to the first match line.
  1179. (setq lines (+ lines (count-lines origpt begpt)))
  1180. (setq marker (make-marker))
  1181. (set-marker marker matchbeg)
  1182. (setq curstring (occur-engine-line begpt endpt keep-props))
  1183. ;; Highlight the matches
  1184. (let ((len (length curstring))
  1185. (start 0))
  1186. (while (and (< start len)
  1187. (string-match regexp curstring start))
  1188. (add-text-properties
  1189. (match-beginning 0) (match-end 0)
  1190. (append
  1191. `(occur-match t)
  1192. (when match-face
  1193. ;; Use `face' rather than `font-lock-face' here
  1194. ;; so as to override faces copied from the buffer.
  1195. `(face ,match-face)))
  1196. curstring)
  1197. (setq start (match-end 0))))
  1198. ;; Generate the string to insert for this match
  1199. (let* ((match-prefix
  1200. ;; Using 7 digits aligns tabs properly.
  1201. (apply #'propertize (format "%7d:" lines)
  1202. (append
  1203. (when prefix-face
  1204. `(font-lock-face prefix-face))
  1205. `(occur-prefix t mouse-face (highlight)
  1206. ;; Allow insertion of text at
  1207. ;; the end of the prefix (for
  1208. ;; Occur Edit mode).
  1209. front-sticky t rear-nonsticky t
  1210. occur-target ,marker follow-link t
  1211. help-echo "mouse-2: go to this occurrence"))))
  1212. (match-str
  1213. ;; We don't put `mouse-face' on the newline,
  1214. ;; because that loses. And don't put it
  1215. ;; on context lines to reduce flicker.
  1216. (propertize curstring 'mouse-face (list 'highlight)
  1217. 'occur-target marker
  1218. 'follow-link t
  1219. 'help-echo
  1220. "mouse-2: go to this occurrence"))
  1221. (out-line
  1222. (concat
  1223. match-prefix
  1224. ;; Add non-numeric prefix to all non-first lines
  1225. ;; of multi-line matches.
  1226. (replace-regexp-in-string
  1227. "\n"
  1228. "\n :"
  1229. match-str)
  1230. ;; Add marker at eol, but no mouse props.
  1231. (propertize "\n" 'occur-target marker)))
  1232. (data
  1233. (if (= nlines 0)
  1234. ;; The simple display style
  1235. out-line
  1236. ;; The complex multi-line display style.
  1237. (setq ret (occur-context-lines
  1238. out-line nlines keep-props begpt endpt
  1239. lines prev-lines prev-after-lines))
  1240. ;; Set first elem of the returned list to `data',
  1241. ;; and the second elem to `prev-after-lines'.
  1242. (setq prev-after-lines (nth 1 ret))
  1243. (nth 0 ret))))
  1244. ;; Actually insert the match display data
  1245. (with-current-buffer out-buf
  1246. (insert data)))
  1247. (goto-char endpt))
  1248. (if endpt
  1249. (progn
  1250. ;; Sum line numbers between first and last match lines.
  1251. (setq lines (+ lines (count-lines begpt endpt)
  1252. ;; Add 1 for empty last match line since
  1253. ;; count-lines returns 1 line less.
  1254. (if (and (bolp) (eolp)) 1 0)))
  1255. ;; On to the next match...
  1256. (forward-line 1))
  1257. (goto-char (point-max)))
  1258. (setq prev-lines (1- lines)))
  1259. ;; Flush remaining context after-lines.
  1260. (when prev-after-lines
  1261. (with-current-buffer out-buf
  1262. (insert (apply #'concat (occur-engine-add-prefix
  1263. prev-after-lines)))))))
  1264. (when (not (zerop matches)) ;; is the count zero?
  1265. (setq globalcount (+ globalcount matches))
  1266. (with-current-buffer out-buf
  1267. (goto-char headerpt)
  1268. (let ((beg (point))
  1269. end)
  1270. (insert (propertize
  1271. (format "%d match%s%s in buffer: %s\n"
  1272. matches (if (= matches 1) "" "es")
  1273. ;; Don't display regexp for multi-buffer.
  1274. (if (> (length buffers) 1)
  1275. "" (format " for \"%s\""
  1276. (query-replace-descr regexp)))
  1277. (buffer-name buf))
  1278. 'read-only t))
  1279. (setq end (point))
  1280. (add-text-properties beg end
  1281. (append
  1282. (when title-face
  1283. `(font-lock-face ,title-face))
  1284. `(occur-title ,buf))))
  1285. (goto-char (point-min)))))))
  1286. ;; Display total match count and regexp for multi-buffer.
  1287. (when (and (not (zerop globalcount)) (> (length buffers) 1))
  1288. (goto-char (point-min))
  1289. (let ((beg (point))
  1290. end)
  1291. (insert (format "%d match%s total for \"%s\":\n"
  1292. globalcount (if (= globalcount 1) "" "es")
  1293. (query-replace-descr regexp)))
  1294. (setq end (point))
  1295. (add-text-properties beg end (when title-face
  1296. `(font-lock-face ,title-face))))
  1297. (goto-char (point-min)))
  1298. (if coding
  1299. ;; CODING is buffer-file-coding-system of the first buffer
  1300. ;; that locally binds it. Let's use it also for the output
  1301. ;; buffer.
  1302. (set-buffer-file-coding-system coding))
  1303. ;; Return the number of matches
  1304. globalcount)))
  1305. (defun occur-engine-line (beg end &optional keep-props)
  1306. (if (and keep-props (if (boundp 'jit-lock-mode) jit-lock-mode)
  1307. (text-property-not-all beg end 'fontified t))
  1308. (if (fboundp 'jit-lock-fontify-now)
  1309. (jit-lock-fontify-now beg end)))
  1310. (if (and keep-props (not (eq occur-excluded-properties t)))
  1311. (let ((str (buffer-substring beg end)))
  1312. (remove-list-of-text-properties
  1313. 0 (length str) occur-excluded-properties str)
  1314. str)
  1315. (buffer-substring-no-properties beg end)))
  1316. (defun occur-engine-add-prefix (lines)
  1317. (mapcar
  1318. #'(lambda (line)
  1319. (concat " :" line "\n"))
  1320. lines))
  1321. (defun occur-accumulate-lines (count &optional keep-props pt)
  1322. (save-excursion
  1323. (when pt
  1324. (goto-char pt))
  1325. (let ((forwardp (> count 0))
  1326. result beg end moved)
  1327. (while (not (or (zerop count)
  1328. (if forwardp
  1329. (eobp)
  1330. (and (bobp) (not moved)))))
  1331. (setq count (+ count (if forwardp -1 1)))
  1332. (setq beg (line-beginning-position)
  1333. end (line-end-position))
  1334. (push (occur-engine-line beg end keep-props) result)
  1335. (setq moved (= 0 (forward-line (if forwardp 1 -1)))))
  1336. (nreverse result))))
  1337. ;; Generate context display for occur.
  1338. ;; OUT-LINE is the line where the match is.
  1339. ;; NLINES and KEEP-PROPS are args to occur-engine.
  1340. ;; LINES is line count of the current match,
  1341. ;; PREV-LINES is line count of the previous match,
  1342. ;; PREV-AFTER-LINES is a list of after-context lines of the previous match.
  1343. ;; Generate a list of lines, add prefixes to all but OUT-LINE,
  1344. ;; then concatenate them all together.
  1345. (defun occur-context-lines (out-line nlines keep-props begpt endpt
  1346. lines prev-lines prev-after-lines)
  1347. ;; Find after- and before-context lines of the current match.
  1348. (let ((before-lines
  1349. (nreverse (cdr (occur-accumulate-lines
  1350. (- (1+ (abs nlines))) keep-props begpt))))
  1351. (after-lines
  1352. (cdr (occur-accumulate-lines
  1353. (1+ nlines) keep-props endpt)))
  1354. separator)
  1355. ;; Combine after-lines of the previous match
  1356. ;; with before-lines of the current match.
  1357. (when prev-after-lines
  1358. ;; Don't overlap prev after-lines with current before-lines.
  1359. (if (>= (+ prev-lines (length prev-after-lines))
  1360. (- lines (length before-lines)))
  1361. (setq prev-after-lines
  1362. (butlast prev-after-lines
  1363. (- (length prev-after-lines)
  1364. (- lines prev-lines (length before-lines) 1))))
  1365. ;; Separate non-overlapping context lines with a dashed line.
  1366. (setq separator "-------\n")))
  1367. (when prev-lines
  1368. ;; Don't overlap current before-lines with previous match line.
  1369. (if (<= (- lines (length before-lines))
  1370. prev-lines)
  1371. (setq before-lines
  1372. (nthcdr (- (length before-lines)
  1373. (- lines prev-lines 1))
  1374. before-lines))
  1375. ;; Separate non-overlapping before-context lines.
  1376. (unless (> nlines 0)
  1377. (setq separator "-------\n"))))
  1378. (list
  1379. ;; Return a list where the first element is the output line.
  1380. (apply #'concat
  1381. (append
  1382. (and prev-after-lines
  1383. (occur-engine-add-prefix prev-after-lines))
  1384. (and separator (list separator))
  1385. (occur-engine-add-prefix before-lines)
  1386. (list out-line)))
  1387. ;; And the second element is the list of context after-lines.
  1388. (if (> nlines 0) after-lines))))
  1389. ;; It would be nice to use \\[...], but there is no reasonable way
  1390. ;; to make that display both SPC and Y.
  1391. (defconst query-replace-help
  1392. "Type Space or `y' to replace one match, Delete or `n' to skip to next,
  1393. RET or `q' to exit, Period to replace one match and exit,
  1394. Comma to replace but not move point immediately,
  1395. C-r to enter recursive edit (\\[exit-recursive-edit] to get out again),
  1396. C-w to delete match and recursive edit,
  1397. C-l to clear the screen, redisplay, and offer same replacement again,
  1398. ! to replace all remaining matches with no more questions,
  1399. ^ to move point back to previous match,
  1400. E to edit the replacement string"
  1401. "Help message while in `query-replace'.")
  1402. (defvar query-replace-map
  1403. (let ((map (make-sparse-keymap)))
  1404. (define-key map " " 'act)
  1405. (define-key map "\d" 'skip)
  1406. (define-key map [delete] 'skip)
  1407. (define-key map [backspace] 'skip)
  1408. (define-key map "y" 'act)
  1409. (define-key map "n" 'skip)
  1410. (define-key map "Y" 'act)
  1411. (define-key map "N" 'skip)
  1412. (define-key map "e" 'edit-replacement)
  1413. (define-key map "E" 'edit-replacement)
  1414. (define-key map "," 'act-and-show)
  1415. (define-key map "q" 'exit)
  1416. (define-key map "\r" 'exit)
  1417. (define-key map [return] 'exit)
  1418. (define-key map "." 'act-and-exit)
  1419. (define-key map "\C-r" 'edit)
  1420. (define-key map "\C-w" 'delete-and-edit)
  1421. (define-key map "\C-l" 'recenter)
  1422. (define-key map "!" 'automatic)
  1423. (define-key map "^" 'backup)
  1424. (define-key map "\C-h" 'help)
  1425. (define-key map [f1] 'help)
  1426. (define-key map [help] 'help)
  1427. (define-key map "?" 'help)
  1428. (define-key map "\C-g" 'quit)
  1429. (define-key map "\C-]" 'quit)
  1430. (define-key map "\e" 'exit-prefix)
  1431. (define-key map [escape] 'exit-prefix)
  1432. map)
  1433. "Keymap that defines the responses to questions in `query-replace'.
  1434. The \"bindings\" in this map are not commands; they are answers.
  1435. The valid answers include `act', `skip', `act-and-show',
  1436. `exit', `act-and-exit', `edit', `edit-replacement', `delete-and-edit',
  1437. `recenter', `automatic', `backup', `exit-prefix', `quit', and `help'.")
  1438. (defvar multi-query-replace-map
  1439. (let ((map (make-sparse-keymap)))
  1440. (set-keymap-parent map query-replace-map)
  1441. (define-key map "Y" 'automatic-all)
  1442. (define-key map "N" 'exit-current)
  1443. map)
  1444. "Keymap that defines additional bindings for multi-buffer replacements.
  1445. It extends its parent map `query-replace-map' with new bindings to
  1446. operate on a set of buffers/files. The difference with its parent map
  1447. is the additional answers `automatic-all' to replace all remaining
  1448. matches in all remaining buffers with no more questions, and
  1449. `exit-current' to skip remaining matches in the current buffer
  1450. and to continue with the next buffer in the sequence.")
  1451. (defun replace-match-string-symbols (n)
  1452. "Process a list (and any sub-lists), expanding certain symbols.
  1453. Symbol Expands To
  1454. N (match-string N) (where N is a string of digits)
  1455. #N (string-to-number (match-string N))
  1456. & (match-string 0)
  1457. #& (string-to-number (match-string 0))
  1458. # replace-count
  1459. Note that these symbols must be preceded by a backslash in order to
  1460. type them using Lisp syntax."
  1461. (while (consp n)
  1462. (cond
  1463. ((consp (car n))
  1464. (replace-match-string-symbols (car n))) ;Process sub-list
  1465. ((symbolp (car n))
  1466. (let ((name (symbol-name (car n))))
  1467. (cond
  1468. ((string-match "^[0-9]+$" name)
  1469. (setcar n (list 'match-string (string-to-number name))))
  1470. ((string-match "^#[0-9]+$" name)
  1471. (setcar n (list 'string-to-number
  1472. (list 'match-string
  1473. (string-to-number (substring name 1))))))
  1474. ((string= "&" name)
  1475. (setcar n '(match-string 0)))
  1476. ((string= "#&" name)
  1477. (setcar n '(string-to-number (match-string 0))))
  1478. ((string= "#" name)
  1479. (setcar n 'replace-count))))))
  1480. (setq n (cdr n))))
  1481. (defun replace-eval-replacement (expression count)
  1482. (let* ((replace-count count)
  1483. (replacement (eval expression)))
  1484. (if (stringp replacement)
  1485. replacement
  1486. (prin1-to-string replacement t))))
  1487. (defun replace-quote (replacement)
  1488. "Quote a replacement string.
  1489. This just doubles all backslashes in REPLACEMENT and
  1490. returns the resulting string. If REPLACEMENT is not
  1491. a string, it is first passed through `prin1-to-string'
  1492. with the `noescape' argument set.
  1493. `match-data' is preserved across the call."
  1494. (save-match-data
  1495. (replace-regexp-in-string "\\\\" "\\\\"
  1496. (if (stringp replacement)
  1497. replacement
  1498. (prin1-to-string replacement t))
  1499. t t)))
  1500. (defun replace-loop-through-replacements (data count)
  1501. ;; DATA is a vector containing the following values:
  1502. ;; 0 next-rotate-count
  1503. ;; 1 repeat-count
  1504. ;; 2 next-replacement
  1505. ;; 3 replacements
  1506. (if (= (aref data 0) count)
  1507. (progn
  1508. (aset data 0 (+ count (aref data 1)))
  1509. (let ((next (cdr (aref data 2))))
  1510. (aset data 2 (if (consp next) next (aref data 3))))))
  1511. (car (aref data 2)))
  1512. (defun replace-match-data (integers reuse &optional new)
  1513. "Like `match-data', but markers in REUSE get invalidated.
  1514. If NEW is non-nil, it is set and returned instead of fresh data,
  1515. but coerced to the correct value of INTEGERS."
  1516. (or (and new
  1517. (progn
  1518. (set-match-data new)
  1519. (and (eq new reuse)
  1520. (eq (null integers) (markerp (car reuse)))
  1521. new)))
  1522. (match-data integers reuse t)))
  1523. (defun replace-match-maybe-edit (newtext fixedcase literal noedit match-data)
  1524. "Make a replacement with `replace-match', editing `\\?'.
  1525. NEWTEXT, FIXEDCASE, LITERAL are just passed on. If NOEDIT is true, no
  1526. check for `\\?' is made to save time. MATCH-DATA is used for the
  1527. replacement. In case editing is done, it is changed to use markers.
  1528. The return value is non-nil if there has been no `\\?' or NOEDIT was
  1529. passed in. If LITERAL is set, no checking is done, anyway."
  1530. (unless (or literal noedit)
  1531. (setq noedit t)
  1532. (while (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\(\\\\\\?\\)"
  1533. newtext)
  1534. (setq newtext
  1535. (read-string "Edit replacement string: "
  1536. (prog1
  1537. (cons
  1538. (replace-match "" t t newtext 3)
  1539. (1+ (match-beginning 3)))
  1540. (setq match-data
  1541. (replace-match-data
  1542. nil match-data match-data))))
  1543. noedit nil)))
  1544. (set-match-data match-data)
  1545. (replace-match newtext fixedcase literal)
  1546. noedit)
  1547. (defvar replace-search-function 'search-forward
  1548. "Function to use when searching for strings to replace.
  1549. It is used by `query-replace' and `replace-string', and is called
  1550. with three arguments, as if it were `search-forward'.")
  1551. (defvar replace-re-search-function 're-search-forward
  1552. "Function to use when searching for regexps to replace.
  1553. It is used by `query-replace-regexp', `replace-regexp',
  1554. `query-replace-regexp-eval', and `map-query-replace-regexp'.
  1555. It is called with three arguments, as if it were
  1556. `re-search-forward'.")
  1557. (defun perform-replace (from-string replacements
  1558. query-flag regexp-flag delimited-flag
  1559. &optional repeat-count map start end)
  1560. "Subroutine of `query-replace'. Its complexity handles interactive queries.
  1561. Don't use this in your own program unless you want to query and set the mark
  1562. just as `query-replace' does. Instead, write a simple loop like this:
  1563. (while (re-search-forward \"foo[ \\t]+bar\" nil t)
  1564. (replace-match \"foobar\" nil nil))
  1565. which will run faster and probably do exactly what you want. Please
  1566. see the documentation of `replace-match' to find out how to simulate
  1567. `case-replace'.
  1568. This function returns nil if and only if there were no matches to
  1569. make, or the user didn't cancel the call."
  1570. (or map (setq map query-replace-map))
  1571. (and query-flag minibuffer-auto-raise
  1572. (raise-frame (window-frame (minibuffer-window))))
  1573. (let* ((case-fold-search
  1574. (if (and case-fold-search search-upper-case)
  1575. (isearch-no-upper-case-p from-string regexp-flag)
  1576. case-fold-search))
  1577. (nocasify (not (and case-replace case-fold-search)))
  1578. (literal (or (not regexp-flag) (eq regexp-flag 'literal)))
  1579. (search-function
  1580. (if regexp-flag
  1581. replace-re-search-function
  1582. replace-search-function))
  1583. (search-string from-string)
  1584. (real-match-data nil) ; The match data for the current match.
  1585. (next-replacement nil)
  1586. ;; This is non-nil if we know there is nothing for the user
  1587. ;; to edit in the replacement.
  1588. (noedit nil)
  1589. (keep-going t)
  1590. (stack nil)
  1591. (replace-count 0)
  1592. (nonempty-match nil)
  1593. (multi-buffer nil)
  1594. (recenter-last-op nil) ; Start cycling order with initial position.
  1595. ;; If non-nil, it is marker saying where in the buffer to stop.
  1596. (limit nil)
  1597. ;; Data for the next match. If a cons, it has the same format as
  1598. ;; (match-data); otherwise it is t if a match is possible at point.
  1599. (match-again t)
  1600. (message
  1601. (if query-flag
  1602. (apply 'propertize
  1603. (substitute-command-keys
  1604. "Query replacing %s with %s: (\\<query-replace-map>\\[help] for help) ")
  1605. minibuffer-prompt-properties))))
  1606. ;; If region is active, in Transient Mark mode, operate on region.
  1607. (when start
  1608. (setq limit (copy-marker (max start end)))
  1609. (goto-char (min start end))
  1610. (deactivate-mark))
  1611. ;; If last typed key in previous call of multi-buffer perform-replace
  1612. ;; was `automatic-all', don't ask more questions in next files
  1613. (when (eq (lookup-key map (vector last-input-event)) 'automatic-all)
  1614. (setq query-flag nil multi-buffer t))
  1615. ;; REPLACEMENTS is either a string, a list of strings, or a cons cell
  1616. ;; containing a function and its first argument. The function is
  1617. ;; called to generate each replacement like this:
  1618. ;; (funcall (car replacements) (cdr replacements) replace-count)
  1619. ;; It must return a string.
  1620. (cond
  1621. ((stringp replacements)
  1622. (setq next-replacement replacements
  1623. replacements nil))
  1624. ((stringp (car replacements)) ; If it isn't a string, it must be a cons
  1625. (or repeat-count (setq repeat-count 1))
  1626. (setq replacements (cons 'replace-loop-through-replacements
  1627. (vector repeat-count repeat-count
  1628. replacements replacements)))))
  1629. (if delimited-flag
  1630. (setq search-function 're-search-forward
  1631. search-string (concat "\\b"
  1632. (if regexp-flag from-string
  1633. (regexp-quote from-string))
  1634. "\\b")))
  1635. (when query-replace-lazy-highlight
  1636. (setq isearch-lazy-highlight-last-string nil))
  1637. (push-mark)
  1638. (undo-boundary)
  1639. (unwind-protect
  1640. ;; Loop finding occurrences that perhaps should be replaced.
  1641. (while (and keep-going
  1642. (not (or (eobp) (and limit (>= (point) limit))))
  1643. ;; Use the next match if it is already known;
  1644. ;; otherwise, search for a match after moving forward
  1645. ;; one char if progress is required.
  1646. (setq real-match-data
  1647. (cond ((consp match-again)
  1648. (goto-char (nth 1 match-again))
  1649. (replace-match-data
  1650. t real-match-data match-again))
  1651. ;; MATCH-AGAIN non-nil means accept an
  1652. ;; adjacent match.
  1653. (match-again
  1654. (and
  1655. (funcall search-function search-string
  1656. limit t)
  1657. ;; For speed, use only integers and
  1658. ;; reuse the list used last time.
  1659. (replace-match-data t real-match-data)))
  1660. ((and (< (1+ (point)) (point-max))
  1661. (or (null limit)
  1662. (< (1+ (point)) limit)))
  1663. ;; If not accepting adjacent matches,
  1664. ;; move one char to the right before
  1665. ;; searching again. Undo the motion
  1666. ;; if the search fails.
  1667. (let ((opoint (point)))
  1668. (forward-char 1)
  1669. (if (funcall
  1670. search-function search-string
  1671. limit t)
  1672. (replace-match-data
  1673. t real-match-data)
  1674. (goto-char opoint)
  1675. nil))))))
  1676. ;; Record whether the match is nonempty, to avoid an infinite loop
  1677. ;; repeatedly matching the same empty string.
  1678. (setq nonempty-match
  1679. (/= (nth 0 real-match-data) (nth 1 real-match-data)))
  1680. ;; If the match is empty, record that the next one can't be
  1681. ;; adjacent.
  1682. ;; Otherwise, if matching a regular expression, do the next
  1683. ;; match now, since the replacement for this match may
  1684. ;; affect whether the next match is adjacent to this one.
  1685. ;; If that match is empty, don't use it.
  1686. (setq match-again
  1687. (and nonempty-match
  1688. (or (not regexp-flag)
  1689. (and (looking-at search-string)
  1690. (let ((match (match-data)))
  1691. (and (/= (nth 0 match) (nth 1 match))
  1692. match))))))
  1693. ;; Optionally ignore matches that have a read-only property.
  1694. (unless (and query-replace-skip-read-only
  1695. (text-property-not-all
  1696. (nth 0 real-match-data) (nth 1 real-match-data)
  1697. 'read-only nil))
  1698. ;; Calculate the replacement string, if necessary.
  1699. (when replacements
  1700. (set-match-data real-match-data)
  1701. (setq next-replacement
  1702. (funcall (car replacements) (cdr replacements)
  1703. replace-count)))
  1704. (if (not query-flag)
  1705. (progn
  1706. (unless (or literal noedit)
  1707. (replace-highlight
  1708. (nth 0 real-match-data) (nth 1 real-match-data)
  1709. start end search-string
  1710. (or delimited-flag regexp-flag) case-fold-search))
  1711. (setq noedit
  1712. (replace-match-maybe-edit
  1713. next-replacement nocasify literal
  1714. noedit real-match-data)
  1715. replace-count (1+ replace-count)))
  1716. (undo-boundary)
  1717. (let (done replaced key def)
  1718. ;; Loop reading commands until one of them sets done,
  1719. ;; which means it has finished handling this
  1720. ;; occurrence. Any command that sets `done' should
  1721. ;; leave behind proper match data for the stack.
  1722. ;; Commands not setting `done' need to adjust
  1723. ;; `real-match-data'.
  1724. (while (not done)
  1725. (set-match-data real-match-data)
  1726. (replace-highlight
  1727. (match-beginning 0) (match-end 0)
  1728. start end search-string
  1729. (or delimited-flag regexp-flag) case-fold-search)
  1730. ;; Bind message-log-max so we don't fill up the message log
  1731. ;; with a bunch of identical messages.
  1732. (let ((message-log-max nil)
  1733. (replacement-presentation
  1734. (if query-replace-show-replacement
  1735. (save-match-data
  1736. (set-match-data real-match-data)
  1737. (match-substitute-replacement next-replacement
  1738. nocasify literal))
  1739. next-replacement)))
  1740. (message message
  1741. (query-replace-descr from-string)
  1742. (query-replace-descr replacement-presentation)))
  1743. (setq key (read-event))
  1744. ;; Necessary in case something happens during read-event
  1745. ;; that clobbers the match data.
  1746. (set-match-data real-match-data)
  1747. (setq key (vector key))
  1748. (setq def (lookup-key map key))
  1749. ;; Restore the match data while we process the command.
  1750. (cond ((eq def 'help)
  1751. (with-output-to-temp-buffer "*Help*"
  1752. (princ
  1753. (concat "Query replacing "
  1754. (if delimited-flag "word " "")
  1755. (if regexp-flag "regexp " "")
  1756. from-string " with "
  1757. next-replacement ".\n\n"
  1758. (substitute-command-keys
  1759. query-replace-help)))
  1760. (with-current-buffer standard-output
  1761. (help-mode))))
  1762. ((eq def 'exit)
  1763. (setq keep-going nil)
  1764. (setq done t))
  1765. ((eq def 'exit-current)
  1766. (setq multi-buffer t keep-going nil done t))
  1767. ((eq def 'backup)
  1768. (if stack
  1769. (let ((elt (pop stack)))
  1770. (goto-char (nth 0 elt))
  1771. (setq replaced (nth 1 elt)
  1772. real-match-data
  1773. (replace-match-data
  1774. t real-match-data
  1775. (nth 2 elt))))
  1776. (message "No previous match")
  1777. (ding 'no-terminate)
  1778. (sit-for 1)))
  1779. ((eq def 'act)
  1780. (or replaced
  1781. (setq noedit
  1782. (replace-match-maybe-edit
  1783. next-replacement nocasify literal
  1784. noedit real-match-data)
  1785. replace-count (1+ replace-count)))
  1786. (setq done t replaced t))
  1787. ((eq def 'act-and-exit)
  1788. (or replaced
  1789. (setq noedit
  1790. (replace-match-maybe-edit
  1791. next-replacement nocasify literal
  1792. noedit real-match-data)
  1793. replace-count (1+ replace-count)))
  1794. (setq keep-going nil)
  1795. (setq done t replaced t))
  1796. ((eq def 'act-and-show)
  1797. (if (not replaced)
  1798. (setq noedit
  1799. (replace-match-maybe-edit
  1800. next-replacement nocasify literal
  1801. noedit real-match-data)
  1802. replace-count (1+ replace-count)
  1803. real-match-data (replace-match-data
  1804. t real-match-data)
  1805. replaced t)))
  1806. ((or (eq def 'automatic) (eq def 'automatic-all))
  1807. (or replaced
  1808. (setq noedit
  1809. (replace-match-maybe-edit
  1810. next-replacement nocasify literal
  1811. noedit real-match-data)
  1812. replace-count (1+ replace-count)))
  1813. (setq done t query-flag nil replaced t)
  1814. (if (eq def 'automatic-all) (setq multi-buffer t)))
  1815. ((eq def 'skip)
  1816. (setq done t))
  1817. ((eq def 'recenter)
  1818. ;; `this-command' has the value `query-replace',
  1819. ;; so we need to bind it to `recenter-top-bottom'
  1820. ;; to allow it to detect a sequence of `C-l'.
  1821. (let ((this-command 'recenter-top-bottom)
  1822. (last-command 'recenter-top-bottom))
  1823. (recenter-top-bottom)))
  1824. ((eq def 'edit)
  1825. (let ((opos (point-marker)))
  1826. (setq real-match-data (replace-match-data
  1827. nil real-match-data
  1828. real-match-data))
  1829. (goto-char (match-beginning 0))
  1830. (save-excursion
  1831. (save-window-excursion
  1832. (recursive-edit)))
  1833. (goto-char opos)
  1834. (set-marker opos nil))
  1835. ;; Before we make the replacement,
  1836. ;; decide whether the search string
  1837. ;; can match again just after this match.
  1838. (if (and regexp-flag nonempty-match)
  1839. (setq match-again (and (looking-at search-string)
  1840. (match-data)))))
  1841. ;; Edit replacement.
  1842. ((eq def 'edit-replacement)
  1843. (setq real-match-data (replace-match-data
  1844. nil real-match-data
  1845. real-match-data)
  1846. next-replacement
  1847. (read-string "Edit replacement string: "
  1848. next-replacement)
  1849. noedit nil)
  1850. (if replaced
  1851. (set-match-data real-match-data)
  1852. (setq noedit
  1853. (replace-match-maybe-edit
  1854. next-replacement nocasify literal noedit
  1855. real-match-data)
  1856. replaced t))
  1857. (setq done t))
  1858. ((eq def 'delete-and-edit)
  1859. (replace-match "" t t)
  1860. (setq real-match-data (replace-match-data
  1861. nil real-match-data))
  1862. (replace-dehighlight)
  1863. (save-excursion (recursive-edit))
  1864. (setq replaced t))
  1865. ;; Note: we do not need to treat `exit-prefix'
  1866. ;; specially here, since we reread
  1867. ;; any unrecognized character.
  1868. (t
  1869. (setq this-command 'mode-exited)
  1870. (setq keep-going nil)
  1871. (setq unread-command-events
  1872. (append (listify-key-sequence key)
  1873. unread-command-events))
  1874. (setq done t)))
  1875. (when query-replace-lazy-highlight
  1876. ;; Force lazy rehighlighting only after replacements.
  1877. (if (not (memq def '(skip backup)))
  1878. (setq isearch-lazy-highlight-last-string nil)))
  1879. (unless (eq def 'recenter)
  1880. ;; Reset recenter cycling order to initial position.
  1881. (setq recenter-last-op nil)))
  1882. ;; Record previous position for ^ when we move on.
  1883. ;; Change markers to numbers in the match data
  1884. ;; since lots of markers slow down editing.
  1885. (push (list (point) replaced
  1886. ;;; If the replacement has already happened, all we need is the
  1887. ;;; current match start and end. We could get this with a trivial
  1888. ;;; match like
  1889. ;;; (save-excursion (goto-char (match-beginning 0))
  1890. ;;; (search-forward (match-string 0))
  1891. ;;; (match-data t))
  1892. ;;; if we really wanted to avoid manually constructing match data.
  1893. ;;; Adding current-buffer is necessary so that match-data calls can
  1894. ;;; return markers which are appropriate for editing.
  1895. (if replaced
  1896. (list
  1897. (match-beginning 0)
  1898. (match-end 0)
  1899. (current-buffer))
  1900. (match-data t)))
  1901. stack)))))
  1902. (replace-dehighlight))
  1903. (or unread-command-events
  1904. (message "Replaced %d occurrence%s"
  1905. replace-count
  1906. (if (= replace-count 1) "" "s")))
  1907. (or (and keep-going stack) multi-buffer)))
  1908. (defvar isearch-error)
  1909. (defvar isearch-forward)
  1910. (defvar isearch-case-fold-search)
  1911. (defvar isearch-string)
  1912. (defvar replace-overlay nil)
  1913. (defun replace-highlight (match-beg match-end range-beg range-end
  1914. string regexp case-fold)
  1915. (if query-replace-highlight
  1916. (if replace-overlay
  1917. (move-overlay replace-overlay match-beg match-end (current-buffer))
  1918. (setq replace-overlay (make-overlay match-beg match-end))
  1919. (overlay-put replace-overlay 'priority 1001) ;higher than lazy overlays
  1920. (overlay-put replace-overlay 'face 'query-replace)))
  1921. (if query-replace-lazy-highlight
  1922. (let ((isearch-string string)
  1923. (isearch-regexp regexp)
  1924. ;; Set isearch-word to nil because word-replace is regexp-based,
  1925. ;; so `isearch-search-fun' should not use `word-search-forward'.
  1926. (isearch-word nil)
  1927. (search-whitespace-regexp nil)
  1928. (isearch-case-fold-search case-fold)
  1929. (isearch-forward t)
  1930. (isearch-error nil))
  1931. (isearch-lazy-highlight-new-loop range-beg range-end))))
  1932. (defun replace-dehighlight ()
  1933. (when replace-overlay
  1934. (delete-overlay replace-overlay))
  1935. (when query-replace-lazy-highlight
  1936. (lazy-highlight-cleanup lazy-highlight-cleanup)
  1937. (setq isearch-lazy-highlight-last-string nil)))
  1938. ;;; replace.el ends here