How Does Vim Auto-Indent Handle Mixed Tabs And Spaces?

2025-09-04 19:39:38 177

4 Answers

Jack
Jack
2025-09-06 14:29:35
If you've ever opened a file that looks like a bento box of tabs and spaces, Vim's auto-indent behavior is surprisingly predictable once you know the pieces involved.

Auto-indent (the basic 'autoindent' option) simply copies the leading characters from the previous line — literally. That means if the previous line starts with a tab, then two spaces, Vim will start the new line with that exact sequence. Nothing clever, just a straightforward copy. Where things get interesting is when you press Tab or when you run reindent commands: Tab insertion is governed by 'expandtab' and 'softtabstop'. If 'expandtab' is set, inserting a tab character from Insert mode actually inserts spaces. If it's unset, Vim inserts a real tab character, and 'softtabstop' affects how many spaces the Tab key represents while editing.

Reformatting with commands like '=' or using cindent/smartindent is different: Vim computes the desired indentation in columns based on 'shiftwidth' and the language indent rules, then writes the indentation according to your tab settings (usually honoring 'expandtab' to decide whether to use spaces, or using tabs where possible when it's unset). Practical tips: use ':set list' to reveal hidden whitespace, ':set tabstop=4 shiftwidth=4 softtabstop=4', ':set expandtab' to normalize new indentation to spaces, and ':retab' to convert existing characters if you want to clean the file up.
Ulysses
Ulysses
2025-09-07 07:42:29
I tend to think about this like a little mechanical copier followed by a formatter. First the copier: with simple auto-indent on, Vim just copies the previous line's indentation characters verbatim — tabs, spaces, whatever sits at the start of the line. That’s why files can look inconsistent when they were edited by multiple people or different editors.

Then the formatter: when you ask Vim to fix indentation (operators like '=', or rules driven by 'cindent'/'indentexpr'), Vim calculates how many columns of indent the language rules demand. After that it writes that number of columns according to your settings. If 'expandtab' is enabled, it writes only spaces. If not, it will try to use tabs (based on 'tabstop') and then spaces for any leftover columns. This is why 'shiftwidth' controls the logical indent step, but 'tabstop' controls how those steps become physical characters.

Practical suggestions from my toolbox: install a tiny plugin like 'vim-sleuth' to auto-detect existing indentation, use ':set list' or ':set listchars' to inspect, and when you want uniform output pick either ':set expandtab' plus ':%retab' to convert tabs to spaces, or ':set noexpandtab' and a consistent tabstop to keep tabs. Also watch out for Makefiles and similar where literal tabs are required — in those files I explicitly force 'noexpandtab' so the copier/formatter won’t break them.
Natalie
Natalie
2025-09-08 09:52:35
Okay, here’s the short technical walk-through from my desk: the plain auto-indent feature copies the prior line’s leading bytes — tabs and spaces — exactly as they are. So if you’ve got a mix on the previous line, the next line will start with that same mix.

What changes behavior is what you do next. Hitting Tab in Insert mode respects 'expandtab' and 'softtabstop' (so Tab can mean spaces or a real tab). Reindenting with '=' or using 'cindent' computes indentation in terms of columns (using 'shiftwidth' as the unit) then converts that column count into characters. That conversion will use spaces if 'expandtab' is set; otherwise Vim will insert tabs where they fit (using 'tabstop' to know tab width). To normalize a file I usually: turn on ':set list', pick a canonical tab/shiftwidth/softtabstop, ':set expandtab' if I want spaces, and then run ':%retab' followed by 'gg=G' to reindent everything.

If you need to preserve literal tabs (like in Makefiles), be careful: modelines or filetype plugins might alter behavior, so set options explicitly per-file.
Arthur
Arthur
2025-09-08 20:02:08
Quick, friendly checklist from my late-night editing sessions: Vim’s basic auto-indent copies the previous line’s leading characters exactly, so mixed tabs+spaces are preserved on the next line.

If you press Tab or reformat, the editor's other settings matter. 'expandtab' makes Tab insert spaces; 'softtabstop' affects how Tab behaves in insert mode; 'shiftwidth' defines the size used by '>' '<' and reindent commands; 'tabstop' tells Vim how wide a real tab is when converting columns into characters. When reindenting, Vim computes the correct column amount and then emits tabs or spaces according to 'expandtab' and 'tabstop'.

To fix a messy file: reveal whitespace with ':set list', choose your canonical settings, then use ':%retab' and a full reindent. Simple, but it saves hours of annoying diffs.
View All Answers
Scan code to download App

Related Books

Mixed signals
Mixed signals
Lydia, 22 year old, beautiful and brave woman who was taken by her Aunt after her parents sudden death. Life hasn't being going on smoothly for her, a cheating boyfriend and her insecurities. One day, Lydia found out all her life has been a life as she found out the reason behind her parents death. On her way to report to the police station, she was taken by unknown and upon all struggle, she was thrown down the sea only to wake up finding a stranger as her savior
Not enough ratings
15 Chapters
Mixed Feelings
Mixed Feelings
"You are mine, No one has a right to touch you, hold you, or love you...You're all mine get that in your thick skull...I'll kill every single one who desires to have you or even think of having you, You belong to me only me your soul, your body everything belongs to me, only me...Do you get that" He said while gripping my chin with pressure, making me look into his eyes. "Please... You're hurting me" I said, trying to free myself from his iron-like grip. "Say it" he shouted on my face, gripping my chin even more tightly. "Yes( sobbing ) yes... I'm yours" I said, sobbing and struggling to be freed from his grip. Vanessa foster 18 years old cute, naive, and kind-hearted person. she was living a normal life with good grades until she meets a devil living in a greek god-like body. Lorenzo Francisco, 26 years old ruthless, cold, unforgiving, manipulative, and merciless businessman. As C.E.O of Francisco group's, he has billions on his name. The wind carries the way he kills and manipulates people in Los Angeles making everyone tremble in fear. He was envied by men and wanted by women. What happens when this dark and aloof billionaire meets the naive Vanessa? Will love win the game? Heartbreak, betrayal, manipulation, suspense, and Romance.
9.5
110 Chapters
Mixed Signals
Mixed Signals
Richard Rossi, co-owner of Petals Cosmetics and Pharmaceuticals gets a sexual experience that shakes his whole being from a young woman who turns out to be the youngest daughter of his partner, Peter Torres. He hides away after the incident miles away from the Torres family. His presence is not required until the sudden passing away of his partner and best friend. Jacqueline Torres is a wild child, the black sheep of the Torres family and the youngest child. On the night of her parents' annual summer party, she meets a man who evokes the female side of her which she had strived to keep buried within her. When she finds out who he is, she vows to make him pay for running out on her. When the runaway co-owner returns to take over after her father's death, Jacqueline begins to question her emotions as memories of that night plague her still. Richard is called upon to take up the responsibility of his company, putting an end to his nomadic lifestyle. He tries to play a distant, fatherly role when he meets with the lady from five years ago but when they encounter dire situations and death targets from all sides, he has a reason to stay, to protect and to love her.
Not enough ratings
17 Chapters
TOO CUTE TO HANDLE
TOO CUTE TO HANDLE
“FRIEND? CAN WE JUST LEAVE IT OPEN FOR NOW?” The nightmare rather than a reality Sky wakes up into upon realizing that he’s in the clutches of the hunk and handsome stranger, Worst he ended up having a one-night stand with him. Running in the series of unfortunate event he calls it all in the span of days of his supposed to be grand vacation. His played destiny only got him deep in a nightmare upon knowing that the president of the student body, head hazer and the previous Sun of the Prestigious University of Royal Knights is none other than the brand perfect Prince and top student in his year, Clay. Entwining his life in the most twisted way as Clay’s aggressiveness, yet not always push him in the boundary of questioning his sexual orientation. It only got worse when the news came crushing his way for the fiancée his mother insisted for is someone that he even didn’t eve dream of having. To his greatest challenge that is not his studies nor his terror teachers but the University's hottest lead. Can he stay on track if there is more than a senior and junior relationship that they both had? What if their senior and junior love-hate relationship will be more than just a mere coincidence? Can they keep the secret that their families had them together for a marriage, whether they like it or not, setting aside their same gender? Can this be a typical love story?
10
54 Chapters
Too Close To Handle
Too Close To Handle
Abigail suffered betrayal by her fiancé and her best friend. They were to have a picturesque cruise wedding, but she discovered them naked in the bed meant for her wedding night. In a fury of anger and a thirst for revenge, she drowned her sorrows in alcohol. The following morning, she awoke in an unfamiliar bed, with her family's sworn enemy beside her.
Not enough ratings
72 Chapters
Desiree mixed genre collection
Desiree mixed genre collection
"Do you believe desire can be holy ,or is it always a sin" ? " Depends. Sometimes it saves you . Sometimes it ruins you." "And if you knew the ending was tragic , could you still want it" ? "Every time " Twenty different tales of obsession, betrayer,and temptation-where love is never simple or safe. From rejection mates and cursed vampire to priest breaking vows ,ex-wives hunting revenge ,and human traped between werewolves and mermaid-These stories test the limit of what we dare to want . Some lovers burn the word for each other. Some are destroyed by their own hunger . But all of them prove one truth; Desire always costs .
Not enough ratings
51 Chapters

Related Questions

What Vim Auto-Indent Commands Adjust Indent Width?

4 Answers2025-09-04 09:02:52
If you're fiddling with Vim's indentation and want precise control, the trio I reach for is :set shiftwidth, :set tabstop, and :set softtabstop. shiftwidth (sw) controls how many spaces a single indentation level uses for operations like >>, <<, and automatic indentation. I usually do :setlocal shiftwidth=4 for projects that use four-space indents. tabstop (ts) sets how many spaces a literal TAB character displays as; use :set tabstop=4 to make existing tabs line up visually with your intended width. softtabstop (sts) affects insert-mode behavior: :set softtabstop=4 makes pressing Backspace or Tab behave like you're working with 4-space logical tabs even if actual file uses tabs. A couple of other practical commands I keep in my .vimrc: :set expandtab to insert spaces instead of real tabs (or :set noexpandtab to keep tabs), :set autoindent to keep the previous line's indentation, and :set cindent or :set smartindent for C-like auto-indenting. If you want the changes to apply only to the current buffer, use :setlocal sw=2 ts=2 sts=2. To reformat an entire file after changing settings, I often run gg=G to reindent the whole buffer, or :retab to convert tabs to spaces (or the reverse with :retab!). These little tweaks saved me hours when I was switching between Python, Makefiles, and Go projects.

How Do I Disable Vim Auto-Indent Temporarily?

4 Answers2025-09-04 20:03:23
Okay, here's a practical and friendly way I handle Vim's auto-indent when I need it out of the way for a few moments. If I just want to paste something without Vim reformatting it, I usually toggle paste mode: :set paste to turn it on, paste the text, then :set nopaste to go back. I often map a key for that so it’s painless, for example :set pastetoggle= or put in my config nnoremap :set paste! to flip it. Paste mode stops auto-indent, indentexpr, and other niceties, so your pasted code won't get mangled. If I need to disable automatic indentation for editing (not just pasting), I prefer buffer-local switches so I don’t mess with other files: :setlocal noautoindent nosmartindent nocindent and, if needed, :setlocal indentexpr= to clear any expression-based indent. To restore, use :setlocal autoindent smartindent cindent or reopen the buffer. Little tip: :set paste? shows whether paste is on. Personally, I use paste for quick fixes and :setlocal for longer edits — keeps things predictable and quiet during a frantic refactor.

Why Is Vim Auto-Indent Not Working After Vimrc Changes?

4 Answers2025-09-04 02:43:46
Man, that frustration is so real — I’ve been there. First thing I do is check whether vim even thinks it should indent: open the file and run :set filetype? and :verbose set autoindent. If filetype is empty or wrong, indent scripts won’t run. If :verbose shows autoindent being turned off by some script, that points to the culprit. Next, consider obvious toggles that silently kill indentation: if you’ve got 'set paste' enabled (or you toggled paste mode earlier with a mapping), indentation won’t behave. Also check whether you disabled 'autoindent', 'smartindent', or 'cindent' by mistake. Use :set paste? and :set autoindent? to inspect current state. If those look fine, source your vimrc manually (:source ~/.vimrc) and watch :messages for errors — a syntax error early in the file can stop the rest of the config from loading, so later indent settings never get applied. Also run vim -u NONE (or nvim -u NORC) to see if a vanilla session indents correctly; if it does, a plugin or a line in your vimrc is to blame. Useful commands: :scriptnames (shows loaded scripts), :verbose set shiftwidth? tabstop? expandtab? and checking ~/.vim/indent or plugin ftplugin files for overrides. If you want, paste the problematic snippet and I’ll poke at it with you.

What Are The Best Vim Auto-Indent Settings For JavaScript?

4 Answers2025-09-04 23:27:43
Okay, this is the hot take I give my friends when they ask how to stop JavaScript files from turning into a jagged mess: treat indentation as a filetype thing, not a global, and use 2 spaces plus an actual JS-aware indent engine. I usually put this in my vimrc (or better, in ftplugin/javascript.vim): filetype plugin indent on autocmd FileType javascript,typescript setlocal shiftwidth=2 softtabstop=2 tabstop=2 expandtab autocmd FileType javascript,typescript setlocal autoindent smartindent Those lines give you consistent 2-space soft tabs (the de facto style for many JS projects) and rely on Vim's smartindent for basic braces. But honestly, for real-world code with ES6/JSX/template literals, install a javascript-indent plugin (like the popular one that provides an indentexpr) and let it set indentexpr for you; it handles arrow functions, template literals and some weird edge cases better than plain smartindent. I also map = to re-indent visually: vmap = = or use gg=G to reformat a whole file. Finally, I pair this with an on-save formatter — 'prettier' is my go-to — so even when teammates differ, my local formatting is predictable. If you want the exact plugin names or a sample ftplugin that runs Prettier on save, I can paste that too.

How Can I Enable Vim Auto-Indent For Python Files?

4 Answers2025-09-04 03:25:38
Honestly, getting Python auto-indent working in vim is one of those tiny victories that makes editing a joy. My go-to is to enable vim's filetype detection and then set sensible Python indentation rules in my config. Add these lines to your ~/.vimrc or init.vim for Neovim: filetype plugin indent on set autoindent set expandtab set shiftwidth=4 set softtabstop=4 set tabstop=4 The first line turns on filetype-specific plugins and indent scripts (this loads vim's python indent file). The rest make tabs into spaces and use four spaces per indent, which is the common Python convention. If you want the setting to apply only to Python buffers, drop the global lines into ~/.vim/ftplugin/python.vim and use setlocal instead of set. If indentation still feels off, check the buffer's filetype with :set filetype? and inspect loaded scripts with :scriptnames. I sometimes install a plugin like 'vim-python-pep8-indent' or use external formatters like 'black' called via a formatter plugin to normalize whitespace. Try opening a .py and typing an indented block — it should behave. If not, tell me what output :set filetype? and :verbose set shiftwidth? give and we can debug further.

