set vim python indent space based on file - python

I know it is possible to set the indent for a specific filetype by
set softtabstop=4
But the problem I am facing is, I have different python script files, some of them are indented with 2 spaces, while some of them are indented with 4 spaces. Is it possible to let vim determine the indent spaces to use (2 or 4) automatically based on the file opened?
Any help will be appreciated.

It looks like this vim plugin will do what you want: https://github.com/requalix/detect-indentation.

There are several plugins that can detect the used indent settings. Some, like my IndentConsistencyCop plugin also warn you about inconsistent indents. The following list is taken from my plugin's documentation:
My own IndentConsistencyCop plugin; automatic triggering is enabled by the companion IndentConsistencyCopAutoCmds plugin.
Indent Finder (vimscript #513) is a Python script and Vim plugin that scans
any loaded buffer and configures the appropriate indent settings
yaifa.vim (vimscript #3096) is a port to vimscript of the above
detectindent.vim (https://github.com/ciaranm/detectindent) by Ciaran
McCreesh tries to auto-detect the indentation settings
GuessIndent (vimscript #4251) is based on detectindent.vim
indentdetect.vim
(https://github.com/ervandew/vimfiles/blob/master/vim/plugin/indentdetect.vim)
by Eric Van Dewoestine performs a simple detection and can set defaults
based on the filespec
matchindent.vim (vimscript #4066) detects tabs, 2 and 4-space indents and
adapts the indent settings accordingly
sleuth.vim (vimscript #4375) by Tim Pope automatically adjusts 'shiftwidth'
and 'tabstop' heuristically (via a simplistic sampling that does not check
for bad or inconsistent indents) or by looking at other files of the same
type
filestyle (vimscript #5065) highlights tabs when 'expandtab' is set,
trailing spaces, and lines longer than 'textwidth', but doesn't actually
check conformance to indent
ShowSpaces (vimscript #5148) highlights spaces inside indentation, per
buffer / filetype.
Indent Detector (vimscript #5195) run when a file is opened or written, has
warnings about mixed tab / space indent, and can adapt Vim's corresponding
options automatically.

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

Python indentation in Spacemacs with hard tabs is off

Let me preface by saying that I am a relatively new emacs/spacemacs convert from vim, so my my knowledge is still pretty basic.
I have spacemacs set up with the python layer, with the additional package of dtrt-indent listed in dotspacemacs-additional-packages. And setting
(dtrt-indent-mode t)
in the dotspacemacs/user-config. I need the dtrt-indent as I am working on a few projects (in python and lua) where I am not the one who sets the indentation rules.
This configuration works fine for python files with soft-tabs of varying length. This configuration also works for lua files that have hard tabs.
When I open a python file indented with hard tabs something seems to get messed up, it appears to think that the indentation is two hard tabs. Meaning, if I have code like this (pretend that the 4 spaces are tabs):
def func():| <--- Cursor
print 'line'
and press enter, I get:
def func():
| <--- Cursor
print 'line'
The status line prints dtrt-indent's message saying:
Note: indent-tabs-mode adjusted to t
Note: As stated I'm pretty new at this, and my spacemacs configuration is pretty sparse. There is nothing else in my user-config, I have not custom layers, I don't even have any additional packages other than dtrt-indent.
EDIT:
python-indent-offset is set to 8
indent-tabs-mode is set to t
tab-width is set to 4
Try M-x whitespace-mode and repeat this experiment. What do you see? Did you indent with spaces or with tabs?
I'm guessing you'll see something like this:
def·func():
········
» print·'line'
This would mean you have python-indent-offset set to 8, indent-tabs-mode set to nil (aka indent with spaces), and tab-width set to 4.
If that's not the case, what are the values of those variables (C-h v python-indent-offset, etc.)?
If that is the case, you can fix the problem by running
(setq-default python-indent-offset 4)

How to indent a block of Python code in Notepad++?

While coding in Matlab, I had the option of smart indenting my code using the shortcut Ctrl+i. Is there a similar option for Python using Notepad++?
Specifically, I am looking for a solution to the following problem:
I want the block
line 1
line 2
line 3
to be converted to
line 1
line 2
line 3
On a side-note, I found this to be surprisingly easy with SE editor (keyboard shortcut: Ctrl+k). I want this feature to be available for other languages as well (in my experience good indentation hasn't killed anyone, regardless of the language).
Just select the text you want indented and hit Tab. To un-indent, select the text and hit Shift+Tab.
If you're in "Normal text file" mode, this will give you tabs (\t characters). If, however, you're in Python mode (which you enter either by saving as a .py file or by selecting Python from the Language menu), it should default to using four spaces instead of tabs. To configure the way tabs work yourself, go to Settings → Preferences → Tab Settings (for Python, this should default to "Tab size: 4" with "Replace by space" checked).
Select all 3 lines and hit the Tab key. To undo this action you can hold down Shift while pressing the Tab key.
Pro Tip: As long as you have at least 2 lines partially selected, you can tab in the entire block.
Example:
If you want to change tab settings there are two locations in Settings -> Preferences
Under Tab Settings: You can change the tab size and you can check off the Replace by space option if you want NPP to use spaces for tabs.
Under MISC: you can check-off Auto-indent in case you have that option turned off.

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

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

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.

Categories

Resources