Repository: akicho8/string-inflection
Branch: master
Commit: 4a2f87d7b47f
Files: 6
Total size: 52.4 KB
Directory structure:
gitextract_tlr7_gab/
├── .gitignore
├── .travis.yml
├── HISTORY.org
├── README.org
├── string-inflection.el
└── test/
└── string-inflection-test.el
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
/*.html
ert.*
*.elc
================================================
FILE: .travis.yml
================================================
language: emacs-lisp
env:
- EMACS=emacs24
- EMACS=emacs-snapshot
matrix:
allow_failures:
- env: EMACS=emacs-snapshot
before_install:
# Install Emacs
- sudo add-apt-repository -y ppa:cassou/emacs
- sudo add-apt-repository -y ppa:ubuntu-elisp
- sudo apt-get update -qq
- sudo apt-get install -qq $EMACS
# # Install Cask
# - curl -fsSkL --max-time 10 --retry 10 --retry-delay 10
# https://raw.github.com/cask/cask/master/go | python
# - export PATH="$HOME/.cask/bin:$PATH"
# - cask
script:
$EMACS --script test/string-inflection-test.el
================================================
FILE: HISTORY.org
================================================
* HISTORY
** Version 1.2.1
The feature that converts spaces in a selected region into underscores is useful when turning English text into method names. It had disappeared over time, and at first I thought it might not be essential, but I quickly realized it was extremely inconvenient without it, so I brought it back. Since many others are likely to find this equally inconvenient, I've made it the default.
If you don't need this feature and prefer to convert each symbol individually, you can do so with the following setting.
=(setq string-inflection-region-selection-behavior 'apply-to-each-symbols)=
** Version 1.2.0
- [[https://github.com/akicho8/string-inflection/pull/44][#44]] Create function for custom selection of string used for inflection
The conversion target range has been changed to vary depending on the mode since the previous version, but if you prefer the previous behavior that was independent of the mode, you can do the following:
=(setq string-inflection-bounds-function 'string-inflection-bounds-of-mode-independent-chunk)=
- [[https://github.com/akicho8/string-inflection/issues/46][#46]] Refactoring of the general name
I've revised some method names that were previously a bit awkward.
The main changes are:
- camelcase -> camel-case
- underscore -> snake-case
- cursor -> point
- word -> symbol
For now, I've kept the old methods using fset, but I might remove them in the future.
** Version 1.1.0
- Support non ascii [[https://github.com/akicho8/string-inflection/pull/39][#39]]
- Use (bounds-of-thing-at-point) for word detection [[https://github.com/akicho8/string-inflection/pull/41][#41]]
- Implement string-inflect-final-position [[https://github.com/akicho8/string-inflection/pull/43][#43]]
=string-inflection-skip-backward-when-done= is deprecated.
Use the =string-inflection-final-position= option instead.
However, leaving it as the default seems to be the easiest to use.
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.
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.
** Version 1.0.16
Fix [[https://github.com/akicho8/string-inflection/issues/34][#34]] kebabing a region can insert an unexpected hyphen
add =string-inflection-erase-chars-when-region= variable
Changed behavior when selecting region.
#+BEGIN_SRC
before: Foo::Bar --> foo_bar
after: Foo::Bar --> foo::bar
#+END_SRC
Include =:= in =string-inflection-erase-chars-when-region= if want to behave as before.
** Version 1.0.14
Merged [[https://github.com/akicho8/string-inflection/pull/32][PR #32]] Use defcustom and Change Some Wording
** Version 1.0.13
Fix [[https://github.com/akicho8/string-inflection/issues/31][#31]] Better Whitespace Handling When Converting a Region
** Version 1.0.12
Fix [[https://github.com/akicho8/string-inflection/issues/30][#30]] string-inflection-underscore affects C++ method accessors
#+BEGIN_SRC
before: fooBar->method --> foo_bar_>method
after: fooBar->method --> foo_bar->method
#+END_SRC
** Version 1.0.11
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
** Version 1.0.10
Merged [[https://github.com/akicho8/string-inflection/pull/26][PR #26]] Add `Capital_Underscore_Form`
add string-inflection-capital-underscore function
The behavior of =string-inflection-all-cycle= has changed
#+BEGIN_SRC
before: foo_bar => FOO_BAR => FooBar => fooBar => foo-bar => foo_bar
after: foo_bar => FOO_BAR => FooBar => fooBar => foo-bar => Foo_Bar => foo_bar
#+END_SRC
** Version 1.0.9
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
** Version 1.0.8
[[https://github.com/akicho8/string-inflection/issues/25][issue #25]]
When it is simply =camel-case=, it means the name with the leading letters in lowercase.
The name with the initial capital letter is called the =pascal-case=.
*** Behavior of the camel-case function has changed
| Before | After |
|--------+--------|
| FooBar | fooBar |
*** Function name changed as well
| Before | After |
|-----------------+-------------|
| camel-case | pascal-case |
| lower-camel-case | camel-case |
*** Add alias
#+BEGIN_SRC elisp
(fset 'string-inflection-upper-camel-case-function 'string-inflection-pascal-case-function)
(fset 'string-inflection-lower-camel-case-function 'string-inflection-camel-case-function)
(fset 'string-inflection-upper-camel-case-p 'string-inflection-pascal-case-p)
(fset 'string-inflection-lower-camel-case-p 'string-inflection-camel-case-p)
#+END_SRC
*** Remove camelize function
Originally we had defined functions of both =camel-case= and =camelize= names.
I deleted the function containing =camelize= to make it simple.
================================================
FILE: README.org
================================================
* foo_bar -> FOO_BAR -> FooBar -> fooBar -> foo-bar -> Foo_Bar -> foo_bar conversion of names
#+html:
#+html:
#+html:
[[https://github.com/akicho8/string-inflection/blob/main/HISTORY.org][Change History]]
** Configuration Examples
*** Example 1
#+BEGIN_SRC elisp
(require 'string-inflection)
;; C-q C-u is similar to the keybinding used by Vz Editor.
(global-unset-key (kbd "C-q"))
(global-set-key (kbd "C-q C-u") 'my-string-inflection-cycle-auto)
(defun my-string-inflection-cycle-auto ()
"switching by major-mode"
(interactive)
(cond
;; for emacs-lisp-mode
((eq major-mode 'emacs-lisp-mode)
(string-inflection-all-cycle))
;; for python
((eq major-mode 'python-mode)
(string-inflection-python-style-cycle))
;; for java
((eq major-mode 'java-mode)
(string-inflection-java-style-cycle))
;; for elixir
((eq major-mode 'elixir-mode)
(string-inflection-elixir-style-cycle))
(t
;; default
(string-inflection-ruby-style-cycle))))
#+END_SRC
*** Example 2
#+BEGIN_SRC elisp
(require 'string-inflection)
;; default
(global-set-key (kbd "C-c C-u") 'string-inflection-all-cycle)
;; for ruby
(add-hook 'ruby-mode-hook
'(lambda ()
(local-set-key (kbd "C-c C-u") 'string-inflection-ruby-style-cycle)))
;; for elixir
(add-hook 'elixir-mode-hook
'(lambda ()
(local-set-key (kbd "C-c C-u") 'string-inflection-elixir-style-cycle)))
;; for java
(add-hook 'java-mode-hook
'(lambda ()
(local-set-key (kbd "C-c C-u") 'string-inflection-java-style-cycle)))
;; for python
(add-hook 'python-mode-hook
'(lambda ()
(local-set-key (kbd "C-c C-u") 'string-inflection-python-style-cycle)))
#+END_SRC
** How to Use
For each of the following, place the point at =emacs_lisp= and type =C-q C-u=, the results will be as follows:
In the case of =string-inflection-ruby-style-cycle=
: emacs_lisp => EMACS_LISP => EmacsLisp => emacs_lisp
In the case of =string-inflection-elixir-style-cycle=
: emacs_lisp => EmacsLisp => emacs_lisp
In the case of =string-inflection-python-style-cycle=
: emacs_lisp => EMACS_LISP => EmacsLisp => emacs_lisp
In the case of =string-inflection-java-style-cycle=
: emacsLisp => EMACS_LISP => EmacsLisp => emacsLisp
In the case of =string-inflection-all-cycle=
: emacs_lisp => EMACS_LISP => EmacsLisp => emacsLisp => emacs-lisp => Emacs_Lisp => emacs_lisp
It is recommended that the major mode functions are used instead of =string-inflection-all-cycle=.
** Standalone Functions
#+BEGIN_SRC elisp
(string-inflection-snake-case-function "EmacsLisp") ; => "emacs_lisp"
(string-inflection-pascal-case-function "emacs_lisp") ; => "EmacsLisp"
(string-inflection-camel-case-function "emacs_lisp") ; => "emacsLisp"
(string-inflection-upcase-function "emacs_lisp") ; => "EMACS_LISP"
(string-inflection-kebab-case-function "emacs_lisp") ; => "emacs-lisp"
(string-inflection-capital-snake-case-function "emacs_lisp") ; => "Emacs_Lisp"
(string-inflection-pascal-case-p "EmacsLisp") ; => t
(string-inflection-pascal-case-p "emacs_lisp") ; => nil
; etc...
#+END_SRC
** Region usage
You can also use this library to convert a region's casing. That applies the
operation to all symbols of the region. If a symbol is only partially covered
by the region, the operation is performed only on that part.
For that, simply select a region and perform =M-x string-inflection-kebab-case= (or any such other function).
** Other configuration options
You can configure where the point shall finish after the inflection operation
using the =string-inflection-final-position= customization option.
** Do not use =string-inflection-all-cycle=
At first glance, this method may seem convenient, but in reality, it was created solely for testing purposes during development. Its role is to verify that all transformation patterns are properly traversed, and it was never intended for regular use. In fact, the developers themselves do not use it at all and strongly discourage its use.
Using this method in practice leads to unnecessary stress, as it forces traversal through every possible transformation pattern, making the conversion process excessively long. Moreover, under the current default settings, the method may not even complete a full cycle depending on the mode in use.
For example, in modes where hyphens are not considered part of variable names, a string like =foo-bar= will be split into =foo= and =bar=, and the transformation will only proceed on =bar=. This means the intended conversion process can be interrupted midway depending on the context.
For these reasons, this method should not be used as part of your regular workflow. It is strictly meant for internal verification during development, and we advise against using it in day-to-day usage.
** Restoring Mode-Agnostic Behavior (Legacy Chunk-Based Matching)
In the past, the transformation target was determined based on character syntax alone, regardless of major mode. Specifically, it would act on a "chunk" near the point that looked like an English-style variable name.
Now, however, the behavior has been improved: the transformation target is determined by the symbol boundaries defined by each major mode. This means the scope of what is considered a variable name is now more precise and language-aware.
Additionally, this abstraction allows the transformation of words containing non-ASCII characters, such as umlauts.
That said, there are cases where the old, mode-agnostic behavior is still more convenient. If you prefer the previous approach, you can restore it by setting the following:
#+BEGIN_SRC elisp
(setq string-inflection-bounds-function
(lambda ()
(cons
(progn (skip-chars-forward "a-zA-Z0-9_-")
(skip-chars-backward "_-")
(point))
(progn (skip-chars-backward "a-zA-Z0-9_-")
(skip-chars-forward "_-")
(point)))))
#+END_SRC
or
#+BEGIN_SRC elisp
(setq string-inflection-bounds-function 'string-inflection-bounds-of-mode-independent-chunk)
#+END_SRC
This method is quite useful and recommended for certain use cases.
================================================
FILE: string-inflection.el
================================================
;;; string-inflection.el --- foo_bar => FOO_BAR => FooBar => fooBar => foo-bar => Foo_Bar => foo_bar conversion of names -*- lexical-binding: t -*-
;; Copyright (C) 2004-2025 Free Software Foundation, Inc.
;; Author: akicho8
;; Keywords: elisp
;; Version: 1.2.1
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; There are three main functions:
;;
;; 1. For Ruby -> string-inflection-ruby-style-cycle (foo_bar => FOO_BAR => FooBar => foo_bar)
;; 2. For Elixir -> string-inflection-elixir-style-cycle (foo_bar => FooBar => foo_bar)
;; 3. For Python -> string-inflection-python-style-cycle (foo_bar => FOO_BAR => FooBar => foo_bar)
;; 4. For Java -> string-inflection-java-style-cycle (fooBar => FOO_BAR => FooBar => fooBar)
;; 5. For All -> string-inflection-all-cycle (foo_bar => FOO_BAR => FooBar => fooBar => foo-bar => Foo_Bar => foo_bar)
;;
;;
;; Example 1:
;;
;; (require 'string-inflection)
;; (global-unset-key (kbd "C-q"))
;; ;; C-q C-u is the key bindings similar to Vz Editor.
;; (global-set-key (kbd "C-q C-u") 'my-string-inflection-cycle-auto)
;;
;; (defun my-string-inflection-cycle-auto ()
;; "switching by major-mode"
;; (interactive)
;; (cond
;; ;; for emacs-lisp-mode
;; ((eq major-mode 'emacs-lisp-mode)
;; (string-inflection-all-cycle))
;; ;; for java
;; ((eq major-mode 'java-mode)
;; (string-inflection-java-style-cycle))
;; ;; for python
;; ((eq major-mode 'python-mode)
;; (string-inflection-python-style-cycle))
;; ;; for elixir
;; ((eq major-mode 'elixir-mode)
;; (string-inflection-elixir-style-cycle))
;; (t
;; ;; default
;; (string-inflection-ruby-style-cycle))))
;;
;;
;; Example 2:
;;
;; (require 'string-inflection)
;;
;; ;; default
;; (global-set-key (kbd "C-c C-u") 'string-inflection-all-cycle)
;;
;; ;; for ruby
;; (add-hook 'ruby-mode-hook
;; '(lambda ()
;; (local-set-key (kbd "C-c C-u") 'string-inflection-ruby-style-cycle)))
;;
;; ;; for elixir
;; (add-hook 'elixir-mode-hook
;; '(lambda ()
;; (local-set-key (kbd "C-c C-u") 'string-inflection-elixir-style-cycle)))
;;
;; ;; for python
;; (add-hook 'python-mode-hook
;; '(lambda ()
;; (local-set-key (kbd "C-c C-u") 'string-inflection-python-style-cycle)))
;;
;; ;; for java
;; (add-hook 'java-mode-hook
;; '(lambda ()
;; (local-set-key (kbd "C-c C-u") 'string-inflection-java-style-cycle)))
;;
;; You can configure where the point should end up after the inflection using the
;; `string-inflection-final-position' option.
;;
;; When a region is active during the inflect operation there are two effects:
;;
;; * If the region marks a part of a symbol the operation is only performed on that
;; part.
;; * If the region contains more than one symbols, the operation is performed on all
;; the symbols in the region.
;; * The region is preserved after the operation.
;;; Code:
(defgroup string-inflection nil
"Change the casing of symbols."
:group 'convenience)
(defcustom string-inflection-final-position 'remain
"Where to finish after the inflection.
This can be `remain' – remain at the initial position but not beyond the end of the inflected string –,
`beginning' – jump to the beginning of the inflection – or
`end' – jump to the end of the inflection."
:group 'string-inflection
:type '(choice (const remain) (const beginning) (const end)))
(defcustom string-inflection-bounds-function (lambda () (bounds-of-thing-at-point 'symbol))
"The function used select strings for inflections.
It should take no arguments and return a cons cell, the car of which should be
the point in the current buffer of the beginning of the string, and the cdr the
point in the current buffer of the end of the string."
:group 'string-inflection
:type 'function)
(defun string-inflection-bounds-of-mode-independent-chunk ()
"In the old specification, it does not depend on mode, but rather uses a chunk like a variable name as a symbol.
Use it like this:
(setq string-inflection-bounds-function 'string-inflection-bounds-of-mode-independent-chunk)"
(cons
(progn (skip-chars-forward "a-zA-Z0-9_-")
(skip-chars-backward "_-")
(point))
(progn (skip-chars-backward "a-zA-Z0-9_-")
(skip-chars-forward "_-")
(point))))
(defcustom string-inflection-region-selection-behavior 'replace-all-spaces-with-underscores
"Behavior applied when a region is selected.
- `replace-all-spaces-with-underscores` : Replace consecutive whitespace with a single underscore.
- `apply-to-each-symbols` : Apply conversion to each symbol in the region (no automatic underscore replacement)."
:type '(choice (const :tag "Convert whitespace to underscores" replace-all-spaces-with-underscores)
(const :tag "Apply conversion to each symbol" apply-to-each-symbols))
:group 'string-inflection)
;; --------------------------------------------------------------------------------
;;;###autoload
(defun string-inflection-ruby-style-cycle ()
"foo_bar => FOO_BAR => FooBar => foo_bar"
(interactive)
(string-inflection--symbol-or-region #'string-inflection-ruby-style-cycle-function))
(fset 'string-inflection-cycle 'string-inflection-ruby-style-cycle)
;;;###autoload
(defun string-inflection-elixir-style-cycle ()
"foo_bar => FooBar => foo_bar"
(interactive)
(string-inflection--symbol-or-region #'string-inflection-elixir-style-cycle-function))
;;;###autoload
(defun string-inflection-python-style-cycle ()
"foo_bar => FOO_BAR => FooBar => foo_bar"
(interactive)
(string-inflection--symbol-or-region #'string-inflection-python-style-cycle-function))
;;;###autoload
(defun string-inflection-java-style-cycle ()
"fooBar => FOO_BAR => FooBar => fooBar"
(interactive)
(string-inflection--symbol-or-region #'string-inflection-java-style-cycle-function))
;;;###autoload
(defun string-inflection-all-cycle ()
"foo_bar => FOO_BAR => FooBar => fooBar => foo-bar => Foo_Bar => foo_bar
At first glance, this method may seem convenient, but in reality, it was created solely for testing purposes during development. Its role is to verify that all transformation patterns are properly traversed, and it was never intended for regular use. In fact, the developers themselves do not use it at all and strongly discourage its use.
Using this method in practice leads to unnecessary stress, as it forces traversal through every possible transformation pattern, making the conversion process excessively long. Moreover, under the current default settings, the method may not even complete a full cycle depending on the mode in use.
For example, in modes where hyphens are not considered part of variable names, a string like `foo-bar' will be split into `foo' and `bar', and the transformation will only proceed on `bar'. This means the intended conversion process can be interrupted midway depending on the context.
For these reasons, this method should not be used as part of your regular workflow. It is strictly meant for internal verification during development, and we advise against using it in day-to-day usage."
(interactive)
(string-inflection--symbol-or-region #'string-inflection-all-cycle-function))
;;;###autoload
(defun string-inflection-toggle ()
"toggle foo_bar <=> FooBar"
(interactive)
(string-inflection--symbol-or-region #'string-inflection-toggle-function))
;;;###autoload
(defun string-inflection-camel-case ()
"FooBar format"
(interactive)
(string-inflection--symbol-or-region #'string-inflection-pascal-case-function))
;;;###autoload
(defun string-inflection-lower-camel-case ()
"fooBar format"
(interactive)
(string-inflection--symbol-or-region #'string-inflection-camel-case-function))
;;;###autoload
(defun string-inflection-snake-case ()
"foo_bar format"
(interactive)
(string-inflection--symbol-or-region #'string-inflection-snake-case-function))
;;;###autoload
(defun string-inflection-capital-snake-case ()
"Foo_Bar format"
(interactive)
(string-inflection--symbol-or-region #'string-inflection-capital-snake-case-function))
;;;###autoload
(defun string-inflection-upcase ()
"FOO_BAR format"
(interactive)
(string-inflection--symbol-or-region #'string-inflection-upcase-function))
;;;###autoload
(defun string-inflection-kebab-case ()
"foo-bar format"
(interactive)
(string-inflection--symbol-or-region #'string-inflection-kebab-case-function))
(fset 'string-inflection-lisp 'string-inflection-kebab-case)
;; --------------------------------------------------------------------------------
(defun string-inflection--count-symbols-between-start-and-end (start end)
"Count the symbols between START and END."
(let ((symbol-num 0))
(goto-char start)
(save-excursion
(while (< (point) end)
(setq symbol-num (1+ symbol-num))
(forward-symbol 1)))
symbol-num))
(defun string-inflection-replace-all-spaces-with-underscores (start end)
"Replace all whitespace characters in the region with underscores."
(interactive "r")
(save-excursion
(save-restriction
(narrow-to-region start end)
(goto-char (point-min))
(while (re-search-forward "[[:space:]]+" nil t)
(replace-match "_"))))
(deactivate-mark))
(defun string-inflection--symbol-or-region (inflect-func)
"Perform INFLECT-FUNC depending on if in region or symbol."
(if (use-region-p)
(if (and (eq string-inflection-region-selection-behavior 'replace-all-spaces-with-underscores))
(string-inflection-replace-all-spaces-with-underscores (region-beginning) (region-end))
(string-inflection--region inflect-func))
(string-inflection--symbol inflect-func)))
(defun string-inflection--symbol (inflect-func)
"Perform INFLECT-FUNC for a symbol occurrence."
(let ((orig-point (point)))
(insert (funcall inflect-func (string-inflection-get-current-symbol)))
(pcase string-inflection-final-position
('remain (goto-char (min orig-point (cdr (funcall string-inflection-bounds-function)))))
('beginning (goto-char (car (funcall string-inflection-bounds-function)))))))
(defun string-inflection--region (inflect-func)
"Perform INFLECT-FUNC for all occurrences in the region."
(let ((orig-point (point))
(start (region-beginning))
(end (region-end)))
(dotimes (_ (string-inflection--count-symbols-between-start-and-end start end))
(let ((orig-length (length (symbol-name (symbol-at-point)))))
(insert (funcall inflect-func (string-inflection-get-current-symbol-limited-by start end)))
(setq end (+ end (- (length (symbol-name (symbol-at-point))) orig-length)))
(forward-symbol 1)
(if-let* ((bounds (funcall string-inflection-bounds-function)))
(goto-char (car bounds)))))
(let ((new-region
(pcase string-inflection-final-position
('remain (if (/= orig-point start) (cons start end) (cons end start)))
('beginning (cons end start))
('end (cons start end)))))
(set-mark (car new-region))
(goto-char (cdr new-region)))
(activate-mark)
(setq deactivate-mark nil)))
(defun string-inflection-get-current-symbol ()
"Gets the symbol near the point"
(interactive)
(if-let* ((bounds (funcall string-inflection-bounds-function))
(start (car bounds))
(end (cdr bounds))
(str (buffer-substring start end)))
(progn
(delete-region start end)
str)
""))
(defun string-inflection-get-current-symbol-limited-by (reg-start reg-end)
"Gets the symbol near the point limited by REG-START and REG-END."
(interactive)
(if-let* ((bounds (funcall string-inflection-bounds-function))
(start (max (car bounds) reg-start))
(end (min (cdr bounds) reg-end))
(str (buffer-substring start end)))
(progn
(delete-region start end)
str)
""))
;; --------------------------------------------------------------------------------
(defun string-inflection-pascal-case-function (str)
"foo_bar => FooBar"
(setq str (string-inflection-snake-case-function str))
(mapconcat 'capitalize (split-string str "_") ""))
(fset 'string-inflection-upper-camel-case-function 'string-inflection-pascal-case-function)
(defun string-inflection-camel-case-function (str)
"foo_bar => fooBar"
(setq str (split-string (string-inflection-snake-case-function str) "_"))
(concat (downcase (car str))
(mapconcat 'capitalize (cdr str) "")))
(fset 'string-inflection-lower-camel-case-function 'string-inflection-camel-case-function)
(defun string-inflection-upcase-function (str)
"FooBar => FOO_BAR"
(upcase (string-inflection-snake-case-function str)))
(defun string-inflection-snake-case-function (str)
"FooBar => foo_bar"
(let ((case-fold-search nil))
(setq str (replace-regexp-in-string "\\([[:lower:][:digit:]]\\)\\([[:upper:]]\\)" "\\1_\\2" str))
(setq str (replace-regexp-in-string "\\([[:upper:]]+\\)\\([[:upper:]][[:lower:]]\\)" "\\1_\\2" str))
(setq str (replace-regexp-in-string "-" "_" str)) ; FOO-BAR => FOO_BAR
(setq str (replace-regexp-in-string "_+" "_" str))
(downcase str)))
(defun string-inflection-capital-snake-case-function (str)
"foo_bar => Foo_Bar"
(setq str (string-inflection-snake-case-function str))
(mapconcat 'capitalize (split-string str "_") "_"))
(defun string-inflection-kebab-case-function (str)
"foo_bar => foo-bar"
(let ((case-fold-search nil))
(setq str (string-inflection-snake-case-function str))
(setq str (replace-regexp-in-string "_" "-" str))))
(defun string-inflection-all-cycle-function (str)
"foo_bar => FOO_BAR => FooBar => fooBar => foo-bar => Foo_Bar => foo_bar
foo => FOO => Foo => foo"
(cond
;; foo => FOO
((string-inflection-symbol-p str)
(string-inflection-upcase-function str))
;; foo_bar => FOO_BAR
((string-inflection-snake-case-p str)
(string-inflection-upcase-function str))
;; FOO_BAR => FooBar
((string-inflection-upcase-p str)
(string-inflection-pascal-case-function str))
;; FooBar => fooBar
;; Foo => foo
((string-inflection-pascal-case-p str)
(string-inflection-camel-case-function str))
;; fooBar => foo-bar
((string-inflection-camel-case-p str)
(string-inflection-kebab-case-function str))
;; foo-bar => Foo_Bar
((string-inflection-kebab-case-p str)
(string-inflection-capital-snake-case-function str))
;; foo-bar => foo_bar
(t
(string-inflection-snake-case-function str))))
(defun string-inflection-ruby-style-cycle-function (str)
"foo_bar => FOO_BAR => FooBar => foo_bar"
(cond
((string-inflection-snake-case-p str)
(string-inflection-upcase-function str))
((string-inflection-upcase-p str)
(string-inflection-pascal-case-function str))
(t
(string-inflection-snake-case-function str))))
(defalias 'string-inflection-python-style-cycle-function
'string-inflection-ruby-style-cycle-function)
(defun string-inflection-elixir-style-cycle-function (str)
"foo_bar => FooBar => foo_bar"
(cond
((string-inflection-snake-case-p str)
(string-inflection-pascal-case-function str))
(t
(string-inflection-snake-case-function str))))
(defun string-inflection-java-style-cycle-function (str)
"fooBar => FOO_BAR => FooBar => fooBar"
(cond
((string-inflection-snake-case-p str)
(string-inflection-upcase-function str))
((string-inflection-camel-case-p str)
(string-inflection-upcase-function str))
((string-inflection-upcase-p str)
(string-inflection-pascal-case-function str))
(t
(string-inflection-camel-case-function str))))
;; Toggle function. But cycle function.
(defun string-inflection-toggle-function (str)
"Not so much the case that in all caps when using normal foo_bar <--> FooBar"
(cond
((string-inflection-snake-case-p str)
(string-inflection-pascal-case-function str))
((string-inflection-pascal-case-p str)
(string-inflection-camel-case-function str))
(t
(string-inflection-snake-case-function str))))
;; --------------------------------------------------------------------------------
(defun string-inflection-symbol-p (str)
"if foo => t"
(let ((case-fold-search nil))
(string-match "\\`[[:lower:][:digit:]]+\\'" str)))
(defun string-inflection-snake-case-p (str)
"if foo_bar => t"
(let ((case-fold-search nil))
(string-match "\\`[[:lower:][:digit:]_]+\\'" str)))
(defun string-inflection-upcase-p (str)
"if FOO_BAR => t"
(let ((case-fold-search nil))
(string-match "\\`[[:upper:][:digit:]_]+\\'" str)))
(defun string-inflection-pascal-case-p (str)
"if FooBar => t"
(let ((case-fold-search nil))
(and
(string-match "[[:lower:]]" str)
(string-match "\\`[[:upper:]][[:lower:][:upper:][:digit:]]+\\'" str))))
(fset 'string-inflection-upper-camel-case-p 'string-inflection-pascal-case-p)
(defun string-inflection-camel-case-p (str)
"if fooBar => t"
(let ((case-fold-search nil))
(and
(string-match "[[:upper:]]" str)
(string-match "\\`[[:lower:]][[:lower:][:upper:][:digit:]]+\\'" str))))
(fset 'string-inflection-lower-camel-case-p 'string-inflection-camel-case-p)
(defun string-inflection-kebab-case-p (str)
"if foo-bar => t"
(string-match "-" str))
(defun string-inflection-capital-snake-case-p (str)
"if Foo_Bar => t"
(let ((case-fold-search nil))
(and
(string-match "_" str)
(string-match "\\`[[:upper:]][[:lower:][:upper:][:digit:]_]+\\'" str))))
;; --------------------------------------------------------------------------------
;; The function names on the left are deprecated and retained for compatibility, while those on the right are the new ones.
;; I'll erase it soon
(fset 'string-inflection-camelcase 'string-inflection-camel-case)
(fset 'string-inflection-camelcase-function 'string-inflection-camel-case-function)
(fset 'string-inflection-camelcase-p 'string-inflection-camel-case-p)
(fset 'string-inflection-capital-underscore-function 'string-inflection-capital-snake-case-function)
(fset 'string-inflection-lower-camelcase 'string-inflection-lower-camel-case)
(fset 'string-inflection-lower-camelcase-function 'string-inflection-lower-camel-case-function)
(fset 'string-inflection-lower-camelcase-p 'string-inflection-lower-camel-case-p)
(fset 'string-inflection-underscore 'string-inflection-snake-case)
(fset 'string-inflection-underscore-function 'string-inflection-snake-case-function)
(fset 'string-inflection-underscore-p 'string-inflection-snake-case-p)
(fset 'string-inflection-upper-camelcase 'string-inflection-upper-camel-case)
(fset 'string-inflection-upper-camelcase-function 'string-inflection-upper-camel-case-function)
(fset 'string-inflection-upper-camelcase-p 'string-inflection-upper-camel-case-p)
(fset 'string-inflection-word-p 'string-inflection-symbol-p)
(provide 'string-inflection)
;;; string-inflection.el ends here
================================================
FILE: test/string-inflection-test.el
================================================
;; -*- compile-command: "emacs --script string-inflection-test.el" -*-
(setq load-path (cons ".." load-path))
(setq load-path (cons "." load-path))
(require 'string-inflection)
;; This test assumes the apply-to-each-symbols mode.
(setq string-inflection-region-selection-behavior 'apply-to-each-symbols)
(require 'ert)
;; -------------------------------------------------------------------------------- cycle function
(ert-deftest test-ruby-style-cycle ()
(should (equal "FOO_BAR" (string-inflection-ruby-style-cycle-function "foo_bar")))
(should (equal "FooBar" (string-inflection-ruby-style-cycle-function "FOO_BAR")))
(should (equal "foo_bar" (string-inflection-ruby-style-cycle-function "FooBar"))))
(ert-deftest test-elixir-style-cycle ()
(should (equal "foo_bar" (string-inflection-elixir-style-cycle-function "FOO_BAR")))
(should (equal "FooBar" (string-inflection-elixir-style-cycle-function "foo_bar")))
(should (equal "foo_bar" (string-inflection-elixir-style-cycle-function "FooBar"))))
(ert-deftest test-java-style-cycle ()
(should (equal "FOO_BAR" (string-inflection-java-style-cycle-function "foo_bar")))
(should (equal "FOO_BAR" (string-inflection-java-style-cycle-function "fooBar")))
(should (equal "FooBar" (string-inflection-java-style-cycle-function "FOO_BAR")))
(should (equal "fooBar" (string-inflection-java-style-cycle-function "FooBar"))))
(ert-deftest test-all-cycle ()
(should (equal "FOO_BAR" (string-inflection-all-cycle-function "foo_bar")))
(should (equal "FooBar" (string-inflection-all-cycle-function "FOO_BAR")))
(should (equal "fooBar" (string-inflection-all-cycle-function "FooBar")))
(should (equal "fooBar" (string-inflection-all-cycle-function "FooBar")))
(should (equal "foo-bar" (string-inflection-all-cycle-function "fooBar")))
(should (equal "Foo_Bar" (string-inflection-all-cycle-function "foo-bar")))
(should (equal "foo_bar" (string-inflection-all-cycle-function "Foo_Bar"))))
;; --------------------------------------------------------------------------------
(ert-deftest test-snake-case ()
(should (equal "foo1_bar" (string-inflection-snake-case-function "foo1_bar")))
(should (equal "foo1_bar" (string-inflection-snake-case-function "FOO1_BAR")))
(should (equal "foo1bar" (string-inflection-snake-case-function "foo1bar")))
(should (equal "foo1_bar" (string-inflection-snake-case-function "foo1__bar")))
(should (equal "foo1_bar" (string-inflection-snake-case-function "Foo1Bar")))
(should (equal "foo1_bar" (string-inflection-snake-case-function "FOO1Bar")))
(should (equal "foo_bar" (string-inflection-snake-case-function "FOO_BAR"))))
(ert-deftest test-consecutive-uppercase ()
(should (equal "a_single_line" (string-inflection-snake-case-function "ASingleLine")))
(should (equal "php_mode" (string-inflection-snake-case-function "PHPMode")))
(should (equal "ends_with_php" (string-inflection-snake-case-function "EndsWithPHP")))
(should (equal "php_and_xml_too" (string-inflection-snake-case-function "PHPAndXMLToo")))
(should (equal "php_and_xml_too" (string-inflection-snake-case-function "phpAndXmlToo")))
(should (equal "ph_pand_xm_ltoo" (string-inflection-snake-case-function "PHPandXMLtoo")))
(should (equal "eĥo_ŝanĝo_ĉiu_ĵaŭde" (string-inflection-snake-case-function "EĤOŜanĝoĈIUĴaŭde"))))
(ert-deftest test-pascal-case ()
(should (equal "Foo1Bar" (string-inflection-pascal-case-function "Foo1Bar")))
(should (equal "Eĥo1Ŝanĝo" (string-inflection-pascal-case-function "Eĥo1Ŝanĝo")))
(should (equal "Foo1Bar" (string-inflection-pascal-case-function "FOO1_BAR")))
(should (equal "Eĥo1Ŝanĝo" (string-inflection-pascal-case-function "EĤO1_ŜANĜO")))
(should (equal "Foo1Bar" (string-inflection-pascal-case-function "FOO1__BAR")))
(should (equal "Eĥo1Ŝanĝo" (string-inflection-pascal-case-function "EĤO1__ŜANĜO")))
(should (equal "Foo" (string-inflection-pascal-case-function "foo")))
(should (equal "Eĥo" (string-inflection-pascal-case-function "eĥo"))))
(ert-deftest test-lower-camel-case ()
(should (equal "fooBar" (string-inflection-camel-case-function "FooBar")))
(should (equal "eĥoŜanĝo" (string-inflection-camel-case-function "EĥoŜanĝo")))
(should (equal "foo1Bar" (string-inflection-camel-case-function "FOO1BAR")))
(should (equal "eĥo1Ŝanĝo" (string-inflection-camel-case-function "EĤO1ŜANĜO"))))
(ert-deftest test-kebab-case ()
(should (equal "foo-bar" (string-inflection-kebab-case-function "FooBar")))
(should (equal "eĥo-ŝanĝo" (string-inflection-kebab-case-function "EĥoŜanĝo"))))
(ert-deftest test-toggle ()
(should (equal "FooBar" (string-inflection-toggle-function "foo_bar")))
(should (equal "EĥoŜanĝo" (string-inflection-toggle-function "eĥo_ŝanĝo")))
(should (equal "fooBar" (string-inflection-toggle-function "FooBar")))
(should (equal "eĥoŜanĝo" (string-inflection-toggle-function "EĥoŜanĝo")))
(should (equal "ĉirkaŭIro" (string-inflection-toggle-function "ĈirkaŭIro")))
(should (equal "foo_bar" (string-inflection-toggle-function "FOO_BAR")))
(should (equal "eĥo_ŝanĝo" (string-inflection-toggle-function "EĤO_ŜANĜO"))))
(ert-deftest test-upcase ()
(should (equal "FOO1_BAR" (string-inflection-upcase-function "foo1_bar")))
(should (equal "EĤO1_ŜANĜO" (string-inflection-upcase-function "eĥo1_ŝanĝo")))
(should (equal "FOO1_BAR" (string-inflection-upcase-function "Foo1Bar")))
(should (equal "EĤO1_ŜANĜO" (string-inflection-upcase-function "Eĥo1Ŝanĝo")))
(should (equal "FOO_BAR" (string-inflection-upcase-function "Foo_bar")))
(should (equal "EĤO_ŜANĜO" (string-inflection-upcase-function "Eĥo_ŝanĝo"))))
(ert-deftest test-capital-snake-case ()
(should (equal "Foo1_Bar" (string-inflection-capital-snake-case-function "foo1_bar")))
(should (equal "Eĥo1_Ŝanĝo" (string-inflection-capital-snake-case-function "eĥo1_ŝanĝo")))
(should (equal "Foo1_Bar" (string-inflection-capital-snake-case-function "FOO1_BAR")))
(should (equal "Eĥo1_Ŝanĝo" (string-inflection-capital-snake-case-function "EĤO1_ŜANĜO")))
(should (equal "Foo1bar" (string-inflection-capital-snake-case-function "foo1bar")))
(should (equal "Eĥo1ŝanĝo" (string-inflection-capital-snake-case-function "eĥo1ŝanĝo")))
(should (equal "Foo1_Bar" (string-inflection-capital-snake-case-function "foo1__bar")))
(should (equal "Eĥo1_Ŝanĝo" (string-inflection-capital-snake-case-function "eĥo1__ŝanĝo")))
(should (equal "Foo1_Bar" (string-inflection-capital-snake-case-function "Foo1Bar")))
(should (equal "Eĥo1_Ŝanĝo" (string-inflection-capital-snake-case-function "Eĥo1Ŝanĝo")))
(should (equal "Foo1_Bar" (string-inflection-capital-snake-case-function "FOO1Bar")))
(should (equal "Eĥo1_Ŝanĝo" (string-inflection-capital-snake-case-function "EĤO1Ŝanĝo")))
(should (equal "Foo_Bar" (string-inflection-capital-snake-case-function "FOO_BAR")))
(should (equal "Eĥo_Ŝanĝo" (string-inflection-capital-snake-case-function "EĤO_ŜANĜO"))))
;; --------------------------------------------------------------------------------
(ert-deftest test-symbol-p ()
(should (string-inflection-symbol-p "foo"))
(should (string-inflection-symbol-p "eĥo"))
(should-not (string-inflection-symbol-p "foo_bar"))
(should-not (string-inflection-symbol-p "eĥo_ŝanĝo")))
(ert-deftest test-snake-case-p ()
(should (string-inflection-snake-case-p "foo"))
(should (string-inflection-snake-case-p "eĥo"))
(should (string-inflection-snake-case-p "foo_bar"))
(should (string-inflection-snake-case-p "eĥo_ŝanĝo")))
(ert-deftest test-pascal-case-p ()
(should (string-inflection-pascal-case-p "Foo"))
(should (string-inflection-pascal-case-p "Eĥo"))
(should (string-inflection-pascal-case-p "FooBar"))
(should (string-inflection-pascal-case-p "EĥoŜanĝo"))
(should-not (string-inflection-pascal-case-p "FOO"))
(should (string-inflection-pascal-case-p "Eĥĥ")))
(ert-deftest test-camel-case-p ()
(should-not (string-inflection-camel-case-p "foo"))
(should-not (string-inflection-camel-case-p "eĥo"))
(should (string-inflection-camel-case-p "fooBar"))
(should (string-inflection-camel-case-p "eĥoŜanĝo")))
(ert-deftest test-lower-upcase-p ()
(should (string-inflection-upcase-p "FOO"))
(should (string-inflection-upcase-p "EĤO"))
(should (string-inflection-upcase-p "FOO_BAR"))
(should (string-inflection-upcase-p "EĤO_ŜANĜO")))
(ert-deftest test-kebab-case-p ()
(should (string-inflection-kebab-case-p "foo-bar"))
(should (string-inflection-kebab-case-p "eĥo-ŝanĝo")))
(ert-deftest test-capital-snake-case-p ()
(should (string-inflection-capital-snake-case-p "Foo_Bar"))
(should (string-inflection-capital-snake-case-p "Eĥo_Ŝanĝo")))
;; -------------------------------------------------------------------------------- Target symbol of point position
(defun buffer-try (str position &optional mode-func)
(with-temp-buffer
(funcall (or mode-func #'fundamental-mode))
(insert str)
(goto-char (apply position))
(prog1
(string-inflection-get-current-symbol)
(kill-this-buffer))))
(ert-deftest test-get-current-symbol-on-point ()
(should (equal "foo" (buffer-try "foo" '(point-max))))
(should (equal "eĥo" (buffer-try "eĥo" '(point-max))))
(should (equal "foo" (buffer-try "foo" '(point-min))))
(should (equal "eĥo" (buffer-try "eĥo" '(point-min))))
(should (equal "" (buffer-try "" '(point-max))))
(should (equal "foo" (buffer-try "foo->bar" '(point-min) #'c-mode)))
(should (equal "eĥo" (buffer-try "eĥo->ŝanĝo" '(point-min) #'c-mode)))
(should (equal "foo-" (buffer-try "foo-" '(point-min))))
(should (equal "eĥo-" (buffer-try "eĥo-" '(point-min))))
(should (equal "foo" (buffer-try "foo-" '(point-min) #'python-mode)))
(should (equal "eĥo" (buffer-try "eĥo-" '(point-min) #'python-mode)))
)
;; -------------------------------------------------------------------------------- Target all of region
(defun region-try-inflect (str &optional inflect mode-func)
(let ((string-inflection-region-selection-behavior 'apply-to-each-symbols))
(with-temp-buffer
(funcall (or mode-func #'fundamental-mode))
(insert str)
(set-mark (point-min))
(goto-char (point-max))
(activate-mark)
(funcall (or inflect #'string-inflection-toggle))
(buffer-string))))
(ert-deftest test-inflect-toggle-in-region ()
(should (equal "Foo" (region-try-inflect "foo"))) ; It was snake_case when old version.
(should (equal "Foo Bar" (region-try-inflect "foo bar"))) ; It was snake_case when old version.
(should (equal "Foo Bar Baz" (region-try-inflect "foo bar baz")))
(should (equal "FooBar BarFoo" (region-try-inflect "foo_bar bar_foo")))
(should (equal "Foo:Bar" (region-try-inflect "foo:bar"))) ; It was snake_case when old version.
(should (equal "Foo::Bar" (region-try-inflect "foo::bar"))) ; It was snake_case when old version.
(should (equal "Foo.Bar" (region-try-inflect "foo.bar")))
(should (equal "Foo().Bar" (region-try-inflect "foo().bar")))
(should (equal "Foo()->Bar" (region-try-inflect "foo()->bar" #'string-inflection-toggle #'c-mode)))
)
(ert-deftest test-inflect-in-region ()
(should (equal "FooBar" (region-try-inflect "foo_bar" #'string-inflection-camel-case)))
(should (equal "FooBar BarFoo" (region-try-inflect "foo_bar bar-foo" #'string-inflection-camel-case)))
(should (equal "fooBar barFoo" (region-try-inflect "foo_bar bar-foo" #'string-inflection-lower-camel-case)))
(should (equal "foo_bar bar_foo" (region-try-inflect "FooBar bar-foo" #'string-inflection-snake-case)))
(should (equal "Foo_Bar Bar_Foo" (region-try-inflect "FooBar bar-foo" #'string-inflection-capital-snake-case)))
(should (equal "FOO_BAR BAR_FOO" (region-try-inflect "FooBar bar-foo" #'string-inflection-upcase)))
(should (equal "foo-bar bar-foo" (region-try-inflect "FooBar bar_foo" #'string-inflection-kebab-case)))
;; https://github.com/akicho8/string-inflection/issues/34
(should (equal ":foo-bar bar" (region-try-inflect ":fooBar bar" #'string-inflection-kebab-case)))
;; ↓Why isn't the test passing?
;; https://github.com/akicho8/string-inflection/pull/48
;; (should (equal ":foo-bar" (region-try-inflect ":fooBar" #'string-inflection-kebab-case)))
;; https://github.com/akicho8/string-inflection/issues/31
(should (equal "\nfoo_bar\nbar_foo\n" (region-try-inflect "\nFooBar\nbar-foo\n" #'string-inflection-snake-case)))
;; https://github.com/akicho8/string-inflection/issues/30
(should (equal "obj_name->meth_name\nobj1_name->meth1_name"
(region-try-inflect "ObjName->MethName\nObj1Name->Meth1Name" #'string-inflection-snake-case #'c++-mode)))
)
(ert-deftest test-cycle-in-region ()
(should (equal "FOO_BAR FooBar foo_bar"
(region-try-inflect "foo_bar FOO_BAR FooBar" #'string-inflection-ruby-style-cycle)))
(should (equal "FooBar foo_bar"
(region-try-inflect "foo_bar FooBar" #'string-inflection-elixir-style-cycle)))
(should (equal "foo_bar FOO_BAR FooBar foo_bar"
(region-try-inflect "fooBar foo_bar FOO_BAR FooBar" #'string-inflection-python-style-cycle)))
(should (equal "FOO_BAR FooBar fooBar"
(region-try-inflect "foo_bar FOO_BAR FooBar" #'string-inflection-java-style-cycle)))
(should (equal "FOO_BAR FooBar fooBar foo-bar Foo_Bar foo_bar"
(region-try-inflect "foo_bar FOO_BAR FooBar fooBar foo-bar Foo_Bar" #'string-inflection-all-cycle)))
)
(defun buffer-try-inflect (str inflect)
(with-temp-buffer
(c-mode)
(insert str)
(goto-char (point-min))
(funcall inflect)
(buffer-string)))
(ert-deftest test-buffer-toggle ()
(should (equal "foo_bar" (buffer-try-inflect "fooBar" 'string-inflection-toggle))))
(ert-deftest test-buffer-snake-case ()
;; https://github.com/akicho8/string-inflection/issues/30
(should (equal "object_name->method" (buffer-try-inflect "objectName->method" 'string-inflection-snake-case)))
(should (equal "object1_name->method" (buffer-try-inflect "object1Name->method" 'string-inflection-snake-case)))
(should (equal "eĥo_ŝanĝo->ĉiuĴaŭde" (buffer-try-inflect "eĥoŜanĝo->ĉiuĴaŭde" 'string-inflection-snake-case))))
(ert-deftest test-buffer-camel-case ()
(should (equal "ObjectName->method" (buffer-try-inflect "object_name->method" 'string-inflection-camel-case)))
(should (equal "Object1Name->method" (buffer-try-inflect "object1_name->method" 'string-inflection-camel-case)))
(should (equal "EĥoŜanĝo->ĉiuĴaŭde" (buffer-try-inflect "eĥo_ŝanĝo->ĉiuĴaŭde" 'string-inflection-camel-case))))
(ert-deftest test-buffer-lower-camel-case ()
(should (equal "objectName->method" (buffer-try-inflect "object_name->method" 'string-inflection-lower-camel-case)))
(should (equal "object1Name->method" (buffer-try-inflect "object1_name->method" 'string-inflection-lower-camel-case)))
(should (equal "eĥoŜanĝo->ĉiuĴaŭde" (buffer-try-inflect "eĥo_ŝanĝo->ĉiuĴaŭde" 'string-inflection-lower-camel-case))))
(defun buffer-try-final-pos (str final-pos inflect initial-pos)
(with-temp-buffer
(setq-local string-inflection-final-position final-pos)
(insert (concat str " fooo"))
(goto-char initial-pos)
(funcall inflect)
(should-not (use-region-p))
(point)))
(ert-deftest test-buffer-remain-simple-lengthen ()
(should (equal (buffer-try-final-pos "FooBar" 'remain #'string-inflection-snake-case 2) 2)))
(ert-deftest test-buffer-end-simple-lengthen ()
(should (equal (buffer-try-final-pos "FooBar" 'end #'string-inflection-snake-case 2) 8)))
(ert-deftest test-buffer-beginning-simple-lengthen ()
(should (equal (buffer-try-final-pos "FooBar" 'beginning #'string-inflection-snake-case 2) 1)))
(ert-deftest test-buffer-remain-simple-shorten-not-at-end ()
(should (equal (buffer-try-final-pos "foo_bar" 'remain #'string-inflection-camel-case 8) 7)))
(ert-deftest test-buffer-remain-simple-shorten-at-end ()
(should (equal (buffer-try-final-pos "foo_bar" 'remain #'string-inflection-camel-case 2) 2)))
(ert-deftest test-buffer-end-simple-shorten ()
(should (equal (buffer-try-final-pos "foo_bar" 'end #'string-inflection-camel-case 2) 7)))
(ert-deftest test-buffer-beginning-simple-shorten ()
(should (equal (buffer-try-final-pos "foo_bar" 'beginning #'string-inflection-camel-case 2) 1)))
(defun region-try-final-pos (str final-pos inverse)
(with-temp-buffer
(setq-local string-inflection-final-position final-pos)
(insert str)
(let ((final-point (point-max)))
(insert " foooo")
(if inverse
(progn (set-mark final-point) (goto-char (point-min)))
(set-mark (point-min)) (goto-char final-point))
(activate-mark))
(string-inflection-snake-case)
(should (use-region-p))
(should-not deactivate-mark)
(cons (point) (cons (region-beginning) (region-end)))))
(ert-deftest test-buffer-remain-region-straight ()
(let* ((state (region-try-final-pos "FooBar" 'remain nil))
(final-pos (car state))
(region (cdr state))
(beginning (car region))
(end (cdr region)))
(should (equal beginning 1))
(should (equal end 8))
(should (equal final-pos 8))))
(ert-deftest test-buffer-remain-region-inversed ()
(let* ((state (region-try-final-pos "FooBar" 'remain t))
(final-pos (car state))
(region (cdr state))
(beginning (car region))
(end (cdr region)))
(should (equal beginning 1))
(should (equal end 8))
(should (equal final-pos 1))))
(ert-deftest test-buffer-end-region-straight ()
(let* ((state (region-try-final-pos "FooBar" 'end nil))
(final-pos (car state))
(region (cdr state))
(beginning (car region))
(end (cdr region)))
(should (equal beginning 1))
(should (equal end 8))
(should (equal final-pos 8))))
(ert-deftest test-buffer-end-region-inverse ()
(let* ((state (region-try-final-pos "FooBar" 'end t))
(final-pos (car state))
(region (cdr state))
(beginning (car region))
(end (cdr region)))
(should (equal beginning 1))
(should (equal end 8))
(should (equal final-pos 8))))
(ert-deftest test-buffer-beginning-region-straight ()
(let* ((state (region-try-final-pos "FooBar" 'beginning nil))
(final-pos (car state))
(region (cdr state))
(beginning (car region))
(end (cdr region)))
(should (equal beginning 1))
(should (equal end 8))
(should (equal final-pos 1))))
(ert-deftest test-buffer-beginning-region-inverse ()
(let* ((state (region-try-final-pos "FooBar" 'beginning t))
(final-pos (car state))
(region (cdr state))
(beginning (car region))
(end (cdr region)))
(should (equal beginning 1))
(should (equal end 8))
(should (equal final-pos 1))))
(defun mixed-region-cycle-try (start end)
;; This only makes sense if selection behavior is 'apply-to-each-symbols.
(let ((string-inflection-region-selection-behavior 'apply-to-each-symbols))
(with-temp-buffer
(text-mode)
(insert "someFunction_to_do_SomeThing FoofooBarbarBarbarFoofoo")
(set-mark start)
(goto-char end)
(activate-mark)
(string-inflection-cycle)
(cons (buffer-string) (cons (region-beginning) (region-end))))))
(ert-deftest test-mixed-symbol-cycle-region-1 ()
(should (equal (car (mixed-region-cycle-try 1 13))
"some_function_to_do_SomeThing FoofooBarbarBarbarFoofoo")))
(ert-deftest test-mixed-symbol-cycle-region-2 ()
(should (equal (car (mixed-region-cycle-try 14 19))
"someFunction_TO_DO_SomeThing FoofooBarbarBarbarFoofoo")))
(ert-deftest test-mixed-symbol-cycle-region-3 ()
(should (equal (car (mixed-region-cycle-try 20 29))
"someFunction_to_do_some_thing FoofooBarbarBarbarFoofoo")))
(ert-deftest test-mixed-symbol-cycle-region-4 ()
(should (equal (car (mixed-region-cycle-try 20 41))
"someFunction_to_do_some_thing foofoo_barbarBarbarFoofoo")))
(ert-deftest test-mixed-symbol-cycle-region-restore-region ()
(should (equal (cdr (mixed-region-cycle-try 20 41)) (cons 20 43))))
(defun region-try-replace-all-spaces-with-underscores (str)
(with-temp-buffer
(insert str)
(set-mark (point-min))
(goto-char (point-max))
(activate-mark)
(funcall #'string-inflection-replace-all-spaces-with-underscores (region-beginning) (region-end))
(buffer-string)))
(ert-deftest test-replace-all-spaces-with-underscores ()
(should (equal "foo_bar" (region-try-replace-all-spaces-with-underscores "foo bar")))
(should (equal "Foo_Bar" (region-try-replace-all-spaces-with-underscores "Foo Bar")))
(should (equal "Foo__Bar" (region-try-replace-all-spaces-with-underscores "Foo _Bar")))
(should (equal "Foo__Bar" (region-try-replace-all-spaces-with-underscores "Foo_ Bar")))
(should (equal "foo_bar_bar-foo" (region-try-replace-all-spaces-with-underscores "foo_bar bar-foo")))
(should (equal "foo_:bar_bar" (region-try-replace-all-spaces-with-underscores "foo :bar bar")))
(should (equal "_Foo_Bar_bar_foo_" (region-try-replace-all-spaces-with-underscores "\nFoo Bar\nbar foo\n"))))
(ert-run-tests-batch t)