Need to double-escape backslashes in langmap?

371 views
Skip to first unread message

Ben Fritz

unread,
Dec 9, 2011, 10:27:20 AM12/9/11
to vim_dev
I'm a little stumped by a problem brought to light by a recent edit to
http://vim.wikia.com/wiki/Using_Vim_with_the_Dvorak_keyboard_layout

:help 'langmap' says:

The 'langmap' option is a list of parts, separated with commas. Each
part can be in one of two forms:
1. A list of pairs. Each pair is a "from" character immediately
followed by the "to" character. Examples: "aA", "aAbBcC".
2. A list of "from" characters, a semi-colon and a list of "to"
characters. Example: "abc;ABC"
Example: "aA,fgh;FGH,cCdDeE"
Special characters need to be preceded with a backslash. These are
";", ',' and backslash itself.

The tip linked above tries to set 'langmap' to include a mapping of
the comma key to a w (because in Dvorak, you press what would be a
comma in QWERTY to get a w, and vice versa).

From the :help entry, I and the tip author would type the following to
accomplish this:

:set langmap=\,w

However, doing so gives:

E357: 'langmap': Matching character missing for w

This works, but I cannot justify why it would be needed:

:set langmap=\\,w

And, as a related problem, this means you need to type FOUR
backslashes to get a single backslash in a langmap. This seems wrong.

e.g. this gives the same error as above:

:set langmap=\\h

But this works:

:set langmap=\\\\h

Am I missing something here? It's certainly surprising behavior that
should be documented if intentional, but I'm not confident it's a
bug...yet.

Vim 7.3.353 "Vim without Cream" build.

Tony Mechelynck

unread,
Dec 9, 2011, 11:44:25 AM12/9/11
to vim...@googlegroups.com, Ben Fritz

What you are missing is documented under :help option-backslash

In order to get a backslash in the value of an option, you need two in
the :set statement; in order to get two, you need four. Similarly, if
you want a space, a tab or a vertical bar to be part of the value of an
option, you need backslash-escaping in the :set statement.

When it is said under 'langmap' that "special characters must be
preceded by a backslash", it means they must be preceded by a backslash
in the _value_ of the option; but _setting_ that value already halves
the number of backslashes in the :set command.

If you want the langmap to change a comma to a w, you need to
backslash-escape the comma so it isn't used as a separator. This is done
by using

:set langmap=\\,w
or
:let &langmap = '\,w'

which are equivalent.

Similarly, to change a backslash to an h, you need

:set langmap=\\\\h
or
:let &langmap = '\\h'

because a backslash-escaped backslash must remain in the value of the
option.


Best regards,
Tony.
--
"It's a small world, but I wouldn't want to have to paint it."
-- Steven Wright

Ben Fritz

unread,
Dec 9, 2011, 2:00:55 PM12/9/11
to vim_dev

On Dec 9, 10:44 am, Tony Mechelynck <antoine.mechely...@gmail.com>
wrote:


> What you are missing is documented under :help option-backslash
>
> In order to get a backslash in the value of an option, you need two in
> the :set statement; in order to get two, you need four. Similarly, if
> you want a space, a tab or a vertical bar to be part of the value of an
> option, you need backslash-escaping in the :set statement.
>
> When it is said under 'langmap' that "special characters must be
> preceded by a backslash", it means they must be preceded by a backslash
> in the _value_ of the option; but _setting_ that value already halves
> the number of backslashes in the :set command.
>

Thanks, Tony; it all makes sense now.

How about a change to :help 'langmap', so that it reads:

The 'langmap' option is a list of parts, separated with commas. Each
part can be in one of two forms:
1. A list of pairs. Each pair is a "from" character immediately
followed by the "to" character. Examples: "aA", "aAbBcC".
2. A list of "from" characters, a semi-colon and a list of "to"
characters. Example: "abc;ABC"

Special characters ';', ',', and backslash itself need to be preceded
in the option value with a backslash, meaning you must escape
backslashes twice in a |:set| command.

Example for mapping the first few alphabetic characters to their
capitalized counterpart, and also mapping '\' to I and ',' to J: >
set langmap=aA,fgh;FGH,cCdDeE,\\\\I,\\,J

Tony Mechelynck

unread,
Dec 9, 2011, 2:42:27 PM12/9/11
to vim...@googlegroups.com, Ben Fritz, Bram Moolenaar
On 09/12/11 20:00, Ben Fritz wrote:
>
>
> On Dec 9, 10:44 am, Tony Mechelynck<antoine.mechely...@gmail.com>
> wrote:
>> What you are missing is documented under :help option-backslash
>>
>> In order to get a backslash in the value of an option, you need two in
>> the :set statement; in order to get two, you need four. Similarly, if
>> you want a space, a tab or a vertical bar to be part of the value of an
>> option, you need backslash-escaping in the :set statement.
>>
>> When it is said under 'langmap' that "special characters must be
>> preceded by a backslash", it means they must be preceded by a backslash
>> in the _value_ of the option; but _setting_ that value already halves
>> the number of backslashes in the :set command.
>>
>
> Thanks, Tony; it all makes sense now.
>
> How about a change to :help 'langmap', so that it reads:
>
> The 'langmap' option is a list of parts, separated with commas. Each
> part can be in one of two forms:
> 1. A list of pairs. Each pair is a "from" character immediately
> followed by the "to" character. Examples: "aA", "aAbBcC".
> 2. A list of "from" characters, a semi-colon and a list of "to"
> characters. Example: "abc;ABC"
> Special characters ';', ',', and backslash itself need to be preceded
> in the option value with a backslash, meaning you must escape
> backslashes twice in a |:set| command.
(see |option-backslash|)

>
> Example for mapping the first few alphabetic characters to their
> capitalized counterpart, and also mapping '\' to I and ',' to J:>
> set langmap=aA,fgh;FGH,cCdDeE,\\\\I,\\,J
>


Best regards,
Tony.
--
Your conscience never stops you from doing anything. It just stops you
from enjoying it.

Reply all
Reply to author
Forward
0 new messages