├── .gitignore
├── .travis.yml
├── HISTORY.org
├── README.org
├── string-inflection.el
└── test
└── string-inflection-test.el
/.gitignore:
--------------------------------------------------------------------------------
1 | /*.html
2 | ert.*
3 | *.elc
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: emacs-lisp
2 | env:
3 | - EMACS=emacs24
4 | - EMACS=emacs-snapshot
5 | matrix:
6 | allow_failures:
7 | - env: EMACS=emacs-snapshot
8 | before_install:
9 | # Install Emacs
10 | - sudo add-apt-repository -y ppa:cassou/emacs
11 | - sudo add-apt-repository -y ppa:ubuntu-elisp
12 | - sudo apt-get update -qq
13 | - sudo apt-get install -qq $EMACS
14 | # # Install Cask
15 | # - curl -fsSkL --max-time 10 --retry 10 --retry-delay 10
16 | # https://raw.github.com/cask/cask/master/go | python
17 | # - export PATH="$HOME/.cask/bin:$PATH"
18 | # - cask
19 | script:
20 | $EMACS --script test/string-inflection-test.el
21 |
--------------------------------------------------------------------------------
/HISTORY.org:
--------------------------------------------------------------------------------
1 | * HISTORY
2 |
3 | ** Version 1.1.0
4 |
5 | - Support non ascii [[https://github.com/akicho8/string-inflection/pull/39][#39]]
6 | - Use (bounds-of-thing-at-point) for word detection [[https://github.com/akicho8/string-inflection/pull/41][#41]]
7 | - Implement string-inflect-final-position [[https://github.com/akicho8/string-inflection/pull/43][#43]]
8 |
9 | =string-inflection-skip-backward-when-done= is deprecated.
10 | Use the =string-inflection-final-position= option instead.
11 | However, leaving it as the default seems to be the easiest to use.
12 |
13 | Previously, the rule for identifying words was shared across all modes. However, with this recent change, we have adapted the word boundaries to reflect the specifics of each mode. As a result, we have eliminated the need for handling edge cases, allowing for simpler and more flexible transformations.
14 |
15 | On the other hand, there are now cases where the range considered as a "word" has become too broad, leading to situations where the intended transformation does not occur. For example, in org-mode, when you try to transform only the "foo_bar" portion of "path/to/foo_bar.txt" by placing the cursor over it, nothing happens. In such cases, you can achieve a partial transformation by selecting "foo_bar" as a range.
16 |
17 | ** Version 1.0.16
18 |
19 | Fix [[https://github.com/akicho8/string-inflection/issues/34][#34]] kebabing a region can insert an unexpected hyphen
20 |
21 | add =string-inflection-erase-chars-when-region= variable
22 |
23 | Changed behavior when selecting region.
24 |
25 | #+BEGIN_SRC
26 | before: Foo::Bar --> foo_bar
27 | after: Foo::Bar --> foo::bar
28 | #+END_SRC
29 |
30 | Include =:= in =string-inflection-erase-chars-when-region= if want to behave as before.
31 |
32 | ** Version 1.0.14
33 |
34 | Merged [[https://github.com/akicho8/string-inflection/pull/32][PR #32]] Use defcustom and Change Some Wording
35 |
36 | ** Version 1.0.13
37 |
38 | Fix [[https://github.com/akicho8/string-inflection/issues/31][#31]] Better Whitespace Handling When Converting a Region
39 |
40 | ** Version 1.0.12
41 |
42 | Fix [[https://github.com/akicho8/string-inflection/issues/30][#30]] string-inflection-underscore affects C++ method accessors
43 |
44 | #+BEGIN_SRC
45 | before: fooBar->method --> foo_bar_>method
46 | after: fooBar->method --> foo_bar->method
47 | #+END_SRC
48 |
49 | ** Version 1.0.11
50 |
51 | Merged [[https://github.com/akicho8/string-inflection/pull/28][PR #28]] Make string-inflection-get-current-word work more sensibly when transient mark mode is off
52 |
53 | ** Version 1.0.10
54 |
55 | Merged [[https://github.com/akicho8/string-inflection/pull/26][PR #26]] Add `Capital_Underscore_Form`
56 |
57 | add string-inflection-capital-underscore function
58 |
59 | The behavior of =string-inflection-all-cycle= has changed
60 |
61 | #+BEGIN_SRC
62 | before: foo_bar => FOO_BAR => FooBar => fooBar => foo-bar => foo_bar
63 | after: foo_bar => FOO_BAR => FooBar => fooBar => foo-bar => Foo_Bar => foo_bar
64 | #+END_SRC
65 |
66 | ** Version 1.0.9
67 |
68 | Bugfix [[https://github.com/akicho8/string-inflection/issues/27][issue #25]] When executing kebab-case etc., point advances to the next word, and the previous word can not be converted continuously
69 |
70 | ** Version 1.0.8
71 |
72 | [[https://github.com/akicho8/string-inflection/issues/25][issue #25]]
73 |
74 | When it is simply =camelcase=, it means the name with the leading letters in lowercase.
75 |
76 | The name with the initial capital letter is called the =pascal-case=.
77 |
78 | *** Behavior of the camelcase function has changed
79 |
80 | | Before | After |
81 | |--------+--------|
82 | | FooBar | fooBar |
83 |
84 | *** Function name changed as well
85 |
86 | | Before | After |
87 | |-----------------+-------------|
88 | | camelcase | pascal-case |
89 | | lower-camelcase | camelcase |
90 |
91 | *** Add alias
92 |
93 | #+BEGIN_SRC elisp
94 | (fset 'string-inflection-upper-camelcase-function 'string-inflection-pascal-case-function)
95 | (fset 'string-inflection-lower-camelcase-function 'string-inflection-camelcase-function)
96 |
97 | (fset 'string-inflection-upper-camelcase-p 'string-inflection-pascal-case-p)
98 | (fset 'string-inflection-lower-camelcase-p 'string-inflection-camelcase-p)
99 | #+END_SRC
100 |
101 | *** Remove camelize function
102 |
103 | Originally we had defined functions of both =camelcase= and =camelize= names.
104 |
105 | I deleted the function containing =camelize= to make it simple.
106 |
--------------------------------------------------------------------------------
/README.org:
--------------------------------------------------------------------------------
1 | * underscore -> UPCASE -> CamelCase conversion of names
2 |
3 | #+html:
4 | #+html:
5 | #+html:
6 |
7 | [[https://github.com/akicho8/string-inflection/blob/master/HISTORY.org][Change History]]
8 |
9 | ** Configuration Examples
10 |
11 | *** Example 1
12 |
13 | #+BEGIN_SRC elisp
14 | (require 'string-inflection)
15 |
16 | ;; C-q C-u is similar to the keybinding used by Vz Editor.
17 | (global-unset-key (kbd "C-q"))
18 | (global-set-key (kbd "C-q C-u") 'my-string-inflection-cycle-auto)
19 |
20 | (defun my-string-inflection-cycle-auto ()
21 | "switching by major-mode"
22 | (interactive)
23 | (cond
24 | ;; for emacs-lisp-mode
25 | ((eq major-mode 'emacs-lisp-mode)
26 | (string-inflection-all-cycle))
27 | ;; for python
28 | ((eq major-mode 'python-mode)
29 | (string-inflection-python-style-cycle))
30 | ;; for java
31 | ((eq major-mode 'java-mode)
32 | (string-inflection-java-style-cycle))
33 | ;; for elixir
34 | ((eq major-mode 'elixir-mode)
35 | (string-inflection-elixir-style-cycle))
36 | (t
37 | ;; default
38 | (string-inflection-ruby-style-cycle))))
39 | #+END_SRC
40 |
41 | *** Example 2
42 |
43 | #+BEGIN_SRC elisp
44 | (require 'string-inflection)
45 |
46 | ;; default
47 | (global-set-key (kbd "C-c C-u") 'string-inflection-all-cycle)
48 |
49 | ;; for ruby
50 | (add-hook 'ruby-mode-hook
51 | '(lambda ()
52 | (local-set-key (kbd "C-c C-u") 'string-inflection-ruby-style-cycle)))
53 |
54 | ;; for elixir
55 | (add-hook 'elixir-mode-hook
56 | '(lambda ()
57 | (local-set-key (kbd "C-c C-u") 'string-inflection-elixir-style-cycle)))
58 |
59 | ;; for java
60 | (add-hook 'java-mode-hook
61 | '(lambda ()
62 | (local-set-key (kbd "C-c C-u") 'string-inflection-java-style-cycle)))
63 |
64 | ;; for python
65 | (add-hook 'python-mode-hook
66 | '(lambda ()
67 | (local-set-key (kbd "C-c C-u") 'string-inflection-python-style-cycle)))
68 |
69 | #+END_SRC
70 |
71 | ** How to Use
72 |
73 | For each of the following, place the cursor at =emacs_lisp= and type =C-q C-u=, the results will be as follows:
74 |
75 | In the case of =string-inflection-ruby-style-cycle=
76 |
77 | : emacs_lisp => EMACS_LISP => EmacsLisp => emacs_lisp
78 |
79 | In the case of =string-inflection-elixir-style-cycle=
80 |
81 | : emacs_lisp => EmacsLisp => emacs_lisp
82 |
83 | In the case of =string-inflection-python-style-cycle=
84 |
85 | : emacs_lisp => EMACS_LISP => EmacsLisp => emacs_lisp
86 |
87 | In the case of =string-inflection-java-style-cycle=
88 |
89 | : emacsLisp => EMACS_LISP => EmacsLisp => emacsLisp
90 |
91 | In the case of =string-inflection-all-cycle=
92 |
93 | : emacs_lisp => EMACS_LISP => EmacsLisp => emacsLisp => emacs-lisp => Emacs_Lisp => emacs_lisp
94 |
95 | It is recommended that the major mode functions are used instead of =string-inflection-all-cycle=.
96 |
97 | ** Standalone Functions
98 |
99 | #+BEGIN_SRC elisp
100 | (string-inflection-underscore-function "EmacsLisp") ; => "emacs_lisp"
101 | (string-inflection-pascal-case-function "emacs_lisp") ; => "EmacsLisp"
102 | (string-inflection-camelcase-function "emacs_lisp") ; => "emacsLisp"
103 | (string-inflection-upcase-function "emacs_lisp") ; => "EMACS_LISP"
104 | (string-inflection-kebab-case-function "emacs_lisp") ; => "emacs-lisp"
105 | (string-inflection-capital-underscore-function "emacs_lisp") ; => "Emacs_Lisp"
106 |
107 | (string-inflection-pascal-case-p "EmacsLisp") ; => t
108 | (string-inflection-pascal-case-p "emacs_lisp") ; => nil
109 | ; etc...
110 | #+END_SRC
111 |
112 | ** Region usage
113 |
114 | You can also use this library to convert a region's casing. That applies the
115 | operation to all symbols of the region. If a symbol is only partially covered
116 | by the region, the operation is performed only on that part.
117 |
118 | For that, simply select a region and perform =M-x string-inflection-kebab-case= (or any such other function).
119 |
120 | ** Other configuration options
121 |
122 | You can configure where the cursor shall finish after the inflection operation
123 | using the =string-inflection-final-position= customization option.
124 |
--------------------------------------------------------------------------------
/string-inflection.el:
--------------------------------------------------------------------------------
1 | ;;; string-inflection.el --- underscore -> UPCASE -> CamelCase -> lowerCamelCase conversion of names -*- lexical-binding: t -*-
2 |
3 | ;; Copyright (C) 2004,2014,2016,2017,2018,2020,2021,2022,2023,2024 Free Software Foundation, Inc.
4 |
5 | ;; Author: akicho8
6 | ;; Keywords: elisp
7 | ;; Version: 1.1.0
8 |
9 | ;; This file is free software; you can redistribute it and/or modify
10 | ;; it under the terms of the GNU General Public License as published by
11 | ;; the Free Software Foundation; either version 2, or (at your option)
12 | ;; any later version.
13 |
14 | ;; This file is distributed in the hope that it will be useful,
15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | ;; GNU General Public License for more details.
18 |
19 | ;; You should have received a copy of the GNU General Public License
20 | ;; along with GNU Emacs; see the file COPYING. If not, write to
21 | ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 | ;; Boston, MA 02111-1307, USA.
23 |
24 | ;;; Commentary:
25 |
26 | ;; There are three main functions:
27 | ;;
28 | ;; 1. For Ruby -> string-inflection-ruby-style-cycle (foo_bar => FOO_BAR => FooBar => foo_bar)
29 | ;; 2. For Elixir -> string-inflection-elixir-style-cycle (foo_bar => FooBar => foo_bar)
30 | ;; 3. For Python -> string-inflection-python-style-cycle (foo_bar => FOO_BAR => FooBar => foo_bar)
31 | ;; 4. For Java -> string-inflection-java-style-cycle (fooBar => FOO_BAR => FooBar => fooBar)
32 | ;; 5. For All -> string-inflection-all-cycle (foo_bar => FOO_BAR => FooBar => fooBar => foo-bar => Foo_Bar => foo_bar)
33 | ;;
34 | ;;
35 | ;; Example 1:
36 | ;;
37 | ;; (require 'string-inflection)
38 | ;; (global-unset-key (kbd "C-q"))
39 | ;; ;; C-q C-u is the key bindings similar to Vz Editor.
40 | ;; (global-set-key (kbd "C-q C-u") 'my-string-inflection-cycle-auto)
41 | ;;
42 | ;; (defun my-string-inflection-cycle-auto ()
43 | ;; "switching by major-mode"
44 | ;; (interactive)
45 | ;; (cond
46 | ;; ;; for emacs-lisp-mode
47 | ;; ((eq major-mode 'emacs-lisp-mode)
48 | ;; (string-inflection-all-cycle))
49 | ;; ;; for java
50 | ;; ((eq major-mode 'java-mode)
51 | ;; (string-inflection-java-style-cycle))
52 | ;; ;; for python
53 | ;; ((eq major-mode 'python-mode)
54 | ;; (string-inflection-python-style-cycle))
55 | ;; ;; for elixir
56 | ;; ((eq major-mode 'elixir-mode)
57 | ;; (string-inflection-elixir-style-cycle))
58 | ;; (t
59 | ;; ;; default
60 | ;; (string-inflection-ruby-style-cycle))))
61 | ;;
62 | ;;
63 | ;; Example 2:
64 | ;;
65 | ;; (require 'string-inflection)
66 | ;;
67 | ;; ;; default
68 | ;; (global-set-key (kbd "C-c C-u") 'string-inflection-all-cycle)
69 | ;;
70 | ;; ;; for ruby
71 | ;; (add-hook 'ruby-mode-hook
72 | ;; '(lambda ()
73 | ;; (local-set-key (kbd "C-c C-u") 'string-inflection-ruby-style-cycle)))
74 | ;;
75 | ;; ;; for elixir
76 | ;; (add-hook 'elixir-mode-hook
77 | ;; '(lambda ()
78 | ;; (local-set-key (kbd "C-c C-u") 'string-inflection-elixir-style-cycle)))
79 | ;;
80 | ;; ;; for python
81 | ;; (add-hook 'python-mode-hook
82 | ;; '(lambda ()
83 | ;; (local-set-key (kbd "C-c C-u") 'string-inflection-python-style-cycle)))
84 | ;;
85 | ;; ;; for java
86 | ;; (add-hook 'java-mode-hook
87 | ;; '(lambda ()
88 | ;; (local-set-key (kbd "C-c C-u") 'string-inflection-java-style-cycle)))
89 | ;;
90 | ;; You can configure where the cursor should end up after the inflection using the
91 | ;; `string-inflection-final-position' option.
92 | ;;
93 | ;; When a region is active during the inflect operation there are two effects:
94 | ;;
95 | ;; * If the region marks a part of a symbol the operation is only performed on that
96 | ;; part.
97 | ;; * If the region contains more than one symbols, the operation is performed on all
98 | ;; the symbols in the region.
99 | ;; * The region is preserved after the operation.
100 |
101 | ;;; Code:
102 |
103 | (defgroup string-inflection nil
104 | "Change the casing of words."
105 | :group 'convenience)
106 |
107 | (defcustom string-inflection-final-position 'remain
108 | "Where to finish after the inflection.
109 | This can be `remain' – remain at the initial position but not beyond the end of the inflected string –,
110 | `beginning' – jump to the beginning of the inflection – or
111 | `end' – jump to the end of the inflection."
112 | :group 'string-inflection
113 | :type '(choice (const remain) (const beginning) (const end)))
114 |
115 | ;; --------------------------------------------------------------------------------
116 |
117 | ;;;###autoload
118 | (defun string-inflection-ruby-style-cycle ()
119 | "foo_bar => FOO_BAR => FooBar => foo_bar"
120 | (interactive)
121 | (string-inflection--single-or-region #'string-inflection-ruby-style-cycle-function))
122 |
123 | (fset 'string-inflection-cycle 'string-inflection-ruby-style-cycle)
124 |
125 | ;;;###autoload
126 | (defun string-inflection-elixir-style-cycle ()
127 | "foo_bar => FooBar => foo_bar"
128 | (interactive)
129 | (string-inflection--single-or-region #'string-inflection-elixir-style-cycle-function))
130 |
131 | ;;;###autoload
132 | (defun string-inflection-python-style-cycle ()
133 | "foo_bar => FOO_BAR => FooBar => foo_bar"
134 | (interactive)
135 | (string-inflection--single-or-region #'string-inflection-python-style-cycle-function))
136 |
137 | ;;;###autoload
138 | (defun string-inflection-java-style-cycle ()
139 | "fooBar => FOO_BAR => FooBar => fooBar"
140 | (interactive)
141 | (string-inflection--single-or-region #'string-inflection-java-style-cycle-function))
142 |
143 | ;;;###autoload
144 | (defun string-inflection-all-cycle ()
145 | "foo_bar => FOO_BAR => FooBar => fooBar => foo-bar => Foo_Bar => foo_bar"
146 | (interactive)
147 | (string-inflection--single-or-region #'string-inflection-all-cycle-function))
148 |
149 | ;;;###autoload
150 | (defun string-inflection-toggle ()
151 | "toggle foo_bar <=> FooBar"
152 | (interactive)
153 | (string-inflection--single-or-region #'string-inflection-toggle-function))
154 |
155 | ;;;###autoload
156 | (defun string-inflection-camelcase ()
157 | "FooBar format"
158 | (interactive)
159 | (string-inflection--single-or-region #'string-inflection-pascal-case-function))
160 |
161 | ;;;###autoload
162 | (defun string-inflection-lower-camelcase ()
163 | "fooBar format"
164 | (interactive)
165 | (string-inflection--single-or-region #'string-inflection-camelcase-function))
166 |
167 | ;;;###autoload
168 | (defun string-inflection-underscore ()
169 | "foo_bar format"
170 | (interactive)
171 | (string-inflection--single-or-region #'string-inflection-underscore-function))
172 |
173 | ;;;###autoload
174 | (defun string-inflection-capital-underscore ()
175 | "Foo_Bar format"
176 | (interactive)
177 | (string-inflection--single-or-region #'string-inflection-capital-underscore-function))
178 |
179 | ;;;###autoload
180 | (defun string-inflection-upcase ()
181 | "FOO_BAR format"
182 | (interactive)
183 | (string-inflection--single-or-region #'string-inflection-upcase-function))
184 |
185 | ;;;###autoload
186 | (defun string-inflection-kebab-case ()
187 | "foo-bar format"
188 | (interactive)
189 | (string-inflection--single-or-region #'string-inflection-kebab-case-function))
190 |
191 | (fset 'string-inflection-lisp 'string-inflection-kebab-case)
192 |
193 | ;; --------------------------------------------------------------------------------
194 |
195 | (defun string-inflection--count-symbols-between-start-and-end (start end)
196 | "Count the symbols between START and END."
197 | (let ((symbol-num 0))
198 | (goto-char start)
199 | (save-excursion
200 | (while (< (point) end)
201 | (setq symbol-num (1+ symbol-num))
202 | (forward-symbol 1)))
203 | symbol-num))
204 |
205 | (defun string-inflection--single-or-region (inflect-func)
206 | "Perform INFLECT-FUNC depending on if in region or single."
207 | (if (use-region-p)
208 | (string-inflection--region inflect-func)
209 | (string-inflection--single inflect-func)))
210 |
211 | (defun string-inflection--single (inflect-func)
212 | "Perform INFLECT-FUNC for a single occurrence."
213 | (let ((orig-point (point)))
214 | (insert (funcall inflect-func (string-inflection-get-current-word)))
215 | (pcase string-inflection-final-position
216 | ('remain (goto-char (min orig-point (cdr (bounds-of-thing-at-point 'symbol)))))
217 | ('beginning (goto-char (car (bounds-of-thing-at-point 'symbol)))))))
218 |
219 | (defun string-inflection--region (inflect-func)
220 | "Perform INFLECT-FUNC for all occurrences in the region."
221 | (let ((orig-point (point))
222 | (start (region-beginning))
223 | (end (region-end)))
224 | (dotimes (_ (string-inflection--count-symbols-between-start-and-end start end))
225 | (let ((orig-length (length (symbol-name (symbol-at-point)))))
226 | (insert (funcall inflect-func (string-inflection-get-current-word-limited-by start end)))
227 | (setq end (+ end (- (length (symbol-name (symbol-at-point))) orig-length)))
228 | (forward-symbol 1)
229 | (if-let* ((bounds (bounds-of-thing-at-point 'symbol)))
230 | (goto-char (car bounds)))))
231 | (let ((new-region
232 | (pcase string-inflection-final-position
233 | ('remain (if (/= orig-point start) (cons start end) (cons end start)))
234 | ('beginning (cons end start))
235 | ('end (cons start end)))))
236 | (set-mark (car new-region))
237 | (goto-char (cdr new-region)))
238 | (activate-mark)
239 | (setq deactivate-mark nil)))
240 |
241 | (defun string-inflection-get-current-word ()
242 | "Gets the symbol near the cursor"
243 | (interactive)
244 | (if-let* ((bounds (bounds-of-thing-at-point 'symbol))
245 | (start (car bounds))
246 | (end (cdr bounds))
247 | (str (buffer-substring start end)))
248 | (progn
249 | (delete-region start end)
250 | str)
251 | ""))
252 |
253 | (defun string-inflection-get-current-word-limited-by (reg-start reg-end)
254 | "Gets the symbol near the cursor limited by REG-START and REG-END."
255 | (interactive)
256 | (if-let* ((bounds (bounds-of-thing-at-point 'symbol))
257 | (start (max (car bounds) reg-start))
258 | (end (min (cdr bounds) reg-end))
259 | (str (buffer-substring start end)))
260 | (progn
261 | (delete-region start end)
262 | str)
263 | ""))
264 |
265 | ;; --------------------------------------------------------------------------------
266 |
267 | (defun string-inflection-pascal-case-function (str)
268 | "foo_bar => FooBar"
269 | (setq str (string-inflection-underscore-function str))
270 | (mapconcat 'capitalize (split-string str "_") ""))
271 |
272 | (fset 'string-inflection-upper-camelcase-function 'string-inflection-pascal-case-function)
273 |
274 | (defun string-inflection-camelcase-function (str)
275 | "foo_bar => fooBar"
276 | (setq str (split-string (string-inflection-underscore-function str) "_"))
277 | (concat (downcase (car str))
278 | (mapconcat 'capitalize (cdr str) "")))
279 |
280 | (fset 'string-inflection-lower-camelcase-function 'string-inflection-camelcase-function)
281 |
282 | (defun string-inflection-upcase-function (str)
283 | "FooBar => FOO_BAR"
284 | (upcase (string-inflection-underscore-function str)))
285 |
286 | (defun string-inflection-underscore-function (str)
287 | "FooBar => foo_bar"
288 | (let ((case-fold-search nil))
289 | (setq str (replace-regexp-in-string "\\([[:lower:][:digit:]]\\)\\([[:upper:]]\\)" "\\1_\\2" str))
290 | (setq str (replace-regexp-in-string "\\([[:upper:]]+\\)\\([[:upper:]][[:lower:]]\\)" "\\1_\\2" str))
291 | (setq str (replace-regexp-in-string "-" "_" str)) ; FOO-BAR => FOO_BAR
292 | (setq str (replace-regexp-in-string "_+" "_" str))
293 | (downcase str)))
294 |
295 | (defun string-inflection-capital-underscore-function (str)
296 | "foo_bar => Foo_Bar"
297 | (setq str (string-inflection-underscore-function str))
298 | (mapconcat 'capitalize (split-string str "_") "_"))
299 |
300 | (defun string-inflection-kebab-case-function (str)
301 | "foo_bar => foo-bar"
302 | (let ((case-fold-search nil))
303 | (setq str (string-inflection-underscore-function str))
304 | (setq str (replace-regexp-in-string "_" "-" str))))
305 |
306 | (defun string-inflection-all-cycle-function (str)
307 | "foo_bar => FOO_BAR => FooBar => fooBar => foo-bar => Foo_Bar => foo_bar
308 | foo => FOO => Foo => foo"
309 | (cond
310 | ;; foo => FOO
311 | ((string-inflection-word-p str)
312 | (string-inflection-upcase-function str))
313 | ;; foo_bar => FOO_BAR
314 | ((string-inflection-underscore-p str)
315 | (string-inflection-upcase-function str))
316 | ;; FOO_BAR => FooBar
317 | ((string-inflection-upcase-p str)
318 | (string-inflection-pascal-case-function str))
319 | ;; FooBar => fooBar
320 | ;; Foo => foo
321 | ((string-inflection-pascal-case-p str)
322 | (string-inflection-camelcase-function str))
323 | ;; fooBar => foo-bar
324 | ((string-inflection-camelcase-p str)
325 | (string-inflection-kebab-case-function str))
326 | ;; foo-bar => Foo_Bar
327 | ((string-inflection-kebab-case-p str)
328 | (string-inflection-capital-underscore-function str))
329 | ;; foo-bar => foo_bar
330 | (t
331 | (string-inflection-underscore-function str))))
332 |
333 | (defun string-inflection-ruby-style-cycle-function (str)
334 | "foo_bar => FOO_BAR => FooBar => foo_bar"
335 | (cond
336 | ((string-inflection-underscore-p str)
337 | (string-inflection-upcase-function str))
338 | ((string-inflection-upcase-p str)
339 | (string-inflection-pascal-case-function str))
340 | (t
341 | (string-inflection-underscore-function str))))
342 |
343 | (defalias 'string-inflection-python-style-cycle-function
344 | 'string-inflection-ruby-style-cycle-function)
345 |
346 | (defun string-inflection-elixir-style-cycle-function (str)
347 | "foo_bar => FooBar => foo_bar"
348 | (cond
349 | ((string-inflection-underscore-p str)
350 | (string-inflection-pascal-case-function str))
351 | (t
352 | (string-inflection-underscore-function str))))
353 |
354 | (defun string-inflection-java-style-cycle-function (str)
355 | "fooBar => FOO_BAR => FooBar => fooBar"
356 | (cond
357 | ((string-inflection-underscore-p str)
358 | (string-inflection-upcase-function str))
359 | ((string-inflection-camelcase-p str)
360 | (string-inflection-upcase-function str))
361 | ((string-inflection-upcase-p str)
362 | (string-inflection-pascal-case-function str))
363 | (t
364 | (string-inflection-camelcase-function str))))
365 |
366 | ;; Toggle function. But cycle function.
367 | (defun string-inflection-toggle-function (str)
368 | "Not so much the case that in all caps when using normal foo_bar <--> FooBar"
369 | (cond
370 | ((string-inflection-underscore-p str)
371 | (string-inflection-pascal-case-function str))
372 | ((string-inflection-pascal-case-p str)
373 | (string-inflection-camelcase-function str))
374 | (t
375 | (string-inflection-underscore-function str))))
376 |
377 | ;; --------------------------------------------------------------------------------
378 |
379 | (defun string-inflection-word-p (str)
380 | "if foo => t"
381 | (let ((case-fold-search nil))
382 | (string-match "\\`[[:lower:][:digit:]]+\\'" str)))
383 |
384 | (defun string-inflection-underscore-p (str)
385 | "if foo_bar => t"
386 | (let ((case-fold-search nil))
387 | (string-match "\\`[[:lower:][:digit:]_]+\\'" str)))
388 |
389 | (defun string-inflection-upcase-p (str)
390 | "if FOO_BAR => t"
391 | (let ((case-fold-search nil))
392 | (string-match "\\`[[:upper:][:digit:]_]+\\'" str)))
393 |
394 | (defun string-inflection-pascal-case-p (str)
395 | "if FooBar => t"
396 | (let ((case-fold-search nil))
397 | (and
398 | (string-match "[[:lower:]]" str)
399 | (string-match "\\`[[:upper:]][[:lower:][:upper:][:digit:]]+\\'" str))))
400 |
401 | (fset 'string-inflection-upper-camelcase-p 'string-inflection-pascal-case-p)
402 |
403 | (defun string-inflection-camelcase-p (str)
404 | "if fooBar => t"
405 | (let ((case-fold-search nil))
406 | (and
407 | (string-match "[[:upper:]]" str)
408 | (string-match "\\`[[:lower:]][[:lower:][:upper:][:digit:]]+\\'" str))))
409 |
410 | (fset 'string-inflection-lower-camelcase-p 'string-inflection-camelcase-p)
411 |
412 | (defun string-inflection-kebab-case-p (str)
413 | "if foo-bar => t"
414 | (string-match "-" str))
415 |
416 | (defun string-inflection-capital-underscore-p (str)
417 | "if Foo_Bar => t"
418 | (let ((case-fold-search nil))
419 | (and
420 | (string-match "_" str)
421 | (string-match "\\`[[:upper:]][[:lower:][:upper:][:digit:]_]+\\'" str))))
422 |
423 | (provide 'string-inflection)
424 | ;;; string-inflection.el ends here
425 |
--------------------------------------------------------------------------------
/test/string-inflection-test.el:
--------------------------------------------------------------------------------
1 | ;; -*- compile-command: "emacs --script string-inflection-test.el" -*-
2 |
3 | (setq load-path (cons ".." load-path))
4 | (setq load-path (cons "." load-path))
5 |
6 | (require 'string-inflection)
7 |
8 | (require 'ert)
9 |
10 | ;; -------------------------------------------------------------------------------- cycle function
11 |
12 | (ert-deftest test-ruby-style-cycle ()
13 | (should (equal "FOO_BAR" (string-inflection-ruby-style-cycle-function "foo_bar")))
14 | (should (equal "FooBar" (string-inflection-ruby-style-cycle-function "FOO_BAR")))
15 | (should (equal "foo_bar" (string-inflection-ruby-style-cycle-function "FooBar"))))
16 |
17 | (ert-deftest test-elixir-style-cycle ()
18 | (should (equal "foo_bar" (string-inflection-elixir-style-cycle-function "FOO_BAR")))
19 | (should (equal "FooBar" (string-inflection-elixir-style-cycle-function "foo_bar")))
20 | (should (equal "foo_bar" (string-inflection-elixir-style-cycle-function "FooBar"))))
21 |
22 | (ert-deftest test-java-style-cycle ()
23 | (should (equal "FOO_BAR" (string-inflection-java-style-cycle-function "foo_bar")))
24 | (should (equal "FOO_BAR" (string-inflection-java-style-cycle-function "fooBar")))
25 | (should (equal "FooBar" (string-inflection-java-style-cycle-function "FOO_BAR")))
26 | (should (equal "fooBar" (string-inflection-java-style-cycle-function "FooBar"))))
27 |
28 | (ert-deftest test-all-cycle ()
29 | (should (equal "FOO_BAR" (string-inflection-all-cycle-function "foo_bar")))
30 | (should (equal "FooBar" (string-inflection-all-cycle-function "FOO_BAR")))
31 | (should (equal "fooBar" (string-inflection-all-cycle-function "FooBar")))
32 | (should (equal "fooBar" (string-inflection-all-cycle-function "FooBar")))
33 | (should (equal "foo-bar" (string-inflection-all-cycle-function "fooBar")))
34 | (should (equal "Foo_Bar" (string-inflection-all-cycle-function "foo-bar")))
35 | (should (equal "foo_bar" (string-inflection-all-cycle-function "Foo_Bar"))))
36 |
37 | ; --------------------------------------------------------------------------------
38 |
39 | (ert-deftest test-underscore ()
40 | (should (equal "foo1_bar" (string-inflection-underscore-function "foo1_bar")))
41 | (should (equal "foo1_bar" (string-inflection-underscore-function "FOO1_BAR")))
42 | (should (equal "foo1bar" (string-inflection-underscore-function "foo1bar")))
43 | (should (equal "foo1_bar" (string-inflection-underscore-function "foo1__bar")))
44 | (should (equal "foo1_bar" (string-inflection-underscore-function "Foo1Bar")))
45 | (should (equal "foo1_bar" (string-inflection-underscore-function "FOO1Bar")))
46 | (should (equal "foo_bar" (string-inflection-underscore-function "FOO_BAR"))))
47 |
48 | (ert-deftest test-consecutive-uppercase ()
49 | (should (equal "a_single_line" (string-inflection-underscore-function "ASingleLine")))
50 | (should (equal "php_mode" (string-inflection-underscore-function "PHPMode")))
51 | (should (equal "ends_with_php" (string-inflection-underscore-function "EndsWithPHP")))
52 | (should (equal "php_and_xml_too" (string-inflection-underscore-function "PHPAndXMLToo")))
53 | (should (equal "php_and_xml_too" (string-inflection-underscore-function "phpAndXmlToo")))
54 | (should (equal "ph_pand_xm_ltoo" (string-inflection-underscore-function "PHPandXMLtoo")))
55 | (should (equal "eĥo_ŝanĝo_ĉiu_ĵaŭde" (string-inflection-underscore-function "EĤOŜanĝoĈIUĴaŭde"))))
56 |
57 | (ert-deftest test-pascal-case ()
58 | (should (equal "Foo1Bar" (string-inflection-pascal-case-function "Foo1Bar")))
59 | (should (equal "Eĥo1Ŝanĝo" (string-inflection-pascal-case-function "Eĥo1Ŝanĝo")))
60 | (should (equal "Foo1Bar" (string-inflection-pascal-case-function "FOO1_BAR")))
61 | (should (equal "Eĥo1Ŝanĝo" (string-inflection-pascal-case-function "EĤO1_ŜANĜO")))
62 | (should (equal "Foo1Bar" (string-inflection-pascal-case-function "FOO1__BAR")))
63 | (should (equal "Eĥo1Ŝanĝo" (string-inflection-pascal-case-function "EĤO1__ŜANĜO")))
64 | (should (equal "Foo" (string-inflection-pascal-case-function "foo")))
65 | (should (equal "Eĥo" (string-inflection-pascal-case-function "eĥo"))))
66 |
67 | (ert-deftest test-lower-camelcase ()
68 | (should (equal "fooBar" (string-inflection-camelcase-function "FooBar")))
69 | (should (equal "eĥoŜanĝo" (string-inflection-camelcase-function "EĥoŜanĝo")))
70 | (should (equal "foo1Bar" (string-inflection-camelcase-function "FOO1BAR")))
71 | (should (equal "eĥo1Ŝanĝo" (string-inflection-camelcase-function "EĤO1ŜANĜO"))))
72 |
73 | (ert-deftest test-kebab-case ()
74 | (should (equal "foo-bar" (string-inflection-kebab-case-function "FooBar")))
75 | (should (equal "eĥo-ŝanĝo" (string-inflection-kebab-case-function "EĥoŜanĝo"))))
76 |
77 | (ert-deftest test-toggle ()
78 | (should (equal "FooBar" (string-inflection-toggle-function "foo_bar")))
79 | (should (equal "EĥoŜanĝo" (string-inflection-toggle-function "eĥo_ŝanĝo")))
80 | (should (equal "fooBar" (string-inflection-toggle-function "FooBar")))
81 | (should (equal "eĥoŜanĝo" (string-inflection-toggle-function "EĥoŜanĝo")))
82 | (should (equal "ĉirkaŭIro" (string-inflection-toggle-function "ĈirkaŭIro")))
83 | (should (equal "foo_bar" (string-inflection-toggle-function "FOO_BAR")))
84 | (should (equal "eĥo_ŝanĝo" (string-inflection-toggle-function "EĤO_ŜANĜO"))))
85 |
86 | (ert-deftest test-upcase ()
87 | (should (equal "FOO1_BAR" (string-inflection-upcase-function "foo1_bar")))
88 | (should (equal "EĤO1_ŜANĜO" (string-inflection-upcase-function "eĥo1_ŝanĝo")))
89 | (should (equal "FOO1_BAR" (string-inflection-upcase-function "Foo1Bar")))
90 | (should (equal "EĤO1_ŜANĜO" (string-inflection-upcase-function "Eĥo1Ŝanĝo")))
91 | (should (equal "FOO_BAR" (string-inflection-upcase-function "Foo_bar")))
92 | (should (equal "EĤO_ŜANĜO" (string-inflection-upcase-function "Eĥo_ŝanĝo"))))
93 |
94 | (ert-deftest test-capital-underscore ()
95 | (should (equal "Foo1_Bar" (string-inflection-capital-underscore-function "foo1_bar")))
96 | (should (equal "Eĥo1_Ŝanĝo" (string-inflection-capital-underscore-function "eĥo1_ŝanĝo")))
97 | (should (equal "Foo1_Bar" (string-inflection-capital-underscore-function "FOO1_BAR")))
98 | (should (equal "Eĥo1_Ŝanĝo" (string-inflection-capital-underscore-function "EĤO1_ŜANĜO")))
99 | (should (equal "Foo1bar" (string-inflection-capital-underscore-function "foo1bar")))
100 | (should (equal "Eĥo1ŝanĝo" (string-inflection-capital-underscore-function "eĥo1ŝanĝo")))
101 | (should (equal "Foo1_Bar" (string-inflection-capital-underscore-function "foo1__bar")))
102 | (should (equal "Eĥo1_Ŝanĝo" (string-inflection-capital-underscore-function "eĥo1__ŝanĝo")))
103 | (should (equal "Foo1_Bar" (string-inflection-capital-underscore-function "Foo1Bar")))
104 | (should (equal "Eĥo1_Ŝanĝo" (string-inflection-capital-underscore-function "Eĥo1Ŝanĝo")))
105 | (should (equal "Foo1_Bar" (string-inflection-capital-underscore-function "FOO1Bar")))
106 | (should (equal "Eĥo1_Ŝanĝo" (string-inflection-capital-underscore-function "EĤO1Ŝanĝo")))
107 | (should (equal "Foo_Bar" (string-inflection-capital-underscore-function "FOO_BAR")))
108 | (should (equal "Eĥo_Ŝanĝo" (string-inflection-capital-underscore-function "EĤO_ŜANĜO"))))
109 |
110 | ;; --------------------------------------------------------------------------------
111 |
112 | (ert-deftest test-word-p ()
113 | (should (string-inflection-word-p "foo"))
114 | (should (string-inflection-word-p "eĥo"))
115 | (should-not (string-inflection-word-p "foo_bar"))
116 | (should-not (string-inflection-word-p "eĥo_ŝanĝo")))
117 |
118 | (ert-deftest test-underscore-p ()
119 | (should (string-inflection-underscore-p "foo"))
120 | (should (string-inflection-underscore-p "eĥo"))
121 | (should (string-inflection-underscore-p "foo_bar"))
122 | (should (string-inflection-underscore-p "eĥo_ŝanĝo")))
123 |
124 | (ert-deftest test-pascal-case-p ()
125 | (should (string-inflection-pascal-case-p "Foo"))
126 | (should (string-inflection-pascal-case-p "Eĥo"))
127 | (should (string-inflection-pascal-case-p "FooBar"))
128 | (should (string-inflection-pascal-case-p "EĥoŜanĝo"))
129 | (should-not (string-inflection-pascal-case-p "FOO"))
130 | (should (string-inflection-pascal-case-p "Eĥĥ")))
131 |
132 | (ert-deftest test-camelcase-p ()
133 | (should-not (string-inflection-camelcase-p "foo"))
134 | (should-not (string-inflection-camelcase-p "eĥo"))
135 | (should (string-inflection-camelcase-p "fooBar"))
136 | (should (string-inflection-camelcase-p "eĥoŜanĝo")))
137 |
138 | (ert-deftest test-lower-upcase-p ()
139 | (should (string-inflection-upcase-p "FOO"))
140 | (should (string-inflection-upcase-p "EĤO"))
141 | (should (string-inflection-upcase-p "FOO_BAR"))
142 | (should (string-inflection-upcase-p "EĤO_ŜANĜO")))
143 |
144 | (ert-deftest test-kebab-case-p ()
145 | (should (string-inflection-kebab-case-p "foo-bar"))
146 | (should (string-inflection-kebab-case-p "eĥo-ŝanĝo")))
147 |
148 | (ert-deftest test-capital-underscore-p ()
149 | (should (string-inflection-capital-underscore-p "Foo_Bar"))
150 | (should (string-inflection-capital-underscore-p "Eĥo_Ŝanĝo")))
151 |
152 | ;; -------------------------------------------------------------------------------- Target word of cursor position
153 |
154 | (defun buffer-try (str position &optional mode-func)
155 | (with-temp-buffer
156 | (funcall (or mode-func #'fundamental-mode))
157 | (insert str)
158 | (goto-char (apply position))
159 | (prog1
160 | (string-inflection-get-current-word)
161 | (kill-this-buffer))))
162 |
163 | (ert-deftest test-get-current-word-on-cursor ()
164 | (should (equal "foo" (buffer-try "foo" '(point-max))))
165 | (should (equal "eĥo" (buffer-try "eĥo" '(point-max))))
166 | (should (equal "foo" (buffer-try "foo" '(point-min))))
167 | (should (equal "eĥo" (buffer-try "eĥo" '(point-min))))
168 | (should (equal "" (buffer-try "" '(point-max))))
169 | (should (equal "foo" (buffer-try "foo->bar" '(point-min) #'c-mode)))
170 | (should (equal "eĥo" (buffer-try "eĥo->ŝanĝo" '(point-min) #'c-mode)))
171 | (should (equal "foo-" (buffer-try "foo-" '(point-min))))
172 | (should (equal "eĥo-" (buffer-try "eĥo-" '(point-min))))
173 | (should (equal "foo" (buffer-try "foo-" '(point-min) #'python-mode)))
174 | (should (equal "eĥo" (buffer-try "eĥo-" '(point-min) #'python-mode)))
175 | )
176 |
177 | ;; -------------------------------------------------------------------------------- Target all of region
178 |
179 | (defun region-try-inflect (str &optional inflect mode-func)
180 | (with-temp-buffer
181 | (funcall (or mode-func #'fundamental-mode))
182 | (insert str)
183 | (set-mark (point-min))
184 | (goto-char (point-max))
185 | (activate-mark)
186 | (funcall (or inflect #'string-inflection-toggle))
187 | (buffer-string)))
188 |
189 | (ert-deftest test-inflect-toggle-in-region ()
190 | (should (equal "Foo" (region-try-inflect "foo"))) ; It was underscore when old version.
191 | (should (equal "Foo Bar" (region-try-inflect "foo bar"))) ; It was underscore when old version.
192 | (should (equal "Foo Bar Baz" (region-try-inflect "foo bar baz")))
193 | (should (equal "FooBar BarFoo" (region-try-inflect "foo_bar bar_foo")))
194 | (should (equal "Foo:Bar" (region-try-inflect "foo:bar"))) ; It was underscore when old version.
195 | (should (equal "Foo::Bar" (region-try-inflect "foo::bar"))) ; It was underscore when old version.
196 | (should (equal "Foo.Bar" (region-try-inflect "foo.bar")))
197 | (should (equal "Foo().Bar" (region-try-inflect "foo().bar")))
198 | (should (equal "Foo()->Bar" (region-try-inflect "foo()->bar" #'string-inflection-toggle #'c-mode)))
199 | )
200 |
201 | (ert-deftest test-inflect-in-region ()
202 | (should (equal "FooBar" (region-try-inflect "foo_bar" #'string-inflection-camelcase)))
203 | (should (equal "FooBar BarFoo" (region-try-inflect "foo_bar bar-foo" #'string-inflection-camelcase)))
204 | (should (equal "fooBar barFoo" (region-try-inflect "foo_bar bar-foo" #'string-inflection-lower-camelcase)))
205 | (should (equal "foo_bar bar_foo" (region-try-inflect "FooBar bar-foo" #'string-inflection-underscore)))
206 | (should (equal "Foo_Bar Bar_Foo" (region-try-inflect "FooBar bar-foo" #'string-inflection-capital-underscore)))
207 | (should (equal "FOO_BAR BAR_FOO" (region-try-inflect "FooBar bar-foo" #'string-inflection-upcase)))
208 | (should (equal "foo-bar bar-foo" (region-try-inflect "FooBar bar_foo" #'string-inflection-kebab-case)))
209 |
210 | ;; https://github.com/akicho8/string-inflection/issues/34
211 | (should (equal ":foo-bar bar" (region-try-inflect ":fooBar bar" #'string-inflection-kebab-case)))
212 |
213 | ;; https://github.com/akicho8/string-inflection/issues/31
214 | (should (equal "\nfoo_bar\nbar_foo\n" (region-try-inflect "\nFooBar\nbar-foo\n" #'string-inflection-underscore)))
215 |
216 | ;; https://github.com/akicho8/string-inflection/issues/30
217 | (should (equal "obj_name->meth_name\nobj1_name->meth1_name"
218 | (region-try-inflect "ObjName->MethName\nObj1Name->Meth1Name" #'string-inflection-underscore #'c++-mode)))
219 | )
220 |
221 | (ert-deftest test-cycle-in-region ()
222 | (should (equal "FOO_BAR FooBar foo_bar"
223 | (region-try-inflect "foo_bar FOO_BAR FooBar" #'string-inflection-ruby-style-cycle)))
224 | (should (equal "FooBar foo_bar"
225 | (region-try-inflect "foo_bar FooBar" #'string-inflection-elixir-style-cycle)))
226 | (should (equal "foo_bar FOO_BAR FooBar foo_bar"
227 | (region-try-inflect "fooBar foo_bar FOO_BAR FooBar" #'string-inflection-python-style-cycle)))
228 | (should (equal "FOO_BAR FooBar fooBar"
229 | (region-try-inflect "foo_bar FOO_BAR FooBar" #'string-inflection-java-style-cycle)))
230 | (should (equal "FOO_BAR FooBar fooBar foo-bar Foo_Bar foo_bar"
231 | (region-try-inflect "foo_bar FOO_BAR FooBar fooBar foo-bar Foo_Bar" #'string-inflection-all-cycle)))
232 | )
233 |
234 | (defun buffer-try-inflect (str inflect)
235 | (with-temp-buffer
236 | (c-mode)
237 | (insert str)
238 | (goto-char (point-min))
239 | (funcall inflect)
240 | (buffer-string)))
241 |
242 | (ert-deftest test-buffer-toggle ()
243 | (should (equal "foo_bar" (buffer-try-inflect "fooBar" 'string-inflection-toggle))))
244 |
245 | (ert-deftest test-buffer-underscore ()
246 | ;; https://github.com/akicho8/string-inflection/issues/30
247 | (should (equal "object_name->method" (buffer-try-inflect "objectName->method" 'string-inflection-underscore)))
248 | (should (equal "object1_name->method" (buffer-try-inflect "object1Name->method" 'string-inflection-underscore)))
249 | (should (equal "eĥo_ŝanĝo->ĉiuĴaŭde" (buffer-try-inflect "eĥoŜanĝo->ĉiuĴaŭde" 'string-inflection-underscore))))
250 |
251 | (ert-deftest test-buffer-camelcase ()
252 | (should (equal "ObjectName->method" (buffer-try-inflect "object_name->method" 'string-inflection-camelcase)))
253 | (should (equal "Object1Name->method" (buffer-try-inflect "object1_name->method" 'string-inflection-camelcase)))
254 | (should (equal "EĥoŜanĝo->ĉiuĴaŭde" (buffer-try-inflect "eĥo_ŝanĝo->ĉiuĴaŭde" 'string-inflection-camelcase))))
255 |
256 | (ert-deftest test-buffer-lower-camelcase ()
257 | (should (equal "objectName->method" (buffer-try-inflect "object_name->method" 'string-inflection-lower-camelcase)))
258 | (should (equal "object1Name->method" (buffer-try-inflect "object1_name->method" 'string-inflection-lower-camelcase)))
259 | (should (equal "eĥoŜanĝo->ĉiuĴaŭde" (buffer-try-inflect "eĥo_ŝanĝo->ĉiuĴaŭde" 'string-inflection-lower-camelcase))))
260 |
261 |
262 | (defun buffer-try-final-pos (str final-pos inflect initial-pos)
263 | (with-temp-buffer
264 | (setq-local string-inflection-final-position final-pos)
265 | (insert (concat str " fooo"))
266 | (goto-char initial-pos)
267 | (funcall inflect)
268 | (should-not (use-region-p))
269 | (point)))
270 |
271 | (ert-deftest test-buffer-remain-simple-lengthen ()
272 | (should (equal (buffer-try-final-pos "FooBar" 'remain #'string-inflection-underscore 2) 2)))
273 |
274 | (ert-deftest test-buffer-end-simple-lengthen ()
275 | (should (equal (buffer-try-final-pos "FooBar" 'end #'string-inflection-underscore 2) 8)))
276 |
277 | (ert-deftest test-buffer-beginning-simple-lengthen ()
278 | (should (equal (buffer-try-final-pos "FooBar" 'beginning #'string-inflection-underscore 2) 1)))
279 |
280 | (ert-deftest test-buffer-remain-simple-shorten-not-at-end ()
281 | (should (equal (buffer-try-final-pos "foo_bar" 'remain #'string-inflection-camelcase 8) 7)))
282 |
283 | (ert-deftest test-buffer-remain-simple-shorten-at-end ()
284 | (should (equal (buffer-try-final-pos "foo_bar" 'remain #'string-inflection-camelcase 2) 2)))
285 |
286 | (ert-deftest test-buffer-end-simple-shorten ()
287 | (should (equal (buffer-try-final-pos "foo_bar" 'end #'string-inflection-camelcase 2) 7)))
288 |
289 | (ert-deftest test-buffer-beginning-simple-shorten ()
290 | (should (equal (buffer-try-final-pos "foo_bar" 'beginning #'string-inflection-camelcase 2) 1)))
291 |
292 |
293 | (defun region-try-final-pos (str final-pos inverse)
294 | (with-temp-buffer
295 | (setq-local string-inflection-final-position final-pos)
296 | (insert str)
297 | (let ((final-point (point-max)))
298 | (insert " foooo")
299 | (if inverse
300 | (progn (set-mark final-point) (goto-char (point-min)))
301 | (set-mark (point-min)) (goto-char final-point))
302 | (activate-mark))
303 | (string-inflection-underscore)
304 | (should (use-region-p))
305 | (should-not deactivate-mark)
306 | (cons (point) (cons (region-beginning) (region-end)))))
307 |
308 |
309 | (ert-deftest test-buffer-remain-region-straight ()
310 | (let* ((state (region-try-final-pos "FooBar" 'remain nil))
311 | (final-pos (car state))
312 | (region (cdr state))
313 | (beginning (car region))
314 | (end (cdr region)))
315 | (should (equal beginning 1))
316 | (should (equal end 8))
317 | (should (equal final-pos 8))))
318 |
319 |
320 | (ert-deftest test-buffer-remain-region-inversed ()
321 | (let* ((state (region-try-final-pos "FooBar" 'remain t))
322 | (final-pos (car state))
323 | (region (cdr state))
324 | (beginning (car region))
325 | (end (cdr region)))
326 | (should (equal beginning 1))
327 | (should (equal end 8))
328 | (should (equal final-pos 1))))
329 |
330 |
331 | (ert-deftest test-buffer-end-region-straight ()
332 | (let* ((state (region-try-final-pos "FooBar" 'end nil))
333 | (final-pos (car state))
334 | (region (cdr state))
335 | (beginning (car region))
336 | (end (cdr region)))
337 | (should (equal beginning 1))
338 | (should (equal end 8))
339 | (should (equal final-pos 8))))
340 |
341 |
342 | (ert-deftest test-buffer-end-region-inverse ()
343 | (let* ((state (region-try-final-pos "FooBar" 'end t))
344 | (final-pos (car state))
345 | (region (cdr state))
346 | (beginning (car region))
347 | (end (cdr region)))
348 | (should (equal beginning 1))
349 | (should (equal end 8))
350 | (should (equal final-pos 8))))
351 |
352 |
353 | (ert-deftest test-buffer-beginning-region-straight ()
354 | (let* ((state (region-try-final-pos "FooBar" 'beginning nil))
355 | (final-pos (car state))
356 | (region (cdr state))
357 | (beginning (car region))
358 | (end (cdr region)))
359 | (should (equal beginning 1))
360 | (should (equal end 8))
361 | (should (equal final-pos 1))))
362 |
363 |
364 | (ert-deftest test-buffer-beginning-region-inverse ()
365 | (let* ((state (region-try-final-pos "FooBar" 'beginning t))
366 | (final-pos (car state))
367 | (region (cdr state))
368 | (beginning (car region))
369 | (end (cdr region)))
370 | (should (equal beginning 1))
371 | (should (equal end 8))
372 | (should (equal final-pos 1))))
373 |
374 |
375 | (defun mixed-region-cycle-try (start end)
376 | (with-temp-buffer
377 | (text-mode)
378 | (insert "someFunction_to_do_SomeThing FoofooBarbarBarbarFoofoo")
379 | (set-mark start)
380 | (goto-char end)
381 | (activate-mark)
382 | (string-inflection-cycle)
383 | (cons (buffer-string) (cons (region-beginning) (region-end)))))
384 |
385 |
386 | (ert-deftest test-mixed-symbol-cycle-region-1 ()
387 | (should (equal (car (mixed-region-cycle-try 1 13))
388 | "some_function_to_do_SomeThing FoofooBarbarBarbarFoofoo")))
389 |
390 |
391 | (ert-deftest test-mixed-symbol-cycle-region-2 ()
392 | (should (equal (car (mixed-region-cycle-try 14 19))
393 | "someFunction_TO_DO_SomeThing FoofooBarbarBarbarFoofoo")))
394 |
395 |
396 | (ert-deftest test-mixed-symbol-cycle-region-3 ()
397 | (should (equal (car (mixed-region-cycle-try 20 29))
398 | "someFunction_to_do_some_thing FoofooBarbarBarbarFoofoo")))
399 |
400 |
401 | (ert-deftest test-mixed-symbol-cycle-region-4 ()
402 | (should (equal (car (mixed-region-cycle-try 20 41))
403 | "someFunction_to_do_some_thing foofoo_barbarBarbarFoofoo")))
404 |
405 |
406 | (ert-deftest test-mixed-symbol-cycle-region-restore-region ()
407 | (should (equal (cdr (mixed-region-cycle-try 20 41)) (cons 20 43))))
408 |
409 |
410 | (ert-run-tests-batch t)
411 |
--------------------------------------------------------------------------------