What I'd really like is an IDE that functions on objects of code and not text files, and diffs and merges thar similarly operate on the syntax tree of the code and not on whether there's an extra newline or not.
Like, code formatting, that's just an implementation detail. Why can't there be a thing to let two people edit the same repo with different formatting preferences without it causing merge conflicts?
Maybe you're already aware of it, but there is difftastic [0], which is a syntax aware diff tool that can also be used with git. Its understanding of syntax is based on treesitter, so it works for most languages. Although I haven't tried, I think most IDEs should also be able to use it.
This is essentially the concept of a "text object" from Vim. Historically, it was somewhat challenging to actually define text objects with the richness of behavior one might want, but now with Tree Sitter and LSP you can have this pretty much for any language or file format.
I feel that the problem is not text but language design. A great language should be close to a pareto optimum for both human and machine legibility. Most languages are optimized for human familiarity, which is definitely not the most machine readable format and probably not the most human readable (in a platonic sense).
Being more specific, most languages, in my opinion, are far too permissive with whitespace and use too many keywords. The former leads to there being no canonical form of the program text and results in reliance on external formatting tools, when the compiler could be just automatically enforcing canonical formatting rules. The latter makes it hard to distinguish between types of words, which is why it is almost necessary to rely on syntax highlighting.
If each program has a unique canonical form, it would be very hard to beat text based diffing on that form. Lisp is quite good from the diffing perspective but weaker on human legibility (for most humans).
Tooling that enforces strict whitespace/formatting rules is a huge pet peeve of mine. It breaks my iteration flow because I have to stop thinking at whatever abstraction layer I'm working at to deal with the minutiae of formatting. I dislike automatic reformats as well, for much the same reason I hate webpages that jump around after loading. Just let me see the code I'm writing without it whizzing off onto adjacent lines because I'm going back and forth over column limits.
I think treesitter is getting us closer to this goal. Many programming modes in emacs now support treesitter, allowing syntax-aware movement operations, code folding, etc. Even where modes haven’t been set up, you can call “treesit-explore” I think for any language for which you have a grammar available and get an outline of the nodes.
Hopefully we’ll continue to see adoption in this space, as it makes it much easier to add syntax highlighting and other basic support for new languages, and it makes it so that any new functionality that operates via treesitter should work with minimal modification for any language.
The helix editor [1] allows you to navigate and select code objects, I use Alt-o all the time which expand the current selection to the parent syntax node. As mentioned by sibling comments, there are also a bunch of diff tools that are syntax aware instead of operating on plain text. All of these are backed by tree-sitter.
related to this: I want structural editing for non-lisp languages so I don't have to deal with measly lines of code, but with entire trees and branches.
Kind of surprised speed isn't listed in here or caching.
It annoys me to no end when auto-complete stops working as it waits on rust-analyzer to finish. Like you had a completed run before; just use that information while you re-compute it!
All of this stuff makes me go 'that should be possible in Emacs', with the exception of colouring tagged comments, which I think is possible in Emacs. I think that ghost/replay thing is possible using Sly and iterating through objects is possible in Slime and Sly.
I often use `hi-lock-symbol-at-point` and related functions for colouring stuff ephemerally, you can persist them if you find something that you need all the time. Extensive guide at https://www.masteringemacs.org/article/highlighting-by-word-... (and of course many packages that expand on this).
iimage-mode does the image thing
Let me know when you implement commit masks in magit, that sounds handy :-)
I would like an IDE that saves files in a consistent format but displays the code in whatever style the user prefers. This shouldn’t be hard to do and would help version control a lot.
A while ago I talked with someone who was working on clang-format and they said they tried this (at Google, I think) and the results were not good: they found people write different code depending on the format. For example, code written to fit in 120 columns but then formatted to 80 columns will look worse than code written for 80 columns, due to minor variations in verbosity and variable names and what not.
I notice this myself a bit when I switch from a fullsize monitor to a laptop screen.
That could be hacked together via some git hooks in theory, like, apply code formatter with your preferences on checkout, apply shared code formatter on checkin. But it's probably more complicated than that.
Saving files as syntax trees instead of code files / ASCII might also do that, but that's a level of abstraction nobody is ready for yet, because you need a tool that can translate to readable code everywhere. It kinda reminds me of EXI, a proposed XML transfer protocol that wouldn't bother translating the document to a readable text format but just transfer as binary, a set of 'events' like the SAX parser approach to achieve much more efficient transfer. I don't believe it ever took off though, it was conceived when JSON quickly became more popular. It was only mentioned once on HN [0] 13 years ago, with one point and zero comments.
Mature IDE's already customize the presentation of things like annotations or comments, inject inline hints, and provide alternate editors for things like XML, markdown, or established UI description formats, etc
Imagine you like two spaces and I like four spaces for indents. With the above idea we both get what we want, locally you see two spaces and I see four, and there's no diff for indents whenever one of us edits a file. Similarly for any other formatting preference.
There's no reason we even have to work on "files". An IDE should be able to show you a module, or function, or call tree, or data dependency graph, anything!
There's so much to be improved in this area.
The only feature in this dimension I've seen is jetbrains injected language editor, where you can edit a string as it's own language thingy.
I was thinking about the commit mask thing recently but imagining it as a part of Git, or an extension.The project I'm on at the moment is a big legacy codebase that requires a bunch of dev-only code changes for:
- functionality (setting API urls; forcing certain screens to appear; overriding config values that come back from an XHR)
- quality of life (skipping delays; turning sounds off)
It would be great to be able to toggle and mix and match these patches locally without risking committing them. A combination of stashes and branches kind of works, but the ergonomics isn't great, especially when there are conflicts.
I do this all the time in IntelliJ/JetBrains based IDEs, using the "changelist" functionality. I have "shelved" different patches I can bring forward, and they each appear in their own changelist. When committing it's from the main changelist, so never accidentally included.
When I make some change for local dev only, I always press the "diff markings" in the margins of the file, and there select that it should go to my "local dev" changelist and not be a part of main.
This is a bit similar to git -p, but the devex is much smoother.
To make sure i don't push temporary local changes to production, I used to have a github workflow that rejected code that contained the word "TODO" or "console.log". This way, i could add TODO comments that actually need to be done before deploying. Now i'm usign github less but my deploy script does the check, and you can probably make a pre-commit hook with this, or pre-push
Commit masks remind me of that time I couldn't run a Java app because it assumed a specific classpath order, but the classpath order is random on each boot, and my randomized classpath makes the app crash.
I've also seen some development teams rely way too much on IDE plugins to get anything done. Horrible software architecture with a 45 minute start-up time, I shit you not. They paid a shitload of money on software licenses for a special JVM/IDE plugin combo that allows them to hotswap almost everything to avoid ever having to restart the app during development.
Oh, it's also pretty much impossible to launch the development version of the app with a stock IDE due to the sheer amount of runtime code modifications from IDE plugins the development version depends on. Great times.
Could you elaborate on the class path order issue?
I can think of pathologic cases where multiple jars contain the same class but only one version is the right one, but how can something like that happen in practice?
A custom modding framework that patches code at runtime to dodge legal issues of binary patching, or more accurately shift the legal issues from us to end consumers. Companies don't pursue end consumers for things like that, or so I heard. Either way, problem was that the modding framework and the app itself shared a couple of libraries. Our modding framework used features of newer versions of libraries, features that the app with outdated libraries didn't have. Sometimes, the class path order put older versions of libraries first, causing the modding framework to use a class, function, etc. that doesn't exist in that version of the library yet. This rarely was an issue since most libraries didn't change much from version to version, but the class path lottery did have a few uncommon combos that made the app crash until you restart your computer.
There needs to pe a standard that all editors understand. Propriatory answers like emacs don't count as some of us do not have the same editor religion.
Personally, I use markdown for comment content, not that IDEs do much with it, at least Markdown supports images with the `` syntax.
I think I've seen some tree-sitter grammars actually define injections such that their comment are rendered with markdown (but now I can't figure out where I saw that, maybe one of the Zed specific ones).
Like, code formatting, that's just an implementation detail. Why can't there be a thing to let two people edit the same repo with different formatting preferences without it causing merge conflicts?
[0] https://difftastic.wilfred.me.uk/
We really lost so much when we moved away from s-expressions in favor of... whatever adhoc stuff we do right now.
Being more specific, most languages, in my opinion, are far too permissive with whitespace and use too many keywords. The former leads to there being no canonical form of the program text and results in reliance on external formatting tools, when the compiler could be just automatically enforcing canonical formatting rules. The latter makes it hard to distinguish between types of words, which is why it is almost necessary to rely on syntax highlighting.
If each program has a unique canonical form, it would be very hard to beat text based diffing on that form. Lisp is quite good from the diffing perspective but weaker on human legibility (for most humans).
Hopefully we’ll continue to see adoption in this space, as it makes it much easier to add syntax highlighting and other basic support for new languages, and it makes it so that any new functionality that operates via treesitter should work with minimal modification for any language.
[1]: https://helix-editor.com/
something like this for Python: https://shaunlebron.github.io/parinfer/
Wasn't that one of the original ideas behind Light Table?
It annoys me to no end when auto-complete stops working as it waits on rust-analyzer to finish. Like you had a completed run before; just use that information while you re-compute it!
iimage-mode does the image thing
Let me know when you implement commit masks in magit, that sounds handy :-)
I notice this myself a bit when I switch from a fullsize monitor to a laptop screen.
Saving files as syntax trees instead of code files / ASCII might also do that, but that's a level of abstraction nobody is ready for yet, because you need a tool that can translate to readable code everywhere. It kinda reminds me of EXI, a proposed XML transfer protocol that wouldn't bother translating the document to a readable text format but just transfer as binary, a set of 'events' like the SAX parser approach to achieve much more efficient transfer. I don't believe it ever took off though, it was conceived when JSON quickly became more popular. It was only mentioned once on HN [0] 13 years ago, with one point and zero comments.
[0] https://news.ycombinator.com/item?id=2312746
Mature IDE's already customize the presentation of things like annotations or comments, inject inline hints, and provide alternate editors for things like XML, markdown, or established UI description formats, etc
There's no reason we even have to work on "files". An IDE should be able to show you a module, or function, or call tree, or data dependency graph, anything!
There's so much to be improved in this area.
The only feature in this dimension I've seen is jetbrains injected language editor, where you can edit a string as it's own language thingy.
- functionality (setting API urls; forcing certain screens to appear; overriding config values that come back from an XHR)
- quality of life (skipping delays; turning sounds off)
It would be great to be able to toggle and mix and match these patches locally without risking committing them. A combination of stashes and branches kind of works, but the ergonomics isn't great, especially when there are conflicts.
When I make some change for local dev only, I always press the "diff markings" in the margins of the file, and there select that it should go to my "local dev" changelist and not be a part of main.
This is a bit similar to git -p, but the devex is much smoother.
I've also seen some development teams rely way too much on IDE plugins to get anything done. Horrible software architecture with a 45 minute start-up time, I shit you not. They paid a shitload of money on software licenses for a special JVM/IDE plugin combo that allows them to hotswap almost everything to avoid ever having to restart the app during development.
Oh, it's also pretty much impossible to launch the development version of the app with a stock IDE due to the sheer amount of runtime code modifications from IDE plugins the development version depends on. Great times.
I can think of pathologic cases where multiple jars contain the same class but only one version is the right one, but how can something like that happen in practice?
I think I've seen some tree-sitter grammars actually define injections such that their comment are rendered with markdown (but now I can't figure out where I saw that, maybe one of the Zed specific ones).