From: James Bunton Date: Thu, 28 Jul 2016 13:42:52 +0000 (+1000) Subject: find-prod-or-test-file X-Git-Url: https://code.delx.au/dotemacs/commitdiff_plain/60cd635627490db83653fe6c54809bc52485623d find-prod-or-test-file --- diff --git a/init.el b/init.el index 2af6ef5..934aa81 100644 --- a/init.el +++ b/init.el @@ -14,6 +14,7 @@ (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") diff --git a/lisp/my-find-test-file.el b/lisp/my-find-test-file.el new file mode 100644 index 0000000..a792203 --- /dev/null +++ b/lisp/my-find-test-file.el @@ -0,0 +1,58 @@ +;;; -*- 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)))))) diff --git a/lisp/my-keys.el b/lisp/my-keys.el index 39b68dc..3cb9160 100644 --- a/lisp/my-keys.el +++ b/lisp/my-keys.el @@ -18,6 +18,7 @@ (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) diff --git a/snippets/emacs-lisp-mode/lexical b/snippets/emacs-lisp-mode/lexical new file mode 100644 index 0000000..5bfd611 --- /dev/null +++ b/snippets/emacs-lisp-mode/lexical @@ -0,0 +1,4 @@ +# name: emacs-lisp-lexical +# key: lexical +# -- +;;; -*- lexical-binding: t -*-