Which Plugins Improve Vim Auto-Indent Accuracy?

4 Answers2025-09-04 05:51:09
Okay, I’ll gush a bit: if you want auto-indent to actually behave instead of randomly guessing, start by combining a detector, a language-aware indenter, and a formatter. I like using vim-sleuth to sniff tabs vs spaces and shiftwidth automatically; it fixes half my headaches before I even open the file. After sleuth, for Neovim I plug in nvim-treesitter with its indent module turned on — it understands syntax much better than old regex-based indent scripts. Pair that with either null-ls or coc.nvim (or ale if you prefer linters/formatters) to run real formatters like prettier, clang-format, shfmt, or rustfmt on save. That lets the language tools correct structural indentation rather than vim guessing. Small extras that helped me: editorconfig-vim to respect project settings, indent-o-matic as a fallback detector in weird repos, and indent-blankline.nvim for visual guides so you can spot mistakes. Also don't forget filetype plugin indent on and sensible defaults (autoindent, smartindent/cindent where appropriate). With those layered, indentation accuracy improves dramatically and my diffs stop being a jungle of whitespace edits.

How Do Filetype Plugins Interact With Vim Auto-Indent?

4 Answers2025-09-04 22:00:34
If you've ever opened a file in Vim and wondered why indentation behaves one way in one project and differently in another, the way filetype plugins and indent scripts interact is the usual culprit. In my messy but beloved setup I keep separate snippets in ~/.vim/ftplugin/ and ~/.vim/indent/ and they each have a job: ftplugin files generally set buffer-local editing options (things like shiftwidth, tabstop, expandtab, mappings) while indent scripts (under indent/) provide indentation logic by setting 'indentexpr', 'cindent', 'indentkeys', or related buffer-local options. Because these are buffer-local, whichever script writes a particular option last wins for that buffer. Practically that means you can get conflicts. An ftplugin might set 'shiftwidth' to 4 for 'python' and an indent script might expect 2; or an indent script will set 'indentexpr' to a custom function that overrides simpler behaviors such as 'autoindent'. The usual fixes I use are: enable both with :filetype plugin indent on, then put overrides in after/ftplugin/ or after/indent/ so they load later; or explicitly set local options with setlocal in a ftplugin; or prevent an indent script with let b:did_indent = 1 if you deliberately want to skip it. For debugging, :scriptnames shows what got sourced, and :verbose setlocal shiftwidth? / :verbose setlocal indentexpr? tell you who last changed a setting. I like keeping ftplugin for styling and small mappings, and leaving indentation math to indent scripts — but I always keep an 'after' copy for those moments when I need the last word.

