I often have to join lines especially in comments in my code. I'm
working in PHP. Due the joining, the comment character from the
beginning of the joined line remains. vim is clever enough to remove the
whitespaces.
Is there a way to configure vim to automatically remove the comment
character and also the the extra space?
Comment characaters can be #, * and //
Example 1, before join
/**
* foo [CURSOR]
* bar
*/
Example 1, after join, currently:
/**
* foo [CURSOR] * bar
*/
Example 1, after join, wished:
/**
* foo [CURSOR] bar
*/
Example 2, before join
// foo
// bar
Example 1, after join, currently:
// foo // bar
Example 1, after join, wished:
// foo bar
thanks!
- Markus
Don't use J to join the lines, but one of the auto formatting commands such as gq.
One way to make it work on one line and the following is to issue gqj.
Cheers,
Ben.
Send instant messages to your online friends http://au.messenger.yahoo.com
> Don't use J to join the lines, but one of the auto formatting commands such as gq.
> One way to make it work on one line and the following is to issue gqj.
I tried the 'gqj' combination, but the only the happening was that the
cursor moved to the next line on the first comment character, there was
no joining. What did I wrong?
1 <?php
2 /**
3 * Foo bar baz
4 * La Fal Bla
5 */
I positioned my cursor on the end of line 3, after gqj it was on line 4
on the '*'.
thank you,
- Markus
How odd. One of your settings must be different. Are you using filetype
detection/syntax highlighting etc., because that should set it right? You haven't
got a mapping or plugin that could be interfering? If not, perhaps doing
:set fo+=q
would help.
If that doesn't do the trick, perhaps show me your output of
:set
(to capture it you can do
:redir > somefile | set | redir END
and then find it in somefile)
Then I can quite probably spot what is different that is causing the trouble.
It definitely works for me, even with vim started without init files and so on. I
place the cursor anywhere on line 3 and do gqj and then the cursor is on the * in
line 3 which then reads
* Foo bar baz La Fal Bla
Ben Schmidt wrote:
> How odd. One of your settings must be different. Are you using filetype
> detection/syntax highlighting etc., because that should set it right? You haven't
> got a mapping or plugin that could be interfering? If not, perhaps doing
>
> :set fo+=q
Comment formatting is activated.
> Then I can quite probably spot what is different that is causing the trouble.
Very nice of you taking the time. The file is attached.
I've to confess that since I discovered the script-configure-ability of
vim I'm changing things left and right as I go ahead, but sometimes it's
hard to track down what has gone havoc and why :)
I'm currently thinking about a brute force hack, which remaps J do go
into the specifics of detecting whether I'm in a comment, join lines and
remove comment-characters:
:map J <ESC>:if getline('.') =~ /\s*\*\s* | normal "dwxdwi <ESC>" | endif
It's just a starting attempt and doesn't even work ;)
cheers,
- Markus
It's the 'w' in your formatoptions. Because your line 3 doesn't end with a space,
Vim thinks the next line starts a new paragraph so it doesn't join it. A
:set fo-=w
should fix it. Or adding a space at the end of all the lines you want joined to
the next. :-)
Of course, if you still want your fo to have 'w' in it, you could make a mapping
to do the joining without it, e.g.
:map J :call JoinWithComments()<CR>
:function! JoinWithComments()
:let oldfo=&fo
:setlocal fo-=w
:normal gqj
:let &fo=oldfo
:endfunc
But I don't see any reason you'd want a 'w' in formatoptions when you're editing
code anyway. Much better to take it out and save it for any occasion you're
editing text in paragraphs with trailing spaces.
Smiles,
Ben Schmidt wrote:
> It's the 'w' in your formatoptions. Because your line 3 doesn't end with a space,
> Vim thinks the next line starts a new paragraph so it doesn't join it. A
>
> :set fo-=w
You're unbelievable :) Yes, that was it. I didn't realized it was there.
I was using "filetype indent on" since sometime and the indent/php.vim
script by default modifiers the formatoptions and also adds the 'w'
flag. I've disabled this now with "let PHP_autoformatcomment=0".
>
> :map J :call JoinWithComments()<CR>
> :function! JoinWithComments()
> :let oldfo=&fo
> :setlocal fo-=w
> :normal gqj
> :let &fo=oldfo
> :endfunc
The one thing I prefer about 'J' is that the cursor is positioned at the
junction, which it isn't with 'gqj'.
I'm still trying to get it with with J and currently would like to have
something like:
autocmd BufRead *.php nmap <buffer> J :call
Mfn_PHP_JoinWithoutCommentChar()<CR>
function! Mfn_PHP_JoinWithoutCommentChar()
normal J2x
endfunction
However this causes a recursion. I tried with nnoremap but it didn't
work either. Do you think you can help me here, too?
> But I don't see any reason you'd want a 'w' in formatoptions when you're editing
> code anyway. Much better to take it out and save it for any occasion you're
> editing text in paragraphs with trailing spaces.
Me neither, thanks again for pointing this out!
sincerely,
- Markus
You probably want BufNewFile,BufRead in your autocmd so you catch the situation
when you do edit a non-existent file (to create it).
> However this causes a recursion. I tried with nnoremap but it didn't
> work either. Do you think you can help me here, too?
If you don't have a particular reason for putting it in a function, just doing
nnoremap <buffer> J J2x
should do the trick, avoiding the recursion, I believe.
If you still want the function, there are two approaches that spring to mind:
(1) you could make use of the feedkeys() function which has an option to not remap
keys. In this case, the body of your function would be
feedkeys('J2x','n')
(2) you could use nnoremap <expr> an <expr> map has an expression as its right
hand side, and then whatever that expression evaluates to becomes the rhs. So, you
make your function return the rhs you actually want for the mapping, and you get
nnoremap <buffer> <expr> J Mfn_PHP_JoinWithoutCommentChar
function! Mfn_PHP_JoinWithoutCommentChar()
return "J2x"
endfunction
The "J2x" is returned from the function, becomes the rhs of the mapping, and then
is executed without remapping.
I think!
I haven't tested any of this.
But that's three alternatives to play with!
Cheers,
Ben Schmidt wrote:
> You probably want BufNewFile,BufRead in your autocmd so you catch the situation
> when you do edit a non-existent file (to create it).
I'm using BufEnter because I only want it to have for PHP files. I think
when I just make BufRead .. map it will be globally.
> (1) you could make use of the feedkeys() function which has an option to not remap
> keys. In this case, the body of your function would be
>
> feedkeys('J2x','n')
Awesome, this worked! You're incredible :)
I've now this:
" When joining lines in a comment, remove the comment character.
autocmd BufEnter *.php nmap <buffer> J :call
Mfn_PHP_JoinWithoutCommentChar()<CR>
function! Mfn_PHP_JoinWithoutCommentChar()
" Only perform our custom join when the current and next line is a
comment
if getline('.') =~ '^\s*\(\*\|#\|//\)' && getline(line('.')+1) =~
'^\s*\(\*\|#\|//\)'
" before doing the join, remove trailing whitespaces
setline('.', substitute(getline('.'), '\s*$', '', ''));
call feedkeys('J2x', 'n')
else
call feedkeys('J', 'n')
endif
endfunc
Works nicely, except that setline() actually does nothing. I've made a
simple testcase, setline(10, 'foo') but there's no modification, though
setline() returns 0. I couldn't find anything in the documentation why
it dosn't work. But that's minor now :)
again, many thanks,
- Markus
Markus Fischer schrieb:
>
> I'm still trying to get it with with J and currently would like to have
> something like:
>
> autocmd BufRead *.php nmap <buffer> J :call Mfn_PHP_JoinWithoutCommentChar()<CR>
> function! Mfn_PHP_JoinWithoutCommentChar()
> normal J2x
> endfunction
>
> However this causes a recursion. I tried with nnoremap but it didn't
> work either. Do you think you can help me here, too?
to prevent the recursion you should use
normal! J2x
instead. The '!' tells Vim not to use mappings.
Regards,
Jürgen
--
Sometimes I think the surest sign that intelligent life exists elsewhere
in the universe is that none of it has tried to contact us. (Calvin)
No, it can be local with BufRead,BufNewFile just like BuEnter.
autocmd BufRead,BufNewFile *.php nmap <buffer> J ...
Using BufEnter would be less efficient, too, as it happens every time you move the
cursor into the buffer, not just when the buffer is opened.
> setline('.', substitute(getline('.'), '\s*$', '', ''));
Setline is a function too, so you need to put a 'call' before it for it to work
(and you don't want the semicolon at the end). It works for me once I have that!
O yeah. Don't believe I forgot about that.
Well, there's yet another alternative.
Grins,
Ben Schmidt wrote:
> No, it can be local with BufRead,BufNewFile just like BuEnter.
>
> autocmd BufRead,BufNewFile *.php nmap <buffer> J ...
Nice!
> Using BufEnter would be less efficient, too, as it happens every time you move the
> cursor into the buffer, not just when the buffer is opened.
>
>> setline('.', substitute(getline('.'), '\s*$', '', ''));
>
> Setline is a function too, so you need to put a 'call' before it for it to work
> (and you don't want the semicolon at the end). It works for me once I have that!
Forgetting "call" bites me all the time. Yes, the ';' is a habit, I guess.
Ben and Jürgen, thanks for the tips. It now works marvelous!
- Markus