Monday, March 28, 2011

Re: Function to write correctly French quotation marks

On Tue, March 29, 2011 8:04 am, Steve wrote:
> Le 23-03-2011, à 17:57:53 +0100, Christian Brabandt (cblists@256bit.org) a
> écrit :
>> On Wed, March 23, 2011 3:20 pm, Steve wrote:
>> > In French, we do not write "word" or 'word', we write « word », with a
>> > non-breakable space after « and before ». Until now, I do:
>> >
>> > <c-k><<<c-k>NSword<c-k>NS<c-k>>>
>> >
>> > which is really not convenient. I'd like a function, say Guillemets(),
>> > which does that automatiquelly. I would then map it to a function key
>> FN
>> > (or whatever else) and just call it in normal mode. Problem, I really
>> > don't have the necessary skills to do that.
>> >
>> > Anybody could help?
>>
>> Does those two mappings help you?
>>
>> :imap <expr> " getline('.')[col('.')-2]=~'\S' ? ' »' : '« '
>> :imap <expr> ' getline('.')[col('.')-2]=~'\S' ? ' »' : '« '
>
> In fact, both don't do anything. I replaced <expr> by <F10> or
> <Leader>gu, but nothing happens. But since I was using vim through a
> putty connexion (from a w XP box), I thought that could be the reason.
> So I installed vim 7.1 on the windows box, then created a _vimrc file
> with both lines, and still nothing.

The idea is, to use an expression-mapping (:h map-expression) and
analyze what is one character before the quote. For example the first
mapping translates to:

:imap " Map in insert mode
<expr> " use an expression-mapping (that is, evaluate the right side of
" the mapping, instead of replacing literally
" " When a quote is typed replace by this expression:

getline('.')[col('.')-2] =~ '\S' ? ' »' : '« '

The right side uses the short form of an if-else statement <expr1> ?
<expr2> : <expr3> which is equivalent to if <expr1> is true, then <expr2>
else <expr3>.

This means, get the character before the quote. If this character
matches a non-space ('\S'), we assume the quotes come after a word has
ended, so you are ending the quote. Therefore we will replace the double
quote by ' »'. Else if the character before the quote does not match
non-whitespace, that means there is some whitespace in front of it and
we assume a new quotation will be started, so the double quote is
replace by '« '

See also the help:
:h expr1
:h getline()
:h col('.')
:h /\S
:h map-expression

> I tried to understand the meaning of those two lines, but failed, even
> with the help of google.
>
>> (the space inside the single quotes was inserted literally as
>> non-breaking
>> space, e.g. by entering <c-k>NS).
>
> I did the same.
>
> I was wondering if a substitution could help, something like:
>
> s/word/« word »/
>
> But I don't know how to catch word (or even several words, maybe with
> visual mode).

You can possibly also do something like this:

nmap <silent> <F10> :s/\(['"]\)\(<C-R><C-W>\)\1/« \2 »/e<cr>

Which should take the word under the cursor and replace it by your the
guillemets, if it has a quotation around it. See :h c_<C-R><C-W>, to
insert the word under the cursor.

The 'e' flag to the :s command, prevents, that an error message is
given, when no match is found and the <silent> prevents, that the
mapping will be echoed in Vims commandline.

The same for visual mode can be expressed like this:

xmap <silent> <F10> :s/\(['"]\)\(\S\+\)\1/« \2 »/eg<cr>

where it will replace all non-whitespace enclosed quotes by the
guillemets, that are inside your visual selection (or more correct, that
are on the lines, defined by your visual selection. You could add the
'\%V' atom at the beginning and end of your pattern, to make sure to
only replace within the visual selected region, but unfortunately the
'\%V' atom has some bugs and doesn't always match correctly).

> More help would be greatly appreciated.

Hope this helps to understand what happens. If you have still problems,
please let us know.

regards,
Christian

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

No comments: