But you still have to look up the individual values right? I'm using Flakes, pinning commit hashes is automatic (lockfile) - but i still have no clue what version any package is on.
As with a lot of comments about Nixlang, the tooling there seems lackluster at best. In this case i'd want tooling to easily know and change package versions, not sweeping changes to your entire package ecosystem. Nix might give me that, but resolving derivations manually is not a great UX, imo.
For languages with relatively uniform package ecosystems (like Rust and Go) there are tools that can generate Nix code for you from lockfiles with exact versions. In practice this usually suffices, because these ecosystems also have to remain compatible with other environments where OS-provided dependencies like C compilers and libs have wildly differing versions.
For most C ecosystem stuff you can try overriding the version, but you'll quickly notice why this is a hard problem: Different software versions want to be built in different ways! Someone would have to therefore maintain the quirks of each package version's build process for each package for all eternity, an insanely huge endeavor.
Also, even if it were possible this would break the Nix binary cache model, because suddenly you'd have an insane combinatorial explosion of not just package versions, but also versions of their dependencies. In order to preserve purity and reproducibility, a change in dependency version means that all dependents have to be rebuilt, taking up insane amounts of CPU and storage on the build farm.
I don't think that your request is unreasonable (I'd love to have this feature!), but it's probably not fully possible in any software distribution ecosystem.
As with a lot of comments about Nixlang, the tooling there seems lackluster at best. In this case i'd want tooling to easily know and change package versions, not sweeping changes to your entire package ecosystem. Nix might give me that, but resolving derivations manually is not a great UX, imo.