Skip to content

Instantly share code, notes, and snippets.

@jaidetree
Created January 31, 2020 01:55
Show Gist options
  • Save jaidetree/650e92d2d958d51572e9a8a71ed847d2 to your computer and use it in GitHub Desktop.
Save jaidetree/650e92d2d958d51572e9a8a71ed847d2 to your computer and use it in GitHub Desktop.
Use like `ack -g "filepattern" | clj -m replacer.replacer PATTERN REPLACEMENT` to interactively replace pattern in every file matching filepattern.
(ns replacer.replacer
(:require
[clojure.string :as s]
[clojure.java.io :as io]))
(defn get-files
[input]
(doall (line-seq (java.io.BufferedReader. input))))
(defn read-prompt
"Reads the next line from stream that is the current value of *in* ."
[]
(let [tty (io/reader "/dev/tty")]
(.readLine tty)))
(defn replace-interactive
[file n line replacement match]
(println line)
(println (str "Replace " match " with " replacement " in " file " line " n ) )
(print "> (y/n) = n ")
(flush)
(let [v (read-prompt)]
(if (= v "y")
replacement
match)))
(defn replace-in-line
[file n line pattern replacement]
(if (re-find pattern line)
(s/replace line pattern #(replace-interactive file n line replacement %1))
line))
(defn replace-in-file
[pattern replacement file]
(let [contents (-> (slurp file)
(s/split #"\n")
(->> (map-indexed #(replace-in-line file %1 %2 pattern replacement))
(s/join "\n")))]
{:path file :contents contents}))
(defn save-file
[{:keys [path contents]}]
(spit path contents))
(defn -main
[search replace]
(let [files (get-files *in*)]
(->> files
(map #(replace-in-file (re-pattern search) replace %))
(map save-file)
(dorun))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment