Vim in insert mode jumps to start of line when entering # [duplicate] - python

When I add a # in insert mode on an empty line in Vim while editing python files, vim moves the # to the beginning of the line, but I would like the # to be inserted at the tab level where I entered it.
For example, when writing this in vim
for i in range(10):
#
the # does not stay there where I entered it.
It is moved like so, by vim.
for i in range(10):
#
Does anyone know of a configuration item in vim that would change this?
If it helps, I am using Ubuntu 8.10.

I found an answer here http://vim.wikia.com/wiki/Restoring_indent_after_typing_hash
It seems that the vim smartindent option is the cause of the problem.
The referenced page above describes work-a-rounds but after reading the help in smartindent in vim itself (:help smartindent), I decided to try cindent instead of smartindent.
I replaced
set smartindent
with
set cindent
in my .vimrc file
and so far it is working perfectly.
This changed also fixed the behavior of '<<' and '>>' for indenting visual blocks that include python comments.
There are more configuration options for and information on indentation in the vim help for smartindent and cindent (:help smartindent and :help cindent).

#PolyThinker Though I see that response a lot to this question, in my opinion it's not a good solution. The editor still thinks it should be indented all the way to left - check this by pushing == on a line that starts with a hash, or pushing = while a block of code with comments in it is highlighted to reindent.
I would strongly recommend filetype indent on, and remove the set smartindent and set autoindent (or set cindent) lines from your vimrc. Someone else (appparently David Bustos) was kind enough to write a full indentation parser for us; it's located at $VIMDIRECTORY/indent/python.vim.
(Paul's cindent solution probably works for python, but filetype indent on is much more generally useful.)

I have the following lines in my .vimrc, seems to be installed by default with my Ubuntu 8.10
set smartindent
inoremap # X^H#
set autoindent
And I don't observe the problem. Maybe you can try this. (Note that ^H should be entered by Ctrl-V Ctrl-H)

My solution to the unindenting of #:
If you use cindent, recognize that it is designed for C and C++ coding. Here, a # means you are creating a #DEFINE or #MACRO(), so the behavior is correct. But for other languages where # is a comment, it is irritating.
The following worked for me:
" cindent enable specific indenting for C code
" set cin nocin
set cin
" cinkeys The default cinkeys causes leading # to unindent to column 0.
" To prevent this, remove the 0# from the definition.
" set cinkeys=0{,0},0),:,0#,!^F,o,O,e - default
set cinkeys=0{,0},0),:,!^F,o,O,e

It's caused by the 'smartindent' feature. If you have :set smartindent in your .vimrc you need to remove it.

Some of the other answers were useful, but none were enough to prevent Vim from reindenting a line when '#' is the first character. PolyThinker's answer didn't work for me, but it gave a clue that '#' could be remapped to "insert a character, then #, then delete the extra character and put the cursor where it should be". This is the mapping that does that:
inoremap # X#<left><backspace><right>
This is needed because vim's syntax packages seem to treat '#' as a special character, no matter how the options are set. I want a line started with '#' to be the same as a line begun with any other character. The most reliable solution I've found is the above mapping, which actually does change the line's first character.
Note: I've found this mapping causes problems after running I#<esc> then pressing "." to redo the previous insertion. I haven't found a solution yet.

My Vim configuration doesn't do that. You might try the python.vim script available from this link: http://www.vim.org/scripts/script.php?script_id=790

I removed set smartindent from ~/.vimrc but it still didn't disable smartindent. When I opened a .py file and ran :set smartindent? it displayed smartindent.
Turns out that further down in the ~/.vimrc was this line:
autocmd BufRead *.py set smartindent cinwords=if,elif,else,for,while,try,except,finally,def,class
^^^^^^^^^^^
Once I deleted "smartindent" from that line, then smartindent was finally disabled and my comments were indented properly again.

Related

VS Code Python autopep8 does not honor 2 spaces hanging indentation

I'm trying to get autopep8 work to properly indent Python code with 2 spaces instead of 4. I'm using VS Code with Python extension which uses autopep8 for formatting. I found here that autopep8 can be configured to use 2 spaces by
"python.formatting.autopep8Args": ["--indent-size=2"]
But it does not work for me.
My situation is like this. When I press enter, it correctly starts the next line with the same indentation as the previous line. Press enter after an open parenthesis, it correctly starts the new line with 2 more spaces. But when I paste or save (I have "editor.formatOnPaste" and "editor.formatOnSave" set to true), the annoying thing happened: all the 2-space indentation inside the parentheses became 4 (other 2-space indentation are unaffected). Why is it doing this and how can I make it 2 spaces everywhere?
====EDIT====
I found out that the pylint error Wrong hanging indentation (remove 2 spaces). [bad-continuation]. It's because my pylintrc has indent-after-paren=2. I'm wondering if autopep8 or other Python formatter can set this property?
I also had to include this in my array in settings.json, similar to yours.
"--ignore E121"
According to https://pypi.org/project/autopep8/, this setting ensures your indents are a multiple of 4. By not enforcing that, the configured tab size in VSCode is used.
E121 - Fix indentation to be a multiple of four.
That being said, your indentation is still "acceptable" according to pep8, so it actually will not change it to the 4 spaces you are expecting in your parens. I had to outdent mine one level, then when it ran again, it didn't change it.
Unfortunately this is actually just a workaround and it actually negatively affects other indention rules...
You can see in the code for pep8 that they hardcode the default tab size to be the "python way" (4 spaces) in:
https://github.com/hhatto/autopep8/blob/120537a051d7f3cbbb5c4ede19b9e515156bd3d1/autopep8.py#L104
That makes it look like the hanging indent is just not respecting the --indent-size option...
Adding --indent-size=2 --ignore=E121 worked for me.
had the same issue, here is the solution:
Navigate to library directory of your environment
Open autopep8.py
Search for "DEFAULT_INDENT_SIZE" and change it to 2

