On a few occasions I ended up "un-nesting" some useful tools which I initially thought are better off encapsulated and out of scope, because it turned out that I need them somewhere else too. Being new, I find it hard to predict how code will evolve.
The simple answer to this is: Don't try to predict how the code will evolve, because eventually it will go in a different direction anyway.
Start of as simple as possible, and when your needs evolve, change the code accordingly. For example, you can start of with just writing the code into one function. If that function becomes to big, move code into nested procedures. If you need that code at other places to, move that nested procedure into a global procedure and so on.
Don't try to be smart in the beginning and anticipate what is going in where. Write your code knowing that you will have to rewrite most if not all of it eventually, otherwise you will build yourself a prison. This is espeically true when you work with classes. If you build a class structure a certain way because you think it will evolve into that direction, you can easily end up completely overengineering your classes with functionality that anticipates future developments, but these developments never happens, but instead your needs change in a way that all of the design you did so far is actually a hinderance.
So keep things simple, because it's easier to rewrite simple code than to rewrite complicated code.
Also, I do not see the improved readability with nesting procedures, it is quite opposite actually, to me anyway. Object's private/public sections kind of makes more sense, they are declared, and if they are also commented this is the most logical and clear, easier to find and review.
That may be true, but if you only ever work in methods and objects, you restrict yourself in a different way, because now to access the methods you are bound to the object/class you are working in. This results for example quite often in putting code that has absolutely nothing to do with the datastructure of that class, into methods of that class, just because it is convinient.
To give an example of code I wrote myself many years ago:
https://github.com/Warfley/AU3IDE/blob/master/Editor/editor.pas#L158Here is the function to read a config file, it's directly part of the editor which is configured with that information. I did it that way because it was easy to build, but this makes this function extremly hard to maintain, like updating config versions in the future and stuff like that is much harder than if I had a generic config reading function, that returns a configuration which is then loaded into the editor.
Generally this project is a great example on how not to design your program. It puts so many different functionalities into single classes that it makes it extremely difficult to navigate. This file contains just one class and has nearly 2000 lines. This is way to much functionality
So as a general rule of thumb I can say: do as little inside a class/object as possible and if you are not sure if you need something to be a method or not, first start with a function with simple input and ouput, and only when you realize you depend to much on internal state, then move it into a method.
Also note, you have visibility on unit level. Everything you put into the interface part of the unit is "public", everything you put in the implementation part is "private". So by organizing your project into files, you can also enforce visibility