Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to get the ~ functionality of vi

20 views
Skip to first unread message

Cecil Westerhof

unread,
May 26, 2016, 6:43:42 PM5/26/16
to
In vi you can use ~ to flip the case of a character. Does Emacs has
something like that?

--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

Emanuel Berg

unread,
May 26, 2016, 9:15:55 PM5/26/16
to
Cecil Westerhof <Ce...@decebal.nl> writes:

> In vi you can use ~ to flip the case of
> a character. Does Emacs has something
> like that?

Try this:

(defun flip-case ()
(interactive)
(let ((c (string-to-char (thing-at-point 'char t))))
(delete-char 1)
(cond ((and (>= c ?A) (<= c ?Z)) (insert-char (downcase c)))
((and (>= c ?a) (<= c ?z)) (insert-char (upcase c)))
(t (insert-char c)))) )
(global-set-key "\C-cf" #'flip-case)

--
underground experts united .... http://user.it.uu.se/~embe8573
Emacs Gnus Blogomatic ......... http://user.it.uu.se/~embe8573/blogomatic
- so far: 42 Blogomatic articles -

Jean-Jacques Rétorré

unread,
May 27, 2016, 12:28:25 AM5/27/16
to
ven. 27 mai 2016, Emanuel Berg <embe...@student.uu.se> disait :

> Cecil Westerhof <Ce...@decebal.nl> writes:
>
>> In vi you can use ~ to flip the case of
>> a character. Does Emacs has something
>> like that?
>
> Try this:
>
> (defun flip-case ()
> (interactive)
> (let ((c (string-to-char (thing-at-point 'char t))))
> (delete-char 1)
> (cond ((and (>= c ?A) (<= c ?Z)) (insert-char (downcase c)))
> ((and (>= c ?a) (<= c ?z)) (insert-char (upcase c)))
> (t (insert-char c)))) )
> (global-set-key "\C-cf" #'flip-case)

That won't work for accented chars.
Probably this should :

(defun flip-case ()
(interactive)
(let ((c (string-to-char (thing-at-point 'char t))))
(delete-char 1)
(insert-char
(if (eq c (upcase c))
(downcase c)
(upcase c))) ) )

--
JJR.

Cecil Westerhof

unread,
May 27, 2016, 4:58:41 AM5/27/16
to
I expected that there was a function I overlooked, but I did not.
Luckily it is easy to add the missing functionality in Emacs. :-D

The thing-at-point did not work for me. I rewrote it to:
(defun flip-case ()
(interactive)
(let ((c (char-after)))
(when c
(delete-char 1)
(insert-char
(if (eq c (upcase c))
(downcase c)
(upcase c))))))

I also added a check for there being a current character.

For the keyboard shortcut I use:
(global-set-key (kbd "C-~") 'flip-case)

I like to flip a lot of characters in one swell swoop.


Thanks for putting me in the right direction.

Thorsten Bonow

unread,
May 27, 2016, 7:33:19 AM5/27/16
to
>>>>> Cecil Westerhof <Ce...@decebal.nl> writes:

> Cecil Westerhof <Ce...@decebal.nl> writes:

> In vi you can use ~ to flip the case of a character. Does Emacs has something
> like that?

Hi,

"viper", the vi emulation already included has `viper-toggle-case'.

So what about this?

(require 'viper); loading viper but not enabling it
(global-set-key "\C-cf" 'viper-toggle-case)

If you don't mind the overhead of loading the whole package for just one
function. But you don't have to reinvent the wheel and use a maintained defun.

Toto

--
Sent from my GNU Emacs running on GNU/Linux

Emanuel Berg

unread,
May 27, 2016, 3:37:46 PM5/27/16
to
Cecil Westerhof <Ce...@decebal.nl> writes:

> The thing-at-point did not work for me.

OK, try

(require 'thingatpt)

first.

It is a useful thing even tho your code is
perhaps (?) better in this case.

> I like to flip a lot of characters in one
> swell swoop.

OK, you can use the C-u prefix to do that.

So `C-c f' is 4^0 = 1,
`C-u C-c f' is 4^1 = 4,
`C-u C-u C-c f' is 4^2 = 16, and so on; and
`C-u x C-c f' is x!

This can be implemented like this:

(require 'cl-macs)

(defun flip-case (times)
(interactive "p")
(cl-dotimes (_ times)
(let ((c (string-to-char (thing-at-point 'char t))))
(delete-char 1)
(cond ((and (>= c ?A) (<= c ?Z)) (insert-char (downcase c)))
((and (>= c ?a) (<= c ?z)) (insert-char (upcase c)))
(t (insert-char c)))) ))

Emanuel Berg

unread,
May 27, 2016, 3:37:47 PM5/27/16
to
Cecil Westerhof <Ce...@decebal.nl> writes:

> The thing-at-point did not work for me.

OK, try

(require 'thingatpt)

first.

It is a useful thing even tho your code is
perhaps (?) better in this case.

> I like to flip a lot of characters in one
> swell swoop.

OK, you can use the C-u prefix to do that.

So `C-c f' is 4^0 = 1,
`C-u C-c f' is 4^1 = 4,
`C-u C-u C-c f' is 4^2 = 16, and so on; and
`C-u x C-c f' is x!

This can be implemented like this:

(require 'cl-macs)

(defun flip-case (times)
(interactive "p")
(cl-dotimes (_ times)
(let ((c (string-to-char (thing-at-point 'char t))))
(delete-char 1)
(cond ((and (>= c ?A) (<= c ?Z)) (insert-char (downcase c)))
((and (>= c ?a) (<= c ?z)) (insert-char (upcase c)))
(t (insert-char c)))) ))

Emanuel Berg

unread,
May 27, 2016, 3:41:48 PM5/27/16
to
Thorsten Bonow <thorste...@withouthat.org>
writes:

> "viper", the vi emulation already included has
> `viper-toggle-case'.
>
> So what about this?
>
> (require 'viper); loading viper but not
> enabling it (global-set-key "\C-cf"
> 'viper-toggle-case)
>
> If you don't mind the overhead of loading the
> whole package for just one function.

One shouldn't mind loading the whole package
for "just one" function.

Also, if the OP is into vi perhaps he wants
more vi things as well!

Also, be sure to check out /usr/bin/vi !

> But you don't have to reinvent the wheel

But if you do, you are pretty darn good!

Kaushal Modi

unread,
Jun 2, 2016, 12:14:31 PM6/2/16
to Thorsten Bonow, help-gn...@gnu.org
Check out http://ergoemacs.org/emacs/modernization_upcase-word.html

Here is my implementation based off that [1].
(needs use-package, hydra and region-bindings-mode packages: all of which I
consider as good as core packages)

(defun xah-cycle-letter-case (arg)
"Cycle the letter case of the selected region or the current word.
Cycles from 'lower' -> 'Capitalize' -> 'UPPER' -> 'lower' -> ..

C-u M-x xah-cycle-letter-case -> Force convert to upper case.
C-u C-u M-x xah-cycle-letter-case -> Force convert to lower case.
C-u C-u C-u M-x xah-cycle-letter-case -> Force capitalize."
(interactive "p")
(let (p1 p2
(deactivate-mark nil)
(case-fold-search nil))
(if (use-region-p)
(setq p1 (region-beginning)
p2 (region-end))
(let ((bds (bounds-of-thing-at-point 'word)))
(setq p1 (car bds)
p2 (cdr bds))))

(cl-case arg
(4 (put this-command 'next-state "UPPER")) ; Force convert to
upper case
(16 (put this-command 'next-state "lower")) ; Force convert to
lower case
(64 (put this-command 'next-state "Capitalize")) ; Force capitalize
(t (when (not (eq last-command this-command))
(save-excursion
(goto-char p1)
(cond
;; lower -> Capitalize
((looking-at "[[:lower:]]") (put this-command
'next-state "Capitalize"))
;; Capitalize -> UPPER
((looking-at "[[:upper:]][[:lower:]]") (put this-command
'next-state "UPPER"))
;; Default: UPPER -> lower
(t (put this-command
'next-state "lower")))))))

(cl-case (string-to-char (get this-command 'next-state)) ;
`string-to-char' returns first character in string
(?U (upcase-region p1 p2)
;; UPPER -> lower
(put this-command 'next-state "lower"))
(?l (downcase-region p1 p2)
;; lower -> Capitalize
(put this-command 'next-state "Capitalize"))
;; Capitalization is a better option here than upcasing the initials
;; because (upcase-initials "abc") -> "Abc" (good)
;; (upcase-initials "ABC") -> "ABC" (not what I expect most
of the times)
;; (capitalize "abc") -> "Abc" (good)
;; (capitalize "ABC") -> "Abc" (good)
(t (capitalize-region p1 p2)
;; Capitalize -> UPPER
(put this-command 'next-state "UPPER")))))
(defun modi/upcase () (interactive) (xah-cycle-letter-case 4))
(defun modi/downcase () (interactive) (xah-cycle-letter-case 16))
(defun modi/capitalize () (interactive) (xah-cycle-letter-case 64))

(bind-keys
:map region-bindings-mode-map
("~" . xah-cycle-letter-case))

(defhydra hydra-change-case (:color blue
:hint nil)
"
_C_apitalize _U_PCASE _d_owncase _<SPC>_ →Cap→UP→down→
"
("C" modi/capitalize)
("c" modi/capitalize)
("U" modi/upcase)
("u" modi/upcase)
("d" modi/downcase)
("l" modi/downcase)
("<SPC>" xah-cycle-letter-case :color red)
("M-c" xah-cycle-letter-case :color red)
("q" nil "cancel" :color blue))

[1]:
https://github.com/kaushalmodi/.emacs.d/blob/aae4262ef4ddb6834683f1c72c56153261b779d5/setup-files/setup-editing.el#L688
--

--
Kaushal Modi

Emanuel Berg

unread,
Jun 2, 2016, 1:15:22 PM6/2/16
to
Kaushal Modi <kausha...@gmail.com> writes:

> Here is my implementation based off that [1].
> (needs use-package, hydra and
> region-bindings-mode packages: all of which
> I consider as good as core packages)
>
> (defun xah-cycle-letter-case ...

That is sure a lot of code compared to the
previous suggestions. What does it add compared
to those?

Of course, there is no principle that says
shorter code is better. Tho in practice, it is
often so...

Kaushal Modi

unread,
Jun 2, 2016, 1:29:18 PM6/2/16
to Emanuel Berg, Help Gnu Emacs mailing list
On Thu, Jun 2, 2016 at 1:21 PM Emanuel Berg <embe...@student.uu.se> wrote:

> That is sure a lot of code compared to the
> previous suggestions. What does it add compared
> to those?
>

It *cycles* the word under point (or region) through all-lowercase,
all-uppercase, and capitalized. Also allows the user to directly set that
text to all-lower/all-upper/all-capitalize.

Also if the text is already all-lower, it will cycle to the next state
intelligently. If it is all-upper to begin with, the next state to cycle to
will be different.

Most of the time, I end up using the hydra bindings.

If I am too lazy, I keep on hitting `M-c` (as per my hydra-binding in my
earlier email) till I get the text in the desired case state.
--

--
Kaushal Modi

Emanuel Berg

unread,
Jun 2, 2016, 4:39:26 PM6/2/16
to
Kaushal Modi <kausha...@gmail.com> writes:

> It *cycles* the word under point (or region)
> through all-lowercase, all-uppercase, and
> capitalized. Also allows the user to directly
> set that text to
> all-lower/all-upper/all-capitalize.
>
> Also if the text is already all-lower, it
> will cycle to the next state intelligently.
> If it is all-upper to begin with, the next
> state to cycle to will be different.
>
> Most of the time, I end up using the
> hydra bindings.
>
> If I am too lazy, I keep on hitting `M-c` (as
> per my hydra-binding in my earlier email)
> till I get the text in the desired
> case state.

"Lazy"?! I think "over-engineering" is
the word :)

What is the hang up with case, anyway? I very
seldom do `upcase-region' but that is it.

But why not.

Here is another approach:

http://user.it.uu.se/~embe8573/conf/emacs-init/caps-back.el

Kaushal Modi

unread,
Jun 2, 2016, 5:01:07 PM6/2/16
to Emanuel Berg, Help Gnu Emacs mailing list
On Thu, Jun 2, 2016 at 4:41 PM Emanuel Berg <embe...@student.uu.se> wrote:

> "Lazy"?! I think "over-engineering" is
> the word :)
>

That's subjective to how often you use that elisp snippet.


> What is the hang up with case, anyway? I very
> seldom do `upcase-region' but that is it.


As I mentioned, that's subjective. I use that function to either
lowercase/uppercase/capitalize at least once every day (not exaggerating).
--

--
Kaushal Modi

Emanuel Berg

unread,
Jun 2, 2016, 5:07:39 PM6/2/16
to
Kaushal Modi <kausha...@gmail.com> writes:

> As I mentioned, that's subjective.

I think it is objective.

Marcin Borkowski

unread,
Jun 3, 2016, 1:19:05 AM6/3/16
to Kaushal Modi, Emanuel Berg, Help Gnu Emacs mailing list

On 2016-06-02, at 23:00, Kaushal Modi <kausha...@gmail.com> wrote:

> On Thu, Jun 2, 2016 at 4:41 PM Emanuel Berg <embe...@student.uu.se> wrote:
>
>> "Lazy"?! I think "over-engineering" is
>> the word :)
>>
>
> That's subjective to how often you use that elisp snippet.
>
>
>> What is the hang up with case, anyway? I very
>> seldom do `upcase-region' but that is it.
>
>
> As I mentioned, that's subjective. I use that function to either
> lowercase/uppercase/capitalize at least once every day (not exaggerating).
> --

FWIW, I never use upcase-region, but I use capitalize-word and
downcase-word quite often, with positive and negative arguments.

Best,

--
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University

Joost Kremers

unread,
Jun 3, 2016, 5:21:11 AM6/3/16
to
Emanuel Berg wrote:
> Kaushal Modi <kausha...@gmail.com> writes:
>
>> As I mentioned, that's subjective.
>
> I think it is objective.

The operative words here being "I think".


--
Joost Kremers joostk...@fastmail.fm
Selbst in die Unterwelt dringt durch Spalten Licht
EN:SiS(9)

Emanuel Berg

unread,
Jun 3, 2016, 6:51:44 AM6/3/16
to
Joost Kremers <joost.m...@gmail.com>
writes:

>>> As I mentioned, that's subjective.
>> I think it is objective.
>
> The operative words here being "I think".

OK, I should have written just "No." - that
would leave out any doubt, what the operative
word is!

There is also another perspective.

Let's say I'm writing an article on K2
in Swedish. I'm going to do it all LaTeX like
this piece on Kon-Tiki [1]. But before I do
that I write everything in plain text. So here
is a future subsection and a paragraph:


ALBERTO ZERAIN


2008 fanns på K2 även den baskiske
soloklättraren Alberto Zerain. De flesta på K2
det året var erfarna klättrare. Men Zerain
klättrade så bra att till och med sherpas
förundrat sökte varandras blickar.

So here, I use `center-region' and
`upcase-region' to do an ad-hoc subtitle, just
to make it look nicer as I work. Perhaps that
nicety will make me feel one per mille more
relaxed and clear headed, which will make the
article two per milles the better!

So I absolutely agree it should be there, as it
is so basic. Vanilla Emacs (and vi I suppose)
should excel in doing basic things, because
that is the fundament to the whole structure.

At the universities they like to teach you "the
top-down approach", e.g.

@book{computer-networking-top-down-approach,
title = {Computer Networking (A Top-Down Approach)},
author = {James Kurose; Keith Ross},
year = 2003,
publisher = {Addison-Wesley},
}

Here is were the universities and I agree to
disagree as I every day of the week prefer the
bottom-up approach, were first small building
blocks are perfected until perfection, to
*then* hold a superstructure of might
and magic!

This is analogous to the sport world. There is
not one boxing gym from Alma-Ata (Almaty) to
New York where the coach says "First we'll
learn everything there is to know about boxing.
Then we'll start throwing jabs." The same with
soldiers, sailors, roofers, horsemen, chimney
sweeps, you name it - day one is the BASICS!

So instead, I'd recommend this book on
networks:

@book{internet-book,
author = {Comer},
ISBN = 0138920923,
publisher = {Pearson},
title = {The Internet Book},
year = 1997
}

In this case, the OP isn't happy with the basic
stuff. So his "might and magic" on top of the
basic stuff is actually a rewind to get the
basic stuff right. And there is nothing wrong
with that. Actually I like it. I still think it
is over-engineering but hey, no one said all
engineers are the same. Some are even very
unsimilar come to think of it...

[1] %% This file: http://user.it.uu.se/~embe8573/articles/kon-tiki/kon-tiki.tex
%% The Biblatex: http://user.it.uu.se/~embe8573/articles/kon-tiki/kon-tiki.bib
%% The PDF: http://user.it.uu.se/~embe8573/articles/kon-tiki/kon-tiki.pdf

--
underground experts united .... http://user.it.uu.se/~embe8573
Emacs Gnus Blogomatic ......... http://user.it.uu.se/~embe8573/blogomatic
- so far: 43 Blogomatic articles -
0 new messages