Prevent Vim from indenting line when typing a colon (:) in Python

Whenever I append a : character in Vim in Python mode, it either:
indents the line
dedents the line
does nothing
What is it even trying to do, and how do I get rid of this behavior?
Certain keys, when pressed, will trigger Vim's indent feature, which will attempt to set the correct amount of indentation on the current line. (You can manually trigger this by typing == in normal mode.)
You can change which keys trigger this behavior, but first you need to know what indenting mode is being used.
First, execute :set indentexpr?. If it is nonempty (I would expect this for Python), then indentexpr mode is being used. In this case, executing :set indentkeys? gives you the list of trigger keys. To remove the colon, execute :setlocal indentkeys-=:.
If indentexpr is empty, then you are probably using cindent mode, and :set cindent? will tell you that cindent is set. In this case, do the same as before, but using cinkeys instead of indentkeys. (Note that indentexpr mode takes precedence over cindent mode.)
Nathan Grigg's answer set me on the right track. I had to make a few changes for my setup.
I had to use :setlocal indentkeys-=<:>, because in my case :set indentkeys? showed indentkeys=0{,0},!^F,o,O,e,<:>,=elif,=except.
Also, putting :setlocal indentkeys-=<:> in .vim/after/ftplugin/python.vim did not work to make the change permanent. I found that there is a built-in vim python indent file that runs AFTER this after-ftplugin file.
To diagnose, open a Python file for editing, and run :scriptnames. That will show you a list of all the vim scripts that have run, in order of precedence. The scripts at the bottom of that list have been applied most recently, and take precedence. See this question on SuperUser for more info.
When I did that, it showed me a built-in vim file at /my-install-path/vim/7.4.1830/share/vim/vim74/indent/python.vim. Sure enough, that was setting <:> as part of the indent keys.
To fix it, I set an autocommand in .vimrc, and that really gets the last word.
autocmd FileType python setlocal indentkeys-=<:>
Update
I had to add :setlocal indentkeys-=: after all. Here's what I have in my .vimrc now.
autocmd FileType python setlocal indentkeys-=<:>
autocmd FileType python setlocal indentkeys-=:
It is trying to be helpful. If you want to turn off all the auto-indenting for the current file,
:setlocal noautoindent
:setlocal nocindent
:setlocal nosmartindent
:setlocal indentexpr=
Or, you can add set in your vimrc file. You can do these per file type too. See here
TL;DR I disabled autoindentation by typing:
:set indentexpr=
then hitting the ENTER key.
It's a quick fix without needing to understand indentkeys ..
Thanks to Christian Long for the docs to indentkeys, where I noticed (my emphasis):
A list of keys that, when typed in Insert mode, cause reindenting of
the current line. Only happens if 'indentexpr' isn't empty.
Tip - you might want to save a copy of the existing value of indentexpr before you clear it out. To see that (and any other values that are set) just type:
:set
HTH

How to maintain tabs when pasting in Vim

