(load-library "my-completion")
(load-library "my-recentf")
(load-library "my-flycheck")
+(load-library "my-find-test-file")
(load-library "my-other-modes")
(load-library "my-minor-modes")
(load-library "my-file-modes")
--- /dev/null
+;;; -*- lexical-binding: t -*-
+
+(require 'cl-lib)
+(require 'counsel)
+
+(defun my/prod-file-p (file)
+ (not (or (string-match-p "test" file)
+ (string-match-p "spec" file))))
+
+(defun my/matching-test-file-p (test-file base-name extension)
+ (let ((found nil))
+ (dolist (pattern (list
+ (concat "test/.*" base-name "[^/]*\\." extension "$")
+ (concat "spec/.*" base-name "[^/]*\\." extension "$")
+ (concat "test[^/]*" base-name "[^/]*\\." extension "$")
+ (concat base-name "[^/]*test\\." extension "$")
+ (concat base-name "[^/]*spec\\." extension "$")))
+ (if (string-match-p pattern test-file)
+ (setq found t)))
+ found))
+
+(defun my/matching-prod-file-p (prod-file base-name extension)
+ (dolist (pattern '("test" "spec" "^\\.*" "\\.*$"))
+ (setq base-name (replace-regexp-in-string pattern "" base-name)))
+ (and (my/prod-file-p prod-file)
+ (string-match-p (concat base-name "[^/]*\\." extension "$") prod-file)))
+
+(defun my/find-prod-or-test-file ()
+ "Find test file in the current Git repository."
+ (interactive)
+
+ (setq counsel--git-dir (locate-dominating-file
+ default-directory ".git"))
+ (if (null counsel--git-dir)
+ (error "Not in a git repository")
+ (setq counsel--git-dir (expand-file-name
+ counsel--git-dir))
+
+ (let* ((default-directory counsel--git-dir)
+ (files (split-string
+ (shell-command-to-string counsel-git-cmd)
+ "\n"
+ t))
+ (base-name (file-name-sans-extension (file-name-nondirectory (buffer-file-name))))
+ (extension (file-name-extension (buffer-file-name)))
+ (predicate (if (my/prod-file-p (buffer-file-name)) #'my/matching-test-file-p #'my/matching-prod-file-p))
+ (results nil))
+
+ (dolist (file files)
+ (if (funcall predicate file base-name extension)
+ (cl-pushnew file results)))
+
+ (cl-case (length results)
+ (0 (message "No matching file found."))
+ (1 (find-file (car results)))
+ (t (ivy-read "Find test file" results
+ :action #'counsel-git-action
+ :caller 'counsel-git))))))
(global-set-key (kbd "C-x c") 'my/kill-buffers-not-in-frame)
(global-set-key (kbd "C-x C-b") 'ibuffer)
(global-set-key (kbd "C-x C-r") 'ivy-recentf)
+(global-set-key (kbd "C-x t") 'my/find-prod-or-test-file)
(global-set-key (kbd "C-c g d") 'git-gutter:popup-hunk)
(global-set-key (kbd "C-c g p") 'git-gutter:previous-hunk)
(global-set-key (kbd "C-c g n") 'git-gutter:next-hunk)