vim key mapping with execute normal not working - vim

I want to highlight trailing space at the end of a line in vim. The following command works:
:match Error /\v\s+\n/
But I'm having trouble mapping this to a key:
nnoremap <leader>w :execute "normal! :match Error " . '/\v\s+\n/' . "\<cr>"
Vim responds with:
E114: Missing quote: "\
E15: Invalid expression: "normal! :match Error " . '/\v\s+\n/' . "\
Update:
Having just seen this: http://vim.wikia.com/wiki/Highlight_unwanted_spaces I've got the mapping working, by just writing:
nnoremap <leader>w :match Error /\v\s+\n/<cr>
Can anyone explaing what the problem is with the original execute normal! ... construct which prevents it from working?

your mapping
I think it should be
nnoremap <leader>w :execute "normal! :match Error " . '/\v\s+\n/' . "\<lt>cr>"<cr>
:help <lt> I am not super aware of exactly why this is needed (once upon a time, my executes, too, were not working, as I had \<esc> and \<cr> in my execute "normal! .."s. Just know that in place or <cr>, you need to use \<lt>cr> for <cr> in this construct.
You also need the <cr> at the end to actually run the :execute ".."<cr> command.
easier solution
Also, I think it's easier to just put
set listchars=trail:·
set list
in your vimrc, and then you will be able to see trailing white space.
Personally, I have set listchars=trail:·,tab:»\ ,extends:» in my vimrc.
and an easy regex search (/\s\+$) reveals the white space, which you can easily delete with d$ ("delete 'till end"). Then once you do that, you can press n. to "go to next" then "repeat" the d$.
cool tip
Once you highlight your search pattern, you can even dgn to "select next occurrence and delete it" in one go -- then you can just repeatedly press . until nothing happens ... :help gn. Also, mess around with cgn; it's pretty neat stuff.
Cheers.

Related

Map :%s/^M//g in vimrc

I'm trying to map a command in my vimrc to remove the carriage return character ^M that I sometimes see in files. :%s/^M//g (^M from ctrl-v, ctrl-m) works pretty easily when I'm in the file, but when I save that in my vimrc, it's no good.
nmap ,dm :%s/^M//g <cr>
I'm guessing it's because ^M is interpretted differently when mapped via vimrc, so I tried escaping it with \, to no avail. How can I map this command so that it removes the carriage return characters?
FWIW, I'm using gVim on Windows.
Almost every vim user reaches a moment he wants to solve this issue elegantly and one thing I figured out is that we also need a solution to get rid of ^M and keep the cursor position at once.
Personally I use a function to preserve my cursor position, because when we get rid of ^M the cursor position will change:
" preserve function
if !exists('*Preserve')
function! Preserve(command)
try
let l:win_view = winsaveview()
"silent! keepjumps keeppatterns execute a:command
silent! execute 'keeppatterns keepjumps ' . a:command
finally
call winrestview(l:win_view)
endtry
endfunction
endif
The propper function to get rid of ^M
" dos2unix ^M
if !exists('*Dos2unixFunction')
fun! Dos2unixFunction() abort
"call Preserve('%s/ $//ge')
call Preserve(":%s/\x0D$//e")
set ff=unix
set bomb
set encoding=utf-8
set fileencoding=utf-8
endfun
endif
com! Dos2Unix :call Dos2unixFunction()
As you can see we are using \x0D$ instead of ^M, which is the hexadecimal code for the ^M
The option set bomb helps considering the file as UTF-8 help here. It helps solving encoding issues.
The function "Preserve" can also be used to many other stuff like reindenting the whole file without "moving" our cursor
command! -nargs=0 Reindent :call Preserve('exec "normal! gg=G"')
The above line will set a "Reindent" command with no arguments "-nargs=0". By the way feel free to stell some pieces of my init.vim here
NOTE: It is worth mention the "ifs" preceding the two functions above, it is called guard, it helps us to avoid loading functions twice in the memory, thus, keeping our vim/neovim responsible as much as possible.

Hitting ENTER on quickfix error jumps to an empty buffer

I'm using GVim 8.1 on Windows 10 with no external plugins.
I have the following set up in my .gvimrc file:
let g:build_file_abs_path = fnamemodify(findfile("windows-build.bat", ";."), ":p:h")
" This build script is a basic wrapper for 'clang.exe file.c -o file.exe' style invocation
let &makeprg=g:build_file_abs_path . "\\windows-build.bat"
nnoremap <silent> <C-B> :cd <C-R>=g:build_file_abs_path<CR> <bar> make! <bar> copen <bar> redraw <bar> cd -<CR>
Now, this automatically opens a quickfix window with the correct compiler output. However, when I press ENTER over the error, the cursor jumps to the buffer for the affected file, yet it is completely blank with a single line. Furthermore, this occurs as I use :cn and :cp commands inside the quickfix window. e.g:
Images showing these two states:
before
after
Please note that:
:verbose nmap <CR> returns no mappings, so there is not conflict there.
I would appreciate it if someone could provide some insight as to how to avoid the buffer becoming empty and actually jump to the error in the appropriate file. Many thanks.
Thanks to Christian Brabandt's comment, I was able to solve the issue. I was misunderstanding the distinction between the working directories of vim and the build script. I made the following changes:
let &makeprg="cd " . g:build_file_abs_path . " && windows-build.bat"
nnoremap <silent> <C-B> :make! <bar> copen <bar> redraw <CR>

What is wrong with this line? nnoremap <C-[> :execute "normal! A{{{\<Esc>"<CR>

I am trying to add this to my vimrc but I am getting problems one it inserts {{{ at the beginning of my vimrc whenever I open it and also it apparently has 'c' in the regiser as the last pressed key so it deletes the first 2 lines when I press j
And when I run the command it complains that
"A{{{\ is missing a quotation mark and is not a command.
This gave me tip. map execute command vim
You don't need use :execute "normal! ..." if you are using nnoremap. This will work.
nnoremap <C-[> A{{{<Esc><CR>

How to delete training characters without annoying `E486: Pattern not found` error?

I'm trying to automatically delete trailing characters at the end of line (on save). According to wiki I create the following mapping:
nmap <silent> <leader>rt :let _s=#/<Bar>:%s/\s\+$//e<Bar>:let #/=_s<Bar>:nohl<CR>
nmap <silent> <leader>w <leader>rt:write<CR>
The problem is when there is no trailing characters the E486: Pattern not found: \s\+$ is occur and interrupt the next :write command. I tried to search something similar to my problem, but get nothing. Any ideas?
what you need is :silent[!] command. You can do:
:silent! %s/\s\+$//
The ! lets silent also skip error messages. But the v:errmsg was set anyway.
Read :h :silent for details.

<cr> doesn't work with `normal!`

I tried:
$ vi +'help|only|set nu|execute "normal! 48G<cr>zt"'
But the zt part doesn't apply. (48 is the Getting Started line)
Could someone please explain why the zt part doesn't work and why this:
$ vi +'help|only|set nu|execute "normal! /^Getting<cr>zt"'
doesn't even apply the search for /^Getting.
You don't need a <cr> after a G command.
vi +'help|only|set nu|execute "normal! 48Gzt"'
works fine for me.
Additionally, you need to specify the Enter character instead of <cr> (which you can write by typing Ctrl-V and then the Enter key) if you want to use search.
The command shows up like this :
vi +'help|only|set nu|execute "normal! /^Getting^Mzt"'
But the ^M is actually the Ctrl-v-Enter binding

Resources