I always indent and comment the end of the nested procedures and it sounds like very bad design to have thousands of lines of code in one.
Maybe code written without oop?
There are two reasons to group instructions, they are:
1. A group of instructions accomplishes a specific, well defined logical task.
2. A group of instructions is executed multiple times.
Those are the two reasons instructions are grouped.
Let's start with case 2 above. If that group is executed in one and only one function/procedure then that group should be nested into that function/procedure to reveal the fact that it is not executed anywhere else. That gives locality which is important because the programmer doesn't have to wonder what other code in the program depends on that sequence of code.
Case 1 is the really interesting one and the one that most programming languages have not addressed satisfactorily (including Pascal.) For the sake of a simple explanation and without loss of generality, presume that there are no sequences of code that are executed multiple times. Also, presume what is the most common case, that the function/procedure is composed of a fairly large number of logical steps. What follows is what usually happens in most languages, including Pascal.
The top level function is broken down into a number of functions/procedures and those functions/procedures are then executed in a mostly linear fashion, I say mostly because some may be part of a loop or if statement or some other code that controls how or when the code is executed. When the programmer reaches that code and sees "SomeFunction(SomeParameter1, SomeParameter2...SomeParameterN), it is quite often necessary for the programmer to "jump" to where "SomeFunction" is implemented to refresh his/her memory to see what the code actually does. If there are 10,000 lines broken into small "acceptable" pieces to some programmers, that means the 10,000 lines are going to be broken into about 200 individual blocks of code. That also means that when the programmer is reading the top level function, he/she will have their attention diverted away from the mainline 200 times. Welcome to spaghetti code and jigsaw-puzzle programming.
The way it should be done is to have a way (a construct of some kind) to group code _inline_ so the programmer can see (and be told) that a sequence of instructions fulfills a specific logical purpose. This is also a way to have the convenience of inline variables without inline variables and local types and constants that is only applicable to a very short sequence of code.
Inline/anonymous functions/procedures _almost_ fulfill the characteristics of the construct I alluded to above but, very unfortunately they require a "()" to cause them to be executed (because they weren't really designed to be a grouping construct.)
10,000 line functions/procedures are a whole lot better, easier to understand and maintain than functions/procedures broken into hundreds of scattered pieces that have to be mentally re-assembled to see what the function does and how it does it.
IOW, today's commonly accepted and supported programming philosophy is: let's make sure to make the big picture as hard to mentally create as possible.