js2r-defuns.el 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. (require 's)
  2. (require 'dash)
  3. (defvar js2r-path-to-tests "/test/"
  4. "Path to tests from a root shared with sources")
  5. (defvar js2r-path-to-sources "/lib/"
  6. "Path to sources from a root shared with tests")
  7. (defvar js2r-test-suffix "-test"
  8. "The suffix added to test files")
  9. (make-variable-buffer-local 'js2r-path-to-tests)
  10. (make-variable-buffer-local 'js2r-path-to-sources)
  11. (make-variable-buffer-local 'js2r-test-suffix)
  12. ;; Toggle between source and test
  13. (defun jump-between-source-and-test-files (arg)
  14. (interactive "P")
  15. (if (looks-like-test-file-name (buffer-file-name))
  16. (jump-to-source-file arg)
  17. (jump-to-test-file arg)))
  18. (defun jump-between-source-and-test-files-other-window (arg)
  19. (interactive "P")
  20. (if (looks-like-test-file-name (buffer-file-name))
  21. (jump-to-source-file-other-window arg)
  22. (jump-to-test-file-other-window arg)))
  23. ;; Duplicate object property node
  24. (defun js2r-duplicate-object-property-node ()
  25. (interactive)
  26. (js2r--guard)
  27. (let ((node (js2r--closest 'js2-object-prop-node-p)))
  28. (goto-char (js2-node-abs-pos node))
  29. (skip-syntax-backward " >")
  30. (insert (buffer-substring (point) (js2-node-abs-end node)) ",")
  31. (skip-syntax-forward " >")))
  32. ;; Rename tests and sources
  33. (defun js2r--rename-file (old-name new-name)
  34. (let ((modified-p (buffer-modified-p)))
  35. (rename-file old-name new-name 1)
  36. (rename-buffer new-name)
  37. (set-visited-file-name new-name)
  38. (set-buffer-modified-p modified-p)))
  39. (defun also-rename-other (old-name new-name)
  40. (let (old-other new-other)
  41. (condition-case nil
  42. (if (and (looks-like-test-file-name old-name)
  43. (looks-like-test-file-name new-name))
  44. (setq old-other (guess-source-file old-name)
  45. new-other (guess-source-file new-name))
  46. (setq old-other (guess-test-file old-name)
  47. new-other (guess-test-file new-name)))
  48. (error nil))
  49. (when (and old-other new-other
  50. (file-exists-p old-other)
  51. (not (file-exists-p new-other))
  52. (yes-or-no-p (format "Also rename %S to %S?" old-other new-other)))
  53. (let ((b (find-buffer-visiting old-other)))
  54. (if b
  55. (with-current-buffer b
  56. (js2r--rename-file old-other new-other))
  57. (rename-file old-other new-other 1))))))
  58. (defun js2r-rename-current-buffer-file ()
  59. "Renames current buffer and file it is visiting."
  60. (interactive)
  61. (let ((name (buffer-name))
  62. (filename (buffer-file-name)))
  63. (if (not (and filename (file-exists-p filename)))
  64. (error "Buffer '%s' is not visiting a file!" name)
  65. (let ((new-name (read-file-name "New name: " filename)))
  66. (cond ((get-buffer new-name)
  67. (error "A buffer named '%s' already exists!" new-name))
  68. (t
  69. (js2r--rename-file filename new-name)
  70. (also-rename-other filename new-name)
  71. (message "File '%s' successfully renamed to '%s'" name (file-name-nondirectory new-name))))))))
  72. ;; Delete tests and sources
  73. (defun also-delete-other (file-name)
  74. (let (other-name)
  75. (condition-case nil
  76. (setq other-name
  77. (if (looks-like-test-file-name file-name)
  78. (guess-source-file file-name)
  79. (guess-test-file file-name)))
  80. (error nil))
  81. (when (and other-name
  82. (file-exists-p other-name)
  83. (yes-or-no-p (format "Also delete %S?" other-name)))
  84. (let ((b (find-buffer-visiting other-name)))
  85. (when b (kill-buffer b)))
  86. (delete-file other-name))))
  87. (defun js2r-delete-current-buffer-file ()
  88. "Removes file connected to current buffer and kills buffer."
  89. (interactive)
  90. (let ((filename (buffer-file-name))
  91. (buffer (current-buffer))
  92. (name (buffer-name)))
  93. (if (not (and filename (file-exists-p filename)))
  94. (ido-kill-buffer)
  95. (when (yes-or-no-p "Are you sure you want to remove this file? ")
  96. (delete-file filename)
  97. (also-delete-other filename)
  98. (kill-buffer buffer)
  99. (message "File '%s' successfully removed" filename)))))
  100. ;; Jump to source-file
  101. (defun jump-to-source-file (arg)
  102. (interactive "P")
  103. (let ((file (guess-source-file (buffer-file-name))))
  104. (if (or (file-exists-p file) arg)
  105. (find-file file)
  106. (error "%s not found." file))))
  107. (defun possible-test-file-suffixes ()
  108. (cons (concat js2r-test-suffix ".js")
  109. '("Test.js" "_test.js" "-test.js")))
  110. (defun looks-like-test-file-name (file-name)
  111. (--any? (s-ends-with-p it file-name) (possible-test-file-suffixes)))
  112. (defun jump-to-source-file-other-window (arg)
  113. (interactive "P")
  114. (let ((file (guess-source-file (buffer-file-name))))
  115. (if (or (file-exists-p file) arg)
  116. (find-file-other-window file)
  117. (error "%s not found." file))))
  118. (defun guess-source-file (file-name)
  119. (unless (looks-like-test-file-name file-name)
  120. (error "This doesn't look like a test file."))
  121. (format "%s/%s.js" (s-chop-suffix "/" (guess-source-folder file-name)) (guess-source-file-name file-name)))
  122. (defun guess-source-file-name (file-name)
  123. (s-chop-suffixes (possible-test-file-suffixes) (file-name-nondirectory file-name)))
  124. (defun guess-source-folder (file-name)
  125. (let ((test-dir (file-name-directory file-name)))
  126. (when (not (string-match-p js2r-path-to-tests test-dir))
  127. (error "Unable to locate source folder. Set js2r-path-to-tests and -sources."))
  128. (let ((source-dir (replace-regexp-in-string
  129. js2r-path-to-tests
  130. js2r-path-to-sources
  131. test-dir)))
  132. (if (file-exists-p source-dir)
  133. source-dir
  134. (error "Unable to locate source folder. Verify js2r-path-to-tests and -sources")))))
  135. ;; Jump to test-file
  136. (defun jump-to-test-file (arg)
  137. (interactive "P")
  138. (let ((file (guess-test-file (buffer-file-name))))
  139. (if (or (file-exists-p file) arg)
  140. (find-file file)
  141. (error "%s not found." file))))
  142. (defun jump-to-test-file-other-window (arg)
  143. (interactive "P")
  144. (let ((file (guess-test-file (buffer-file-name))))
  145. (if (or (file-exists-p file) arg)
  146. (find-file-other-window file)
  147. (error "%s not found." file))))
  148. (defun guess-test-file (file-name)
  149. (when (looks-like-test-file-name file-name)
  150. (error "Looks like you're already in the test file."))
  151. (or (test-file-that-exists file-name "-test")
  152. (test-file-that-exists file-name "_test")
  153. (test-file-that-exists file-name "Test")
  154. (test-file-name file-name js2r-test-suffix)))
  155. (defun test-file-that-exists (file-name suffix)
  156. (let ((file (test-file-name file-name suffix)))
  157. (if (file-exists-p file) file nil)))
  158. (defun test-file-name (file-name suffix)
  159. (format "%s/%s%s.js" (s-chop-suffix "/" (guess-test-folder file-name)) (test-file-name-stub file-name) suffix))
  160. (defun test-file-name-stub (file-name)
  161. (s-chop-suffix ".js" (file-name-nondirectory file-name)))
  162. (defun guess-test-folder (file-name)
  163. (let ((source-dir (file-name-directory file-name)))
  164. (when (not (string-match-p js2r-path-to-sources source-dir))
  165. (error "Unable to locate test folder. Set js2r-path-to-tests and -sources."))
  166. (let ((test-dir (replace-regexp-in-string
  167. js2r-path-to-sources
  168. js2r-path-to-tests
  169. source-dir)))
  170. (if (file-exists-p test-dir)
  171. test-dir
  172. (error "Unable to locate test folder. Verify js2r-path-to-tests")))))
  173. ;; Toggle assert/refute
  174. (defun toggle-assert-refute ()
  175. (interactive)
  176. (save-excursion
  177. (end-of-line)
  178. (re-search-backward "\\(assert\\|refute\\)")
  179. (if (looking-at "assert")
  180. (progn
  181. (kill-word 1)
  182. (insert "refute"))
  183. (kill-word 1)
  184. (insert "assert"))))
  185. ;; Mark a js2-node in right window
  186. (defun remove-js2-mark-overlay ()
  187. (interactive)
  188. (mapc #'(lambda (o)
  189. (when (eq (overlay-get o 'type) 'mark-js2-in-right-window)
  190. (delete-overlay o)))
  191. (overlays-in (point-min) (point-max))))
  192. (defmacro mark-js2-in-right-window (func)
  193. `(progn
  194. (kill-comment nil)
  195. (windmove-right)
  196. (remove-js2-mark-overlay)
  197. (let* ((node ,func)
  198. (beg (js2-node-abs-pos node))
  199. (end (js2-node-abs-end node))
  200. (o (make-overlay beg end nil nil t)))
  201. (overlay-put o 'face 'region)
  202. (overlay-put o 'type 'mark-js2-in-right-window)
  203. (windmove-left)
  204. (save-excursion
  205. (insert (format " ;; %s" (js2-node-short-name node)))))))
  206. (provide 'js2r-defuns)