I’m missing context here, but FWIW, many small files are generally nicer for my workflow.
emac’s switch buffer assumes you don’t want to switch to a buffer you already have open, so it sorts open buffers to the bottom of the list. I.e., it takes more key strokes to open a 2nd or 3rd view of the same file than a 1st view. Instead, many decently named files make it easy for me to swtich buffers to roughly where I want go.
Files don’t provide much of a barrier, e.g. I incrementally search a project with M-s r, seamlessly jumping between files as I go through the candidates.
Features like the LanguageServer’s find references and go to definition also jump across files seemlessly.
For what seems like decades, in various languages and systems, I’ve advocated for including this kind of information programmatically. I’m fairly confident people would use these tools if they were easy. Not always, probably not most of the time, but way more than they do adding a few see alsos ad hoc by hand.
I made a doc system like this several years ago for a common lisp project (and I think some other project as well)
You can put somewhere, maybe at the top of a file, or near one function a “see also group”. Just a list of functions each of which should refer to the others in its doc string.
I also wrote a package manager and other stuff in that repo. I never got a response from devs. Years later, one approached me about it, but by then I’d moved on.
I wrote macros for writing functions. I tried to provide standard error message templates so that similar messages don’t differ. Like sometimes active sometimes passive voice. Do you first say what you wanted, or first say the wrong thing you got. In most languages, these are all over the place within a single project. With error messages and docs I was inspired by Mathematica. The interfaces, docs, and error messages are highly uniform in Mathematica. I assume this was S. Wolfram’s hand enforcing it from the beginning.