Okay I think I understand your core issue. My position is that you do one indent per open scope and those should be done by tabs. Since those usually appear at the beginning of the line there's no problem because tabs behave exactly like you want them to (equal X spaces). It also produces nice boxes, especially in C like languages if I may say so, personally I think Python forcing you to obey this principle is actually a good think to teach people. Can look like this:
+--------------------------------------+
|namespace foo |
|{ |
| +------------------------------+ |
|[TAB]|void bar(args) | |
|[TAB]|{ | |
| | +-----------------+ | |
|[TAB]|[TAB]|while (condition)| | |
|[TAB]|[TAB]|{ | | |
|[TAB]|[TAB]|[TAB]// body | | |
|[TAB]|[TAB]|} | | |
| | +-----------------+ | |
| | | |
| | // and another scope | |
| | +-----------------+ | |
|[TAB]|[TAB]|if (condition) | | |
|[TAB]|[TAB]|{ | | |
|[TAB]|[TAB]|[TAB]// body | | |
|[TAB]|[TAB]|} | | |
| | +-----------------+ | |
|[TAB]|} | |
| +------------------------------+ |
|} |
+--------------------------------------+
Your problem appears when a new scope does not seeem to start at the beginning of a line, correct? For example like this:
+--------------------------------------+
|namespace foo |
|{ |
| +------------------------------+ |
|[TAB]|auto bar(args) | |
| | // function body | |
|[TAB]|{ | |
|[TAB]|[TAB]return baz([args](){ | |
|[TAB]|[TAB][TAB]// lambda body | |
|[TAB]|[TAB]}); | |
|[TAB]|} | |
| +------------------------------+ |
|} |
+--------------------------------------+
If you try to draw a rectangle around only the lambda you have to "indent" the body by spaces to make it nicely aligned like this
+--------------------------------------+
|namespace foo |
|{ |
| +------------------------------+ |
|[TAB]|auto bar(args) | |
|[TAB]|{ | |
| | +----------+ | |
|[TAB]|[TAB]return baz(|[args](){ | | |
|[TAB]|[TAB][TAB] | ... | | |
| |[TAB] |} | | |
| | +----------+ | |
| |[TAB]); | |
|[TAB]|} | |
| +------------------------------+ |
|} |
+--------------------------------------+
and someone misguided could have the really bad idea of first wanting to align a box and then doing the indent for the lambda scope:
+--------------------------------------+
|namespace foo |
|{ |
| +------------------------------+ |
|[TAB]|auto bar(args) | |
|[TAB]|{ | |
| | +----------+ | |
|[TAB]|[TAB]return baz(|[args](){ | | |
|[TAB]|[TAB] |[TAB]... | | |
| |[TAB] |} | | |
| | +----------+ | |
| |[TAB]); | |
|[TAB]|} | |
| +------------------------------+ |
|} |
+--------------------------------------+
That obviously leads to problems, yes, but that is simply someone who did not understand "tabs for indent, spaces for alignment" then. You should train that person better, it's really not that hard and also there's tools that can easily warn on such things. Banning tabs gets rid of this problem but it also gets rid of the advantage tabs have, namely that the indentation can look differently to many people without causing any VCS problems. And that's worth a lot more than saving a one time 2 minute work of enforcing a check for such things in the VCS for a single person.