Can Vim Auto-Indent Be Configured Per Project Directory?

4 Answers2025-09-04 16:52:11
I'll be blunt: yes, you absolutely can set up Vim to auto-indent differently per project directory, and I've done it a bunch of times across projects with different coding styles. When I need a project-specific policy I usually pick one of three safe routes: use a repository-level '.editorconfig' with the EditorConfig Vim plugin (works across editors and is a huge life-saver), add per-project autocommands in my global vimrc that match the project path, or—if I must—use a controlled local vimrc mechanism (with security checks). For example, in your main vimrc you can add an autocmd that applies settings only when the buffer lives under a particular path: augroup proj_indent autocmd! autocmd BufRead,BufNewFile /path/to/myproj/* setlocal shiftwidth=4 tabstop=4 expandtab augroup END That keeps the rules scoped to files under that directory. I avoid blindly enabling 'exrc' because executing arbitrary project .vimrc files can be risky; instead I either require a checked-in '.editorconfig' or use a trusted plugin like 'localvimrc' that prompts you before sourcing. Also remember to use setlocal so other projects aren’t affected. For Neovim, the same autocmds work, but I often detect the project root via an LSP/root_pattern helper and then apply settings dynamically. Overall, choose EditorConfig if you want a cross-editor approach, or autocommands if you prefer staying purely in Vim land.
Explore and read good novels for free
Free access to a vast number of good novels on GoodNovel app. Download the books you like and read anywhere & anytime.
Read books for free on the app
SCAN CODE TO READ ON APP
DMCA.com Protection Status