1. 3

    I wrote this, thanks for sharing. csvquote is a handy little tool that uses a handy little trick of replacing quotes and newlines inside a quoted section with control characters that can later be reversed back out.

    It probably has use in formats besides CSV files.

    1. 1

      This is really clever - using ASCII “record separator” and “unit separator” to escape \n and ‘,’. They’re < 128 so this is utf-8 safe.

      1. 3

        There are a whole bunch of unprintables < 32. The NUL byte/0 is not bad as a field separator and emacs RMAIL has long used ASCII 1 as a delimiter. Etc. I am usually a bit surprised when people choose ASCII chars whose names actually suggest their roles.

        Why, if you terminate all fields with \0 instead of “separating/delimiting” them with some final record separator then you could even mmap the file read-only and random access any string as a C string with no allocation (well, the kernel allocates pages for you upon mmap). Of course you would need a (not bad to build, very fast to access) index (to rows and/or rows & cols) to make that format useful.

    1. 9

      This was for an application used to personalize smart cards when issuing credit cards, government IDs, passports, etc. It was used all around the world but for one customer it would crash on startup. We tracked it down to an database error. Our installer created the database schema and inserted the current version into a field called VERSION. When our application would start up and it checked the “version” field to confirm that it was the expected value (to ensure it wasn’t running against the database schema version it was written against).

      Manually checking the value showed that it was fine. And it worked fine everywhere except this one customer. The error was that there was no column named “version”, but looking at the schema there clearly was. The only difference was that the scheme writing code was in UPPERCASE and the SQL in the app was lowercase. But SQL isn’t case sensitive and we confirmed that the customer had set their SQL Server instance to non-case sensitive.

      I was two days away from an overnight flight to Ankara when I figured it out. Luckily for my employer, I had spent a few weeks in Turkey doing the post-college backback around Europe thing back when recent college graduates could still afford that kind of thing, so I knew a little bit about Turkey and specifically the Turkish alphabet. Which has two ‘i’s - one with the little dot and one without. So, “select version from app” doesn’t uppercase to “SELECT VERSION FROM APP” when using the Turkish alphabet. It becomes “SELECT VERSİON FROM APP” (look closely).

      A quick google today shows that lots of people have been bitten by that Turkish ı, but this was in the 90s and was the first time I had heard about it.

      1. 3

        This is an interesting idea. I think one reason it’s never been adopted is that it needs browser support to work well To do this right now, you’d need the auth page to trigger a p12 download and you’d have to load it manually, I suppose. Browsers have all dropped the old native support for things like CSRs (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/keygen) and offering to store application/x-x509-user-cert mime types in the browser’s key store.

        I assume the client-side certs would be short-lived, with some equivalent of OAuth’s refresh_token. More analogous to OAuth access tokens than the typical TLS client certs.

        The big problem I see is that since the API authentication is implicit in the browser’s state when using mutual-auth TLS, wouldn’t APIs become vulnerable to CSRF attacks?

        1. 3

          Yes, and even if you have smartcard infrastructure and can make your users use one, browser UX is horrible. For example, in Chrome, if your certificate is expired, the browser won’t tell you that, unless you have the browser console open. Another issue is the (in theory) simple problem of “logging a user out”, so that say, they can hand their computer to another person and let them login to the same site under a different identity. Chrome caches the client certificate and does not provide an API for clearing that cache:


          In the world where you control your user’s full desktop experience and they have to use your software, you can say, “quit the browser to logout,” but that’s not an acceptable user experience for a commercial website.

          Of course it’s easy to imagine that Chrome would prioritize these issues if usage was more common but it’s clear that most commercials orgs in the industry are not in the mood to be the early adopters here on behalf of their users.

        1. 24

          I’m the original designer of the Atreus; happy to answer any questions.

          1. 1

            Why do you choose a fixed Split keyboard, instead of an adjustable split keyboard?

            I can’t find the reason in your blog post neither in Atreus repository.


            • Fixed split, I mean such Atreus.
            • Adjustable split, I mean such ErgoDox.
            1. 1

              Found. https://technomancy.us/172 Thanks for a very thorough history, reasoning, and decision.

              I work from local coffee shops frequently, and the Advantage is just too clunky to toss in a bag and tote around.

              Update: I’ve designed by own keyboard, which is meant to be a smaller, more travel-friendly complement to the Ergodox that shares a lot of its characteristics.

            2. 1

              Do you find it difficult to switch back and forth between the Atreus and a standard keyboard? I would be concerned that, given time, that it would be problematic given how many keys on the Atreus require using a layer. Would switch between keyboard types cause me to focus too much on the typing and not what I am typing.

              1. 4

                I’ve found that the weirder the weird keyboard is, the easier it is to switch between the weird one and a normal one. I used to use a standard qwerty 60% keyboard at work, with lots special bindings/layers, and a normal laptop at home. This was constantly problematic because I’d try to use my special arrow key bindings and they obviously didn’t work anywhere.

                I’ve since switched to a kinesis for “work” (now my desk) and I no longer have any problems typing on my laptop because it’s so much different in every way. I also got an atreus and played around with it for a bit and I feel like it is likely in the “weird enough to be okay” territory due to the non-staggered key layout (forgot the technical term for this)

                The only exception to this rule is that I can hardly use a computer if caps-lock isn’t bound to control, but that’s a different problem.

                1. 1

                  I actually do this. Surprisingly enough, switching is mostly painless. I use Colemak on all keyboards, and muscle memory works itself out somehow, at least 95%.

                  1. 1

                    My experience as a laptop user is that even though I greatly prefer the Atreus, having to plug it into my laptop means that I don’t use it 100% of the time; sometimes I’ll open my laptop for something really quick and won’t get the external keyboard plugged in. This is infrequent, but for me it has been enough for me to maintain my ability to type on a conventional keyboard.

                    However, if you only very rarely use a laptop, this might not apply; can’t speak to that.

                  2. 1

                    How easy is it to use a three-finger chord key? I have a keyboardio model 1 and find that three-finger chords - in particular the alt-shift-arrows that I use all the time in Eclipse - become an effectively impossible to type four-finger chord (since arrow keys need a modifier).

                    1. 1

                      Depends on which three fingers! I’ve been using ctrl-alt-letter chords since long before building the Atreus, because I’m an Emacs user. I don’t use any programs which require you to hold down shift while moving the cursor, so I can’t really say authoritatively, but alt-shift-arrows sounds like a key chord I would like to rebind to something less awkward even on a conventional keyboard.

                      If that was a combo I had to use a lot and could not fix in software for some reason, I would probably remap my keyboard so that the alt key was adjacent to the shift key so that a single thumb could hit both.

                    2. 1

                      Got mine one month ago and I’m experimenting different layouts. I’m quite happy with just the main layer and a symbols+numbers+f-keys layer, and I still have a bunch of unused keys in the second layer.

                      The software is nice, but I wish it allowed sending macros (for typing accented characters using a non-international US keymap, for instance). I might try menelaus at some point if you think it can handle that.

                      The article mentions it was designed with a resting position for the pinkies at Z and ‘/’ in mind. Is that correct? I might experiment with that configuration using them also as shift modifiers when pressed.

                      1. 1

                        The software is nice, but I wish it allowed sending macros (for typing accented characters using a non-international US keymap, for instance).

                        I’m like … 99% sure that this limitation is part of the GUI frontend, not the underlying firmware implementation itself. So the path of least resistance would be to build Kaleidoscope.

                        I might try menelaus at some point if you think it can handle that.

                        It definitely can’t handle that out of the box, but depending on your relative familiarity with C++ toolchains vs Scheme, it could conceivably be easier to implement that functionality to Menelaus vs configuring that as existing functionality in Kaleidoscope. Only one way to find out!

                        1. 1

                          What about the last bit? Do you rest the pinkies at Z and /?

                          1. 1

                            Oh, no I keep them on A and semicolon normally, but I hit the outermost top keys with my ring finger instead of the pinky. The pinky only hits A/Z and semicolon/slash (well, the dvorak equivalents of where those are on qwerty) and occasionally enter/esc; tho I usually use Ctrl-m instead of the enter key since it sends the ASCII equivalent of enter.

                    1. 33

                      Someone on Reddit put it best:

                      Java devs never fail to be parodies of themselves.

                      This is so spot on.

                      Java is actually a good language, it’s the ecosystem that kills it for me. By “the ecosystem”, I don’t just mean the tooling (e.g. Java build tools are universally awful AFAICT), but the developers themselves. So much Java I read is just “magic”. Magic annotations, magic dependency injection, interfaces over classes that there is only one of etc. etc.

                      The author points out very good failures in the way its been architected, but the code in the OP isn’t all that strange looking to me as Java, and that’s a pretty damning statement.

                      I wish Java had a better audience around it. The Kotlin ecosystem seems better, but I’ve never used it.

                      1. 25

                        (edit: my first pass at this came off a little overly negative in a way that I think betrays the seriousness of my point)

                        I’m not sure Java actually is a good language. My first introduction to Java was as the primarily language that was used in college, and even as a pretty green programmer them (I’d started writing C and C++ a few years earlier in high school, but I was definitely not a good programmer), I found it awfully questionable. In the intervening 15 years I’ve managed to avoid it, until quite recently. It’s been really eye-opening to see how the language has evolved in that time, but not really in a good way. Perhaps it’s because I’ve largely written OOP off as a bad idea that shouldn’t have ever taken off like it did, and is certainly outstaying it’s welcome, but I find that Java, and even the JVM itself, to be a masters class in solving the wrong problem in the most complex possible way. The complexity in java seems to be like glitter, you can’t touch anything with getting covered in it, and once it’s on you you’ll never get it off. Even working with people that I generally hold in high regard as developers, I see that the ecosystem has forced them into patterns and architecture that I think is questionable- except it’s not because to do anything better would be to try to work against every single design decision in the language and ecosystem. There’s simply no reasonable way to write good Java, the best you can reasonably hope for is to write as little java as possible, and hope the absurd complexity giltter doesn’t spread to all of your connected services by way of the blind “the whole world is Java” assumptions that the JVM ecosystem wants to make on your behalf.

                        I say Java here, but realistically I think that all JVM languages end up falling into the same gravitational well. I’ve been using Kotlin lately, and from what I’ve seen of Scala and Clojure they are all infected by the same inescabable fractally wrong view of the world that is imposed by the JVM, by way of the JVM itself being born from the primordeal ooze of bad decisions and oop-kool-aid that led to Java in the first place. Kotlin in particular suffers from being not only unable to escape the Java ecosystem, but also from generally being a poorly designed language. Everything it adds to java, it adds in such a superficial and impotent way that a slight breeze knocks over the facade and you realize you’re stuck back in the Kingdom of the Nouns all over again.

                        1. 7

                          I tend to agree about the java part. The constructs at your disposal requires you to write very very verbose code, even for simple things. But I disagree about the JVM bit. I find it a pretty good runtime system. Although it tend to eat its fair share of RAM, the GCs and the JIT are first class. Overall, you get pretty decent perf without too much thought. Also, Having written a lot of clojure, it’s vastly different from java, couldn’t be further from the Kingdom of the Nouns.

                          1. 14

                            The JVM feels to me like it was written for a world that just didn’t really ever happen. It promised cross platform compatibility, that never really materialized since there are only two real meaningful places where the jvm is heavily used these days (x86 linux servers and arm Linux phones). Even where the jvm itself is running on multiple platforms, it’s not running the same workloads across it. We would have been every bit as well off with a toolset that made native cross compilation feasible (go and rust), and probably would have been no worse off even with the old C and C++ cross compilation story. Love it or hate it, JavaScript is what actually fulfilled the promises that java made and never was able to keep.

                            Other promises that JVM made either never made sense- language interoperability always existed before java, and exists outside of it now. All the JVM did was fracture the environment by making it nearly impossible to produce native code- it’s a vampire if you look at it in terms of interoperability, unless you want to use gcc to compile your java code. The isolation and runtime management is, consistently, 90% of the work involved in deploying any java application I’ve used, and at the end of the day everyone does that work twice now because most workloads are getting deployed in cloud native containers anyway- so the JVM is superfluous there. GC is a pain in the JVM and has been done as well elsewhere without requiring the rest of the baggage of its runtime and jitter.

                            Looking at performance, I’m dubious that it has much going for it. It’s still not a contender in the same space as C or C++, and in many cases the pain of native interop make it slower than even python because python can rely on native code for a lot of heavy lifting. I’ve even seen fairly well optimized JVM code fail to keep up with reasonably (perf) naive Haskell.

                            Even with instrumentation, the supposed killer feature of the jvm, I have yet to see anything I can’t get out of a native application with native tooling and instrumentation, and the case is getting weaker by the day as more and more application telemetry moves up and down the stack away from the application itself and into either tracing layers in front of services, or tooling built around things like ebpf that live very low down in the system and allow you to instrument everything.

                            The JVM is at best a middle-of-the road performance language with a largely superfluous ecosystem. It might have been a good idea when it was created, and I have no doubt a lot of smart engineering went into its implementation, but it’s time we give it up and realize it’s a sunken cost that we need to leave to the history books as a quirky artifact of the peculiar compute and business environment of the early 90s.

                            1. 3

                              Clojure’s okay (and still way better than Java, IMO) but suffers from pretty poor error handling compared to other Lisp environments.

                            2. 4

                              I really don’t like how Java makes optimization of its runtime overcomplicated, then has the gall to make you deal with the complexity. There is no reason to be manually tuning GC and heap sizes when every other runtime, including CLR implementations, can deal with this efficiently and automatically. They might be complex, unlike the JVM, they’re not complex and making you deal with that complexity.

                              1. 3

                                Just curious what you dislike about Kotlin’s design? It seems like you make two points: that Kotlin can’t escape Java and, separately, that it’s poorly designed. I agree with the former, but in light of the former, I find Kotlin to be pretty well-designed. They fixed Java’s horrible nullness issues and even kludged in free functions to the JVM, which is neat. Data classes are a band-aid, but still help for the 80% of cases where they can apply. Same with sealed classes (I’d much prefer pattern matching akin to Rust, Swift, OCaml).

                                1. 13

                                  My biggest issue is that everything feels like a kluge. Null tracking at the type level is fine, but they didn’t really go far enough with the syntax to make it as useful as it could have been- rust does better here by allowing you to lift values from an error context inside of a function. The language tries to push you toward immutability with val and var, but it’s superficial because you’re getting immutable references to largely mutable data structures without even getting a convenient deep copy. Extension methods are a fine way of adding capabilities to an object, but you can’t use them to fulfill an interface ala go, or outright extend a class with an interface implementation ala Haskell typeclasses, so you’re left with basically a pile of functions that swap an explicit argument for a this reference, and in the process you are conceptually adding a lot of complexity to the interface of an object with no good associated abstraction mechanism to be explicit about it. Even the nature of the language as a cross platform language that can target jvm, llvm, and web asm seems fundamentally flawed because in practice the language itself seems to lack enough of a stand alone ecosystem to ever be viable when it’s not being backed up by the jvm, and even if you did have a native or web ecosystem the design choices they made seem to be, as far as I can tell, about the worst approach I’ve ever seen to cross platform interoperability.

                                  Ultimately the features they’ve added all follow this pattern of having pulled a good idea from elsewhere but having an implementation that seems to not fulfill the deeper reason for the feature. The only underlying principle seems to be “make java suck less”. That is, of course, a bar buried so low in the ground it’s in danger of being melted by the earths core, and I would say they did cross over that bar- kotlin does suck less than Java, but what’s astonishing to me is how for such a low bar they still seem to have managed to cross over it just barely.

                                  1. 4

                                    I share every single one of those sentiments, but I’ve excused many of them specifically because of the limitations of being a JVM language. (interfaces at class definition, no const, no clones)

                                    I’ve almost taken it upon myself to periodically go and correct people in the Kotlin subreddit that val does not make things immutable, and that Kotlin has not cured the need for defensive copies in getters.

                                    I think the idea of making Kotlin cross-platform is totally stupid for those same reasons you point out. All of that is a limitation of wanting to be on the JVM and/or close to Java semantics. Why they hell would you want to export that to non-JVM platforms?

                                    Thanks for the response.

                              2. 12

                                I have a completely opposite opinion. Java is not the best language out there, I prefer Scala and Kotlin, but the selling point for me is the ecosystem: great tooling (tools simply work in lots of cases), great platform (lots of platforms are covered, really awesome backward compatibility, stability), great API (it might be far fetched, but I have a feeling that Java’s stdlib is one of the most feature-packed runtimes out there, if not the most?). The “magic” is the same problem as everywhere else; it’s magic until you know the details. Also just because there’s a dependency injection trend in the backend development world, it doesn’t mean that you should use DI in different projects. Interfaces of classes are a Java thing; it wouldn’t exist if the language was more sophisticated.

                                Maybe I’m comparing Java’s ecosystem to C++ – because with C/C++, the tooling is in appalling state, the standard library is awful and I’m not sure what it tries to achieve at times. So I guess I have a very low standards to compare to :P

                                1. 3

                                  Java has an incredibly rich ecosystem, that’s true. What annoys me though, is that every single tool in the Java ecosystem is written in Java, meaning you have a ton of CLI programs which take a couple of seconds just to heat up the JVM. Once the JVM is hot and ready to actually do work, the task is over and all that JIT work is lost.

                                  At least C/C++ tooling is fast :p

                                  1. 2

                                    That’s true, JVM startup time is a pain point. But there are several walkarounds for that:

                                    • some tools use build server approach (gradle), so that startup time is less slow ;)
                                    • some tools like sbt (scala build tool) use build server + shell approach, and it’s possible to use a thin client to invoke a command on this build server (e.g. ‘sbt-client’ written in rust). This makes Scala compilation take less time than compiling a C++ application.
                                    • GraalVM native-image is pushed right now, which allows to compile JVM (java, kotlin, scala) application to native code without the use of JRE. This allows writing tools that have non-noticeable startup time, just like tools written in e.g. Go. I was testing some of my small tools with it and it was able to compile a small Clojure app to native code. This tool had same startup speed than a C++ application. Unfortunately, GraalVM can’t compile every app yet, but they’re working on it ;)

                                    Also C/C++ tooling is fast, but C++ compilation is nowhere near being fast. Changing one header file often means recompilation of the first half of the project. Bad build system (e.g. in manually written Makefiles) that doesn’t track dependencies properly sometimes produces invalid binaries that fail at runtime, because some of the compilation units weren’t recompiled when they should be. It can be a real mess.

                                2. 10

                                  I wish Java had a better audience around it.

                                  That doesn’t seem terribly likely to happen.

                                  1. Java was never aimed at programmers who value power, succinctness, and simplicity - or programmers who want to explore paradigms other than OO (although newer versions of the lanaguage seem to be somewhat relaxing the Kingdom of Nouns[1] restrictions). It was intended to improve the lives of C++ programmers and their ilk[2].

                                  2. Java is frequently used in large, corporate, environments where programmers are considered (and treated as) fungible. “The new COBOL”, as it were[3].

                                  3. The JVM itself allows programmers not falling into (1) and (2) to abandon the Java language itself - Clojure, Scala, Kotlin, and Armed Bear Common Lisp spring (heh) to mind. Most of the best JVM programmers I know aren’t actually using Java. Most of the ‘Java shops’ I’ve worked with in the past decade are now, really, ‘JVM shops’.

                                  My observation is that most - to be clear, not all - people who continue using Java in 2020 are forced to do so by legacy codebases, and / or companies that won’t let them adopt new languages, even JVM languages. I honestly believe this is the proximate cause of the audience problem you describe. (Not the root cause, mind you).

                                  Edited: I’m amused by the fact that the first two, nearly concurrent, replies both reference Yegge’s nouns blog post :)

                                  [1] http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html

                                  [2] “We were after the C++ programmers. We managed to drag a lot of them about halfway to Lisp.” - Gosling. http://www.paulgraham.com/icad.html

                                  [3] https://www.infoworld.com/article/3438158/is-java-the-next-cobol.html

                                  1. 5

                                    Java is a horrible language. No mortal can mentally hold on to a class hierarchy where inheritance is more than a few levels deep. Furthermore it is a bad way to add “another layer of abstraction” , because it just paints you more and more into a corner.

                                    (Clojure is a great language, you can add layers of abstraction to solve problems, without just digging yourself deeper.)

                                    1. 3

                                      But one can write Java programs without abusing inheritance, and even pretty much without inheritance.

                                      1. 1

                                        Yes. I agree that Java is a horrible language, but class inheritance doesn’t even make the list of things I find poor about it.

                                    2. 3

                                      I don’t agree that Java is a good language at all, but I wanted to hard-agree at the distaste for magic annotations and DI frameworks.

                                      1. 1

                                        Java is actually a good language, it’s the ecosystem that kills it for me. By “the ecosystem”, I don’t just mean the tooling (e.g. Java build tools are universally awful AFAICT), but the developers themselves. So much Java I read is just “magic”. Magic annotations, magic dependency injection, interfaces over classes that there is only one of etc. etc.

                                        I don’t agree with this - in my experience, “magic” is “code that integrates my application-specific functionality with a massively feature-rich general purpose framework”. It’s magic in the sense that you need to understand the enclosing framework to understand why those annotations are there and their semantics, but they do real work. Work I’d have to do myself if I didn’t use them.

                                        You don’t see this much in other languages, but it’s because “massively feature-rich general purpose frameworks” aren’t common outside of Java. The ones that do exist seem to have punted on important architectural decisions - you don’t need a dependency injection framework if your data layer objects are just global values (I’m looking at you, Django).

                                        I’ve definitely felt this urge before - why do I need all this spring crap? Then I end up re-implementing half of that magic myself and not as well.

                                        1. 1

                                          What language has tooling that you like? Curious what you are comparing the Java build tools with

                                          1. 2

                                            Rust and Go (at least since Go modules) I find both intuitive and fast. I am still not sure how to properly build a Java application without an IDE.

                                            1. 1

                                              $ ./gradlew build

                                        1. 3

                                          Any variable that holds a scalar value must have the units in the name. In other words, you should never have a variable named timeout. You always need to know the units, and you’re going to get it wrong if it’s not right in your face. Even if you think it’s obvious from the context, it won’t be. Naming it timeoutSeconds is going to save you hours of debugging.

                                          (Possibly, this doesn’t apply to languages that can embed that information in the type system. Although even then I’m not sure…)

                                          1. 8

                                            Advent of Code day 1.

                                            1. 1

                                              Me too! My test this year is to write it in Pharo Smalltalk

                                              1. 1

                                                Me too! Day one is done, now i need to learn how to check Smalltalk code into git. The alien environment takes getting used to, but you get glimpses of why people love it.

                                                1. 1

                                                  I’m still stuck on problem two. I have one method day1p2 and make heavy use of lambda blocks. I hope it’s idiomatic enough.

                                                  Are temporary vars in the traditional railroad tracks of python idiomatic? I don’t think so…

                                                  Edit! Found a solution! I hope it’s idiomatic…

                                            1. 16

                                              If you like awk and sed (and other unix tools designed to be inserted into a pipeline), the best tool for json isn’t jq, it’s gron (https://github.com/TomNomNom/gron). gron turns tree-structured json into the line structured data that unix tools expect and allows you to search and edit it using familiar tools like sed, rather than having to learn jq’s mini-language (that I have to look up every time I need it).

                                              It creates a one-per-line entry for each field with a dot-separated hierarchical key.

                                              $ echo '{"name": "mark", "age": 49}' | gron
                                              json = {};
                                              json.age = 49;
                                              json.name = "mark";

                                              gron -u undo’s gron-formatted data back into json, so you can make pipelines like <json source> | gron | <commands in pipeline> | gron -u.

                                              For example:

                                              $ echo '{"name": "mark", "age": 49}' | gron | grep age | gron -u
                                                "age": 49
                                              1. 2

                                                I do prefer it over jq, but the = and ; in the output are annoying.

                                                1. 2
                                              1. 3

                                                Most of these I install via Chocolatey. It’s not clear to me if that’s something you’ll be able to do, though. This is my standard Windows toolset and with it I don’t really miss *nix that much.

                                                Gvim (plus exuberant ctags) - of course

                                                ConsoleZ - a better Windows console. It can get confused by resizes, but it’s otherwise great. I prefer it to conemu because it has “copy on select” and “copy word on double click”

                                                Clink - This gives me vi mode in a command prompt and usable tab-completion.

                                                UnxUtils - I prefer this to cygwin or WSL because it does things the Windows way - in particular, it understands backslashes for directory separators and drive letters - so it works better with the rest of the Windows ecosystem, which isn’t going to understand filenames that start with /mnt/d.

                                                I usually install a Windows gawk too - it’s not part of UnxUtils. And I use the ssh/scp from Window Git or WSL if I need it.

                                                1. 2


                                                  “Test source folders will be preselected in the New JUnit Test Case-Wizard”

                                                  YAAY!!! This has been a (minor) annoyance for a long time. Eclipse defaulted to putting my tests in src/main/java instead of src/test/java for maven projects, and fixing it required me to tab back through a good dozen controls or switch to the mouse. Every time I made a new test case.

                                                  This is going to save me many, many seconds.

                                                  1. 10

                                                    This feels spot on. Whenever I get inspired to try to fix something I don’t like about Eclipse, I spend a few hours hacking and then get so discouraged fighting the complexity that I give up. The only good documentation is for the deprecated 3.x API. The 4.x API is much more complex and I can’t see any advantage to it.

                                                    It’s really a shame, because Eclipse seems like a better Java editor than IntelliJ to me, which is why I still use it. Writing Java in Eclipse feels totally different than any other language/editor experience - I’m manipulating Java syntactic elements rather than editing text. The shift-alt-arrow “select java syntactic element” operation is the best example. Instead of selecting by text-editor concepts like “word” or “line”, it’s selecting by Java concepts, like block or method call. I couldn’t find the equivalent operation in IntelliJ

                                                    There’s a quote by someone like Martin Fowler where he says that he’d like an editor that works exclusively by ADT transforms (I couldn’t find the exact quote). At it’s best, Eclipse feels like that. I assume that’s what Lisp people feel like when using paredit.

                                                    But wow, is the rest of the experience janky as hell. I’ve maintained RCP apps before, I’ve been writing Java since the 90s, and it’s open source, so in theory I should be able to fix the problems I see. If it weren’t so complex underneath, I’m sure it would still be winning.