Skip to content

Instantly share code, notes, and snippets.

@mcav
Created September 26, 2013 21:24
Show Gist options
  • Save mcav/6720785 to your computer and use it in GitHub Desktop.
Save mcav/6720785 to your computer and use it in GitHub Desktop.
Converts vim-style TAGS files to emacs TAGS files.
(ns easytags.core
(:require [clojure.string :as str]))
(def fs (js/require "fs"))
(def format (.-format (js/require "util")))
(set! *print-fn* #(.log js/console))
(defn strip-regex [re]
(when re
(-> re
(str/replace #"^/\^" "")
(str/replace #"\$/$" "")
(str/replace "\\" ""))))
(defn parse-ctags [s]
(remove nil?
(for [line (.split s "\n")]
(let [[_ symbol file regex line]
(or
(re-find #"^(\S+)\s+(\S+)\s+([^;]+).*?(?:lineno:(\d+))" line)
(re-find #"^(\S+)\s+(\S+)\s+([^;]+)?" line))]
(when (and symbol regex)
{:symbol symbol, :file file, :regex (strip-regex regex) :line line})))))
(defn ctags->etags [s]
(str/join
(for [[file symbols] (group-by :file (parse-ctags s))]
(let [byte-data (str/join "\n" (for [{:keys [symbol regex line]} symbols]
(format "%s\x7f%s\x01%s" regex symbol (or line ""))))]
(format "\x0c\n%s,%s\n%s" file (count byte-data) byte-data)))))
(def data (atom ""))
(defn read-stdin []
(doto js/process.stdin
(.resume)
(.setEncoding "utf8")
(.on "data" #(swap! data str %))
(.on "end" #(.write process.stdout (ctags->etags @data)))))
(defn -main []
(let [s (str (.readFileSync fs (get js/process.argv 2 "TAGS")))]
(if (.-isTTY js/process.stdin)
(.write process.stdout (ctags->etags s))
(read-stdin))))
(set! *main-cli-fn* -main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment