3

I have been trying to set up a shortcut for jumping between a JavaScript implementation and test. I have particular requirements that are making examples I see harder to apply.

I currently work with many very small javascript projects. The structure of the project normally has its tests in a mirrored directory structure (like so: )

lib/foo.js lib/someDir/bar.js test/fooSpec.js test/someDir/barSpec.js

So the spec files are not in the same directory, as the implementation

I first was looking at examples for ff-find-other-file, but they were for situations when the files were located in the same directories. I'm looking to configure it a little more dynamically (walking up the directory tree until lib, then adding a similar path with test replacing lib)

I also know projectile has a function for doing just this. I use projectile in my setup, but when attempting to use its built in method (C-c p t) I get the message "Project type not supported!". Interestingly enough, projectile is able to list all my test files via (C-c p T). Is there way of configuring projectile for javascript, so that it knows how to find a corresponding spec file?

I also saw the project toggle test, but am looking for a more automatic solution. It requires a configuration for each project to enable toggling between tests. This is rather inconvenient to me because when working with Node/JS I bounce between many projects (it's very common to divide an application into many very small projects with their own tests). I also often look at external dependencies, and then their specs. More often then not they have this structure. Having to configure toggle test each time I need to use this feature makes it not very useful.

2
  • Projectile has the command projectile-find-other-file that works the same as ff-find-other-file, except that it lists all possible other files in your project. You can custom with projectile-other-file-alist variable, Commented Jan 12, 2015 at 19:10
  • FWIW, the ff-search-directories variable provides limited functionality for finding files in other directories (albeit not arbitrary directory walking). See stackoverflow.com/questions/23660637/smarter-ff-find-other-file Commented Jan 12, 2015 at 20:54

2 Answers 2

4

I know nothing about projectile, but if I needed something like what you described, I'd possibly go with something like this:

(defun jump-to-test () (interactive) (find-file-other-window (cl-loop with parts = (reverse (split-string (buffer-file-name) "/")) with fname = (file-name-sans-extension (cl-first parts)) for (name . rest) on (cl-rest parts) until (string-equal name "lib") collect name into names finally (cl-return (mapconcat 'identity (nconc (reverse rest) (list "test") (reverse names) (list (format "%sSpec.js" fname))) "/"))))) 
3
  • thanks, this is nearly exactly what i'm looking for. And is educating me on elisp. I made a gist containing the opposite side (jump to implementation from test). How about a means to determine which path structure I'm currently in, so that I can call the appropriate function using the same keystroke Commented Jan 12, 2015 at 20:01
  • 1
    never-mind, updated the gist containing the function. Thanks for the help. You've made my day! Commented Jan 12, 2015 at 20:18
  • @MikeMcFarland ha! Glad I could help :) Commented Jan 12, 2015 at 23:07
2

Tweaked wvxvw's answer to provide it as a toggle between files. It also doesn't open it in a new window.

(defun js-jump-to (current from to format-name) (find-file (cl-loop with parts = (reverse current) with fname = (file-name-sans-extension (cl-first parts)) for (name . rest) on (cl-rest parts) until (string-equal name from) collect name into names finally (cl-return (mapconcat 'identity (nconc (reverse rest) (list to) (reverse names) (list (funcall format-name fname) )) "/" ))))) (defun js-format-impl-name (fname) (format "%s.js" (replace-regexp-in-string "Spec" "" fname))) (defun js-format-test-name (fname) (format "%sSpec.js" fname)) (defun js-jump-to-implementation-or-test () (interactive) (let ((current (split-string (buffer-file-name) "/"))) (cond ((member "test" current) (js-jump-to current "test" "lib" 'js-format-impl-name)) ((member "lib" current) (js-jump-to current "lib" "test" 'js-format-test-name)) (t (error "not within a test or lib directory")) ))) 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.