I've been able to get by so far with the inbuilt doc and reading the code for installed packages, etc. I can read other people's config and reasonably copy needed chunks, debug issues (I've submitted PRs to magit, org mode, and Doom to fix various issues).
The problem is that the last little bit to get to a fluent understanding has been elusive, e.g. how some of the macro-heavy features work (e.g. the common lisp stuff), or how to handle async code (e.g. how magit runs a command, and then refreshes the buffer after it completes). I have this fluency to some degree for the languages I'm paid to produce code in (e.g. C++, to some extent; Stroustrip himself said his knowledge of C++ was "7 out of 10 on a good day" or something like that), but these last few advanced features have been a tough nut to crack in elisp.
The good thing is that the source is always right there and you can read it or set breakpoints and step through it to see how things work.
> how to handle async code (e.g. how magit runs a command, and then refreshes the buffer after it completes)
Emacs's primary mechanism for async code is: spawning an asynchronous process and interacting with them using a process filter/sentinel. This allows you to do things like detect when that process has emitted a certain output or signal and run some code based on that.
For example, magit user the process-sentinel for a pull/fetch command to call (magit-refresh) to refresh the buffer. (How to fish: I guessed that magit-refresh was probably the function refreshing the buffers, set a breakpoint in it, and voila now I have the entire stackframe.)
Relevant pages from info: "(elisp) Filter Functions", "(elisp) Sentinels".
The problem is that the last little bit to get to a fluent understanding has been elusive, e.g. how some of the macro-heavy features work (e.g. the common lisp stuff), or how to handle async code (e.g. how magit runs a command, and then refreshes the buffer after it completes). I have this fluency to some degree for the languages I'm paid to produce code in (e.g. C++, to some extent; Stroustrip himself said his knowledge of C++ was "7 out of 10 on a good day" or something like that), but these last few advanced features have been a tough nut to crack in elisp.