Personal emacs config
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
7.6 KiB

  1. ;;; js2r-conveniences.el --- Convenience functions for js2-refactor -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2012-2014 Magnar Sveen
  3. ;; Copyright (C) 2015-2016 Magnar Sveen and Nicolas Petton
  4. ;; Author: Magnar Sveen <magnars@gmail.com>,
  5. ;; Nicolas Petton <nicolas@petton.fr>
  6. ;; Keywords: conveniences
  7. ;; This program is free software; you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation, either version 3 of the License, or
  10. ;; (at your option) any later version.
  11. ;; This program is distributed in the hope that it will be useful,
  12. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;; GNU General Public License for more details.
  15. ;; You should have received a copy of the GNU General Public License
  16. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. ;;; Commentary:
  18. ;; Convenience functions for logging statements by inserting
  19. ;; `console.log' statements and moving lines respecting object
  20. ;; literal syntax.
  21. ;;; Code:
  22. (require 'js2r-helpers)
  23. (defun js2r-log-this (arg)
  24. "Log of the node at point, adding a 'console.log()' statement.
  25. With a prefix argument ARG, use JSON pretty-printing for logging."
  26. (interactive "P")
  27. (js2r--guard)
  28. (let* ((log-info (js2r--figure-out-what-to-log-where))
  29. (stmt (car log-info))
  30. (pos (cdr log-info)))
  31. (save-excursion
  32. (goto-char pos)
  33. (when (looking-at "[;{]")
  34. (forward-char 1))
  35. (newline-and-indent)
  36. (if arg
  37. (progn (insert "console.log(\"" stmt " = \");")
  38. (newline-and-indent)
  39. (insert "console.dir(" stmt ", { depth:null, colors: true });"))
  40. (insert "console.log(\"" stmt " = \", " stmt ");")))))
  41. (defun js2r-debug-this ()
  42. "Debug the node at point, adding a 'debug()' statement."
  43. (interactive)
  44. (js2r--guard)
  45. (let* ((log-info (js2r--figure-out-what-to-log-where))
  46. (stmt (car log-info))
  47. (pos (cdr log-info)))
  48. (save-excursion
  49. (goto-char pos)
  50. (when (looking-at "[;{]")
  51. (forward-char 1))
  52. (newline-and-indent)
  53. (insert "debug(" (js2r--wrap-text stmt " = %s") ", " stmt ");"))))
  54. (defun js2r--figure-out-what-to-log-where ()
  55. "Return a dotted pair containing the statement to log and the
  56. position where the log should be inserted."
  57. (let ((parent-stmt (js2-node-parent-stmt (js2-node-at-point))))
  58. (if (use-region-p)
  59. (cons (buffer-substring (region-beginning) (region-end))
  60. (js2r--find-suitable-log-position-around parent-stmt))
  61. (let* ((node (js2r--name-node-at-point))
  62. (parent (js2-node-parent node)))
  63. (cond
  64. ((js2-function-node-p parent)
  65. (cons (js2-name-node-name node)
  66. (js2-node-abs-pos (js2-function-node-body parent))))
  67. ((js2-prop-get-node-p parent)
  68. (cons (buffer-substring (js2-node-abs-pos parent) (js2-node-abs-end parent))
  69. (js2r--find-suitable-log-position-around parent-stmt)))
  70. (:else
  71. (cons (js2-name-node-name node)
  72. (js2r--find-suitable-log-position-around parent-stmt))))))))
  73. (defun js2r--find-suitable-log-position-around (parent-stmt)
  74. "Return the position close to PARENT-STMT where the log statement should be inserted."
  75. (if (js2-return-node-p parent-stmt)
  76. (save-excursion
  77. (goto-char (js2-node-abs-pos parent-stmt))
  78. (beginning-of-line)
  79. (forward-char -1)
  80. (point))
  81. (js2-node-abs-end parent-stmt)))
  82. (defun js2r-split-string ()
  83. "Split the string node at point. If the string is already split, join it instead."
  84. (interactive)
  85. (when (js2r--point-inside-string-p)
  86. (let ((delimiter (js2r--string-delimiter (js2-node-at-point))))
  87. (if (looking-back " \"")
  88. (progn
  89. (forward-char -2)
  90. (insert " +")
  91. (forward-char -2))
  92. (if (looking-at (regexp-quote (format "%s + %s" delimiter delimiter)))
  93. (delete-char 5)
  94. (insert (format "%s + %s" delimiter delimiter)))))))
  95. (defun js2r--string-delimiter (node)
  96. "Return the delimiter character of the string node NODE.
  97. It can be a single or double quote."
  98. (save-excursion
  99. (goto-char (js2-node-abs-pos node))
  100. (char-to-string (following-char))))
  101. (defun move-line-down ()
  102. "Move the current line down one line."
  103. (interactive)
  104. (let ((col (current-column)))
  105. (save-excursion
  106. (forward-line)
  107. (transpose-lines 1))
  108. (forward-line)
  109. (move-to-column col)))
  110. (defun move-line-up ()
  111. "Move the current line up one line."
  112. (interactive)
  113. (let ((col (current-column)))
  114. (transpose-lines 1)
  115. (forward-line -2)
  116. (move-to-column col)))
  117. (defun js2r-move-line-down ()
  118. "Move the current line down one line.
  119. Make sure commas are placed correctly when moving a line up or
  120. down in an object or array literal."
  121. (interactive)
  122. (if (and (js2r--current-line-is-a-list-item)
  123. (js2r--next-line-is-a-list-item))
  124. (js2r--move-line-down-as-list-item)
  125. (move-line-down))
  126. (funcall indent-line-function))
  127. (defun js2r-move-line-up ()
  128. "Move the current line up one line.
  129. Make sure commas are placed correctly when moving a line up or
  130. down in an object or array literal."
  131. (interactive)
  132. (if (and (js2r--current-line-is-a-list-item)
  133. (js2r--previous-line-is-a-list-item))
  134. (js2r--move-line-up-as-list-item)
  135. (move-line-up))
  136. (funcall indent-line-function))
  137. (defun js2r--current-line-is-prefixed-with-list-item-start ()
  138. "Return whether the current line is prefixed with '{' or '['."
  139. (save-excursion
  140. (back-to-indentation)
  141. (looking-back "\\({\\|\\[\\|,\\)\\(\s\\|\n\\|\t\\)*")))
  142. (defun js2r--current-line-is-postfixed-with-list-item-end ()
  143. "Return whether the current line is postfixed with '{' or '['."
  144. (save-excursion
  145. (end-of-line)
  146. (or (looking-back ",\s*") ; line ends in comma
  147. (looking-at "\\(\s\\|\n\\|\t\\)*\\(\\]\\|}\\)"))))
  148. (defun js2r--current-line-is-a-list-item ()
  149. "Return whether the current line contain an array or object literal."
  150. (and (js2r--current-line-is-prefixed-with-list-item-start)
  151. (js2r--current-line-is-postfixed-with-list-item-end)))
  152. (defun js2r--next-line-is-a-list-item ()
  153. "Return whether the current line contain an array or object literal."
  154. (save-excursion
  155. (forward-line)
  156. (js2r--current-line-is-a-list-item)))
  157. (defun js2r--previous-line-is-a-list-item ()
  158. "Return whether the previous line contain an array or object literal, and only that."
  159. (save-excursion
  160. (forward-line -1)
  161. (js2r--current-line-is-a-list-item)))
  162. (defun js2r--current-line-has-comma ()
  163. "Return whether the current line ends with a comma."
  164. (save-excursion
  165. (end-of-line)
  166. (looking-back ",\s*")))
  167. (defun js2r--previous-line-has-comma ()
  168. "Return whether the previous line ends with a comma."
  169. (save-excursion
  170. (forward-line -1)
  171. (js2r--current-line-has-comma)))
  172. (defun js2r--move-line-down-as-list-item ()
  173. "Move the current line containing a list literal down one line, and also move the comma."
  174. (move-line-down)
  175. (if (not (js2r--previous-line-has-comma))
  176. (save-excursion
  177. (end-of-line)
  178. (delete-char -1)
  179. (forward-line -1)
  180. (end-of-line)
  181. (insert ","))))
  182. (defun js2r--move-line-up-as-list-item ()
  183. "Move the current line containing a list literal up one line, and also move the comma."
  184. (move-line-up)
  185. (if (not (js2r--current-line-has-comma))
  186. (save-excursion
  187. (end-of-line)
  188. (insert ",")
  189. (forward-line)
  190. (end-of-line)
  191. (delete-char -1))))
  192. (provide 'js2r-conveniences)
  193. ;;; js2r-conveniences.el ends here