I read this stack thread on how to save a mapping permanently in vim.
I went to /etc/vim/vimrc and added the :map ,k :!python % <enter> in the first line of the file. When I open a new python file with vim the command responds by showing :!python % <enter> at the bottom of the screen. But it doesn't execute automatically. How do I fix this command to execute 'enter' automatically?
i think you rather want to use a local version ~/.vimrc for local settings than editing global settings in the file /etc/vim/vimrc. There you can add:
let maplocalleader=","
map <localleader>k :!python %<cr>
i would advise to not use ^M as explained in ZyX comment to ghoti's answer see
Edit
ZyX' comment made me change the code above to
filetype plugin on
augroup ft_python
au!
au FileType python nnoremap ,k :!python %<cr>
augroup END
which keeps ,k from messing with other stuff
filetype plugin on says that we want to have things done if a file has a certain filetype - in our case python
augroup ft_python says i want to have a group of autocommands := "commands that are invoked when opening a file" with that group-name
au! removes all autocommands
au Filetype python declares an autocommand=au for all files of type python
augroup END leaves the group ft_python and goes back to general settings
so this makes it possible to have ,k act as 'compile' in python but when i accidentally press ,k in another file say a c-source code, it does nothing (or the things i told ,k to be for c-source code somewhere else in my .vimrc).
Put in a literal carriage return character instead - press Ctrl + V, then Enter when writing the map:
:map ,k :!python %^M
You'll see the carriage return shown as ^M after typing the sequence Ctrl + V, then press the enter key.
That Ctrl + V key tells vim to insert the next character that you type.
The answer I was looking for is to paste :map :!python % <enter> in ~/.vimrc
Related
How can i write a hook function that will place the cursor at the end of the file on opening a file.
In elisp, it looks approximately like this,
(add-hook 'open-buffer-hook
(lambda () (end-of-buffer)))
In vim, I can open a file and press :$ to go to the end but i am keen on doing it via a hook.
Using autocmd you may hook into BufReadPost and execute something like G$ in normal mode to advance to the last line and the last character.
autocmd BufReadPost * :normal G$
I used BufReadPost to cause this command to run after the file is fully read into the buffer. The * applies this rule to all buffer types, but you could limit it by FileType or by filename pattern as well. See :help autocmd for more details.
An autocommand seems too much to me.
In your shell,
$ vim file +$
opens file in Vim and jumps to the last line.
In Vim,
:edit +$ file
opens file and jumps to the last line.
This works with other related commands like :vsplit or :tabedit.
It you just want to open files from the command line, you can use
vim +':norm G$' file.txt
I tried to put the following in my file header:
#!/bin/sh
# vim:set ts=2 sts=2 sw=2 expandtab:
# vim:map <leader>t :w\|:!./script.sh <cr>:
But Vim always complains about the map, saying that it's invalid. I also tried nnoremap with no success. What should I do to fix this (I want it in this file only)?
Modelines are only for options.
If you want this mapping only for that file, add this snippet to your ~/.vimrc:
augroup ThisFile
autocmd!
autocmd BufRead,BufNew /path/to/file nnoremap <buffer> <leader>t :w\|:!./script.sh <cr>:
augroup END
edit
It looks like you want a mapping for executing the current file. If so, you are really chasing the wrong rabbit, here, and also crashing real hard in the XY Problem wall.
You can use % as a synonym for "the file associated with the current buffer" so, assuming your script is executable, this command would execute it:
:w|!./%<CR>
Therefore, you could simply put this generic mapping in your ~/.vimrc:
nnoremap <leader>t :w\|!./%<CR>
Note 1: See :help c_% for the meaning of % and in that context.
Note 2: The bar needs to be escaped when used in a mapping, see :help map_bar.
Is there a way to search the list of recently used file in Vim? The list can be displayed using
browse old
but / does not work. I am aware of some plugins (e.g. MRU) but would prefer to not use a plugin.
Here's a short scriptlet that opens the file list in a scratch buffer. As a bonus, it defines a local <Enter> mapping to :edit the current file. With this, you can search with all built-in commands like /:
:new +setl\ buftype=nofile | 0put =v:oldfiles | nnoremap <buffer> <CR> :e <C-r>=getline('.')<CR><CR>
If you really want to avoid a plugin:
:new The old files will be printed into this buffer
:redir #X where X is a temporary register`
:silent echo(v:oldfiles) 'Silent' is there to not actually print onto your screen
:redir END
"Xp paste the temporary register
(optional) Do some regex-fu to put each file on its own line.
Put the above into a function and voila. Also :help redir
It's actually not very hard to write a simple (simplistic?) MRU command with completion that works like :edit or :split:
" this is our 'main' function: it couldn't be simpler
function! MRU(arg)
execute 'edit ' . a:arg
endfunction
" the completion function, again it's very simple
function! MRUComplete(ArgLead, CmdLine, CursorPos)
return filter(copy(v:oldfiles), 'v:val =~ a:ArgLead')
endfunction
" the actual command
" it accepts only one argument
" it's set to use the function above for completion
command! -nargs=1 -complete=customlist,MRUComplete MRU call MRU(<f-args>)
Here is a .vimrc version of code above. Just add following lines to .vimrc and map to desired keys (in my case it is 'o). In addition define patterns to remove "junk" files. Also cursor is placed at the top for convenience.
Most hard thing is to map an Enter inside nested nmap. ^V is the result of doubled Ctrl-V. ^R is the result of Ctrl-V+Ctrl-R. ^M is the result of Ctrl-V+Enter. You need manually repeat those symbols - not just Copy/Paste. Spent hours to understand this magic - so I'm glad to share. This technology lets you add own macroses in .vimrc.
" Browse Old Files
nnoremap <silent> 'o :enew<CR>:set buftype=nofile<CR>:set nobuflisted<CR>:exe "0put =v:oldfiles"<CR>:nmap <buffer> ^V^V^M :e ^V^V^R=getline('.')^V^V^M^V^V^M<CR>:g/\v(stdout\|nerd\|fugitive)/d<CR>:0<CR>
This is my take on Ingo's answer above for my .vimrc:
Opens the old files in either a vertical split or tab, then maps enter to open file under cursor! magic!
" open old files list and map enter to open line
" vertical split
noremap <leader>vv :vnew +setl\ buftype=nofile <bar> 0put =v:oldfiles <bar> nnoremap <lt>buffer> <lt>CR> :e <lt>C-r>=getline('.')<lt>CR><lt>CR><CR><CR>
" in new tab
noremap <leader>vt :tabnew +setl\ buftype=nofile <bar> 0put =v:oldfiles <bar> nnoremap <lt>buffer> <lt>CR> :e <lt>C-r>=getline('.')<lt>CR><lt>CR <CR><CR>
Weird issue here: I'm trying to avoid the Esc key to exit from insert mode. I stumbled upon this article: http://vim.wikia.com/wiki/Avoid_the_escape_key and I liked the following solution:
" Two letters.
:imap çç <Esc>
When in gVim I type:
:imap çç <Esc>
I does work. But when I try to make it default by putting it in my _vimrc file:
imap çç <ESC>
I doesn't work. It gives me no error, but does not work. Every other letter works, but it seems that specifically the letter ç doesn't.
You could write :
au VimEnter * imap çç <ESC>
in your .vimrc . au is short of autocmd and it is used to tell vim that you want to execute this one as a semicolon command. VimEnter is telling vim to execute it on startup.
The syntax is :
autocmd events pattern command
You could also see the help for autocmd
Try using the following:
Add
scriptencoding utf-8
set encoding=utf-8
at the very beginning of your vimrc.
Be sure that vimrc is saved in UTF-8 itself.
what I am using now is ,
autocmd BufWritePost *.py !python PythonTidy.py % %
It really call the tidy programe and change the file, but the vim does not reload the new file.
And I do not want to install another plugin for it.
=======================
note: I found it's dangerous about this feature, PythonTidy will will output a empty file if the command faild, it means if you have syntax error, you will lose your file unless press "u" to get it,but you can't save before you fix syntax error.
I call :!PythonTidy % % manually after pylint complete now.
Use BufWritePre instead of BufWritePost and combine Vim range filtering with PythonTidy’s stdin/stdout mode.
autocmd FileType python autocmd BufWritePre <buffer> let s:saveview = winsaveview() | exe '%!python PythonTidy.py' | call winrestview(s:saveview) | unlet s:saveview
(The use of autocmd FileType python autocmd BufWritePre <buffer> makes this a bit more accurate than matching on a glob pattern: it means “any time a Python file is detected, install this autocmd for that buffer” – so it works independently of file name.)
Unfortunately this cannot preserve your cursor position if you undo the filtering. (You are filtering a whole-file range; when undoing a filter operation, the cursor jumps to the first line in the range; so you end up at the top of the file.) I was hoping to find a way to create a no-op undo state, before, so you could hit u twice and get back to the right place, but I can’t make that work as yet. Maybe someone else knows how.
hi the following fixed the cursor postion problem
function! PythonTidySaver()
let oldpos=getpos('.')
%!PythonTidy
call setpos('.',oldpos)
endfunction
autocmd! bufwritepost *.py call PythonTidySaver()
Based on :help :e:
*:e* *:edit*
:e[dit] [++opt] [+cmd] Edit the current file. This is useful to re-edit the
current file, when it has been changed outside of Vim.
This fails when changes have been made to the current
buffer and 'autowriteall' isn't set or the file can't
be written.
Also see |++opt| and |+cmd|.
{Vi: no ++opt}
So you'd need to use :e after updating the file externally. However, :! doesn't let you use | normally (see :help :!), so you need to wrap it:
autocmd BufWritePost *.py execute "!python PythonTidy.py % %" | e
(:autocmd doesn't interpret | normally either, which is why you don't need to escape it yet again.)