Skip to content

Instantly share code, notes, and snippets.

@inlinechan
Created October 21, 2016 06:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inlinechan/7049b563f75bc48a64596c166ab6ccd2 to your computer and use it in GitHub Desktop.
Save inlinechan/7049b563f75bc48a64596c166ab6ccd2 to your computer and use it in GitHub Desktop.
;;; package --- Summary
;;; Commentary:
;; You may a hook for flycheck to set flycheck-clang-include-path automatically upon buffer open
;;
;; (add-hook 'flycheck-mode-hook
;; '(lambda()
;; (let ((include-path (compdb-get-include-path)))
;; (when include-path
;; (make-local-variable 'flycheck-clang-include-path)
;; (setq flycheck-clang-include-path include-path)))))
;;; Code:
(defun compdb-parse (db file)
"Parse compilation database DB of FILE and return list of include path."
(when (file-exists-p db)
(with-temp-buffer
(insert-file-contents db)
(goto-char (point-min))
(let ((end (search-forward file))
(begin (search-backward "\"command\":")))
;; (list begin end)
(compdb-get-include-path-list begin end)
))
))
(defun compdb-get-include-path-list (begin end)
"Parse from BEGIN to END and return list of include path."
(let ((result nil)
(current begin))
(while (and current (< current end))
(setq current (re-search-forward "-I\\([A-Za-z0-9-_/.]+\\)" end t))
(if (null result)
(setq result (list (match-string 1)))
(add-to-list 'result (match-string 1))))
result))
;; http://stackoverflow.com/a/1684795/2229134
(defun compdb-find-compdb (dir)
"Find compilation database starting from DIR."
(if (file-directory-p dir)
(append
(directory-files dir t "compile_commands.json")
(apply 'append (mapcar 'compdb-find-compdb (directory-files dir t "[^.]+"))))))
(defun compdb-find-compdb-within-depth (dir &optional max-depth depth)
"Find compilation database from DIR.
Repeat until it find before reaching MAX-DEPTH.
DEPTH is used for recursive call."
(let ((max-depth (or max-depth 4))
(depth (or depth 0)))
(if (> depth max-depth)
nil
(or (compdb-find-compdb dir)
(compdb-find-compdb-within-depth (file-name-directory dir) max-depth (1+ depth))))))
(defun compdb-get-include-path ()
"Get include-path list from current buffer."
;; (let ((db (compdb-find-compdb (file-name-directory (buffer-file-name)))))
(let* ((max-depth 4)
(dir (directory-file-name (file-name-directory (buffer-file-name))))
(db (compdb-find-compdb-within-depth dir max-depth)))
(when db
(compdb-parse (car db) (buffer-file-name)))))
;; This hook should be moved to another place.
(add-hook 'flycheck-mode-hook
'(lambda()
(let ((include-path (compdb-get-include-path)))
(when include-path
(make-local-variable 'flycheck-clang-include-path)
(setq flycheck-clang-include-path include-path)))))
(provide 'compdb)
;;; compdb.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment