add *-from-space-dwim
2 files changed, 231 insertions(+), 0 deletions(-)

M caser.el
M tests.el
M caser.el +79 -0
@@ 250,6 250,85 @@ to dashcase ARG words."
 (defvar caser-dashcase-repeat-map (define-keymap "d" #'caser-dashcase-dwim))
 (put #'caser-dashcase-dwim 'repeat-map 'caser-dashcase-repeat-map)
 
+(defun caser--convert-whitespace (beginning-point end-point string-to-convert-to)
+  "Convert every space to STRING-TO-CONVERT-TO.
+
+This only converts between BEGINNING-POINT and END-POINT."
+  (save-excursion
+    (goto-char beginning-point)
+    (let ((end-marker (make-marker)))
+      (move-marker end-marker end-point)
+      (while (re-search-forward (rx (one-or-more ?\s)) (marker-position end-marker) t)
+        (replace-match string-to-convert-to)))))
+
+(defun caser--from-space-dwim-helper (words region-function)
+  "Helper function for *-from-space-dwim functions.
+
+This cases WORDS words, unless the region is active.
+
+It uses REGION-FUNCTION to case the region."
+  (if (use-region-p)
+      (let ((beginning (region-beginning))
+            (end (region-end))
+            (starting-point-marker (point-marker))
+            (end-marker (make-marker)))
+        (move-marker end-marker end)
+
+        (set-marker-insertion-type starting-point-marker nil)
+        (caser--convert-whitespace beginning
+                                   end
+                                   "-")
+        (funcall region-function beginning (marker-position end-marker))
+        (goto-char starting-point-marker))
+    (let* ((starting-end (point))
+           (other-end (progn (caser--forward-word words)
+                             (point)))
+           (beginning (min starting-end other-end))
+           (end (max starting-end other-end))
+           (end-marker (make-marker))
+           (point-at-end-marker (make-marker)))
+      (set-marker end-marker end)
+      (set-marker point-at-end-marker other-end)
+      (set-marker-insertion-type point-at-end-marker (equal starting-end beginning))
+
+      (caser--convert-whitespace beginning end "-")
+      (funcall region-function beginning (marker-position end-marker))
+
+      (goto-char point-at-end-marker))))
+
+(defun caser-dashcase-from-space-dwim (&optional words)
+  "Dashcase what you mean, including converting spaces to dashes.
+
+If the region is active, dashcase it; otherwise dashcase the word at point.
+
+This converts it from camelCase or snake_case to dash-case.
+
+If the region is active, this function calls `caser-dashcase-region'.
+Otherwise, it calls `caser-dashcase-word', with prefix argument passed to it
+to dashcase WORDS words."
+  (interactive "*p")
+  (caser--from-space-dwim-helper words #'caser-dashcase-region))
+
+(defun caser-snakecase-from-space-dwim (&optional words)
+  "Snakecase what you mean, including converting spaces to underscores.
+
+If the region is active, snakecase it; otherwise snakecase WORDS
+words at point, defaulting to 1.
+
+This converts it from camelCase or dash-case to snake_case."
+  (interactive "*p")
+  (caser--from-space-dwim-helper words #'caser-snakecase-region))
+
+(defun caser-camelcase-from-space-dwim (&optional words)
+  "Camelcase what you mean, including converting spaces to underscores.
+
+If the region is active, camelcase it; otherwise camelcase WORDS
+words at point, defaulting to 1.
+
+This converts it from snake_case or dash-case to camelCase."
+  (interactive "*p")
+  (caser--from-space-dwim-helper words #'caser-camelcase-region))
+
 ;;suggested.
 ;; (bind-key "M-C" #'caser-camelcase-dwim)
 ;; (bind-key "M-S" #'caser-snakecase-dwim)

          
M tests.el +152 -0
@@ 862,3 862,155 @@ you all"
                  (caser//on-temp-buffer-point
                    "|hi +-_=there friends"
                    (caser--forward-word 2)))))
+
+;; convert-from-whitespace
+(ert-deftest convert-whitespace/no-whitespace ()
+  (should (equal "hi-there"
+                 (caser//on-temp-buffer
+                  "hi-there"
+                  (caser--convert-whitespace (point-min)
+                                             (point-max)
+                                             "-")))))
+
+(ert-deftest convert-whitespace/single-whitespace ()
+  (should (equal "hi-there"
+                 (caser//on-temp-buffer
+                  "hi there"
+                  (caser--convert-whitespace (point-min)
+                                             (point-max)
+                                             "-")))))
+
+(ert-deftest convert-whitespace/duplicate-whitespace ()
+  (should (equal "hi-there"
+                 (caser//on-temp-buffer
+                  "hi    there"
+                  (caser--convert-whitespace (point-min)
+                                             (point-max)
+                                             "-")))))
+
+(ert-deftest convert-whitespace/more-than-one-whitespace ()
+  (should (equal "hi-there-to-you"
+                 (caser//on-temp-buffer
+                  "hi    there to  you"
+                  (caser--convert-whitespace (point-min)
+                                             (point-max)
+                                             "-")))))
+
+(ert-deftest convert-whitespace/obeys-points ()
+  (should (equal "hi  _there_to  you"
+                 (caser//on-temp-buffer
+                  "hi    there to  you"
+                  (caser--convert-whitespace 5
+                                             13
+                                             "_")))))
+
+(ert-deftest convert-whitespace/multiple-whitespace-doesnt-overlap-other-words ()
+  (should (equal "a_b c d e"
+                 (caser//on-temp-buffer
+                  "a          b c d e"
+                  (caser--convert-whitespace 1
+                                             13
+                                             "_")))))
+
+;;dashcase-from-space-dwim tests
+
+(ert-deftest dashcase-from-space-dwim/single-whitespace ()
+  (should (equal "|hi-there"
+                 (caser//on-temp-buffer-point
+                   "|hi there"
+                   (set-mark (point-max))
+                   (activate-mark)
+                   (caser-dashcase-from-space-dwim)))))
+
+(ert-deftest dashcase-from-space-dwim/region-forward/single-whitespace ()
+  (should (equal "|hi-there"
+                 (caser//on-temp-buffer-point
+                   "|hi there"
+                   (set-mark (point-max))
+                   (activate-mark)
+                   (caser-dashcase-from-space-dwim)))))
+
+(ert-deftest dashcase-from-space-dwim/region-backward/lots-of-whitespace ()
+  (should (equal "hi-there|"
+                 (caser//on-temp-buffer-point
+                   "hi    there|"
+                   (set-mark (point-min))
+                   (activate-mark)
+                   (caser-dashcase-from-space-dwim)))))
+
+(ert-deftest dashcase-from-space-dwim/region-backward/middle-of-string ()
+  (should (equal "a    |b-c-d  e"
+                 (caser//on-temp-buffer-point
+                   "a    |b           c   d  e"
+                   (set-mark 23)
+                   (activate-mark)
+                   (caser-dashcase-from-space-dwim)))))
+
+(ert-deftest dashcase-from-space-dwim/positive-argument/1 ()
+  (should (equal "hi| there"
+                 (caser//on-temp-buffer-point
+                   "|hi there"
+                   (caser-dashcase-from-space-dwim 1)))))
+
+(ert-deftest dashcase-from-space-dwim/positive-argument/2 ()
+  (should (equal "hi-there|"
+                 (caser//on-temp-buffer-point
+                   "|hi there"
+                   (caser-dashcase-from-space-dwim 2)))))
+
+
+(ert-deftest dashcase-from-space-dwim/positive-argument/3 ()
+  (should (equal "hi there-to-everybody| around"
+                 (caser//on-temp-buffer-point
+                   "hi |there to   everybody around"
+                   (caser-dashcase-from-space-dwim 3)))))
+
+(ert-deftest dashcase-from-space-dwim/negative-argument/-3 ()
+  (should (equal "hi |there-to-everybody around"
+                 (caser//on-temp-buffer-point
+                   "hi there to everybody| around"
+                   (caser-dashcase-from-space-dwim -3)))))
+
+(ert-deftest dashcase-from-space-dwim/region-forward/space-and-camelcase ()
+  (should (equal "hi there-to-everybody| around"
+                 (caser//on-temp-buffer-point
+                   "hi there toEverybody| around"
+                   (set-mark 5)
+                   (activate-mark)
+                   (caser-dashcase-from-space-dwim)))))
+
+;;snakecase-from-space-dwim tests
+
+(ert-deftest snakecase-from-space-dwim/region-backward/space-and-dashcase ()
+  (should (equal "hi there_to_everybody| around"
+                 (caser//on-temp-buffer-point
+                   "hi there to-everybody| around"
+                   (set-mark 5)
+                   (activate-mark)
+                   (caser-snakecase-from-space-dwim)))))
+
+(ert-deftest snakecase-from-space-dwim/positive-argument ()
+  (should (equal "ok   this is_a_new_thing_that| goes on"
+                 (caser//on-temp-buffer-point
+                   "ok   this |is      a-newThing   that goes on"
+                   (caser-snakecase-from-space-dwim 3)))))
+
+(ert-deftest snakecase-from-space-dwim/region-forward/lots-of-things ()
+  (should (equal "hi |there_to_everybody_i_know_around here"
+                 (caser//on-temp-buffer-point
+                   "hi |there    to-everybodyIKnow    around here"
+                   (set-mark 35)
+                   (activate-mark)
+                   (caser-snakecase-from-space-dwim)))))
+
+;;camelcase-from-space-dwim
+
+(ert-deftest camelcase-from-space-dwim/region-forward/lots-of-things ()
+  (should (equal "this   |isALotOfWordsThat matter"
+                 (caser//on-temp-buffer-point
+                   "this   |is a-lot_of    words      that matter"
+                   (set-mark 34)
+                   (activate-mark)
+                   (caser-camelcase-from-space-dwim)))))
+
+;;; tests.el ends here