I use the tab key to indent my python code in Vim, but whenever I copy and paste a block Vim replaces every tab with 4 spaces, which raises an IndentationError
I tried setting :set paste as suggested in related questions but it makes no difference
Other sites suggest pasting 'tabless' code and using the visual editor to re-indent, but this is asking for trouble when it comes to large blocks
Are there any settings I can apply to vim to maintain tabs on copy/paste?
Thanks for any help with this :)
edit:
I am copying and pasting within vim using the standard gnome-terminal techniques (ctrl+shift+c / mouse etc.)
my .vimrc is:
syntax on
set ts=4
if has("terminfo")
let &t_Co=8
let &t_Sf="\e[3%p1%dm"
let &t_Sb="\e[4%p1%dm"
else
let &t_Co=8
let &t_Sf="\e[3%dm"
let &t_Sb="\e[4%dm"
endif
I looked up that ts -> Sets tab stops to n for text input, but don't know what value would maintain a tab character
See :h tabstop for all the options and how they interact with each other.
These are good settings if you prefer tabs:
set tabstop=4
set shiftwidth=4
set noexpandtab
With these settings, you hit <Tab> and you get <Tab>.
These are good settings if you prefer spaces:
set tabstop=4
set shiftwidth=4
set expandtab
With these settings, you hit <Tab> and you get <Space><Space><Space><Space>.
Whatever you choose, you should not use your terminal key bindings for copying/pasting. Inside Vim, you should "yank" with y and "put" with p or P; optionally using a specific register like "ay/"ap to yank/put to/from the content of #a or "+y/"+p to yank/paste to/from the system clipboard (if your Vim is built with clipboard support).
As a side note, you should use the long form names of your settings as they are more readable than their short counterpart. Your future self will thank you.
I was middle-click-pasting into a terminal vim instance. I have this in my vimrc:
set tabstop=2 " (ts)
set softtabstop=2 " (sts) Turned off with 0
set shiftwidth=2 " (sw) Used for autoindent, and << and >>
set expandtab " (et) Expand tabs to spaces
I ran
:set paste
:set noexpandtab
and vim preserved the tabs that were in the source text. Without overriding my expandtab setting, vim was auto-expanding the tabs in the source text.
What romainl said. Also, there are a few other settings that I find useful. Here is an excerpt from my .vimrc:
set autoindent " always set autoindenting on"
set smartindent " use smart indent if there is no indent file"
set tabstop=4 " <tab> inserts 4 spaces"
set softtabstop=4 " <BS> over an autoindent deletes 4 spaces."
set smarttab " Handle tabs more intelligently"
set expandtab " Use spaces, not tabs, for autoindent/tab key."
set shiftwidth=4 " an indent level is 4 spaces wide."
set shiftround " rounds indent to a multiple of shiftwidth"
In vim, enter :h <setting> for each of these settings to learn more about what they do,
First, make sure your indent settings represent your preferred style, as romainl has shown in his answer.
If you must paste code from outside Vim (e.g. a selection from another terminal), the :retab! command can fix up the spaces to Tabs; for the pasted text the full command with the proper range would be
:'[,']retab!
Alternatively, you could try pasting with the "*]p command, which automatically adapts the indent to the cursor position (see :help ]p).

Reindenting Python code in Vim

I need to enclose a block of code with a for loop. As this is Python I need to take care of indenting and increment the number of tabs by one. Any easy way to do this in Vim?
You can manually adjust indentation with < and >, and == will auto-indent a block of code.
Also, Indenting Python with Vim might be of help for getting some more advanced auto-indentation.
Lastly, ]p is a handy way to insert a yanked block of code, indenting it to the proper level (try yanking your block, moving the cursor to the start of your for loop, then pressing ]p).
Try hitting V for visual line mode, select the area you want to indent, and hit >. Other motions besides V are good, too.
Use this to indent or dedent code.
The fastest way you can try is v i p > from inside the block of code you want to indent. That wraps Visual mode Inside Paragraph, and > indents the selected code.
As well as the other excellent answers here, I would suggest adding this to your ~/.vimrc file:
vnoremap < <gv
vnoremap > >gv
This will make it so that when you select text in visual mode (press v) and then press > or < it won't drop you out of visual mode.
The following lines will also make vim try to auto-indent lines for you which can be useful:
set autoindent
set smartindent
Although you will need to disable this when you paste text in or it will try to indent it.
You can turn paste mode on/off with a key, mapped like this:
set pastetoggle=<F6>
Now F6 will toggle paste mode to allow you to paste text in without the auto-indent screwing it up.

vim highlighting everything in red

I added a print line to a python script while the script was executing, and now all the text is highlighted in red when I open the file. Opening and closing the file doesn't get rid of it. Opening a second python file momentarily fixed the problem, but then closing file and reopening brought the problem back. Now it wont go away at all. Any body know what could cause this?
This happens sometimes in vim when it goes to highlight syntax on multi-line comments. Occasionally everything after the multi-line comment also becomes colored the same as the comment.
I am unsure whether this is a legit bug in vim, or in the actual syntax settings for Python (e.g. python.vim), but I definitely experience this from time-to-time.
For a quick fix, you might try typing:
:hi Error NONE
And then hit Enter.
Old thread, but hope this helps.
By mistake I did a "/." on my vim screen, which highlighted all lines in red. If I open any other file, the red highlighting stays.
Try searching for some other keyword, let's say "/word" - doesn't matter word exists or not. It restores the color.
You probably have an unterminated multiline string. They start and end with either three single or three double quotes.
''' <== this is the start of a multiline string
this is still in the string
this is the last line '''
As per this article http://vim.wikia.com/wiki/Fix_syntax_highlighting, I mapped F12 to resync the syntax highlighting from the start of the file. It has worked better in some instances where <ctrl-l> didn't.
noremap <F12> <Esc>:syntax sync fromstart<CR>
inoremap <F12> <C-o>:syntax sync fromstart<CR>

Categories

Resources